From 89500c5d847d9c3dc7fdb47dbff96101a94a99f3 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 27 Jul 2016 11:34:20 +0100 Subject: [PATCH] gsk: Bind GL context to the GL profiler Similarly to how we bind it to the GL driver object used by the GSK GL renderer. --- gsk/gskglprofiler.c | 73 ++++++++++++++++++++++++++++++++++++-- gsk/gskglprofilerprivate.h | 2 +- gsk/gskglrenderer.c | 46 ++++++++++++------------ 3 files changed, 94 insertions(+), 27 deletions(-) diff --git a/gsk/gskglprofiler.c b/gsk/gskglprofiler.c index ac89fac432..0d58ee89d1 100644 --- a/gsk/gskglprofiler.c +++ b/gsk/gskglprofiler.c @@ -10,6 +10,8 @@ struct _GskGLProfiler { GObject parent_instance; + GdkGLContext *gl_context; + /* Creating GL queries is kind of expensive, so we pay the * price upfront and create a circular buffer of queries */ @@ -20,6 +22,14 @@ struct _GskGLProfiler gboolean first_frame : 1; }; +enum { + PROP_GL_CONTEXT = 1, + + N_PROPERTIES +}; + +static GParamSpec *gsk_gl_profiler_properties[N_PROPERTIES]; + G_DEFINE_TYPE (GskGLProfiler, gsk_gl_profiler, G_TYPE_OBJECT) static void @@ -29,13 +39,68 @@ gsk_gl_profiler_finalize (GObject *gobject) glDeleteQueries (N_QUERIES, self->gl_queries); + g_clear_object (&self->gl_context); + G_OBJECT_CLASS (gsk_gl_profiler_parent_class)->finalize (gobject); } +static void +gsk_gl_profiler_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GskGLProfiler *self = GSK_GL_PROFILER (gobject); + + switch (prop_id) + { + case PROP_GL_CONTEXT: + self->gl_context = g_value_dup_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +gsk_gl_profiler_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GskGLProfiler *self = GSK_GL_PROFILER (gobject); + + switch (prop_id) + { + case PROP_GL_CONTEXT: + g_value_set_object (value, self->gl_context); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + static void gsk_gl_profiler_class_init (GskGLProfilerClass *klass) { - G_OBJECT_CLASS (klass)->finalize = gsk_gl_profiler_finalize; + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = gsk_gl_profiler_set_property; + gobject_class->get_property = gsk_gl_profiler_get_property; + gobject_class->finalize = gsk_gl_profiler_finalize; + + gsk_gl_profiler_properties[PROP_GL_CONTEXT] = + g_param_spec_object ("gl-context", + "GL Context", + "The GdkGLContext used by the GL profiler", + GDK_TYPE_GL_CONTEXT, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (gobject_class, N_PROPERTIES, gsk_gl_profiler_properties); } static void @@ -48,9 +113,11 @@ gsk_gl_profiler_init (GskGLProfiler *self) } GskGLProfiler * -gsk_gl_profiler_new (void) +gsk_gl_profiler_new (GdkGLContext *context) { - return g_object_new (GSK_TYPE_GL_PROFILER, NULL); + g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL); + + return g_object_new (GSK_TYPE_GL_PROFILER, "gl-context", context, NULL); } void diff --git a/gsk/gskglprofilerprivate.h b/gsk/gskglprofilerprivate.h index 51777c0ac8..5b2a24b09f 100644 --- a/gsk/gskglprofilerprivate.h +++ b/gsk/gskglprofilerprivate.h @@ -8,7 +8,7 @@ G_BEGIN_DECLS #define GSK_TYPE_GL_PROFILER (gsk_gl_profiler_get_type ()) G_DECLARE_FINAL_TYPE (GskGLProfiler, gsk_gl_profiler, GSK, GL_PROFILER, GObject) -GskGLProfiler * gsk_gl_profiler_new (void); +GskGLProfiler * gsk_gl_profiler_new (GdkGLContext *context); void gsk_gl_profiler_begin_gpu_region (GskGLProfiler *profiler); guint64 gsk_gl_profiler_end_gpu_region (GskGLProfiler *profiler); diff --git a/gsk/gskglrenderer.c b/gsk/gskglrenderer.c index 37c6ec32b2..b2d8c1dc5c 100644 --- a/gsk/gskglrenderer.c +++ b/gsk/gskglrenderer.c @@ -79,8 +79,6 @@ struct _GskGLRenderer { GskRenderer parent_instance; - GdkGLContext *context; - graphene_matrix_t mvp; graphene_frustum_t frustum; @@ -91,6 +89,7 @@ struct _GskGLRenderer GQuark uniforms[N_UNIFORMS]; GQuark attributes[N_ATTRIBUTES]; + GdkGLContext *gl_context; GskGLDriver *gl_driver; GskGLProfiler *gl_profiler; GskShaderBuilder *shader_builder; @@ -118,7 +117,7 @@ gsk_gl_renderer_dispose (GObject *gobject) { GskGLRenderer *self = GSK_GL_RENDERER (gobject); - g_clear_object (&self->context); + g_clear_object (&self->gl_context); G_OBJECT_CLASS (gsk_gl_renderer_parent_class)->dispose (gobject); } @@ -148,7 +147,7 @@ gsk_gl_renderer_create_buffers (GskGLRenderer *self, static void gsk_gl_renderer_destroy_buffers (GskGLRenderer *self) { - if (self->context == NULL) + if (self->gl_context == NULL) return; if (!self->has_buffers) @@ -156,7 +155,7 @@ gsk_gl_renderer_destroy_buffers (GskGLRenderer *self) GSK_NOTE (OPENGL, g_print ("Destroying buffers\n")); - gdk_gl_context_make_current (self->context); + gdk_gl_context_make_current (self->gl_context); if (self->texture_id != 0) { @@ -187,14 +186,14 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self) self->attributes[POSITION] = gsk_shader_builder_add_attribute (builder, "aPosition"); self->attributes[UV] = gsk_shader_builder_add_attribute (builder, "aUv"); - if (gdk_gl_context_get_use_es (self->context)) + if (gdk_gl_context_get_use_es (self->gl_context)) { gsk_shader_builder_set_version (builder, SHADER_VERSION_GLES); gsk_shader_builder_set_vertex_preamble (builder, "es2_common.vs.glsl"); gsk_shader_builder_set_fragment_preamble (builder, "es2_common.fs.glsl"); gsk_shader_builder_add_define (builder, "GSK_GLES", "1"); } - else if (gdk_gl_context_is_legacy (self->context)) + else if (gdk_gl_context_is_legacy (self->gl_context)) { gsk_shader_builder_set_version (builder, SHADER_VERSION_GL_LEGACY); gsk_shader_builder_set_vertex_preamble (builder, "gl_common.vs.glsl"); @@ -260,14 +259,14 @@ gsk_gl_renderer_realize (GskRenderer *renderer) /* If we didn't get a GdkGLContext before realization, try creating * one now, for our exclusive use. */ - if (self->context == NULL) + if (self->gl_context == NULL) { GdkWindow *window = gsk_renderer_get_window (renderer); if (window == NULL) return FALSE; - self->context = gdk_window_create_gl_context (window, &error); + self->gl_context = gdk_window_create_gl_context (window, &error); if (error != NULL) { g_critical ("Unable to create GL context for renderer: %s", @@ -278,7 +277,7 @@ gsk_gl_renderer_realize (GskRenderer *renderer) } } - gdk_gl_context_realize (self->context, &error); + gdk_gl_context_realize (self->gl_context, &error); if (error != NULL) { g_critical ("Unable to realize GL renderer: %s", error->message); @@ -286,11 +285,11 @@ gsk_gl_renderer_realize (GskRenderer *renderer) return FALSE; } - gdk_gl_context_make_current (self->context); + gdk_gl_context_make_current (self->gl_context); g_assert (self->gl_driver == NULL); - self->gl_driver = gsk_gl_driver_new (self->context); - self->gl_profiler = gsk_gl_profiler_new (); + self->gl_driver = gsk_gl_driver_new (self->gl_context); + self->gl_profiler = gsk_gl_profiler_new (self->gl_context); GSK_NOTE (OPENGL, g_print ("Creating buffers and programs\n")); if (!gsk_gl_renderer_create_programs (self)) @@ -304,10 +303,10 @@ gsk_gl_renderer_unrealize (GskRenderer *renderer) { GskGLRenderer *self = GSK_GL_RENDERER (renderer); - if (self->context == NULL) + if (self->gl_context == NULL) return; - gdk_gl_context_make_current (self->context); + gdk_gl_context_make_current (self->gl_context); /* We don't need to iterate to destroy the associated GL resources, * as they will be dropped when we finalize the GskGLDriver @@ -320,7 +319,7 @@ gsk_gl_renderer_unrealize (GskRenderer *renderer) g_clear_object (&self->gl_profiler); g_clear_object (&self->gl_driver); - if (self->context == gdk_gl_context_get_current ()) + if (self->gl_context == gdk_gl_context_get_current ()) gdk_gl_context_clear_current (); } @@ -713,7 +712,7 @@ gsk_gl_renderer_validate_tree (GskGLRenderer *self, { int n_nodes; - if (self->context == NULL) + if (self->gl_context == NULL) { GSK_NOTE (OPENGL, g_print ("No valid GL context associated to the renderer")); return FALSE; @@ -721,7 +720,7 @@ gsk_gl_renderer_validate_tree (GskGLRenderer *self, n_nodes = gsk_render_node_get_size (root); - gdk_gl_context_make_current (self->context); + gdk_gl_context_make_current (self->gl_context); self->render_items = g_array_sized_new (FALSE, FALSE, sizeof (RenderItem), n_nodes); @@ -752,10 +751,10 @@ gsk_gl_renderer_clear_tree (GskGLRenderer *self) { int i; - if (self->context == NULL) + if (self->gl_context == NULL) return; - gdk_gl_context_make_current (self->context); + gdk_gl_context_make_current (self->gl_context); for (i = 0; i < self->render_items->len; i++) { @@ -786,10 +785,10 @@ gsk_gl_renderer_render (GskRenderer *renderer, guint i; guint64 gpu_time; - if (self->context == NULL) + if (self->gl_context == NULL) return; - gdk_gl_context_make_current (self->context); + gdk_gl_context_make_current (self->gl_context); gsk_renderer_get_viewport (renderer, &viewport); @@ -841,6 +840,7 @@ gsk_gl_renderer_render (GskRenderer *renderer, GSK_NOTE (OPENGL, g_print ("GPU time: %" G_GUINT64_FORMAT " nsec\n", gpu_time)); out: + /* XXX: Add GdkDrawingContext API */ gdk_cairo_draw_from_gl (gdk_drawing_context_get_cairo_context (context), gdk_drawing_context_get_window (context), self->texture_id, @@ -848,7 +848,7 @@ out: gsk_renderer_get_scale_factor (renderer), 0, 0, viewport.size.width, viewport.size.height); - gdk_gl_context_make_current (self->context); + gdk_gl_context_make_current (self->gl_context); gsk_gl_renderer_clear_tree (self); gsk_gl_renderer_destroy_buffers (self); }