libweston: Add the ability to determine if a dmabuf is scanout-capable
authorMarius Vlad <marius.vlad@collabora.com>
Sat, 16 Nov 2019 18:26:52 +0000 (20:26 +0200)
committerMarius Vlad <marius.vlad@collabora.com>
Thu, 21 Nov 2019 11:54:50 +0000 (13:54 +0200)
Adds a new callback 'can_scanout_dmabuf' in weston_backend, which
can be set by the back-end do determine if the buffer supplied can be
imported directly by KMS.

This patch adds a wrapper over it, 'weston_compositor_dmabuf_can_scanout'
which is called before importing the dmabuf in the GPU if the
direct_display dmabuf is being set. If that's true and the check
failed, we refuse to create a wl_buffer.

This patch avoids importing in the GPU.

Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
libweston/backend.h
libweston/compositor.c
libweston/libweston-internal.h
libweston/linux-dmabuf.c

index baf670738b027e0307ddc1a8723c658e14aa3eb5..ff10b3631284d72e6211c837075ca91179365cb0 100644 (file)
@@ -95,6 +95,18 @@ struct weston_backend {
         */
        void (*device_changed)(struct weston_compositor *compositor,
                               dev_t device, bool added);
+
+       /** Verifies if the dmabuf can be used directly/scanned-out by the HW.
+        *
+        * @param compositor The compositor.
+        * @param buffer The dmabuf to verify.
+        *
+        * Determines if the buffer can be imported directly by the display
+        * controller/HW. Back-ends can use this to check if the supplied
+        * buffer can be scanned-out, as to void importing it into the GPU.
+        */
+       bool (*can_scanout_dmabuf)(struct weston_compositor *compositor,
+                                  struct linux_dmabuf_buffer *buffer);
 };
 
 /* weston_head */
index 55f43af4fa218db7a5021517c1ddd9d25a6e8a72..3531a21315f4a8a339782fc86e3ba2eaf8475138 100644 (file)
@@ -7519,6 +7519,18 @@ weston_compositor_import_dmabuf(struct weston_compositor *compositor,
        return renderer->import_dmabuf(compositor, buffer);
 }
 
+WL_EXPORT bool
+weston_compositor_dmabuf_can_scanout(struct weston_compositor *compositor,
+               struct linux_dmabuf_buffer *buffer)
+{
+       struct weston_backend *backend = compositor->backend;
+
+       if (backend->can_scanout_dmabuf == NULL)
+               return false;
+
+       return backend->can_scanout_dmabuf(compositor, buffer);
+}
+
 WL_EXPORT void
 weston_version(int *major, int *minor, int *micro)
 {
index 2099f3bce8d8af55ba6c34f10791c66449c7b584..66c38e86fa323dd00bab4a2d00f3e13730936326 100644 (file)
@@ -79,6 +79,9 @@ weston_compositor_add_pending_output(struct weston_output *output,
 bool
 weston_compositor_import_dmabuf(struct weston_compositor *compositor,
                                struct linux_dmabuf_buffer *buffer);
+bool
+weston_compositor_dmabuf_can_scanout(struct weston_compositor *compositor,
+                                       struct linux_dmabuf_buffer *buffer);
 void
 weston_compositor_offscreen(struct weston_compositor *compositor);
 
index 48b16e16fa1b53bda08206737018d7f5f0b416f8..796e982664e76419f01d909d71a927700114d3a5 100644 (file)
@@ -259,9 +259,18 @@ params_create_common(struct wl_client *client,
                }
        }
 
+       if (buffer->direct_display) {
+               if (!weston_compositor_dmabuf_can_scanout(buffer->compositor,
+                                                         buffer))
+                       goto err_failed;
+
+               goto avoid_gpu_import;
+       }
+
        if (!weston_compositor_import_dmabuf(buffer->compositor, buffer))
                goto err_failed;
 
+avoid_gpu_import:
        buffer->buffer_resource = wl_resource_create(client,
                                                     &wl_buffer_interface,
                                                     1, buffer_id);
@@ -368,6 +377,7 @@ linux_dmabuf_create_params(struct wl_client *client,
                wl_resource_create(client,
                                   &zwp_linux_buffer_params_v1_interface,
                                   version, params_id);
+       buffer->direct_display = false;
        if (!buffer->params_resource)
                goto err_dealloc;