gl renderer: Only send clip corners if we need to
authorTimm Bäder <mail@baedert.org>
Sat, 14 Dec 2019 14:41:32 +0000 (15:41 +0100)
committerTimm Bäder <mail@baedert.org>
Tue, 7 Jan 2020 16:27:15 +0000 (17:27 +0100)
We change the clip bounds a lot more ofthen than the clip corners and
they are already split up in the shader, so only send the corners if we
need to.

gsk/gl/gskglrenderer.c
gsk/gl/gskglrenderops.c
gsk/gl/opbuffer.h

index 1713c5e7578f0b685a150abade09e1fff0f456f6..7f7767097723be9c54e9702d740282a66a68179f 100644 (file)
@@ -2521,9 +2521,19 @@ static inline void
 apply_clip_op (const Program *program,
                const OpClip  *op)
 {
-  OP_PRINT (" -> Clip: %s", gsk_rounded_rect_to_string (&op->clip));
   glUniform4fv (program->clip_rect_bounds_location, 1, (float *)&op->clip.bounds);
-  glUniform2fv (program->clip_rect_corners_location, 4, (float *)&op->clip.corner);
+
+  if (op->send_corners)
+    {
+      OP_PRINT (" -> Clip: %s", gsk_rounded_rect_to_string (&op->clip));
+      glUniform2fv (program->clip_rect_corners_location, 4, (float *)&op->clip.corner);
+    }
+  else
+    {
+      OP_PRINT (" -> clip: %f, %f, %f, %f",
+                op->clip.bounds.origin.x, op->clip.bounds.origin.y,
+                op->clip.bounds.size.width, op->clip.bounds.size.height);
+    }
 }
 
 static inline void
index c2c7858dfbe6d09e69a4dbeb74298d0f1543f06e..5ab089493f13bcd762bb777e062136213101d26b 100644 (file)
@@ -8,6 +8,23 @@ rect_equal (const graphene_rect_t *a,
   return memcmp (a, b, sizeof (graphene_rect_t)) == 0;
 }
 
+static inline gboolean
+rounded_rect_corners_equal (const GskRoundedRect *r1,
+                            const GskRoundedRect *r2)
+{
+  int i;
+
+  if (!r1)
+    return FALSE;
+
+  for (i = 0; i < 4; i ++)
+    if (r1->corner[i].width != r2->corner[i].width ||
+        r1->corner[i].height != r2->corner[i].height)
+      return FALSE;
+
+  return TRUE;
+}
+
 static inline ProgramState *
 get_current_program_state (RenderOpBuilder *builder)
 {
@@ -252,6 +269,7 @@ ops_set_program (RenderOpBuilder *builder,
 
       opc = ops_begin (builder, OP_CHANGE_CLIP);
       opc->clip = *builder->current_clip;
+      opc->send_corners = !rounded_rect_corners_equal (builder->current_clip, &program_state->clip);
       program_state->clip = *builder->current_clip;
     }
 
@@ -273,15 +291,25 @@ ops_set_clip (RenderOpBuilder      *builder,
   OpClip *op;
 
   if (current_program_state &&
-      memcmp (&current_program_state->clip, clip,sizeof (GskRoundedRect)) == 0)
+      rounded_rect_equal (&current_program_state->clip, clip))
     return;
 
   if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_CLIP)))
-    op = op_buffer_add (&builder->render_ops, OP_CHANGE_CLIP);
+    {
+      op = op_buffer_add (&builder->render_ops, OP_CHANGE_CLIP);
+      op->send_corners = !current_program_state ||
+                         !rounded_rect_corners_equal (&current_program_state->clip, clip);
+    }
+  else
+    {
+      /* If the op before sent the corners, this one needs, too */
+      op->send_corners |= !current_program_state ||
+                          !rounded_rect_corners_equal (&current_program_state->clip, clip);
+    }
 
   op->clip = *clip;
 
-  if (builder->current_program != NULL)
+  if (current_program_state)
     current_program_state->clip = *clip;
 }
 
index 04ae79949099c66f5fdde9dca1af6e06f50e5cb9..8578bc108be644a7fe7cc76b96a73e3462d8c883 100644 (file)
@@ -88,6 +88,7 @@ typedef struct
 typedef struct
 {
   GskRoundedRect clip;
+  guint send_corners: 1;
 } OpClip;
 
 typedef struct