[gtk/wip/chergert/glproto] next: simplify texture pool



commit f10d60cb41a0b7cd10b9498bb1dceb65b405f449
Author: Christian Hergert <chergert redhat com>
Date:   Tue Feb 23 12:16:38 2021 -0800

    next: simplify texture pool
    
    We didn't end up using the ability to reuse textures, so we can remove
    a bunch of the complexity from the pool and use it as a general container
    for the textures as well as some texture management.

 gsk/next/gskgldriver.c             |  69 ++-----------------
 gsk/next/gskgldriverprivate.h      |   5 --
 gsk/next/gskgltexturepool.c        | 135 +++++++------------------------------
 gsk/next/gskgltexturepoolprivate.h |  11 ++-
 4 files changed, 34 insertions(+), 186 deletions(-)
---
diff --git a/gsk/next/gskgldriver.c b/gsk/next/gskgldriver.c
index 8c6223e4f0..2e42a92af7 100644
--- a/gsk/next/gskgldriver.c
+++ b/gsk/next/gskgldriver.c
@@ -122,12 +122,9 @@ gsk_next_driver_collect_unused_textures (GskNextDriver *self,
         {
           g_hash_table_iter_steal (&iter);
 
-          g_assert (t->width_link.prev == NULL);
-          g_assert (t->width_link.next == NULL);
-          g_assert (t->width_link.data == t);
-          g_assert (t->height_link.prev == NULL);
-          g_assert (t->height_link.next == NULL);
-          g_assert (t->height_link.data == t);
+          g_assert (t->link.prev == NULL);
+          g_assert (t->link.next == NULL);
+          g_assert (t->link.data == t);
 
           /* Steal this texture and put it back into the pool */
           remove_texture_key_for_id (self, t->texture_id);
@@ -542,16 +539,6 @@ 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;
 }
 
@@ -770,12 +757,6 @@ gsk_next_driver_load_texture (GskNextDriver   *self,
  * to upload data, map to a framebuffer, or other uses which may
  * modify the texture immediately.
  *
- * Use this instead of gsk_next_driver_acquire_texture() when you need
- * to be able to modify the texture immediately instead of just when the
- * pipeline is executing. Otherwise, gsk_next_driver_acquire_texture()
- * provides more chances for re-use of textures, reducing the VRAM overhead
- * on the GPU.
- *
  * Use gsk_next_driver_release_texture() to release this texture back into
  * the pool so it may be reused later in the pipeline.
  *
@@ -795,8 +776,7 @@ gsk_next_driver_create_texture (GskNextDriver *self,
 
   texture = gsk_gl_texture_pool_get (&self->texture_pool,
                                      width, height,
-                                     min_filter, mag_filter,
-                                     TRUE);
+                                     min_filter, mag_filter);
   g_hash_table_insert (self->textures,
                        GUINT_TO_POINTER (texture->texture_id),
                        texture);
@@ -804,47 +784,6 @@ gsk_next_driver_create_texture (GskNextDriver *self,
   return texture;
 }
 
-/**
- * gsk_next_driver_acquire_texture:
- * @self: a #GskNextDriver
- * @width: the min width of the texture necessary
- * @height: the min height of the texture necessary
- * @min_filter: GL_NEAREST or GL_LINEAR
- * @mag_filter: GL_NEAREST or GL_LINEAR
- *
- * This function acquires a #GskGLTexture from the texture pool. Doing
- * so increases the chances for reduced VRAM usage in the GPU by having
- * fewer textures in use at one time. Batches later in the stream can
- * use the same texture memory of a previous batch.
- *
- * Consumers of this function are not allowed to modify @texture
- * immediately, it must wait until batches are being processed as
- * the texture may contain contents used earlier in the pipeline.
- *
- * Returns: a #GskGLTexture that may be returned to the pool with
- *   gsk_next_driver_release_texture().
- */
-GskGLTexture *
-gsk_next_driver_acquire_texture (GskNextDriver *self,
-                                 float          width,
-                                 float          height,
-                                 int            min_filter,
-                                 int            mag_filter)
-{
-  GskGLTexture *texture;
-
-  g_assert (GSK_IS_NEXT_DRIVER (self));
-
-  texture = gsk_gl_texture_pool_get (&self->texture_pool,
-                                     width, height,
-                                     min_filter, mag_filter,
-                                     FALSE);
-  g_hash_table_insert (self->textures,
-                       GUINT_TO_POINTER (texture->texture_id),
-                       texture);
-  return texture;
-}
-
 /**
  * gsk_next_driver_release_texture:
  * @self: a #GskNextDriver
diff --git a/gsk/next/gskgldriverprivate.h b/gsk/next/gskgldriverprivate.h
index dd97265538..8d96bca4b0 100644
--- a/gsk/next/gskgldriverprivate.h
+++ b/gsk/next/gskgldriverprivate.h
@@ -154,11 +154,6 @@ GskGLTexture      *gsk_next_driver_create_texture        (GskNextDriver        *
                                                           float                 height,
                                                           int                   min_filter,
                                                           int                   mag_filter);
-GskGLTexture      *gsk_next_driver_acquire_texture       (GskNextDriver        *self,
-                                                          float                 width,
-                                                          float                 height,
-                                                          int                   min_filter,
-                                                          int                   mag_filter);
 void               gsk_next_driver_release_texture       (GskNextDriver        *self,
                                                           GskGLTexture         *texture);
 void               gsk_next_driver_release_texture_by_id (GskNextDriver        *self,
diff --git a/gsk/next/gskgltexturepool.c b/gsk/next/gskgltexturepool.c
index 6c8b26669b..e81c04632a 100644
--- a/gsk/next/gskgltexturepool.c
+++ b/gsk/next/gskgltexturepool.c
@@ -20,8 +20,6 @@
 
 #include "config.h"
 
-#include <string.h>
-
 #include <gdk/gdktextureprivate.h>
 
 #include "gskgltexturepoolprivate.h"
@@ -32,10 +30,8 @@ gsk_gl_texture_free (GskGLTexture *texture)
 {
   if (texture != NULL)
     {
-      g_assert (texture->width_link.prev == NULL);
-      g_assert (texture->width_link.next == NULL);
-      g_assert (texture->height_link.prev == NULL);
-      g_assert (texture->height_link.next == NULL);
+      g_assert (texture->link.prev == NULL);
+      g_assert (texture->link.next == NULL);
 
       if (texture->user)
         g_clear_pointer (&texture->user, gdk_texture_clear_render_data);
@@ -62,21 +58,26 @@ gsk_gl_texture_free (GskGLTexture *texture)
 void
 gsk_gl_texture_pool_init (GskGLTexturePool *self)
 {
-  memset (self, 0, sizeof *self);
+  g_queue_init (&self->queue);
 }
 
 void
 gsk_gl_texture_pool_clear (GskGLTexturePool *self)
 {
-  guint *texture_ids = g_newa (guint, self->by_width.length);
+  guint *free_me = NULL;
+  guint *texture_ids;
   guint i = 0;
 
-  while (self->by_width.length > 0)
+  if G_LIKELY (self->queue.length <= 1024)
+    texture_ids = g_newa (guint, self->queue.length);
+  else
+    texture_ids = free_me = g_new (guint, self->queue.length);
+
+  while (self->queue.length > 0)
     {
-      GskGLTexture *head = g_queue_peek_head (&self->by_width);
+      GskGLTexture *head = g_queue_peek_head (&self->queue);
 
-      g_queue_unlink (&self->by_width, &head->width_link);
-      g_queue_unlink (&self->by_height, &head->height_link);
+      g_queue_unlink (&self->queue, &head->link);
 
       texture_ids[i++] = head->texture_id;
       head->texture_id = 0;
@@ -84,11 +85,12 @@ gsk_gl_texture_pool_clear (GskGLTexturePool *self)
       gsk_gl_texture_free (head);
     }
 
-  g_assert (self->by_width.length == 0);
-  g_assert (self->by_height.length == 0);
+  g_assert (self->queue.length == 0);
 
   if (i > 0)
     glDeleteTextures (i, texture_ids);
+
+  g_free (free_me);
 }
 
 void
@@ -100,52 +102,14 @@ gsk_gl_texture_pool_put (GskGLTexturePool *self,
   g_assert (self != NULL);
   g_assert (texture != NULL);
   g_assert (texture->user == NULL);
-  g_assert (texture->width_link.prev == NULL);
-  g_assert (texture->width_link.next == NULL);
-  g_assert (texture->width_link.data == texture);
-  g_assert (texture->height_link.prev == NULL);
-  g_assert (texture->height_link.next == NULL);
-  g_assert (texture->height_link.data == texture);
+  g_assert (texture->link.prev == NULL);
+  g_assert (texture->link.next == NULL);
+  g_assert (texture->link.data == texture);
 
   if (texture->permanent)
-    {
-      gsk_gl_texture_free (texture);
-      return;
-    }
-
-  sibling = NULL;
-  for (GList *iter = self->by_width.head;
-       iter != NULL;
-       iter = iter->next)
-    {
-      GskGLTexture *other = iter->data;
-
-      if (other->width > texture->width ||
-          (other->width == texture->width &&
-           other->height > texture->height))
-        break;
-
-      sibling = iter;
-    }
-
-  g_queue_insert_after_link (&self->by_width, sibling, &texture->width_link);
-
-  sibling = NULL;
-  for (GList *iter = self->by_height.head;
-       iter != NULL;
-       iter = iter->next)
-    {
-      GskGLTexture *other = iter->data;
-
-      if (other->height > texture->height ||
-          (other->height == texture->height &&
-           other->width > texture->width))
-        break;
-
-      sibling = iter;
-    }
-
-  g_queue_insert_after_link (&self->by_height, sibling, &texture->height_link);
+    gsk_gl_texture_free (texture);
+  else
+    g_queue_push_tail_link (&self->queue, &texture->link);
 }
 
 GskGLTexture *
@@ -153,60 +117,14 @@ gsk_gl_texture_pool_get (GskGLTexturePool *self,
                          int               width,
                          int               height,
                          int               min_filter,
-                         int               mag_filter,
-                         gboolean          always_create)
+                         int               mag_filter)
 {
   GskGLTexture *texture;
 
-  if (always_create)
-    goto create_texture;
-
-  if (width >= height)
-    {
-      for (GList *iter = self->by_width.head;
-           iter != NULL;
-           iter = iter->next)
-        {
-          texture = iter->data;
-
-          if (texture->width >= width &&
-              texture->height >= height &&
-              texture->min_filter == min_filter &&
-              texture->mag_filter == mag_filter)
-            {
-              g_queue_unlink (&self->by_width, &texture->width_link);
-              g_queue_unlink (&self->by_height, &texture->height_link);
-
-              return texture;
-            }
-        }
-    }
-  else
-    {
-      for (GList *iter = self->by_height.head;
-           iter != NULL;
-           iter = iter->next)
-        {
-          texture = iter->data;
-
-          if (texture->width >= width &&
-              texture->height >= height &&
-              texture->min_filter == min_filter &&
-              texture->mag_filter == mag_filter)
-            {
-              g_queue_unlink (&self->by_width, &texture->width_link);
-              g_queue_unlink (&self->by_height, &texture->height_link);
-
-              return texture;
-            }
-        }
-    }
-
-create_texture:
+  g_assert (self != NULL);
 
   texture = g_slice_new0 (GskGLTexture);
-  texture->width_link.data = texture;
-  texture->height_link.data = texture;
+  texture->link.data = texture;
   texture->min_filter = min_filter;
   texture->mag_filter = mag_filter;
 
@@ -241,8 +159,7 @@ gsk_gl_texture_new (guint  texture_id,
 
   texture = g_slice_new0 (GskGLTexture);
   texture->texture_id = texture_id;
-  texture->width_link.data = texture;
-  texture->height_link.data = texture;
+  texture->link.data = texture;
   texture->min_filter = min_filter;
   texture->mag_filter = mag_filter;
   texture->width = width;
diff --git a/gsk/next/gskgltexturepoolprivate.h b/gsk/next/gskgltexturepoolprivate.h
index 1410fa30d6..c55243e795 100644
--- a/gsk/next/gskgltexturepoolprivate.h
+++ b/gsk/next/gskgltexturepoolprivate.h
@@ -27,8 +27,7 @@ G_BEGIN_DECLS
 
 typedef struct _GskGLTexturePool
 {
-  GQueue by_width;
-  GQueue by_height;
+  GQueue queue;
 } GskGLTexturePool;
 
 struct _GskGLTextureSlice
@@ -50,9 +49,8 @@ struct _GskGLTextureNineSlice
 
 struct _GskGLTexture
 {
-  /* Used to sort by width/height in pool */
-  GList width_link;
-  GList height_link;
+  /* Used to insert into queue */
+  GList link;
 
   /* Identifier of the frame that created it */
   gint64 last_used_in_frame;
@@ -85,8 +83,7 @@ GskGLTexture                *gsk_gl_texture_pool_get       (GskGLTexturePool *se
                                                             int               width,
                                                             int               height,
                                                             int               min_filter,
-                                                            int               mag_filter,
-                                                            gboolean          always_create);
+                                                            int               mag_filter);
 void                         gsk_gl_texture_pool_put       (GskGLTexturePool *self,
                                                             GskGLTexture     *texture);
 GskGLTexture                *gsk_gl_texture_new            (guint             texture_id,


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