[gtk/wip/chergert/glproto: 478/526] remove append_val from hot path




commit 9498702ba3fa676a447e871defcc6e0148967ec1
Author: Christian Hergert <chergert redhat com>
Date:   Mon Feb 8 14:58:07 2021 -0800

    remove append_val from hot path
    
    we can pre-determine the array size for this so we can avoid extraneous
    calls in the hot path.

 gsk/next/gskgluniformstate.c        | 33 ++++++++++++++++++++++++---------
 gsk/next/gskgluniformstateprivate.h | 14 ++++++++------
 2 files changed, 32 insertions(+), 15 deletions(-)
---
diff --git a/gsk/next/gskgluniformstate.c b/gsk/next/gskgluniformstate.c
index 9512ad13ab..2d8e8020de 100644
--- a/gsk/next/gskgluniformstate.c
+++ b/gsk/next/gskgluniformstate.c
@@ -107,7 +107,7 @@ clear_program_info (gpointer data)
   GskGLUniformProgram *program_info = data;
 
   g_clear_pointer (&program_info->uniform_info, g_array_unref);
-  g_clear_pointer (&program_info->changed, g_array_unref);
+  g_clear_pointer (&program_info->changed, g_free);
 }
 
 GskGLUniformState *
@@ -155,14 +155,14 @@ program_changed (GskGLUniformState *state,
 {
   if (info->changed == FALSE)
     {
-      const GskGLUniformProgram *program_info = &g_array_index (state->program_info, GskGLUniformProgram, 
program);
+      GskGLUniformProgram *program_info = &g_array_index (state->program_info, GskGLUniformProgram, program);
 
       g_assert (program < state->program_info->len);
 
       info->changed = TRUE;
       info->initial = FALSE;
 
-      g_array_append_val (program_info->changed, location);
+      program_info->changed[program_info->n_changed++] = location;
     }
 }
 
@@ -179,8 +179,11 @@ gsk_gl_uniform_state_clear_program (GskGLUniformState *state,
 
   program_info = &g_array_index (state->program_info, GskGLUniformProgram, program);
 
-  g_clear_pointer (&program_info->changed, g_array_unref);
   g_clear_pointer (&program_info->uniform_info, g_array_unref);
+
+  program_info->n_changed = 0;
+  program_info->changed_len = 0;
+  g_clear_pointer (&program_info->changed, g_free);
 }
 
 static inline guint
@@ -197,7 +200,7 @@ alloc_alignment (guint current_pos,
   return align - masked;
 }
 
-static gpointer
+static inline gpointer
 alloc_uniform_data (GskGLUniformState *state,
                     guint              size,
                     guint             *offset)
@@ -291,7 +294,9 @@ setup_info:
 
       program_info = &g_array_index (state->program_info, GskGLUniformProgram, program);
       program_info->uniform_info = g_array_new (FALSE, TRUE, sizeof (GskGLUniformInfo));
-      program_info->changed = g_array_new (FALSE, FALSE, sizeof (guint));
+      program_info->changed = NULL;
+      program_info->n_changed = 0;
+      program_info->changed_len = 0;
     }
 
   g_assert (program_info != NULL);
@@ -318,6 +323,16 @@ setup_info:
   info->array_count = array_count;
   info->initial = TRUE;
 
+  /* Ensure we have enough space in program_info->changed to hold
+   * values up to this location so that we never have to allocate
+   * when marking a program changed.
+   */
+  if (location >= program_info->changed_len)
+    {
+      program_info->changed_len = location + 1;
+      program_info->changed = g_realloc_n (program_info->changed, program_info->changed_len, sizeof (guint));
+    }
+
   *infoptr = info;
 
   return state->values_buf + offset;
@@ -706,7 +721,7 @@ gsk_gl_uniform_state_set1fv (GskGLUniformState *state,
 
   if ((u = get_uniform (state, program, GSK_GL_UNIFORM_FORMAT_1FV, count, location, &info)))
     {
-      gboolean changed = info->initial || memcmp (u, value, sizeof *u  * count) != 0;
+      gboolean changed = info->initial || memcmp (u, value, sizeof *u * count) != 0;
 
       if (changed)
         {
@@ -813,7 +828,7 @@ gsk_gl_uniform_state_end_frame (GskGLUniformState *state)
 
   for (guint i = 0; i < state->program_info->len; i++)
     {
-      const GskGLUniformProgram *program_info = &g_array_index (state->program_info, GskGLUniformProgram, i);
+      GskGLUniformProgram *program_info = &g_array_index (state->program_info, GskGLUniformProgram, i);
 
       if (program_info->uniform_info == NULL)
         continue;
@@ -841,7 +856,7 @@ gsk_gl_uniform_state_end_frame (GskGLUniformState *state)
           allocator += size;
         }
 
-      program_info->changed->len = 0;
+      program_info->n_changed = 0;
     }
 
   state->values_pos = allocator;
diff --git a/gsk/next/gskgluniformstateprivate.h b/gsk/next/gskgluniformstateprivate.h
index 2e89ca9680..55df886ea4 100644
--- a/gsk/next/gskgluniformstateprivate.h
+++ b/gsk/next/gskgluniformstateprivate.h
@@ -34,7 +34,9 @@ typedef struct _GskGLUniformProgram
    * elements used to map location->info), we use this to determine the
    * specific uniforms that changed this frame.
    */
-  GArray *changed;
+  guint *changed;
+  guint  changed_len : 16;
+  guint  n_changed : 16;
 } GskGLUniformProgram;
 
 typedef struct _GskGLUniformState
@@ -211,12 +213,12 @@ gsk_gl_uniform_state_get_uniform_data (const GskGLUniformState *state,
       break;                                                                                       \
                                                                                                    \
     program_info = &g_array_index (state->program_info, GskGLUniformProgram, program_id);          \
-    if (program_info->changed->len == 0)                                                           \
+    if (program_info->n_changed == 0)                                                              \
       break;                                                                                       \
                                                                                                    \
-    for (guint z = 0; z < program_info->changed->len; z++)                                         \
+    for (guint z = 0; z < program_info->n_changed; z++)                                            \
       {                                                                                            \
-        guint location = g_array_index (program_info->changed, guint, z);                          \
+        guint location = program_info->changed[z];                                                 \
         GskGLUniformInfo *info = &g_array_index (program_info->uniform_info,                       \
                                                  GskGLUniformInfo,                                 \
                                                  location);                                        \
@@ -229,14 +231,14 @@ gsk_gl_uniform_state_get_uniform_data (const GskGLUniformState *state,
         info->send_corners = FALSE;                                                                \
       }                                                                                            \
                                                                                                    \
-    program_info->changed->len = 0;                                                                \
+    program_info->n_changed = 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;
+  return g_array_index (self->program_info, GskGLUniformProgram, program_id).n_changed;
 }
 
 G_END_DECLS


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