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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4061>
This commit is contained in:
Sebastian Wick 2024-10-02 18:21:19 +02:00 committed by Marge Bot
parent aea9afa6ec
commit f467a31d56
5 changed files with 88 additions and 0 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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");
}