summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorAnton Kindestam <antonki@kth.se>2017-11-09 09:54:28 +0100
committerJan Ekström <jeebjp@gmail.com>2017-12-03 17:30:17 +0200
commitcc16cd5aa4578dc09057eed120e799c0d43ff21b (patch)
treec4924aa1f94a34cd45d0846c5356715c7aa1e5cc /video
parent04e5fbde438fffdbf60fe70ed1918cceb1c46244 (diff)
downloadmpv-cc16cd5aa4578dc09057eed120e799c0d43ff21b.tar.bz2
mpv-cc16cd5aa4578dc09057eed120e799c0d43ff21b.tar.xz
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).
Diffstat (limited to 'video')
-rw-r--r--video/out/opengl/context_drm_egl.c62
1 files 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 <unistd.h>
#include <gbm.h>
+#include <drm_fourcc.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
@@ -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;