From f467a31d56b503101eaa28e31bfa85c5da07a785 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Wed, 2 Oct 2024 18:21:19 +0200 Subject: [PATCH] onscreen: Get device and window handle for onscreens This adds a new method which returns the device and window handle for onscreen framebuffers. Renderdoc uses those handles to target what it is going to capture. Part-of: --- cogl/cogl/cogl-onscreen.c | 13 +++++++++++ cogl/cogl/cogl-onscreen.h | 9 ++++++++ cogl/cogl/winsys/cogl-onscreen-glx.c | 21 +++++++++++++++++ cogl/cogl/winsys/cogl-onscreen-xlib.c | 18 +++++++++++++++ src/backends/native/meta-onscreen-native.c | 27 ++++++++++++++++++++++ 5 files changed, 88 insertions(+) diff --git a/cogl/cogl/cogl-onscreen.c b/cogl/cogl/cogl-onscreen.c index 2ecb28a4f..155445774 100644 --- a/cogl/cogl/cogl-onscreen.c +++ b/cogl/cogl/cogl-onscreen.c @@ -516,3 +516,16 @@ cogl_onscreen_get_frame_counter (CoglOnscreen *onscreen) return priv->frame_counter; } + +gboolean +cogl_onscreen_get_window_handles (CoglOnscreen *onscreen, + gpointer *device_out, + gpointer *window_out) +{ + CoglOnscreenClass *klass = COGL_ONSCREEN_GET_CLASS (onscreen); + + if (!klass->get_window_handles) + return FALSE; + + return klass->get_window_handles (onscreen, device_out, window_out); +} diff --git a/cogl/cogl/cogl-onscreen.h b/cogl/cogl/cogl-onscreen.h index c6ca0a3d0..d6cd6b2e0 100644 --- a/cogl/cogl/cogl-onscreen.h +++ b/cogl/cogl/cogl-onscreen.h @@ -78,6 +78,10 @@ struct _CoglOnscreenClass GError **error); int (* get_buffer_age) (CoglOnscreen *onscreen); + + gboolean (* get_window_handles) (CoglOnscreen *onscreen, + gpointer *device_out, + gpointer *window_out); }; /** @@ -402,4 +406,9 @@ cogl_onscreen_remove_frame_callback (CoglOnscreen *onscreen, COGL_EXPORT int64_t cogl_onscreen_get_frame_counter (CoglOnscreen *onscreen); +COGL_EXPORT gboolean +cogl_onscreen_get_window_handles (CoglOnscreen *onscreen, + gpointer *device_out, + gpointer *window_out); + G_END_DECLS diff --git a/cogl/cogl/winsys/cogl-onscreen-glx.c b/cogl/cogl/winsys/cogl-onscreen-glx.c index eadccfaac..25e480559 100644 --- a/cogl/cogl/winsys/cogl-onscreen-glx.c +++ b/cogl/cogl/winsys/cogl-onscreen-glx.c @@ -528,6 +528,26 @@ cogl_onscreen_glx_get_buffer_age (CoglOnscreen *onscreen) return age; } +static gboolean +cogl_onscreen_glx_get_window_handles (CoglOnscreen *onscreen, + gpointer *device_out, + gpointer *window_out) +{ + CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer); + CoglXlibRenderer *xlib_renderer = + _cogl_xlib_renderer_get_data (cogl_context->display->renderer); + GLXDrawable drawable; + + drawable = onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; + + *device_out = xlib_renderer->xdpy; + *window_out = (gpointer) drawable; + + return TRUE; +} + static void cogl_onscreen_glx_flush_notification (CoglOnscreen *onscreen) { @@ -1067,4 +1087,5 @@ cogl_onscreen_glx_class_init (CoglOnscreenGlxClass *klass) cogl_onscreen_glx_swap_buffers_with_damage; onscreen_class->swap_region = cogl_onscreen_glx_swap_region; onscreen_class->get_buffer_age = cogl_onscreen_glx_get_buffer_age; + onscreen_class->get_window_handles = cogl_onscreen_glx_get_window_handles; } diff --git a/cogl/cogl/winsys/cogl-onscreen-xlib.c b/cogl/cogl/winsys/cogl-onscreen-xlib.c index 8e74297ab..f036dc507 100644 --- a/cogl/cogl/winsys/cogl-onscreen-xlib.c +++ b/cogl/cogl/winsys/cogl-onscreen-xlib.c @@ -170,6 +170,22 @@ cogl_onscreen_xlib_allocate (CoglFramebuffer *framebuffer, return parent_class->allocate (framebuffer, error); } +static gboolean +cogl_onscreen_xlib_get_window_handles (CoglOnscreen *onscreen, + gpointer *device_out, + gpointer *window_out) +{ + CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (onscreen); + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer); + CoglDisplayEGL *cogl_display_egl = cogl_context->display->winsys; + + *device_out = cogl_display_egl->egl_context; + *window_out = (gpointer) onscreen_xlib->xwin; + + return TRUE; +} + static void cogl_onscreen_xlib_dispose (GObject *object) { @@ -259,8 +275,10 @@ cogl_onscreen_xlib_class_init (CoglOnscreenXlibClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); CoglFramebufferClass *framebuffer_class = COGL_FRAMEBUFFER_CLASS (klass); + CoglOnscreenClass *onscreen_class = COGL_ONSCREEN_CLASS (klass); object_class->dispose = cogl_onscreen_xlib_dispose; framebuffer_class->allocate = cogl_onscreen_xlib_allocate; + onscreen_class->get_window_handles = cogl_onscreen_xlib_get_window_handles; } diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c index 2eaeb2141..74ff112d6 100644 --- a/src/backends/native/meta-onscreen-native.c +++ b/src/backends/native/meta-onscreen-native.c @@ -1734,6 +1734,32 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen, return TRUE; } +static gboolean +meta_onscreen_native_get_window_handles (CoglOnscreen *onscreen, + gpointer *device_out, + gpointer *window_out) +{ + MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer); + CoglDisplayEGL *cogl_display_egl = cogl_context->display->winsys; + gpointer window = NULL; + + if (onscreen_native->gbm.surface) + window = onscreen_native->gbm.surface; +#ifdef HAVE_EGL_DEVICE + else if (onscreen_native->egl.stream) + window = onscreen_native->egl.stream; +#endif + + if (!window) + return FALSE; + + *device_out = cogl_display_egl->egl_context; + *window_out = window; + return TRUE; +} + static void add_onscreen_frame_info (MetaCrtc *crtc) { @@ -2944,6 +2970,7 @@ meta_onscreen_native_class_init (MetaOnscreenNativeClass *klass) onscreen_class->swap_buffers_with_damage = meta_onscreen_native_swap_buffers_with_damage; onscreen_class->direct_scanout = meta_onscreen_native_direct_scanout; + onscreen_class->get_window_handles = meta_onscreen_native_get_window_handles; blit_source_quark = g_quark_from_static_string ("Blit source"); }