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,