From 49ac60e3469700d53605403dc90c2a9bde1596dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 25 Nov 2021 17:15:54 +0100 Subject: [PATCH] cogl/renderer: Add 'is_dma_buf_supported()' vfunc Returns TRUE if the active renderer backend can allocate DMA buffers. This is the case hardware accelerated GBM backends, but FALSE for surfaceless (i.e. no render node) and EGLDevice (legacy NVIDIA paths). While software based gbm devices can allocate DMA buffers, we don't want to allocate them for offscreen rendering, as we really only use these for inter process transfers, and as buffers allocated for scanout doesn't use the relevant API, making it return FALSE for these solves that. Part-of: --- cogl/cogl/cogl-renderer.c | 11 +++++++++ cogl/cogl/cogl-renderer.h | 10 ++++++++ cogl/cogl/winsys/cogl-winsys-private.h | 28 ++++++++++++++-------- src/backends/native/meta-renderer-native.c | 23 ++++++++++++++++++ 4 files changed, 62 insertions(+), 10 deletions(-) diff --git a/cogl/cogl/cogl-renderer.c b/cogl/cogl/cogl-renderer.c index 5b37d8634..38f7a36d7 100644 --- a/cogl/cogl/cogl-renderer.c +++ b/cogl/cogl/cogl-renderer.c @@ -773,6 +773,17 @@ cogl_renderer_create_dma_buf (CoglRenderer *renderer, return NULL; } +gboolean +cogl_renderer_is_dma_buf_supported (CoglRenderer *renderer) +{ + const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer); + + if (winsys->renderer_is_dma_buf_supported) + return winsys->renderer_is_dma_buf_supported (renderer); + else + return FALSE; +} + void cogl_renderer_bind_api (CoglRenderer *renderer) { diff --git a/cogl/cogl/cogl-renderer.h b/cogl/cogl/cogl-renderer.h index 70910c07b..eef0e40ad 100644 --- a/cogl/cogl/cogl-renderer.h +++ b/cogl/cogl/cogl-renderer.h @@ -419,6 +419,16 @@ cogl_renderer_create_dma_buf (CoglRenderer *renderer, int height, GError **error); + +/** + * cogl_renderer_is_dma_buf_supported: (skip) + * @renderer: A #CoglRenderer + * + * Returns: %TRUE if DMA buffers can be allocated + */ +COGL_EXPORT gboolean +cogl_renderer_is_dma_buf_supported (CoglRenderer *renderer); + /** * cogl_renderer_bind_api: (skip) */ diff --git a/cogl/cogl/winsys/cogl-winsys-private.h b/cogl/cogl/winsys/cogl-winsys-private.h index b323a704d..45aec7ea6 100644 --- a/cogl/cogl/winsys/cogl-winsys-private.h +++ b/cogl/cogl/winsys/cogl-winsys-private.h @@ -73,11 +73,12 @@ typedef struct _CoglWinsysVtable GCallback (*renderer_get_proc_address) (CoglRenderer *renderer, - const char *name, - gboolean in_core); + const char *name, + gboolean in_core); gboolean - (*renderer_connect) (CoglRenderer *renderer, GError **error); + (*renderer_connect) (CoglRenderer *renderer, + GError **error); void (*renderer_disconnect) (CoglRenderer *renderer); @@ -86,7 +87,8 @@ typedef struct _CoglWinsysVtable (*renderer_outputs_changed) (CoglRenderer *renderer); gboolean - (*display_setup) (CoglDisplay *display, GError **error); + (*display_setup) (CoglDisplay *display, + GError **error); void (*display_destroy) (CoglDisplay *display); @@ -97,11 +99,15 @@ typedef struct _CoglWinsysVtable int height, GError **error); + gboolean + (*renderer_is_dma_buf_supported) (CoglRenderer *renderer); + void (*renderer_bind_api) (CoglRenderer *renderer); gboolean - (*context_init) (CoglContext *context, GError **error); + (*context_init) (CoglContext *context, + GError **error); void (*context_deinit) (CoglContext *context); @@ -115,15 +121,15 @@ typedef struct _CoglWinsysVtable (*texture_pixmap_x11_free) (CoglTexturePixmapX11 *tex_pixmap); gboolean - (*texture_pixmap_x11_update) (CoglTexturePixmapX11 *tex_pixmap, + (*texture_pixmap_x11_update) (CoglTexturePixmapX11 *tex_pixmap, CoglTexturePixmapStereoMode stereo_mode, - gboolean needs_mipmap); + gboolean needs_mipmap); void (*texture_pixmap_x11_damage_notify) (CoglTexturePixmapX11 *tex_pixmap); CoglTexture * - (*texture_pixmap_x11_get_texture) (CoglTexturePixmapX11 *tex_pixmap, + (*texture_pixmap_x11_get_texture) (CoglTexturePixmapX11 *tex_pixmap, CoglTexturePixmapStereoMode stereo_mode); #endif @@ -131,10 +137,12 @@ typedef struct _CoglWinsysVtable (*fence_add) (CoglContext *ctx); gboolean - (*fence_is_complete) (CoglContext *ctx, void *fence); + (*fence_is_complete) (CoglContext *ctx, + void *fence); void - (*fence_destroy) (CoglContext *ctx, void *fence); + (*fence_destroy) (CoglContext *ctx, + void *fence); } CoglWinsysVtable; diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index d63ac23bf..28ea94e9d 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -970,6 +970,27 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer, return NULL; } +static gboolean +meta_renderer_native_is_dma_buf_supported (CoglRenderer *cogl_renderer) +{ + CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; + MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform; + MetaRenderDevice *render_device = renderer_gpu_data->render_device; + + switch (renderer_gpu_data->mode) + { + case META_RENDERER_NATIVE_MODE_GBM: + return meta_render_device_is_hardware_accelerated (render_device); + case META_RENDERER_NATIVE_MODE_SURFACELESS: +#ifdef HAVE_EGL_DEVICE + case META_RENDERER_NATIVE_MODE_EGL_DEVICE: +#endif + return FALSE; + } + + g_assert_not_reached (); +} + static gboolean meta_renderer_native_init_egl_context (CoglContext *cogl_context, GError **error) @@ -1114,6 +1135,8 @@ get_native_cogl_winsys_vtable (CoglRenderer *cogl_renderer) vtable.renderer_connect = meta_renderer_native_connect; vtable.renderer_disconnect = meta_renderer_native_disconnect; vtable.renderer_create_dma_buf = meta_renderer_native_create_dma_buf; + vtable.renderer_is_dma_buf_supported = + meta_renderer_native_is_dma_buf_supported; vtable_inited = TRUE; }