[gtk/wip/chergert/glproto: 908/920] avoid some repeated g_array_set_size() calls




commit 4867010646bcf8ae7fa8bfc7f5e766a3f9e0eecc
Author: Christian Hergert <chergert redhat com>
Date:   Thu Feb 4 14:31:27 2021 -0800

    avoid some repeated g_array_set_size() calls

 gsk/next/gskglcommandqueue.c        | 45 ++++++++++++++++++++++++++++---------
 gsk/next/gskgluniformstateprivate.h |  7 ++++++
 2 files changed, 41 insertions(+), 11 deletions(-)
---
diff --git a/gsk/next/gskglcommandqueue.c b/gsk/next/gskglcommandqueue.c
index 1f697912ec..76484a8532 100644
--- a/gsk/next/gskglcommandqueue.c
+++ b/gsk/next/gskglcommandqueue.c
@@ -373,17 +373,22 @@ gsk_gl_command_queue_uniform_snapshot_cb (const GskGLUniformInfo *info,
                                           guint                   location,
                                           gpointer                user_data)
 {
-  GskGLCommandQueue *self = user_data;
+  GArray *uniforms = user_data;
   GskGLCommandUniform *uniform;
+  guint index;
 
   g_assert (info != NULL);
   g_assert (info->initial == FALSE);
   g_assert (info->changed == TRUE);
-  g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
 
-  g_array_set_size (self->batch_uniforms, self->batch_uniforms->len+1);
+  /* To avoid calling g_array_set_size() a bunch in this callback,
+   * we've already "set_size()" before the callback was called and
+   * so we can instead be certain the size is large enough and use
+   * ++ on length directly.
+   */
+  index = uniforms->len++;
 
-  uniform = &g_array_index (self->batch_uniforms, GskGLCommandUniform, self->batch_uniforms->len-1);
+  uniform = &g_array_index (uniforms, GskGLCommandUniform, index);
   uniform->location = location;
   uniform->info = *info;
 }
@@ -393,6 +398,7 @@ gsk_gl_command_queue_end_draw (GskGLCommandQueue *self)
 {
   GskGLCommandBatch *last_batch;
   GskGLCommandBatch *batch;
+  guint n_changed;
 
   g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
   g_assert (self->batches->len > 0);
@@ -418,13 +424,30 @@ gsk_gl_command_queue_end_draw (GskGLCommandQueue *self)
   batch->draw.framebuffer = self->attachments->fbo.id;
   self->attachments->fbo.changed = FALSE;
 
-  /* Track the list of uniforms that changed */
-  batch->draw.uniform_offset = self->batch_uniforms->len;
-  gsk_gl_uniform_state_snapshot (self->uniforms,
-                                 batch->any.program,
-                                 gsk_gl_command_queue_uniform_snapshot_cb,
-                                 self);
-  batch->draw.uniform_count = self->batch_uniforms->len - batch->draw.uniform_offset;
+  /* To avoid many g_array_set_size() calls, we first resize the
+   * array to be large enough for all our changes. Then we just ++
+   * from the callback.
+   */
+  n_changed = gsk_gl_uniform_state_get_n_changed (self->uniforms, batch->any.program);
+
+  if (n_changed)
+    {
+      g_array_set_size (self->batch_uniforms, self->batch_uniforms->len + n_changed);
+      self->batch_uniforms->len -= n_changed;
+
+      /* Store information about uniforms that changed */
+      batch->draw.uniform_offset = self->batch_uniforms->len;
+      gsk_gl_uniform_state_snapshot (self->uniforms,
+                                     batch->any.program,
+                                     gsk_gl_command_queue_uniform_snapshot_cb,
+                                     self->batch_uniforms);
+      batch->draw.uniform_count = self->batch_uniforms->len - batch->draw.uniform_offset;
+    }
+  else
+    {
+      batch->draw.uniform_offset = 0;
+      batch->draw.uniform_count = 0;
+    }
 
   /* Track the bind attachments that changed */
   batch->draw.bind_offset = self->batch_binds->len;
diff --git a/gsk/next/gskgluniformstateprivate.h b/gsk/next/gskgluniformstateprivate.h
index b95a87e97e..2e89ca9680 100644
--- a/gsk/next/gskgluniformstateprivate.h
+++ b/gsk/next/gskgluniformstateprivate.h
@@ -232,6 +232,13 @@ gsk_gl_uniform_state_get_uniform_data (const GskGLUniformState *state,
     program_info->changed->len = 0;                                                                \
   } G_STMT_END
 
+static inline guint
+gsk_gl_uniform_state_get_n_changed (GskGLUniformState *self,
+                                    guint              program_id)
+{
+  return g_array_index (self->program_info, GskGLUniformProgram, program_id).changed->len;
+}
+
 G_END_DECLS
 
 #endif /* GSK_GL_UNIFORM_STATE_PRIVATE_H */


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