[gtk/wip/chergert/glproto] handle changes to array length



commit 468d5ff9b4e1e96827d741bd2c1c301b3abb4395
Author: Christian Hergert <chergert redhat com>
Date:   Fri Jan 29 12:30:58 2021 -0800

    handle changes to array length
    
    this is important when the array length changes such as when n_color_stops
    means we extend the length of an array.

 gsk/next/gskgluniformstate.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)
---
diff --git a/gsk/next/gskgluniformstate.c b/gsk/next/gskgluniformstate.c
index 3006b8977d..6fb070b6e0 100644
--- a/gsk/next/gskgluniformstate.c
+++ b/gsk/next/gskgluniformstate.c
@@ -73,6 +73,8 @@ static guint8 uniform_sizes[] = {
     g_assert (uniform_sizes[format] > 0);                                                         \
     u = alloc_uniform_data(state->uniform_data, uniform_sizes[format] * MAX (1, count), &offset); \
     (info)->offset = offset;                                                                      \
+    /* We might have increased array length */                                                    \
+    (info)->array_count = count;                                                                  \
   } G_STMT_END
 
 typedef struct
@@ -174,6 +176,8 @@ alloc_uniform_data (GByteArray *buffer,
   guint old_len = buffer->len;
 
   g_assert (size > 0);
+  g_assert (align == 4 || align == 8 || align == 16);
+  g_assert (masked < align);
 
   /* Try to give a more natural alignment based on the size
    * of the uniform. In case it's greater than 4 try to at least
@@ -229,10 +233,23 @@ get_uniform (GskGLUniformState  *state,
       if (info->format == 0)
         goto setup_info;
 
-      if G_LIKELY (format == info->format && array_count <= info->array_count)
+      if G_LIKELY (format == info->format)
         {
-          *infoptr = info;
-          return state->uniform_data->data + info->offset;
+          if G_LIKELY (array_count <= info->array_count)
+            {
+              *infoptr = info;
+              return state->uniform_data->data + info->offset;
+            }
+
+          /* We found the uniform, but there is not enough space for the
+           * amount that was requested. Instead, allocate new space and
+           * set the value to "initial" so that the caller just writes
+           * over the previous value.
+           *
+           * This can happen when using dynamic array lengths like the
+           * "n_color_stops" in gradient shaders.
+           */
+          goto setup_info;
         }
       else
         {


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