mirror of https://github.com/mpv-player/mpv
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).
This commit is contained in:
parent
04e5fbde43
commit
cc16cd5aa4
|
@ -25,6 +25,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <gbm.h>
|
#include <gbm.h>
|
||||||
|
#include <drm_fourcc.h>
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
#include <EGL/eglext.h>
|
#include <EGL/eglext.h>
|
||||||
|
|
||||||
|
@ -71,6 +72,8 @@ struct priv {
|
||||||
struct gbm gbm;
|
struct gbm gbm;
|
||||||
struct framebuffer *fb;
|
struct framebuffer *fb;
|
||||||
|
|
||||||
|
uint32_t primary_plane_format;
|
||||||
|
|
||||||
bool active;
|
bool active;
|
||||||
bool waiting_for_flip;
|
bool waiting_for_flip;
|
||||||
|
|
||||||
|
@ -122,7 +125,7 @@ static bool init_gbm(struct ra_ctx *ctx)
|
||||||
p->gbm.device,
|
p->gbm.device,
|
||||||
p->kms->mode.hdisplay,
|
p->kms->mode.hdisplay,
|
||||||
p->kms->mode.vdisplay,
|
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);
|
GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
|
||||||
if (!p->gbm.surface) {
|
if (!p->gbm.surface) {
|
||||||
MP_ERR(ctx->vo, "Failed to create GBM surface.\n");
|
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 stride = gbm_bo_get_stride(bo);
|
||||||
uint32_t handle = gbm_bo_get_handle(bo).u32;
|
uint32_t handle = gbm_bo_get_handle(bo).u32;
|
||||||
|
|
||||||
int ret = drmModeAddFB(fb->fd, fb->width, fb->height,
|
int ret = drmModeAddFB2(fb->fd, fb->width, fb->height,
|
||||||
32, 32, stride, handle, &fb->id);
|
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) {
|
if (ret) {
|
||||||
MP_ERR(ctx->vo, "Failed to create framebuffer: %s\n", mp_strerror(errno));
|
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)
|
static bool drm_egl_init(struct ra_ctx *ctx)
|
||||||
{
|
{
|
||||||
if (ctx->opts.probing) {
|
if (ctx->opts.probing) {
|
||||||
|
@ -355,6 +406,11 @@ static bool drm_egl_init(struct ra_ctx *ctx)
|
||||||
return false;
|
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)) {
|
if (!init_gbm(ctx)) {
|
||||||
MP_ERR(ctx->vo, "Failed to setup GBM.\n");
|
MP_ERR(ctx->vo, "Failed to setup GBM.\n");
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in New Issue