From cc16cd5aa4578dc09057eed120e799c0d43ff21b Mon Sep 17 00:00:00 2001 From: Anton Kindestam Date: Thu, 9 Nov 2017 09:54:28 +0100 Subject: video: probe format of primary plane in drm/egl context We need to support hardware/drivers which do not support ARGB8888 in their primary plane. We also use p->primary_plane_format when creating the gbm surface, to make sure it always matches (in actuality there should be little difference). --- video/out/opengl/context_drm_egl.c | 62 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/video/out/opengl/context_drm_egl.c b/video/out/opengl/context_drm_egl.c index 3526e2bdf6..61913091d8 100644 --- a/video/out/opengl/context_drm_egl.c +++ b/video/out/opengl/context_drm_egl.c @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -71,6 +72,8 @@ struct priv { struct gbm gbm; struct framebuffer *fb; + uint32_t primary_plane_format; + bool active; bool waiting_for_flip; @@ -122,7 +125,7 @@ static bool init_gbm(struct ra_ctx *ctx) p->gbm.device, p->kms->mode.hdisplay, p->kms->mode.vdisplay, - GBM_FORMAT_XRGB8888, + p->primary_plane_format, // drm_fourcc.h defs should be gbm-compatible GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); if (!p->gbm.surface) { MP_ERR(ctx->vo, "Failed to create GBM surface.\n"); @@ -155,8 +158,13 @@ static void update_framebuffer_from_bo(struct ra_ctx *ctx, struct gbm_bo *bo) uint32_t stride = gbm_bo_get_stride(bo); uint32_t handle = gbm_bo_get_handle(bo).u32; - int ret = drmModeAddFB(fb->fd, fb->width, fb->height, - 32, 32, stride, handle, &fb->id); + int ret = drmModeAddFB2(fb->fd, fb->width, fb->height, + p->primary_plane_format, + (uint32_t[4]){handle, 0, 0, 0}, + (uint32_t[4]){stride, 0, 0, 0}, + (uint32_t[4]){0, 0, 0, 0}, + &fb->id, 0); + if (ret) { MP_ERR(ctx->vo, "Failed to create framebuffer: %s\n", mp_strerror(errno)); } @@ -328,6 +336,49 @@ static void drm_egl_uninit(struct ra_ctx *ctx) } } +// If primary plane supports ARGB8888 we want to use that, but if it doesn't we +// fall back on XRGB8888. If the driver does not support atomic there is no +// particular reason to be using ARGB8888, so we fall back to XRGB8888 (another +// reason is that we do not have the convenient atomic_ctx and its convenient +// primary_plane field). +static bool probe_primary_plane_format(struct ra_ctx *ctx) +{ + struct priv *p = ctx->priv; + if (!p->kms->atomic_context) { + p->primary_plane_format = DRM_FORMAT_XRGB8888; + MP_VERBOSE(ctx->vo, "Not using DRM Atomic: Use DRM_FORMAT_XRGB8888 for primary plane.\n"); + return true; + } + + drmModePlane *drmplane = + drmModeGetPlane(p->kms->fd, p->kms->atomic_context->primary_plane->id); + bool have_argb8888 = false; + bool have_xrgb8888 = false; + bool result = false; + for (unsigned int i = 0; i < drmplane->count_formats; ++i) { + if (drmplane->formats[i] == DRM_FORMAT_ARGB8888) { + have_argb8888 = true; + } else if (drmplane->formats[i] == DRM_FORMAT_XRGB8888) { + have_xrgb8888 = true; + } + } + + if (have_argb8888) { + p->primary_plane_format = DRM_FORMAT_ARGB8888; + MP_VERBOSE(ctx->vo, "DRM_FORMAT_ARGB8888 supported by primary plane.\n"); + result = true; + } else if (have_xrgb8888) { + p->primary_plane_format = DRM_FORMAT_XRGB8888; + MP_VERBOSE(ctx->vo, + "DRM_FORMAT_ARGB8888 not supported by primary plane: " + "Falling back to DRM_FORMAT_XRGB8888.\n"); + result = true; + } + + drmModeFreePlane(drmplane); + return result; +} + static bool drm_egl_init(struct ra_ctx *ctx) { if (ctx->opts.probing) { @@ -355,6 +406,11 @@ static bool drm_egl_init(struct ra_ctx *ctx) return false; } + if (!probe_primary_plane_format(ctx)) { + MP_ERR(ctx->vo, "No suitable format found on DRM primary plane.\n"); + return false; + } + if (!init_gbm(ctx)) { MP_ERR(ctx->vo, "Failed to setup GBM.\n"); return false; -- cgit v1.2.3