[gtk] gl: Do less work to maintain caches



commit 8839e10d44e240d8e6e342dd1a7d8d1bc7f78b69
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Oct 11 20:42:24 2019 -0400

    gl: Do less work to maintain caches
    
    Remember which atlases were removed, and only
    check those when looking for icons or glyphs
    to remove. For most frames, we don't have to
    check at all since no atlases were removed.

 gsk/gl/gskglglyphcache.c          | 45 ++++++++++++++++++++-----------------
 gsk/gl/gskglglyphcacheprivate.h   |  3 ++-
 gsk/gl/gskgliconcache.c           | 47 +++++++++++++++++++++------------------
 gsk/gl/gskgliconcacheprivate.h    |  3 ++-
 gsk/gl/gskglrenderer.c            |  9 +++++---
 gsk/gl/gskgltextureatlas.c        |  4 +++-
 gsk/gl/gskgltextureatlasprivate.h |  3 ++-
 7 files changed, 65 insertions(+), 49 deletions(-)
---
diff --git a/gsk/gl/gskglglyphcache.c b/gsk/gl/gskglglyphcache.c
index f6206ca1f4..0357f9910d 100644
--- a/gsk/gl/gskglglyphcache.c
+++ b/gsk/gl/gskglglyphcache.c
@@ -312,41 +312,46 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache         *cache,
 }
 
 void
-gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self)
+gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self,
+                                GPtrArray       *removed_atlases)
 {
   GHashTableIter iter;
   GlyphCacheKey *key;
   GskGLCachedGlyph *value;
-  guint dropped = 0;
 
   self->timestamp++;
 
-  g_hash_table_iter_init (&iter, self->hash_table);
-  while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value))
+  if (removed_atlases->len > 0)
     {
-      guint pos;
+      guint dropped = 0;
 
-      if (!g_ptr_array_find (self->atlases->atlases, value->atlas, &pos))
+      g_hash_table_iter_init (&iter, self->hash_table);
+      while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value))
         {
-          g_hash_table_iter_remove (&iter);
-          dropped++;
+          if (g_ptr_array_find (removed_atlases, value->atlas, NULL))
+            {
+              g_hash_table_iter_remove (&iter);
+              dropped++;
+            }
         }
-      else
+
+      GSK_NOTE(GLYPH_CACHE, if (dropped > 0) g_message ("Dropped %d glyphs", dropped));
+    }
+
+  g_hash_table_iter_init (&iter, self->hash_table);
+  while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value))
+    {
+      const guint age = self->timestamp - value->timestamp;
+
+      if (age > MAX_FRAME_AGE)
         {
-          const guint age = self->timestamp - value->timestamp;
+          GskGLTextureAtlas *atlas = value->atlas;
 
-          if (age > MAX_FRAME_AGE)
+          if (atlas && value->used)
             {
-              GskGLTextureAtlas *atlas = value->atlas;
-
-              if (atlas && value->used)
-                {
-                  gsk_gl_texture_atlas_mark_unused (atlas, value->draw_width, value->draw_height);
-                  value->used = FALSE;
-                }
+              gsk_gl_texture_atlas_mark_unused (atlas, value->draw_width, value->draw_height);
+              value->used = FALSE;
             }
         }
     }
-
-  GSK_NOTE(GLYPH_CACHE, if (dropped > 0) g_message ("Dropped %d glyphs", dropped));
 }
diff --git a/gsk/gl/gskglglyphcacheprivate.h b/gsk/gl/gskglglyphcacheprivate.h
index da1b018fd3..dbe5196cca 100644
--- a/gsk/gl/gskglglyphcacheprivate.h
+++ b/gsk/gl/gskglglyphcacheprivate.h
@@ -72,7 +72,8 @@ GskGLGlyphCache *        gsk_gl_glyph_cache_new             (GdkDisplay *display
                                                              GskGLTextureAtlases *atlases);
 GskGLGlyphCache *        gsk_gl_glyph_cache_ref             (GskGLGlyphCache *self);
 void                     gsk_gl_glyph_cache_unref           (GskGLGlyphCache        *self);
