[mutter/gbsneto/dmabuf-screencast: 4/8] renderer-native: Implement onscreen DMABuf exporting



commit 555f28848f2701f401029a1e25b6ae8fd336c6d2
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Mon Dec 9 10:05:37 2019 -0300

    renderer-native: Implement onscreen DMABuf exporting
    
    Create a new gbm_bo using the same parameters of the onscreen, and export
    the new bo's DMA buffer fd. The new bo lives as long as necessary to be
    used, and reused, by PipeWire.
    
    Unfortunately, PipeWire doesn't support modifiers properly, so use the
    linear format for now. For now, a hardcoded format of DRM_FORMAT_XRGB8888
    is set, so we don't need to negotiate the format with PipeWire early.
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1086

 src/backends/native/meta-renderer-native.c | 71 ++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)
---
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 5a7fcd045..03f57cfc8 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -2394,6 +2394,76 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
   COGL_TRACE_END (MetaRendererNativePostKmsUpdate);
 }
 
+static CoglOnscreenDmabufHandle *
+meta_onscreen_native_capture_dmabuf (CoglOnscreen  *onscreen,
+                                     GError       **error)
+{
+  CoglContext *cogl_context = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglRenderer *cogl_renderer = cogl_context->display->renderer;
+  CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
+  MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform;
+  MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
+  CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
+  MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
+  MetaGpuKms *gpu_kms = onscreen_native->render_gpu;
+  int dmabuf_fd = -1;
+
+  renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
+                                                         gpu_kms);
+  switch (renderer_gpu_data->mode)
+    {
+    case META_RENDERER_NATIVE_MODE_GBM:
+      {
+        MetaDrmBufferGbm *drm_buffer_gbm;
+        CoglFramebuffer *dmabuf_fb;
+        struct gbm_bo *current_bo;
+        struct gbm_bo *new_bo;
+        uint32_t height;
+        uint32_t width;
+
+        drm_buffer_gbm = META_DRM_BUFFER_GBM (onscreen_native->gbm.current_fb);
+        current_bo = meta_drm_buffer_gbm_get_bo (drm_buffer_gbm);
+        width = gbm_bo_get_width (current_bo);
+        height = gbm_bo_get_height (current_bo);
+
+        new_bo = gbm_bo_create (renderer_gpu_data->gbm.device,
+                                width, height, DRM_FORMAT_XRGB8888,
+                                GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR);
+        dmabuf_fd = gbm_bo_get_fd (new_bo);
+
+        if (dmabuf_fd == -1)
+          {
+            g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS,
+                         "Failed to export dumb drm buffer: %s",
+                         g_strerror (errno));
+            return NULL;
+          }
+
+        dmabuf_fb = create_dmabuf_image (onscreen,
+                                         dmabuf_fd,
+                                         width, height,
+                                         gbm_bo_get_stride (current_bo),
+                                         gbm_bo_get_offset (current_bo, 0),
+                                         DRM_FORMAT_MOD_LINEAR,
+                                         DRM_FORMAT_XRGB8888,
+                                         error);
+
+        if (*error)
+          return NULL;
+
+        return cogl_onscreen_dmabuf_handle_new (dmabuf_fb, dmabuf_fd, new_bo,
+                                                (GDestroyNotify) gbm_bo_destroy);
+      }
+      break;
+#ifdef HAVE_EGL_DEVICE
+    case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
+      break;
+#endif
+    }
+
+  return NULL;
+}
+
 static gboolean
 meta_renderer_native_init_egl_context (CoglContext *cogl_context,
                                        GError     **error)
@@ -3201,6 +3271,7 @@ get_native_cogl_winsys_vtable (CoglRenderer *cogl_renderer)
       vtable.onscreen_swap_region = NULL;
       vtable.onscreen_swap_buffers_with_damage =
         meta_onscreen_native_swap_buffers_with_damage;
+      vtable.onscreen_capture_dmabuf = meta_onscreen_native_capture_dmabuf;
 
       vtable.context_get_clock_time = meta_renderer_native_get_clock_time;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]