compositor-drm: report modifiers from drm-backend

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 bbdc80a..3ccb1bb 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -3217,6 +3217,56 @@
 	}
 }
 
+static void
+drm_query_dmabuf_modifiers (struct weston_compositor *compositor, int format,
+                               uint64_t **modifiers, int *num_modifiers)
+{
+       struct drm_backend *b = to_drm_backend(compositor);
+       struct drm_plane *p;
+       uint64_t has_prime;
+       uint32_t i, j;
+       int ret;
+
+       assert(modifiers);
+       assert(num_modifiers);
+
+       *num_modifiers = 0;
+
+       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;
+       }
+
+       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 != format)
+                               continue;
+
+                       if (p->formats[i].count_modifiers <= 0)
+                               continue;
+
+                       *modifiers = calloc(p->formats[i].count_modifiers, sizeof(uint64_t));
+                       if (*modifiers == NULL) {
+                               *num_modifiers = 0;
+                               return;
+                       }
+
+                       for (j = 0; j < p->formats[i].count_modifiers; j++) {
+                               (*modifiers)[j] = p->formats[i].modifiers[j];
+                       }
+                       *num_modifiers = p->formats[i].count_modifiers;
+               }
+
+               if (*num_modifiers > 0)
+                       break;
+       }
+}
+
 /**
  * Test if drm driver can import dmabuf
  *
@@ -7324,6 +7374,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.query_dmabuf_modifiers = drm_query_dmabuf_modifiers;
 	b->base.import_dmabuf = drm_import_dmabuf;
 
 	weston_setup_vt_switch_bindings(compositor);
diff --git a/libweston/compositor.h b/libweston/compositor.h
index 3e1dc1e..b9de5ef 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -1032,6 +1032,9 @@
 
 	void (*query_dmabuf_formats)(struct weston_compositor* compositor,
 					int **formats, int *num_formats);
+    void (*query_dmabuf_modifiers)(struct weston_compositor *compositor,
+                    int format, uint64_t **modifiers,
+                    int *num_modifiers);
 	bool (*import_dmabuf)(struct weston_compositor* compositor,
 					struct linux_dmabuf_buffer *dmabuf);
 };
diff --git a/libweston/linux-dmabuf.c b/libweston/linux-dmabuf.c
index d908b82..0f96e5f 100644
--- a/libweston/linux-dmabuf.c
+++ b/libweston/linux-dmabuf.c
@@ -527,14 +527,40 @@
 	free(formats);
 	formats = NULL;
 
-	if (compositor->backend->query_dmabuf_formats) {
+	if (compositor->backend->query_dmabuf_formats && compositor->backend->query_dmabuf_modifiers) {
 		compositor->backend->query_dmabuf_formats(compositor, &formats, &num_formats);
 
 		if (!formats)
 			return;
 
 		for (i = 0; i < num_formats; i++) {
-			zwp_linux_dmabuf_v1_send_format(resource, formats[i]);
+			compositor->backend->query_dmabuf_modifiers(compositor,
+							     formats[i],
+							     &modifiers,
+							     &num_modifiers);
+
+			/* send DRM_FORMAT_MOD_INVALID token when no modifiers are supported
+			 * for this format */
+			if (num_modifiers == 0) {
+				num_modifiers = 1;
+				modifiers = &modifier_invalid;
+			}
+			for (j = 0; j < num_modifiers; j++) {
+				if (version >= ZWP_LINUX_DMABUF_V1_MODIFIER_SINCE_VERSION) {
+					uint32_t modifier_lo = modifiers[j] & 0xFFFFFFFF;
+					uint32_t modifier_hi = modifiers[j] >> 32;
+					zwp_linux_dmabuf_v1_send_modifier(resource,
+									  formats[i],
+									  modifier_hi,
+									  modifier_lo);
+				} else if (modifiers[j] == DRM_FORMAT_MOD_LINEAR ||
+					   modifiers == &modifier_invalid) {
+					zwp_linux_dmabuf_v1_send_format(resource,
+									formats[i]);
+				}
+			}
+			if (modifiers != &modifier_invalid)
+				free(modifiers);
 		}
 		free(formats);
 	}