-void                     gsk_gl_glyph_cache_begin_frame     (GskGLGlyphCache        *self);
+void                     gsk_gl_glyph_cache_begin_frame     (GskGLGlyphCache        *self,
+                                                             GPtrArray              *removed_atlases);
 gboolean                 gsk_gl_glyph_cache_lookup          (GskGLGlyphCache        *self,
                                                              GlyphCacheKey          *lookup,
                                                              GskGLDriver            *driver,
diff --git a/gsk/gl/gskgliconcache.c b/gsk/gl/gskgliconcache.c
index 93ac0897d7..da3838219a 100644
--- a/gsk/gl/gskgliconcache.c
+++ b/gsk/gl/gskgliconcache.c
@@ -64,40 +64,43 @@ gsk_gl_icon_cache_unref (GskGLIconCache *self)
 }
 
 void
-gsk_gl_icon_cache_begin_frame (GskGLIconCache *self)
+gsk_gl_icon_cache_begin_frame (GskGLIconCache *self,
+                               GPtrArray      *removed_atlases)
 {
   GHashTableIter iter;
   GdkTexture *texture;
   IconData *icon_data;
 
-  /* Increase frame age of all icons */
+  /* Drop icons on removed atlases */
+  if (removed_atlases->len > 0)
+    {
+      g_hash_table_iter_init (&iter, self->icons);
+      while (g_hash_table_iter_next (&iter, (gpointer *)&texture, (gpointer *)&icon_data))
+        {
+          if (g_ptr_array_find (removed_atlases, icon_data->atlas, NULL))
+            g_hash_table_iter_remove (&iter);
+        }
+    }
+  
+  /* Increase frame age of all remaining icons */
   g_hash_table_iter_init (&iter, self->icons);
   while (g_hash_table_iter_next (&iter, (gpointer *)&texture, (gpointer *)&icon_data))
     {
-      guint pos;
+      icon_data->frame_age ++;
 
-      if (!g_ptr_array_find (self->atlases->atlases, icon_data->atlas, &pos))
-        {
-          g_hash_table_iter_remove (&iter);
-        }
-      else
+      if (icon_data->frame_age > MAX_FRAME_AGE)
         {
-          icon_data->frame_age ++;
-
-          if (icon_data->frame_age > MAX_FRAME_AGE)
+          if (icon_data->used)
             {
-
-              if (icon_data->used)
-                {
-                  const int w = icon_data->texture_rect.size.width  * icon_data->atlas->width;
-                  const int h = icon_data->texture_rect.size.height * icon_data->atlas->height;
-
-                  gsk_gl_texture_atlas_mark_unused (icon_data->atlas, w + 2, h + 2);
-                  icon_data->used = FALSE;
-                }
-              /* We do NOT remove the icon here. Instead, We wait until we drop the entire atlas.
-               * This way we can revive it when we use it again. */
+              const int w = icon_data->texture_rect.size.width  * icon_data->atlas->width;
+              const int h = icon_data->texture_rect.size.height * icon_data->atlas->height;
+              gsk_gl_texture_atlas_mark_unused (icon_data->atlas, w + 2, h + 2);
+              icon_data->used = FALSE;
             }
+
+          /* We do NOT remove the icon here. Instead, We wait until we drop the entire atlas.
+           * This way we can revive it when we use it again.
+           */
         }
     }
 }
diff --git a/gsk/gl/gskgliconcacheprivate.h b/gsk/gl/gskgliconcacheprivate.h
index ade371b930..5785871bf2 100644
--- a/gsk/gl/gskgliconcacheprivate.h
+++ b/gsk/gl/gskgliconcacheprivate.h
@@ -24,7 +24,8 @@ GskGLIconCache * gsk_gl_icon_cache_new            (GdkDisplay *display,
                                                    GskGLTextureAtlases *atlases);
 GskGLIconCache * gsk_gl_icon_cache_ref            (GskGLIconCache        *self);
 void             gsk_gl_icon_cache_unref          (GskGLIconCache        *self);
