[gtk/wip/chergert/glproto] break job into a prepare and render phase



commit e1950789dcf69f4b509ab481e72345c271b8f451
Author: Christian Hergert <chergert redhat com>
Date:   Sun Dec 20 10:31:56 2020 -0800

    break job into a prepare and render phase
    
    this, if we can add some thread-safety helpers to GdkGLContext may allow
    us to build something that prepares the work on the main thread w/o any
    synchronization, but render on a GL thread.
    
    There are places where that could be really useful, like macOS where we
    want to block the CVDisplayLink to perform our GL operations.

 gsk/next/gskglrenderer.c         | 12 ++++++------
 gsk/next/gskglrenderjob.c        | 27 ++++++++++++++++++++-------
 gsk/next/gskglrenderjobprivate.h | 19 ++++++++++---------
 3 files changed, 36 insertions(+), 22 deletions(-)
---
diff --git a/gsk/next/gskglrenderer.c b/gsk/next/gskglrenderer.c
index 19c67e671e..6d72b3af99 100644
--- a/gsk/next/gskglrenderer.c
+++ b/gsk/next/gskglrenderer.c
@@ -224,16 +224,15 @@ gsk_gl_renderer_render (GskRenderer          *renderer,
   viewport.size.width = gdk_surface_get_width (surface) * scale_factor;
   viewport.size.height = gdk_surface_get_height (surface) * scale_factor;
 
+  gdk_draw_context_begin_frame (GDK_DRAW_CONTEXT (context), update_area);
   job = gsk_gl_render_job_new (self->driver,
-                               root,
                                &viewport,
                                scale_factor,
                                render_region,
                                0,
                                FALSE);
-
-  gdk_draw_context_begin_frame (GDK_DRAW_CONTEXT (context), update_area);
-  gsk_gl_render_job_run (job);
+  gsk_gl_render_job_prepare (job, root);
+  gsk_gl_render_job_render (job);
   gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (context));
 
   gsk_gl_render_job_free (job);
