compositor-drm: support 10bit NV12 dmabuf import
Upstream-Status: Inappropriate [i.MX-specific]
Signed-off-by: Haihua Hu <jared.hu@nxp.com>
diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index a2c8f67..0648796 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -3198,6 +3198,42 @@
}
}
+/**
+ * Test if drm driver can import dmabuf
+ *
+ * called by compositor when a dmabuf comes to test if this buffer
+ * can used by drm driver directly
+ */
+static bool
+drm_import_dmabuf(struct weston_compositor *compositor,
+ struct linux_dmabuf_buffer *dmabuf)
+{
+ struct drm_backend *b = to_drm_backend(compositor);
+ struct drm_plane *p;
+ uint64_t has_prime;
+ uint32_t i;
+ int ret;
+
+ ret = drmGetCap (b->drm.fd, DRM_CAP_PRIME, &has_prime);
+ if (ret || !(bool) (has_prime & DRM_PRIME_CAP_IMPORT)) {
+ weston_log("drm backend not support import DMABUF\n");
+ return false;
+ }
+
+ wl_list_for_each(p, &b->plane_list, link) {
+ if (p->type != WDRM_PLANE_TYPE_OVERLAY)
+ continue;
+
+ for (i = 0; i < p->count_formats; i++) {
+ if (p->formats[i].format == dmabuf->attributes.format
+ && dmabuf->attributes.format == DRM_FORMAT_P010)
+ return true;
+ }
+ }
+
+ return false;
+}
+
#ifdef HAVE_DRM_ATOMIC
static void
atomic_flip_handler(int fd, unsigned int frame, unsigned int sec,
@@ -7179,6 +7215,7 @@
b->base.repaint_cancel = drm_repaint_cancel;
b->base.create_output = drm_output_create;
b->base.query_dmabuf_formats = drm_query_dmabuf_formats;
+ b->base.import_dmabuf = drm_import_dmabuf;
weston_setup_vt_switch_bindings(compositor);
diff --git a/libweston/compositor.c b/libweston/compositor.c
index 1c4c386..50c4f8e 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -6699,8 +6699,15 @@
struct linux_dmabuf_buffer *buffer)
{
struct weston_renderer *renderer;
+ struct weston_backend *backend;
renderer = compositor->renderer;
+ backend = compositor->backend;
+
+ /* first try backend import, if fail, fallback to render import */
+ if (backend->import_dmabuf)
+ if(backend->import_dmabuf(compositor, buffer))
+ return true;
if (renderer->import_dmabuf == NULL)
return false;
diff --git a/libweston/compositor.h b/libweston/compositor.h
index 51c569f..3e1dc1e 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -1032,6 +1032,8 @@
void (*query_dmabuf_formats)(struct weston_compositor* compositor,
int **formats, int *num_formats);
+ bool (*import_dmabuf)(struct weston_compositor* compositor,
+ struct linux_dmabuf_buffer *dmabuf);
};
/** Callback for saving calibration
diff --git a/libweston/gl-renderer.c b/libweston/gl-renderer.c
index eade1b2..a926cc3 100644
--- a/libweston/gl-renderer.c
+++ b/libweston/gl-renderer.c
@@ -2269,6 +2269,20 @@
int i;
int ret;
+ /**
+ * if backend can handle dmabuf directly, then we only need set
+ * size to buffer.
+ * */
+ if (surface->compositor->backend->import_dmabuf) {
+ struct weston_compositor *compositor = surface->compositor;
+ struct weston_backend *backend = surface->compositor->backend;
+ if (backend->import_dmabuf(compositor, dmabuf)){
+ buffer->width = dmabuf->attributes.width;
+ buffer->height = dmabuf->attributes.height;
+ return;
+ }
+ }
+
if (!gr->has_dmabuf_import) {
linux_dmabuf_buffer_send_server_error(dmabuf,
"EGL dmabuf import not supported");
diff --git a/libweston/pixel-formats.c b/libweston/pixel-formats.c
index df84a9f..1ea1b19 100644
--- a/libweston/pixel-formats.c
+++ b/libweston/pixel-formats.c
@@ -265,6 +265,12 @@
.vsub = 2,
},
{
+ .format = DRM_FORMAT_P010,
+ .num_planes = 2,
+ .hsub = 2,
+ .vsub = 2,
+ },
+ {
.format = DRM_FORMAT_NV21,
SAMPLER_TYPE(EGL_TEXTURE_Y_UV_WL),
.num_planes = 2,