-void             gsk_gl_icon_cache_begin_frame    (GskGLIconCache        *self);
+void             gsk_gl_icon_cache_begin_frame    (GskGLIconCache        *self,
+                                                   GPtrArray             *removed_atlases);
 void             gsk_gl_icon_cache_lookup_or_add  (GskGLIconCache        *self,
                                                    GdkTexture            *texture,
                                                    int                   *out_texture_id,
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index e0e5420df1..2600a35c90 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -3181,6 +3181,7 @@ gsk_gl_renderer_do_render (GskRenderer           *renderer,
   GskProfiler *profiler;
   gint64 gpu_time, cpu_time, start_time;
 #endif
+  GPtrArray *removed;
 
 #ifdef G_ENABLE_DEBUG
   profiler = gsk_renderer_get_profiler (renderer);
@@ -3204,10 +3205,12 @@ gsk_gl_renderer_do_render (GskRenderer           *renderer,
                               ORTHO_FAR_PLANE);
   graphene_matrix_scale (&projection, 1, -1, 1);
 
-  gsk_gl_texture_atlases_begin_frame (self->atlases);
-  gsk_gl_glyph_cache_begin_frame (self->glyph_cache);
-  gsk_gl_icon_cache_begin_frame (self->icon_cache);
+  removed = g_ptr_array_new ();
+  gsk_gl_texture_atlases_begin_frame (self->atlases, removed);
+  gsk_gl_glyph_cache_begin_frame (self->glyph_cache, removed);
+  gsk_gl_icon_cache_begin_frame (self->icon_cache, removed);
   gsk_gl_shadow_cache_begin_frame (&self->shadow_cache, self->gl_driver);
+  g_ptr_array_unref (removed);
 
   ops_set_projection (&self->op_builder, &projection);
   ops_set_viewport (&self->op_builder, viewport);
diff --git a/gsk/gl/gskgltextureatlas.c b/gsk/gl/gskgltextureatlas.c
index 04dbb710b6..3349d06cf7 100644
--- a/gsk/gl/gskgltextureatlas.c
+++ b/gsk/gl/gskgltextureatlas.c
@@ -74,7 +74,8 @@ write_atlas_to_png (GskGLTextureAtlas *atlas,
 #endif
 
 void
-gsk_gl_texture_atlases_begin_frame (GskGLTextureAtlases *self)
+gsk_gl_texture_atlases_begin_frame (GskGLTextureAtlases *self,
+                                    GPtrArray           *removed)
 {
   int i;
 
@@ -94,6 +95,7 @@ gsk_gl_texture_atlases_begin_frame (GskGLTextureAtlases *self)
               atlas->texture_id = 0;
             }
 
+          g_ptr_array_add (removed, atlas);
           g_ptr_array_remove_index (self->atlases, i);
        }
     }
diff --git a/gsk/gl/gskgltextureatlasprivate.h b/gsk/gl/gskgltextureatlasprivate.h
index 2864fd8d05..fc4f0365c0 100644
--- a/gsk/gl/gskgltextureatlasprivate.h
+++ b/gsk/gl/gskgltextureatlasprivate.h
@@ -35,7 +35,8 @@ GskGLTextureAtlases *gsk_gl_texture_atlases_new         (void);
 GskGLTextureAtlases *gsk_gl_texture_atlases_ref         (GskGLTextureAtlases *atlases);
 void                 gsk_gl_texture_atlases_unref       (GskGLTextureAtlases *atlases);
 
-void                 gsk_gl_texture_atlases_begin_frame (GskGLTextureAtlases *atlases);
+void                 gsk_gl_texture_atlases_begin_frame (GskGLTextureAtlases *atlases,
+                                                         GPtrArray           *removed);
 gboolean             gsk_gl_texture_atlases_pack        (GskGLTextureAtlases *atlases,
                                                          int                  width,
                                                          int                  height,


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