@@ -270,8 +269,9 @@ gsk_gl_renderer_render_texture (GskRenderer           *renderer,
 
   gsk_gl_command_queue_autorelease_framebuffer (self->command_queue, fbo_id);
 
-  job = gsk_gl_render_job_new (self->driver, root, viewport, 1, NULL, fbo_id, TRUE);
-  gsk_gl_render_job_run (job);
+  job = gsk_gl_render_job_new (self->driver, viewport, 1, NULL, fbo_id, TRUE);
+  gsk_gl_render_job_prepare (job, root);
+  gsk_gl_render_job_render (job);
   gsk_gl_render_job_free (job);
 
   return create_texture_from_texture (context, texture_id, width, height);
diff --git a/gsk/next/gskglrenderjob.c b/gsk/next/gskglrenderjob.c
index 0a5a73dfdb..7c13a7a4bd 100644
--- a/gsk/next/gskglrenderjob.c
+++ b/gsk/next/gskglrenderjob.c
@@ -23,6 +23,7 @@
 
 #include "config.h"
 
+#include <gdk/gdkglcontextprivate.h>
 #include <string.h>
 
 #include "gskglcommandqueueprivate.h"
@@ -35,7 +36,6 @@
 struct _GskGLRenderJob
 {
   GskNextDriver     *driver;
-  GskRenderNode     *root;
   cairo_region_t    *region;
   guint              framebuffer;
   graphene_rect_t    viewport;
@@ -307,7 +307,6 @@ gsk_gl_render_job_transform_bounds (GskGLRenderJob        *job,
 
 GskGLRenderJob *
 gsk_gl_render_job_new (GskNextDriver         *driver,
-                       GskRenderNode         *root,
                        const graphene_rect_t *viewport,
                        float                  scale_factor,
                        const cairo_region_t  *region,
@@ -319,13 +318,11 @@ gsk_gl_render_job_new (GskNextDriver         *driver,
   GskGLRenderJob *job;
 
   g_return_val_if_fail (GSK_IS_NEXT_DRIVER (driver), NULL);
-  g_return_val_if_fail (root != NULL, NULL);
   g_return_val_if_fail (viewport != NULL, NULL);
   g_return_val_if_fail (scale_factor > 0, NULL);
 
   job = g_slice_new0 (GskGLRenderJob);
   job->driver = g_object_ref (driver);
-  job->root = gsk_render_node_ref (root);
   job->clip = g_array_new (FALSE, FALSE, sizeof (GskGLRenderClip));
   job->modelview = g_array_new (FALSE, FALSE, sizeof (GskGLRenderModelview));
   job->framebuffer = framebuffer;
@@ -338,7 +335,6 @@ gsk_gl_render_job_new (GskNextDriver         *driver,
   job->flip_y = !!flip_y;
 
   init_projection_matrix (&job->projection, viewport, flip_y);
-
   gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, scale_factor, scale_factor));
 
   /* Setup our initial clip. If region is NULL then we are drawing the
@@ -366,6 +362,8 @@ gsk_gl_render_job_new (GskNextDriver         *driver,
                                                        clip_rect->size.width,
                                                        clip_rect->size.height));
 
+  gsk_gl_command_queue_bind_framebuffer (driver->command_queue, framebuffer);
+
   return job;
 }
 
@@ -380,7 +378,6 @@ gsk_gl_render_job_free (GskGLRenderJob *job)
     }
 
   g_clear_object (&job->driver);
-  g_clear_pointer (&job->root, gsk_render_node_unref);
   g_clear_pointer (&job->region, cairo_region_destroy);
   g_clear_pointer (&job->modelview, g_array_unref);
   g_clear_pointer (&job->clip, g_array_unref);
@@ -388,7 +385,23 @@ gsk_gl_render_job_free (GskGLRenderJob *job)
 }
 
 void
-gsk_gl_render_job_run (GskGLRenderJob *job)
+gsk_gl_render_job_prepare (GskGLRenderJob *job,
+                           GskRenderNode  *root)
+{
+  GdkGLContext *context;
+
+  g_return_if_fail (job != NULL);
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (GSK_IS_NEXT_DRIVER (job->driver));
+
+  context = gsk_next_driver_get_context (job->driver);
+
+  gdk_gl_context_push_debug_group (context, "Adding render ops");
+  gdk_gl_context_pop_debug_group (context);
+}
+
+void
+gsk_gl_render_job_render (GskGLRenderJob *job)
 {
   g_return_if_fail (job != NULL);
   g_return_if_fail (GSK_IS_NEXT_DRIVER (job->driver));
diff --git a/gsk/next/gskglrenderjobprivate.h b/gsk/next/gskglrenderjobprivate.h
index 3d3440c80c..2c89078332 100644
--- a/gsk/next/gskglrenderjobprivate.h
+++ b/gsk/next/gskglrenderjobprivate.h
@@ -23,14 +23,15 @@
 
 #include "gskgltypes.h"
 
-GskGLRenderJob *gsk_gl_render_job_new  (GskNextDriver         *driver,
-                                        GskRenderNode         *root,
-                                        const graphene_rect_t *viewport,
-                                        float                  scale_factor,
-                                        const cairo_region_t  *region,
-                                        guint                  framebuffer,
-                                        gboolean               flip_y);
-void            gsk_gl_render_job_free (GskGLRenderJob        *job);
-void            gsk_gl_render_job_run  (GskGLRenderJob        *job);
+GskGLRenderJob *gsk_gl_render_job_new     (GskNextDriver         *driver,
+                                           const graphene_rect_t *viewport,
+                                           float                  scale_factor,
+                                           const cairo_region_t  *region,
+                                           guint                  framebuffer,
+                                           gboolean               flip_y);
+void            gsk_gl_render_job_free    (GskGLRenderJob        *job);
+void            gsk_gl_render_job_prepare (GskGLRenderJob        *job,
+                                           GskRenderNode         *root);
+void            gsk_gl_render_job_render  (GskGLRenderJob        *job);
 
 #endif /* __GSK_GL_RENDER_JOB_H__ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]