37#include <EGL/eglext.h>
40#include <drm_fourcc.h>
42#include <xf86drmMode.h>
76 *resources = drmModeGetResources(fd);
77 if (*resources == NULL) {
78 LOGERROR(
"drmdevice: %s: cannot retrieve DRM resources (%d): %m", __FUNCTION__, errno);
93 if (drmGetCap(fd, DRM_CAP_DUMB_BUFFER, &test) < 0 || test == 0)
96 if (drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) != 0)
99 if (drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1) != 0)
102 if (drmGetCap(fd, DRM_CAP_PRIME, &test) < 0)
105 if (drmGetCap(fd, DRM_PRIME_CAP_EXPORT, &test) < 0)
108 if (drmGetCap(fd, DRM_PRIME_CAP_IMPORT, &test) < 0)
114#define MAX_DRM_DEVICES 64
123 int num_devices, fd = -1;
126 if (num_devices < 0) {
127 LOGERROR(
"drmdevice: %s: drmGetDevices2 failed: %s", __FUNCTION__, strerror(-num_devices));
131 for (
int i = 0; i < num_devices && fd < 0; i++) {
132 drmDevicePtr device = devices[i];
135 if (!(device->available_nodes & (1 << DRM_NODE_PRIMARY)))
137 fd = open(device->nodes[DRM_NODE_PRIMARY], O_RDWR);
153 drmFreeDevices(devices, num_devices);
156 LOGERROR(
"drmdevice: %s: no drm device found!", __FUNCTION__);
166 drmModeConnector *connector = NULL;
170 for (i = 0; i < resources->count_connectors; i++) {
171 connector = drmModeGetConnector(fd, resources->connectors[i]);
172 if (connector && connector->connection == DRM_MODE_CONNECTED)
174 drmModeFreeConnector(connector);
182 for (i = 0; i < resources->count_connectors; i++) {
183 connector = drmModeGetConnector(fd, resources->connectors[i]);
184 if (connector && connector->count_modes > 0)
186 drmModeFreeConnector(connector);
198 uint32_t objectType,
const char *propName, uint64_t *value)
202 drmModePropertyPtr Prop;
203 drmModeObjectPropertiesPtr objectProps =
204 drmModeObjectGetProperties(fdDrm, objectID, objectType);
206 for (i = 0; i < objectProps->count_props; i++) {
207 if ((Prop = drmModeGetProperty(fdDrm, objectProps->props[i])) == NULL)
208 LOGDEBUG2(
L_DRM,
"drmdevice: %s: Unable to query property", __FUNCTION__);
210 if (strcmp(propName, Prop->name) == 0) {
211 *value = objectProps->prop_values[i];
215 drmModeFreeProperty(Prop);
221 drmModeFreeObjectProperties(objectProps);
224 LOGDEBUG2(
L_DRM,
"drmdevice: %s: Unable to find value for property \'%s\'.", __FUNCTION__, propName);
238 drmModeRes *resources;
239 drmModeConnector *connector;
240 drmModeEncoder *encoder = NULL;
241 drmModeModeInfo *drmmode = NULL;
243 drmModePlaneRes *planeRes;
250 LOGERROR(
"drmdevice: %s: Could not open device!", __FUNCTION__);
254 LOGDEBUG2(
L_DRM,
"drmdevice: %s: fd: %d DRM have %i connectors, %i crtcs, %i encoders", __FUNCTION__,
255 m_fdDrm, resources->count_connectors, resources->count_crtcs,
256 resources->count_encoders);
261 LOGERROR(
"drmdevice: %s: cannot retrieve DRM connector (%d): %m", __FUNCTION__, errno);
268 for (i = 0; i < connector->count_modes; i++) {
269 drmModeModeInfo *current_mode = &connector->modes[i];
272 drmmode = current_mode;
273 LOGDEBUG2(
L_DRM,
"drmdevice: %s: Use user requested mode: %dx%d@%d", __FUNCTION__, drmmode->hdisplay, drmmode->vdisplay, drmmode->vrefresh);
278 LOGWARNING(
"drmdevice: %s: User requested mode not found, try default modes", __FUNCTION__);
281 uint32_t preferred_hz[3] = {50, 60, 0};
287 while (!drmmode && preferred_hz[j]) {
288 for (i = 0, width = 0; i < connector->count_modes; i++) {
289 drmModeModeInfo *current_mode = &connector->modes[i];
290 if (preferred_hz[j] && current_mode->vrefresh != preferred_hz[j])
293 int current_width = current_mode->hdisplay;
294 if (current_width > width) {
295 drmmode = current_mode;
296 width = current_width;
303 LOGDEBUG2(
L_DRM,
"drmdevice: %s: Use mode with the biggest width: %dx%d@%d", __FUNCTION__,
304 drmmode->hdisplay, drmmode->vdisplay, drmmode->vrefresh);
308 LOGERROR(
"drmdevice: %s: No monitor mode found! Probably no monitor connected, giving up!", __FUNCTION__);
315 for (i = 0; i < resources->count_encoders; i++) {
316 encoder = drmModeGetEncoder(
m_fdDrm, resources->encoders[i]);
317 if (encoder->encoder_id == connector->encoder_id)
319 drmModeFreeEncoder(encoder);
329 LOGERROR(
"drmdevice: %s: No crtc found!", __FUNCTION__);
337 for (i = 0; i < resources->count_crtcs; i++) {
338 if (resources->crtcs[i] ==
m_crtcId) {
349 LOGINFO(
"DRM Setup: Using Monitor Mode %dx%d@%.2fHz, m_crtcId %d crtc_idx %d",
352 drmModeFreeConnector(connector);
356 if ((planeRes = drmModeGetPlaneResources(
m_fdDrm)) == NULL) {
357 LOGERROR(
"drmdevice: %s: cannot retrieve PlaneResources (%d): %m", __FUNCTION__, errno);
369 std::vector<cDrmPlane> overlayNV12Candidates;
371 for (j = 0; j < planeRes->count_planes; j++) {
372 plane = drmModeGetPlane(
m_fdDrm, planeRes->planes[j]);
375 LOGERROR(
"drmdevice: %s: cannot query DRM-KMS plane %d", __FUNCTION__, j);
381 char pixelformats[256];
385 DRM_MODE_OBJECT_PLANE,
"type", &type)) {
386 LOGDEBUG2(
L_DRM,
"drmdevice: %s: Failed to get property 'type'", __FUNCTION__);
389 DRM_MODE_OBJECT_PLANE,
"zpos", &zpos)) {
390 LOGDEBUG2(
L_DRM,
"drmdevice: %s: Failed to get property 'zpos'", __FUNCTION__);
395 LOGDEBUG2(
L_DRM,
"drmdevice: %s: %s: id %i possible_crtcs %i", __FUNCTION__,
396 (type == DRM_PLANE_TYPE_PRIMARY) ?
"PRIMARY " :
397 (type == DRM_PLANE_TYPE_OVERLAY) ?
"OVERLAY " :
398 (type == DRM_PLANE_TYPE_CURSOR) ?
"CURSOR " :
"UNKNOWN",
399 plane->plane_id, plane->possible_crtcs);
400 strcpy(pixelformats,
" ");
403 for (k = 0; k < plane->count_formats; k++) {
404 if (encoder->possible_crtcs & plane->possible_crtcs) {
406 switch (plane->formats[k]) {
407 case DRM_FORMAT_NV12:
408 snprintf(tmp,
sizeof(tmp),
" %4.4s", (
char *)&plane->formats[k]);
409 strcat(pixelformats, tmp);
410 if (type == DRM_PLANE_TYPE_PRIMARY && !best_primary_video_plane.
GetId()) {
411 best_primary_video_plane.
SetId(plane->plane_id);
412 best_primary_video_plane.
SetType(type);
413 best_primary_video_plane.
SetZpos(zpos);
414 strcat(pixelformats,
"! ");
416 if (type == DRM_PLANE_TYPE_OVERLAY && !best_overlay_video_plane.
GetId()) {
417 best_overlay_video_plane.
SetId(plane->plane_id);
418 best_overlay_video_plane.
SetType(type);
419 best_overlay_video_plane.
SetZpos(zpos);
420 strcat(pixelformats,
"! ");
423 if (type == DRM_PLANE_TYPE_OVERLAY) {
425 cand.
SetId(plane->plane_id);
428 overlayNV12Candidates.push_back(cand);
431 case DRM_FORMAT_ARGB8888:
432 snprintf(tmp,
sizeof(tmp),
" %4.4s", (
char *)&plane->formats[k]);
433 strcat(pixelformats, tmp);
434 if (type == DRM_PLANE_TYPE_PRIMARY) {
435 best_primary_osd_plane.
SetId(plane->plane_id);
436 best_primary_osd_plane.
SetType(type);
437 best_primary_osd_plane.
SetZpos(zpos);
438 strcat(pixelformats,
"! ");
440 if (type == DRM_PLANE_TYPE_OVERLAY) {
441 best_overlay_osd_plane.
SetId(plane->plane_id);
442 best_overlay_osd_plane.
SetType(type);
443 best_overlay_osd_plane.
SetZpos(zpos);
444 strcat(pixelformats,
"! ");
454 drmModeFreePlane(plane);
458 if (best_primary_video_plane.
GetId() && best_overlay_osd_plane.
GetId()) {
467 }
else if (best_overlay_video_plane.
GetId() && best_primary_osd_plane.
GetId()) {
478 LOGERROR(
"drmdevice: %s: No suitable planes found!", __FUNCTION__);
484 for (
cDrmPlane &cand : overlayNV12Candidates) {
485 uint32_t pid = cand.
GetId();
488 if (!best_overlay_pip_plane.
GetId() || pid > best_overlay_pip_plane.
GetId()) {
489 best_overlay_pip_plane = cand;
493 if (best_overlay_pip_plane.
GetId()) {
499 LOGWARNING(
"drmdevice: %s: No suitable plane for Picture-in-Picture found. PIP will be disabled.", __FUNCTION__);
503 if (best_primary_video_plane.
GetId()) {
504 LOGDEBUG2(
L_DRM,
"drmdevice: %s: best_primary_video_plane: plane_id %d, type %s, zpos %" PRIu64
"", __FUNCTION__,
505 best_primary_video_plane.
GetId(), best_primary_video_plane.
GetType() == DRM_PLANE_TYPE_PRIMARY ?
"PRIMARY" :
"OVERLAY", best_primary_video_plane.
GetZpos());
507 if (best_overlay_video_plane.
GetId()) {
508 LOGDEBUG2(
L_DRM,
"drmdevice: %s: best_overlay_video_plane: plane_id %d, type %s, zpos %" PRIu64
"", __FUNCTION__,
509 best_overlay_video_plane.
GetId(), best_overlay_video_plane.
GetType() == DRM_PLANE_TYPE_PRIMARY ?
"PRIMARY" :
"OVERLAY", best_overlay_video_plane.
GetZpos());
511 if (best_primary_osd_plane.
GetId()) {
512 LOGDEBUG2(
L_DRM,
"drmdevice: %s: best_primary_osd_plane: plane_id %d, type %s, zpos %" PRIu64
"", __FUNCTION__,
513 best_primary_osd_plane.
GetId(), best_primary_osd_plane.
GetType() == DRM_PLANE_TYPE_PRIMARY ?
"PRIMARY" :
"OVERLAY", best_primary_osd_plane.
GetZpos());
515 if (best_overlay_osd_plane.
GetId()) {
516 LOGDEBUG2(
L_DRM,
"drmdevice: %s: best_overlay_osd_plane: plane_id %d, type %s, zpos %" PRIu64
"", __FUNCTION__,
517 best_overlay_osd_plane.
GetId(), best_overlay_osd_plane.
GetType() == DRM_PLANE_TYPE_PRIMARY ?
"PRIMARY" :
"OVERLAY", best_overlay_osd_plane.
GetZpos());
519 if (best_overlay_pip_plane.
GetId()) {
520 LOGDEBUG2(
L_DRM,
"drmdevice: %s: best_overlay_pip_plane: plane_id %d, type %s, zpos %" PRIu64
"", __FUNCTION__,
521 best_overlay_pip_plane.
GetId(), best_overlay_pip_plane.
GetType() == DRM_PLANE_TYPE_PRIMARY ?
"PRIMARY" :
"OVERLAY", best_overlay_pip_plane.
GetZpos());
549 strcpy(str_zpos,
"drmdevice: Init: zpos values are wrong, so ");
552 strcat(str_zpos,
"hardcode them to 0 and 1, because they are equal");
556 strcat(str_zpos,
"switch them");
564 if (drmSetMaster(
m_fdDrm) < 0) {
565 LOGDEBUG2(
L_DRM,
"drmdevice: Failed to set drm master, try authorize instead: {}", strerror(errno));
568 if (drmGetMagic(
m_fdDrm, &magic) < 0)
569 LOGFATAL(
"drmdevice: Failed to get drm magic: {}", strerror(errno));
571 if (drmAuthMagic(
m_fdDrm, magic) < 0)
572 LOGFATAL(
"drmdevice: Failed to authorize drm magic: {}", strerror(errno));
575 drmModeFreePlaneResources(planeRes);
576 drmModeFreeEncoder(encoder);
577 drmModeFreeResources(resources);
580 LOGINFO(
"DRM setup - CRTC: %i video_plane: %i (%s %" PRIu64
") osd_plane: %i (%s %" PRIu64
") pip_plane: %i (%s %" PRIu64
") m_useZpos: %d",
593 LOGINFO(
"DRM setup - CRTC: %i video_plane: %i (%s %" PRIu64
") osd_plane: %i (%s %" PRIu64
") m_useZpos: %d (pip disbled)",
609 if (InitGbm(
m_drmModeInfo.hdisplay,
m_drmModeInfo.vdisplay, DRM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING)) {
610 LOGERROR(
"drmdevice: %s: failed to init gbm device and surface!", __FUNCTION__);
616 LOGERROR(
"drmdevice: %s: failed to init egl!", __FUNCTION__);
636int cDrmDevice::InitGbm(
int w,
int h, uint32_t format, uint64_t modifier)
638 m_pGbmDevice = gbm_create_device(
m_fdDrm);
640 LOGERROR(
"drmdevice: %s: failed to create gbm device!", __FUNCTION__);
644 m_pGbmSurface = gbm_surface_create(m_pGbmDevice, w, h, format, modifier);
645 if (!m_pGbmSurface) {
646 LOGERROR(
"drmdevice: %s: failed to create %d x %d surface bo", __FUNCTION__, w, h);
653PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = NULL;
654PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC get_platform_surface = NULL;
656static const EGLint context_attribute_list[] =
658 EGL_CONTEXT_CLIENT_VERSION, 2,
665EGLConfig cDrmDevice::GetEGLConfig(
void)
667 EGLint config_attribute_list[] = {
669 EGL_STENCIL_SIZE, EGL_DONT_CARE,
670 EGL_DEPTH_SIZE, EGL_DONT_CARE,
671 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
672 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
675 EGLConfig *configs =
nullptr;
678 EGL_CHECK(eglGetConfigs(m_eglDisplay, NULL, 0, &count));
680 LOGFATAL(
"drmdevice: %s: no EGL configs to choose from", __FUNCTION__);
684 configs = (EGLConfig *)malloc(count *
sizeof(*configs));
686 LOGFATAL(
"drmdevice: %s: can't allocate space for EGL configs", __FUNCTION__);
688 EGL_CHECK(eglChooseConfig(m_eglDisplay, config_attribute_list, configs, count, &matched));
691 LOGFATAL(
"drmdevice: %s: no EGL configs with appropriate attributes", __FUNCTION__);
694 LOGDEBUG2(
L_OPENGL,
"drmdevice: %s: %d appropriate EGL configs found, which match attributes", __FUNCTION__, matched);
696 EGLConfig chosen = NULL;
697 for (
int i = 0; i < matched; ++i) {
699 EGL_CHECK(eglGetConfigAttrib(m_eglDisplay, configs[i], EGL_NATIVE_VISUAL_ID, &gbm_format));
701 if (gbm_format == GBM_FORMAT_ARGB8888) {
709 LOGFATAL(
"drmdevice: %s: no matching gbm config found", __FUNCTION__);
720int cDrmDevice::InitEGL(
void)
722 EGLint iMajorVersion, iMinorVersion;
724 PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress(
"eglGetPlatformDisplayEXT");
725 assert(get_platform_display != NULL);
726 PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC get_platform_surface = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)eglGetProcAddress(
"eglCreatePlatformWindowSurfaceEXT");
727 assert(get_platform_surface != NULL);
729 EGL_CHECK(m_eglDisplay = get_platform_display(EGL_PLATFORM_GBM_KHR, m_pGbmDevice, NULL));
731 LOGERROR(
"drmdevice: %s: failed to get eglDisplay", __FUNCTION__);
735 if (!eglInitialize(m_eglDisplay, &iMajorVersion, &iMinorVersion)) {
736 LOGERROR(
"drmdevice: %s: eglInitialize failed", __FUNCTION__);
740 LOGDEBUG2(
L_OPENGL,
"drmdevice: %s: Using display %p with EGL version %d.%d", __FUNCTION__, m_eglDisplay, iMajorVersion, iMinorVersion);
741 EGL_CHECK(
LOGDEBUG2(
L_OPENGL,
" EGL Version: \"%s\"", eglQueryString(m_eglDisplay, EGL_VERSION)));
742 EGL_CHECK(
LOGDEBUG2(
L_OPENGL,
" EGL Vendor: \"%s\"", eglQueryString(m_eglDisplay, EGL_VENDOR)));
743 EGL_CHECK(
LOGDEBUG2(
L_OPENGL,
" EGL Extensions: \"%s\"", eglQueryString(m_eglDisplay, EGL_EXTENSIONS)));
744 EGL_CHECK(
LOGDEBUG2(
L_OPENGL,
" EGL APIs: \"%s\"", eglQueryString(m_eglDisplay, EGL_CLIENT_APIS)));
746 EGLConfig eglConfig = GetEGLConfig();
748 EGL_CHECK(eglBindAPI(EGL_OPENGL_ES_API));
749 EGL_CHECK(m_eglContext = eglCreateContext(m_eglDisplay, eglConfig, EGL_NO_CONTEXT, context_attribute_list));
751 LOGERROR(
"drmdevice: %s: failed to create eglContext", __FUNCTION__);
755 EGL_CHECK(m_eglSurface = get_platform_surface(m_eglDisplay, eglConfig, m_pGbmSurface, NULL));
756 if (m_eglSurface == EGL_NO_SURFACE) {
757 LOGERROR(
"drmdevice: %s: failed to create eglSurface", __FUNCTION__);
761 EGLint s_width, s_height;
762 EGL_CHECK(eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_WIDTH, &s_width));
763 EGL_CHECK(eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_HEIGHT, &s_height));
765 LOGDEBUG2(
L_OPENGL,
"drmdevice: %s: GLSurface %p on EGLDisplay %p for %d x %d BO created", __FUNCTION__, m_eglSurface, m_eglDisplay, s_width, s_height);
767 m_glInitiated =
true;
768 LOGINFO(
"DRM Setup: EGL context initialized");
773static void drm_fb_destroy_callback(
struct gbm_bo *bo,
void *data)
775 int drm_fd = gbm_device_get_fd(gbm_bo_get_device(bo));
779 drmModeRmFB(drm_fd, buf->
Id());
784__attribute__ ((weak))
union gbm_bo_handle
785gbm_bo_get_handle_for_plane(struct gbm_bo *bo,
int plane);
787__attribute__ ((weak))
int
788gbm_bo_get_fd(
struct gbm_bo *bo);
790__attribute__ ((weak)) uint64_t
791gbm_bo_get_modifier(
struct gbm_bo *bo);
793__attribute__ ((weak))
int
794gbm_bo_get_plane_count(
struct gbm_bo *bo);
796__attribute__ ((weak)) uint32_t
797gbm_bo_get_stride_for_plane(
struct gbm_bo *bo,
int plane);
799__attribute__ ((weak)) uint32_t
800gbm_bo_get_offset(
struct gbm_bo *bo,
int plane);
809cDrmBuffer *cDrmDevice::GetBufFromBo(
struct gbm_bo *bo)
812 uint32_t mod_flags = 0;
819 buf =
new cDrmBuffer(
m_fdDrm, gbm_bo_get_width(bo), gbm_bo_get_height(bo), gbm_bo_get_format(bo), bo);
821 if (gbm_bo_get_handle_for_plane && gbm_bo_get_modifier &&
822 gbm_bo_get_plane_count && gbm_bo_get_stride_for_plane &&
824 uint64_t modifiers[4] = {0};
825 modifiers[0] = gbm_bo_get_modifier(bo);
826 const int num_planes = gbm_bo_get_plane_count(bo);
828 for (
int i = 0; i < num_planes; i++) {
829 buf->
SetHandle(i, gbm_bo_get_handle_for_plane(bo, i).u32);
830 buf->
SetPitch(i, gbm_bo_get_stride_for_plane(bo, i));
831 buf->
SetOffset(i, gbm_bo_get_offset(bo, i));
832 modifiers[i] = modifiers[0];
841 mod_flags = DRM_MODE_FB_MODIFIERS;
842 LOGDEBUG2(
L_DRM,
"drmdevice: %s: Using modifier %" PRIx64
"", __FUNCTION__, modifiers[0]);
854 LOGDEBUG2(
L_DRM,
"drmdevice: %s: Modifiers failed!", __FUNCTION__);
857 uint32_t tmpHandle[4] = { gbm_bo_get_handle(bo).u32, 0, 0, 0};
858 uint32_t tmpStride[4] = { gbm_bo_get_stride(bo), 0, 0, 0};
859 uint32_t tmpSize[4] = { buf->
Height() * buf->
Width() * buf->
Pitch(0), 0, 0, 0};
860 memcpy(buf->
PrimeHandle(), tmpHandle,
sizeof(tmpHandle));
861 memcpy(buf->
Pitch(), tmpStride,
sizeof(tmpStride));
862 memcpy(buf->
Size(), tmpSize,
sizeof(tmpSize));
863 memset(buf->
Offset(), 0, 16);
875 LOGFATAL(
"drmdevice: %s: cannot create framebuffer (%d): %m", __FUNCTION__, errno);
880 uint32_t pixFmt = buf->
PixFmt();
881 LOGDEBUG2(
L_DRM,
"drmdevice: %s: New GL buffer %d x %d pix_fmt %4.4s fb_id %d", __FUNCTION__,
884 gbm_bo_set_user_data(bo, buf, drm_fb_destroy_callback);
896 for (i = 0; i < resources->count_crtcs; i++) {
897 const uint32_t crtc_mask = 1 << i;
898 const uint32_t crtc_id = resources->crtcs[i];
899 if (encoder->possible_crtcs & crtc_mask) {
914 for (i = 0; i < connector->count_encoders; i++) {
915 const uint32_t encoder_id = connector->encoders[i];
916 drmModeEncoder *encoder = drmModeGetEncoder(
m_fdDrm, encoder_id);
920 drmModeFreeEncoder(encoder);
954 uint32_t objectID, uint32_t objectType,
955 const char *propName, uint64_t value)
959 drmModePropertyPtr Prop;
960 drmModeObjectPropertiesPtr objectProps =
961 drmModeObjectGetProperties(
m_fdDrm, objectID, objectType);
963 for (i = 0; i < objectProps->count_props; i++) {
964 if ((Prop = drmModeGetProperty(
m_fdDrm, objectProps->props[i])) == NULL)
965 LOGDEBUG2(
L_DRM,
"drmdevice: %s: Unable to query property", __FUNCTION__);
967 if (strcmp(propName, Prop->name) == 0) {
969 drmModeFreeProperty(Prop);
973 drmModeFreeProperty(Prop);
976 drmModeFreeObjectProperties(objectProps);
979 LOGDEBUG2(
L_DRM,
"drmdevice: %s Unable to find value for property \'%s\'.", __FUNCTION__, propName);
981 return drmModeAtomicAddProperty(ModeReq, objectID,
id, value);
void SetNumPlanes(int numPlanes)
void SetOffset(int idx, uint32_t offset)
void SetNumObjects(int numObjects)
void SetSize(int idx, uint32_t size)
void SetPitch(int idx, uint32_t pitch)
uint32_t PrimeHandle(int idx)
void SetHandle(int idx, uint32_t handle)
void SetObjectIndex(int idx, uint32_t objIdx)
void SetDmaBufHandle(uint32_t fd)
uint32_t m_userReqDisplayRefreshRate
user requested display refresh rate
int m_userReqDisplayHeight
user requested display height
drmModeModeInfo m_drmModeInfo
mode info
int CreatePropertyBlob(uint32_t *)
Creates a property blob.
cDrmPlane m_videoPlane
the video drm plane
cDrmDevice(cVideoRender *, const char *)
cDrmDevice constructor
int SetPropertyRequest(drmModeAtomicReqPtr, uint32_t, uint32_t, const char *, uint64_t)
Add a property to a request.
int32_t FindCrtcForConnector(const drmModeRes *, const drmModeConnector *)
Finds the CRTC_ID for the given connector.
int HandleEvent(void)
Polls for a drm event.
int m_userReqDisplayWidth
user requested display width
cDrmPlane m_pipPlane
the pip drm plane
drmModeCrtc * m_drmModeCrtcSaved
saved CRTC infos
int m_fdDrm
drm file descriptor
uint64_t m_zposPip
zpos of pip plane
void SaveCrtc(void)
Saves information of a CRTC.
~cDrmDevice(void)
cDrmDevice destructor
uint32_t m_connectorId
connector id
void RestoreCrtc(void)
Restore information of a CRTC.
void Close(void)
Close drm file handle.
uint32_t m_crtcId
current crtc ID
uint32_t m_crtcIndex
current crtc index
cVideoRender * m_pRender
pointer to cVideoRender object
int Init(void)
Initiate the drm device.
uint64_t m_zposPrimary
zpos of primary plane
drmEventContext m_drmEventCtx
drm event context
bool m_useZpos
is set, if drm hardware can use zpos
cDrmPlane m_osdPlane
the osd drm plane
void InitEvent(void)
Init the event context.
uint64_t m_zposOverlay
zpos of overlay plane
cDrmPlane - DRM plane class
int HasZpos(int)
Check, if the plane is able to set the zpos property.
void FillProperties(int)
Fill the plane properties.
void SetZpos(uint64_t zpos)
void SetType(uint64_t type)
cVideoRender - Video render class
void SetScreenSize(int, int, double)
Wrapper to set the screen size in the device.
static int TestCaps(int fd)
Test drm capabilities.
static int FindDrmDevice(drmModeRes **resources)
Find and open a suitable device with the wanted capabilities.
static int32_t FindCrtcForEncoder(const drmModeRes *resources, const drmModeEncoder *encoder)
Finds the CRTC_ID for the given encoder.
static int get_resources(int fd, drmModeRes **resources)
static int GetPropertyValue(int fdDrm, uint32_t objectID, uint32_t objectType, const char *propName, uint64_t *value)
Gets a property value.
static drmModeConnector * FindDrmConnector(int fd, drmModeRes *resources)
Find a suitable connector, preferably a connected one.
Logger class header file.
#define LOGFATAL
Logger macros.
Rendering class header file.