forked from AuroraMiddleware/gtk
Merge branch 'wip/otte/display-gl' into 'master'
Add gdk_display_create_gl_context() See merge request GNOME/gtk!4083
This commit is contained in:
commit
883b2223c1
@ -646,7 +646,6 @@ create_cairo_texture (NodeEditorWindow *self)
|
||||
GskRenderer *renderer;
|
||||
GskRenderNode *node;
|
||||
GdkTexture *texture;
|
||||
GdkSurface *surface;
|
||||
|
||||
paintable = gtk_picture_get_paintable (GTK_PICTURE (self->picture));
|
||||
if (paintable == NULL ||
|
||||
@ -659,9 +658,8 @@ create_cairo_texture (NodeEditorWindow *self)
|
||||
if (node == NULL)
|
||||
return NULL;
|
||||
|
||||
surface = gtk_native_get_surface (gtk_widget_get_native (GTK_WIDGET (self)));
|
||||
renderer = gsk_cairo_renderer_new ();
|
||||
gsk_renderer_realize (renderer, surface, NULL);
|
||||
gsk_renderer_realize (renderer, NULL, NULL);
|
||||
|
||||
texture = gsk_renderer_render_texture (renderer, node, NULL);
|
||||
gsk_render_node_unref (node);
|
||||
@ -839,16 +837,18 @@ node_editor_window_add_renderer (NodeEditorWindow *self,
|
||||
GskRenderer *renderer,
|
||||
const char *description)
|
||||
{
|
||||
GdkSurface *surface;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
surface = gtk_native_get_surface (GTK_NATIVE (self));
|
||||
g_assert (surface != NULL);
|
||||
|
||||
if (renderer != NULL && !gsk_renderer_realize (renderer, surface, NULL))
|
||||
if (!gsk_renderer_realize (renderer, NULL, NULL))
|
||||
{
|
||||
g_object_unref (renderer);
|
||||
return;
|
||||
GdkSurface *surface = gtk_native_get_surface (GTK_NATIVE (self));
|
||||
g_assert (surface != NULL);
|
||||
|
||||
if (!gsk_renderer_realize (renderer, surface, NULL))
|
||||
{
|
||||
g_object_unref (renderer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
paintable = gtk_renderer_paintable_new (renderer, gtk_picture_get_paintable (GTK_PICTURE (self->picture)));
|
||||
|
@ -1325,6 +1325,38 @@ gdk_display_prepare_gl (GdkDisplay *self,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_display_create_gl_context:
|
||||
* @self: a `GdkDisplay`
|
||||
* @error: return location for an error
|
||||
*
|
||||
* Creates a new `GdkGLContext` for the `GdkDisplay`.
|
||||
*
|
||||
* The context is disconnected from any particular surface or surface
|
||||
* and cannot be used to draw to any surface. It can only be used to
|
||||
* draw to non-surface framebuffers like textures.
|
||||
*
|
||||
* If the creation of the `GdkGLContext` failed, @error will be set.
|
||||
* Before using the returned `GdkGLContext`, you will need to
|
||||
* call [method@Gdk.GLContext.make_current] or [method@Gdk.GLContext.realize].
|
||||
*
|
||||
* Returns: (transfer full) (nullable): the newly created `GdkGLContext`
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
GdkGLContext *
|
||||
gdk_display_create_gl_context (GdkDisplay *self,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (self), NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
if (!gdk_display_prepare_gl (self, error))
|
||||
return NULL;
|
||||
|
||||
return gdk_gl_context_new (self, NULL);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_display_get_gl_context:
|
||||
* @self: the `GdkDisplay`
|
||||
|
@ -71,6 +71,9 @@ gboolean gdk_display_supports_input_shapes (GdkDisplay *display);
|
||||
GDK_AVAILABLE_IN_4_4
|
||||
gboolean gdk_display_prepare_gl (GdkDisplay *self,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_4_6
|
||||
GdkGLContext *gdk_display_create_gl_context(GdkDisplay *self,
|
||||
GError **error);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDisplay *gdk_display_get_default (void);
|
||||
|
@ -276,7 +276,8 @@ gdk_draw_context_get_surface (GdkDrawContext *context)
|
||||
|
||||
/**
|
||||
* gdk_draw_context_begin_frame:
|
||||
* @context: the `GdkDrawContext` used to draw the frame
|
||||
* @context: the `GdkDrawContext` used to draw the frame. The context must
|
||||
* have a surface.
|
||||
* @region: minimum region that should be drawn
|
||||
*
|
||||
* Indicates that you are beginning the process of redrawing @region
|
||||
@ -308,7 +309,10 @@ void
|
||||
gdk_draw_context_begin_frame (GdkDrawContext *context,
|
||||
const cairo_region_t *region)
|
||||
{
|
||||
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
|
||||
|
||||
g_return_if_fail (GDK_IS_DRAW_CONTEXT (context));
|
||||
g_return_if_fail (priv->surface != NULL);
|
||||
g_return_if_fail (region != NULL);
|
||||
|
||||
gdk_draw_context_begin_frame_full (context, FALSE, region);
|
||||
@ -411,6 +415,7 @@ gdk_draw_context_end_frame (GdkDrawContext *context)
|
||||
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
|
||||
|
||||
g_return_if_fail (GDK_IS_DRAW_CONTEXT (context));
|
||||
g_return_if_fail (priv->surface != NULL);
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (priv->surface))
|
||||
return;
|
||||
|
@ -722,15 +722,19 @@ gdk_gl_context_init (GdkGLContext *self)
|
||||
|
||||
/* Must have called gdk_display_prepare_gl() before */
|
||||
GdkGLContext *
|
||||
gdk_gl_context_new_for_surface (GdkSurface *surface)
|
||||
gdk_gl_context_new (GdkDisplay *display,
|
||||
GdkSurface *surface)
|
||||
{
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkGLContext *shared = gdk_display_get_gl_context (display);
|
||||
GdkGLContext *shared;
|
||||
|
||||
g_assert (surface == NULL || display == gdk_surface_get_display (surface));
|
||||
|
||||
/* assert gdk_display_prepare_gl() had been called */
|
||||
shared = gdk_display_get_gl_context (display);
|
||||
g_assert (shared);
|
||||
|
||||
return g_object_new (G_OBJECT_TYPE (shared),
|
||||
"display", display,
|
||||
"surface", surface,
|
||||
NULL);
|
||||
}
|
||||
|
@ -99,7 +99,8 @@ gboolean gdk_gl_backend_can_be_used (GdkGLBackend
|
||||
GError **error);
|
||||
void gdk_gl_backend_use (GdkGLBackend backend_type);
|
||||
|
||||
GdkGLContext * gdk_gl_context_new_for_surface (GdkSurface *surface);
|
||||
GdkGLContext * gdk_gl_context_new (GdkDisplay *display,
|
||||
GdkSurface *surface);
|
||||
|
||||
gboolean gdk_gl_context_is_api_allowed (GdkGLContext *self,
|
||||
GdkGLAPI api,
|
||||
|
@ -1171,7 +1171,7 @@ gdk_surface_get_paint_gl_context (GdkSurface *surface,
|
||||
* Before using the returned `GdkGLContext`, you will need to
|
||||
* call [method@Gdk.GLContext.make_current] or [method@Gdk.GLContext.realize].
|
||||
*
|
||||
* Returns: (transfer full) (nullable): the newly created `GdkGLContext`
|
||||
* Returns: (transfer full): the newly created `GdkGLContext`
|
||||
*/
|
||||
GdkGLContext *
|
||||
gdk_surface_create_gl_context (GdkSurface *surface,
|
||||
@ -1183,7 +1183,7 @@ gdk_surface_create_gl_context (GdkSurface *surface,
|
||||
if (!gdk_display_prepare_gl (surface->display, error))
|
||||
return NULL;
|
||||
|
||||
return gdk_gl_context_new_for_surface (surface);
|
||||
return gdk_gl_context_new (surface->display, surface);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -90,12 +90,10 @@ gsk_gl_renderer_realize (GskRenderer *renderer,
|
||||
GskGLRenderer *self = (GskGLRenderer *)renderer;
|
||||
GdkGLContext *context = NULL;
|
||||
GskGLDriver *driver = NULL;
|
||||
GdkDisplay *display;
|
||||
gboolean ret = FALSE;
|
||||
gboolean debug_shaders = FALSE;
|
||||
|
||||
g_assert (GSK_IS_GL_RENDERER (self));
|
||||
g_assert (GDK_IS_SURFACE (surface));
|
||||
|
||||
if (self->context != NULL)
|
||||
return TRUE;
|
||||
|
||||
@ -103,8 +101,18 @@ gsk_gl_renderer_realize (GskRenderer *renderer,
|
||||
g_assert (self->context == NULL);
|
||||
g_assert (self->command_queue == NULL);
|
||||
|
||||
if (!(context = gdk_surface_create_gl_context (surface, error)) ||
|
||||
!gdk_gl_context_realize (context, error))
|
||||
if (surface == NULL)
|
||||
{
|
||||
display = gdk_display_get_default (); /* FIXME: allow different displays somehow ? */
|
||||
context = gdk_display_create_gl_context (display, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
display = gdk_surface_get_display (surface);
|
||||
context = gdk_surface_create_gl_context (surface, error);
|
||||
}
|
||||
|
||||
if (!context || !gdk_gl_context_realize (context, error))
|
||||
goto failure;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
@ -112,7 +120,7 @@ gsk_gl_renderer_realize (GskRenderer *renderer,
|
||||
debug_shaders = TRUE;
|
||||
#endif
|
||||
|
||||
if (!(driver = gsk_gl_driver_for_display (gdk_surface_get_display (surface), debug_shaders, error)))
|
||||
if (!(driver = gsk_gl_driver_for_display (display, debug_shaders, error)))
|
||||
goto failure;
|
||||
|
||||
self->command_queue = gsk_gl_driver_create_command_queue (driver, context);
|
||||
|
@ -59,7 +59,8 @@ gsk_cairo_renderer_realize (GskRenderer *renderer,
|
||||
{
|
||||
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
|
||||
|
||||
self->cairo_context = gdk_surface_create_cairo_context (surface);
|
||||
if (surface)
|
||||
self->cairo_context = gdk_surface_create_cairo_context (surface);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ static GParamSpec *gsk_renderer_properties[N_PROPS];
|
||||
|
||||
static gboolean
|
||||
gsk_renderer_real_realize (GskRenderer *self,
|
||||
GdkSurface *surface,
|
||||
GdkSurface *surface,
|
||||
GError **error)
|
||||
{
|
||||
GSK_RENDERER_WARN_NOT_IMPLEMENTED_METHOD (self, realize);
|
||||
@ -189,12 +189,12 @@ gsk_renderer_class_init (GskRendererClass *klass)
|
||||
/**
|
||||
* GskRenderer:realized: (attributes org.gtk.Property.get=gsk_renderer_is_realized)
|
||||
*
|
||||
* Whether the renderer has been associated with a surface.
|
||||
* Whether the renderer has been associated with a surface or draw context.
|
||||
*/
|
||||
gsk_renderer_properties[PROP_REALIZED] =
|
||||
g_param_spec_boolean ("realized",
|
||||
"Realized",
|
||||
"The renderer has been associated with a surface",
|
||||
"The renderer has been associated with a surface or draw context",
|
||||
FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
@ -281,11 +281,14 @@ gsk_renderer_is_realized (GskRenderer *renderer)
|
||||
/**
|
||||
* gsk_renderer_realize:
|
||||
* @renderer: a `GskRenderer`
|
||||
* @surface: the `GdkSurface` renderer will be used on
|
||||
* @surface: (nullable): the `GdkSurface` renderer will be used on
|
||||
* @error: return location for an error
|
||||
*
|
||||
* Creates the resources needed by the @renderer to render the scene
|
||||
* graph.
|
||||
*
|
||||
* Since GTK 4.6, the surface may be `NULL`, which allows using
|
||||
* renderers without having to create a surface.
|
||||
*/
|
||||
gboolean
|
||||
gsk_renderer_realize (GskRenderer *renderer,
|
||||
@ -296,10 +299,11 @@ gsk_renderer_realize (GskRenderer *renderer,
|
||||
|
||||
g_return_val_if_fail (GSK_IS_RENDERER (renderer), FALSE);
|
||||
g_return_val_if_fail (!gsk_renderer_is_realized (renderer), FALSE);
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (surface), FALSE);
|
||||
g_return_val_if_fail (surface == NULL || GDK_IS_SURFACE (surface), FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
priv->surface = g_object_ref (surface);
|
||||
if (surface)
|
||||
priv->surface = g_object_ref (surface);
|
||||
|
||||
if (!GSK_RENDERER_GET_CLASS (renderer)->realize (renderer, surface, error))
|
||||
{
|
||||
@ -399,13 +403,15 @@ gsk_renderer_render_texture (GskRenderer *renderer,
|
||||
|
||||
/**
|
||||
* gsk_renderer_render:
|
||||
* @renderer: a `GskRenderer`
|
||||
* @renderer: a realized `GskRenderer`
|
||||
* @root: a `GskRenderNode`
|
||||
* @region: (nullable): the `cairo_region_t` that must be redrawn or %NULL
|
||||
* for the whole window
|
||||
*
|
||||
* Renders the scene graph, described by a tree of `GskRenderNode` instances,
|
||||
* ensuring that the given @region gets redrawn.
|
||||
* Renders the scene graph, described by a tree of `GskRenderNode` instances
|
||||
* to the renderer's surface, ensuring that the given @region gets redrawn.
|
||||
*
|
||||
* If the renderer has no associated surface, this function does nothing.
|
||||
*
|
||||
* Renderers must ensure that changes of the contents given by the @root
|
||||
* node as well as the area given by @region are redrawn. They are however
|
||||
@ -428,6 +434,9 @@ gsk_renderer_render (GskRenderer *renderer,
|
||||
g_return_if_fail (GSK_IS_RENDER_NODE (root));
|
||||
g_return_if_fail (priv->root_node == NULL);
|
||||
|
||||
if (priv->surface == NULL)
|
||||
return;
|
||||
|
||||
if (region == NULL || priv->prev_node == NULL || GSK_RENDERER_DEBUG_CHECK (renderer, FULL_REDRAW))
|
||||
{
|
||||
clip = cairo_region_create_rectangle (&(GdkRectangle) {
|
||||
|
@ -114,12 +114,19 @@ gsk_vulkan_renderer_update_images_cb (GdkVulkanContext *context,
|
||||
|
||||
static gboolean
|
||||
gsk_vulkan_renderer_realize (GskRenderer *renderer,
|
||||
GdkSurface *window,
|
||||
GdkSurface *surface,
|
||||
GError **error)
|
||||
{
|
||||
GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer);
|
||||
|
||||
self->vulkan = gdk_surface_create_vulkan_context (window, error);
|
||||
if (surface == NULL)
|
||||
{
|
||||
g_set_error (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_UNSUPPORTED,
|
||||
"The Vulkan renderer does not support surfaceless rendering yet.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
self->vulkan = gdk_surface_create_vulkan_context (surface, error);
|
||||
if (self->vulkan == NULL)
|
||||
return FALSE;
|
||||
|
||||
|
@ -765,7 +765,6 @@ add_test (const char *name,
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GdkSurface *surface;
|
||||
int result;
|
||||
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
@ -776,12 +775,10 @@ main (int argc, char *argv[])
|
||||
add_test ("/memorytexture/download_float_1x1", test_download_float_1x1);
|
||||
add_test ("/memorytexture/download_float_4x4", test_download_float_4x4);
|
||||
|
||||
surface = gdk_surface_new_toplevel (gdk_display_get_default());
|
||||
gl_renderer = gsk_gl_renderer_new ();
|
||||
if (!gsk_renderer_realize (gl_renderer, surface, NULL))
|
||||
if (!gsk_renderer_realize (gl_renderer, NULL, NULL))
|
||||
{
|
||||
g_clear_object (&gl_renderer);
|
||||
g_clear_object (&surface);
|
||||
}
|
||||
|
||||
result = g_test_run ();
|
||||
@ -791,7 +788,6 @@ main (int argc, char *argv[])
|
||||
gsk_renderer_unrealize (gl_renderer);
|
||||
g_clear_object (&gl_renderer);
|
||||
}
|
||||
g_clear_object (&surface);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -64,7 +64,6 @@ texture_download_thread (GTask *task,
|
||||
static void
|
||||
texture_threads (void)
|
||||
{
|
||||
GdkSurface *surface;
|
||||
GskRenderer *gl_renderer;
|
||||
GskRenderNode *node;
|
||||
GMainLoop *loop;
|
||||
@ -73,15 +72,13 @@ texture_threads (void)
|
||||
GError *error = NULL;
|
||||
|
||||
/* 1. Get a GL renderer */
|
||||
surface = gdk_surface_new_toplevel (gdk_display_get_default());
|
||||
gl_renderer = gsk_gl_renderer_new ();
|
||||
if (!gsk_renderer_realize (gl_renderer, surface, &error))
|
||||
if (!gsk_renderer_realize (gl_renderer, NULL, &error))
|
||||
{
|
||||
g_test_skip (error->message);
|
||||
|
||||
g_clear_error (&error);
|
||||
g_clear_object (&gl_renderer);
|
||||
g_clear_object (&surface);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -116,7 +113,6 @@ texture_threads (void)
|
||||
gsk_renderer_unrealize (gl_renderer);
|
||||
g_clear_pointer (&loop, g_main_loop_unref);
|
||||
g_clear_object (&gl_renderer);
|
||||
g_clear_object (&surface);
|
||||
g_main_context_release (NULL);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user