[gtk/wip/chergert/glproto: 414/526] defer frame cleanup until after we swap buffers




commit dfeed1e07c1529a935a34cb45003afbd875c0ee4
Author: Christian Hergert <chergert redhat com>
Date:   Tue Feb 2 16:25:25 2021 -0800

    defer frame cleanup until after we swap buffers
    
    there is no sense in blocking on resource destruction while we are in a
    point of critical timing to deliver frames.

 gsk/next/gskgldriver.c        | 49 ++++++++++++++++++++++++++++++++-----------
 gsk/next/gskgldriverprivate.h |  1 +
 gsk/next/gskglrenderer.c      |  4 ++++
 3 files changed, 42 insertions(+), 12 deletions(-)
---
diff --git a/gsk/next/gskgldriver.c b/gsk/next/gskgldriver.c
index 77c5888739..064fba44c1 100644
--- a/gsk/next/gskgldriver.c
+++ b/gsk/next/gskgldriver.c
@@ -552,6 +552,41 @@ gsk_next_driver_end_frame (GskNextDriver *self)
   gsk_gl_texture_library_end_frame (GSK_GL_TEXTURE_LIBRARY (self->icons));
   gsk_gl_texture_library_end_frame (GSK_GL_TEXTURE_LIBRARY (self->glyphs));
 
+#if 0
+  g_print ("End Frame: textures=%u with_key=%u reverse=%u pool=%u:%u atlases=%u\n",
+           g_hash_table_size (self->textures),
+           g_hash_table_size (self->key_to_texture_id),
+           g_hash_table_size (self->texture_id_to_key),
+           self->texture_pool.by_width.length,
+           self->texture_pool.by_height.length,
+           self->atlases->len);
+#endif
+
+  self->in_frame = FALSE;
+}
+
+/**
+ * gsk_next_driver_after_frame:
+ * @self: a #GskNextDriver
+ *
+ * This function does post-frame cleanup operations.
+ *
+ * It differs from gsk_next_driver_end_frame() in that you should call it
+ * after you have requested the GL buffers swapped using
+ * gdk_draw_context_end_frame() on the target surface's context. This helps
+ * ensure that we do not block on destroying resources when we really just
+ * want to get the frame delivered.
+ */
+void
+gsk_next_driver_after_frame (GskNextDriver *self)
+{
+  g_return_if_fail (GSK_IS_NEXT_DRIVER (self));
+  g_return_if_fail (self->in_frame == FALSE);
+
+  /* Release any render targets (possibly adding them to
+   * self->autorelease_framebuffers) so we can release the FBOs immediately
+   * afterwards.
+   */
   while (self->render_targets->len > 0)
     {
       GskGLRenderTarget *render_target = g_ptr_array_index (self->render_targets, self->render_targets->len 
- 1);
@@ -563,6 +598,7 @@ gsk_next_driver_end_frame (GskNextDriver *self)
       self->render_targets->len--;
     }
 
+  /* Now that we have collected render targets, release all the FBOs */
   if (self->autorelease_framebuffers->len > 0)
     {
       glDeleteFramebuffers (self->autorelease_framebuffers->len,
@@ -570,20 +606,9 @@ gsk_next_driver_end_frame (GskNextDriver *self)
       self->autorelease_framebuffers->len = 0;
     }
 
-#if 0
-  g_print ("End Frame: textures=%u with_key=%u reverse=%u pool=%u:%u atlases=%u\n",
-           g_hash_table_size (self->textures),
-           g_hash_table_size (self->key_to_texture_id),
-           g_hash_table_size (self->texture_id_to_key),
-           self->texture_pool.by_width.length,
-           self->texture_pool.by_height.length,
-           self->atlases->len);
-#endif
-
+  /* Release any cached textures we used during the frame */
   gsk_gl_texture_pool_clear (&self->texture_pool);
 
-  self->in_frame = FALSE;
-
   /* Reset command queue to our shared queue incase we have operations
    * that need to be processed outside of a frame (such as callbacks
    * from external systems such as GDK).
diff --git a/gsk/next/gskgldriverprivate.h b/gsk/next/gskgldriverprivate.h
index 61f88c9143..8df5d85523 100644
--- a/gsk/next/gskgldriverprivate.h
+++ b/gsk/next/gskgldriverprivate.h
@@ -135,6 +135,7 @@ guint              gsk_next_driver_release_render_target (GskNextDriver        *
 void               gsk_next_driver_begin_frame           (GskNextDriver        *self,
                                                           GskGLCommandQueue    *command_queue);
 void               gsk_next_driver_end_frame             (GskNextDriver        *self);
+void               gsk_next_driver_after_frame           (GskNextDriver        *self);
 GdkTexture        *gsk_next_driver_create_gdk_texture    (GskNextDriver        *self,
                                                           guint                 texture_id);
 guint              gsk_next_driver_lookup_texture        (GskNextDriver        *self,
diff --git a/gsk/next/gskglrenderer.c b/gsk/next/gskglrenderer.c
index 499682f935..7ffa221d62 100644
--- a/gsk/next/gskglrenderer.c
+++ b/gsk/next/gskglrenderer.c
@@ -221,6 +221,8 @@ gsk_next_renderer_render (GskRenderer          *renderer,
   gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (self->context));
 
   cairo_region_destroy (render_region);
+
+  gsk_next_driver_after_frame (self->driver);
 }
 
 static GdkTexture *
@@ -258,6 +260,8 @@ gsk_next_renderer_render_texture (GskRenderer           *renderer,
       texture = gsk_next_driver_create_gdk_texture (self->driver, texture_id);
       gsk_next_driver_end_frame (self->driver);
       gsk_gl_render_job_free (job);
+
+      gsk_next_driver_after_frame (self->driver);
     }
 
   return g_steal_pointer (&texture);


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