[gtk] gl renderer: Make RoundedRect work in gles



commit 1243174e5370f258dbd963895be430adbd708490
Author: Timm Bäder <mail baedert org>
Date:   Mon Dec 16 06:16:26 2019 +0100

    gl renderer: Make RoundedRect work in gles
    
    Which can't return struct types containing arrays. So let's revert to
    the previous version but still send the rect along as a vec4[3];

 gsk/gl/gskglrenderer.c                          | 47 +++++---------
 gsk/gl/gskglrenderopsprivate.h                  | 15 ++---
 gsk/resources/glsl/blur.glsl                    |  4 +-
 gsk/resources/glsl/border.glsl                  |  9 +--
 gsk/resources/glsl/color_matrix.glsl            |  2 +-
 gsk/resources/glsl/inset_shadow.glsl            |  7 ++-
 gsk/resources/glsl/outset_shadow.glsl           |  5 +-
 gsk/resources/glsl/preamble.fs.glsl             | 82 ++++++++++++++-----------
 gsk/resources/glsl/unblurred_outset_shadow.glsl | 10 +--
 9 files changed, 87 insertions(+), 94 deletions(-)
---
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index 999120cb01..ee52e72c77 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -53,30 +53,12 @@
                 g_assert_cmpint (self->program_name ## _program.program_name.uniform_basename ## _location, 
, -1); \
               }G_STMT_END
 
-#define INIT_PROGRAM_UNIFORM_RECT_LOCATION(program_name, uniform_basename) \
-              G_STMT_START{\
-                self->program_name ## _program.program_name.uniform_basename ## _bounds_location = \
-                              glGetUniformLocation(self->program_name ## _program.id, "u_" #uniform_basename 
".bounds");\
-                g_assert_cmpint (self->program_name ## _program.program_name.uniform_basename ## 
_bounds_location, >, -1); \
-                self->program_name ## _program.program_name.uniform_basename ## _corners_location = \
-                              glGetUniformLocation(self->program_name ## _program.id, "u_" #uniform_basename 
".corners");\
-                g_assert_cmpint (self->program_name ## _program.program_name.uniform_basename ## 
_corners_location, >, -1); \
-              }G_STMT_END
-
 #define INIT_COMMON_UNIFORM_LOCATION(program_ptr, uniform_basename) \
               G_STMT_START{\
                 program_ptr->uniform_basename ## _location =  \
                               glGetUniformLocation(program_ptr->id, "u_" #uniform_basename);\
               }G_STMT_END
 
-#define INIT_COMMON_UNIFORM_RECT_LOCATION(program_ptr, uniform_basename) \
-              G_STMT_START{\
-                program_ptr->uniform_basename ## _bounds_location =  \
-                              glGetUniformLocation(program_ptr->id, "u_" #uniform_basename ".bounds");\
-                program_ptr->uniform_basename ## _corners_location =  \
-                              glGetUniformLocation(program_ptr->id, "u_" #uniform_basename ".corners");\
-              }G_STMT_END
-
 typedef enum
 {
   FORCE_OFFSCREEN  = 1 << 0,
@@ -2521,19 +2503,22 @@ static inline void
 apply_clip_op (const Program *program,
                const OpClip  *op)
 {
-  glUniform4fv (program->clip_rect_bounds_location, 1, (float *)&op->clip.bounds);
+  int count;
 
   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);
+      count = 3;
     }
   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);
+      count = 1;
     }
+
+  glUniform4fv (program->clip_rect_location, count, (float *)&op->clip.bounds);
 }
 
 static inline void
@@ -2549,8 +2534,7 @@ apply_inset_shadow_op (const Program  *program,
   glUniform4fv (program->inset_shadow.color_location, 1, (float *)op->color);
   glUniform2fv (program->inset_shadow.offset_location, 1, op->offset);
   glUniform1f (program->inset_shadow.spread_location, op->spread);
-  glUniform4fv (program->inset_shadow.outline_rect_bounds_location, 1, (float *)&op->outline.bounds);
-  glUniform2fv (program->inset_shadow.outline_rect_corners_location, 4, (float *)&op->outline.corner);
+  glUniform4fv (program->inset_shadow.outline_rect_location, 3, (float *)&op->outline.bounds);
 }
 
 static inline void
@@ -2561,8 +2545,7 @@ apply_unblurred_outset_shadow_op (const Program  *program,
   glUniform4fv (program->unblurred_outset_shadow.color_location, 1, (float *)op->color);
   glUniform2fv (program->unblurred_outset_shadow.offset_location, 1, op->offset);
   glUniform1f (program->unblurred_outset_shadow.spread_location, op->spread);
-  glUniform4fv (program->unblurred_outset_shadow.outline_rect_bounds_location, 1, (float 
*)&op->outline.bounds);
-  glUniform2fv (program->unblurred_outset_shadow.outline_rect_corners_location, 4, (float 
*)&op->outline.corner);
+  glUniform4fv (program->unblurred_outset_shadow.outline_rect_location, 3, (float *)&op->outline.bounds);
 }
 
 static inline void
@@ -2570,8 +2553,7 @@ apply_outset_shadow_op (const Program  *program,
                         const OpShadow *op)
 {
   OP_PRINT (" -> outset shadow");
-  glUniform4fv (program->outset_shadow.outline_rect_bounds_location, 1, (float *)&op->outline.bounds);
-  glUniform2fv (program->outset_shadow.outline_rect_corners_location, 4, (float *)&op->outline.corner);
+  glUniform4fv (program->outset_shadow.outline_rect_location, 3, (float *)&op->outline.bounds);
 }
 
 static inline void
@@ -2599,8 +2581,7 @@ apply_border_op (const Program  *program,
 {
   OP_PRINT (" -> Border Outline");
 
-  glUniform4fv (program->border.outline_rect_bounds_location, 1, (float *)&op->outline.bounds);
-  glUniform2fv (program->border.outline_rect_corners_location, 4, (float *)&op->outline.corner);
+  glUniform4fv (program->border.outline_rect_location, 3, (float *)&op->outline.bounds);
 }
 
 static inline void
@@ -2751,7 +2732,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer  *self,
 
       INIT_COMMON_UNIFORM_LOCATION (prog, alpha);
       INIT_COMMON_UNIFORM_LOCATION (prog, source);
-      INIT_COMMON_UNIFORM_RECT_LOCATION (prog, clip_rect);
+      INIT_COMMON_UNIFORM_LOCATION (prog, clip_rect);
       INIT_COMMON_UNIFORM_LOCATION (prog, viewport);
       INIT_COMMON_UNIFORM_LOCATION (prog, projection);
       INIT_COMMON_UNIFORM_LOCATION (prog, modelview);
@@ -2782,21 +2763,21 @@ gsk_gl_renderer_create_programs (GskGLRenderer  *self,
   INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, color);
   INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, spread);
   INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, offset);
-  INIT_PROGRAM_UNIFORM_RECT_LOCATION (inset_shadow, outline_rect);
+  INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, outline_rect);
 
   /* outset shadow */
-  INIT_PROGRAM_UNIFORM_RECT_LOCATION (outset_shadow, outline_rect);
+  INIT_PROGRAM_UNIFORM_LOCATION (outset_shadow, outline_rect);
 
   /* unblurred outset shadow */
   INIT_PROGRAM_UNIFORM_LOCATION (unblurred_outset_shadow, color);
   INIT_PROGRAM_UNIFORM_LOCATION (unblurred_outset_shadow, spread);
   INIT_PROGRAM_UNIFORM_LOCATION (unblurred_outset_shadow, offset);
-  INIT_PROGRAM_UNIFORM_RECT_LOCATION (unblurred_outset_shadow, outline_rect);
+  INIT_PROGRAM_UNIFORM_LOCATION (unblurred_outset_shadow, outline_rect);
 
   /* border */
   INIT_PROGRAM_UNIFORM_LOCATION (border, color);
   INIT_PROGRAM_UNIFORM_LOCATION (border, widths);
-  INIT_PROGRAM_UNIFORM_RECT_LOCATION (border, outline_rect);
+  INIT_PROGRAM_UNIFORM_LOCATION (border, outline_rect);
 
   /* cross fade */
   INIT_PROGRAM_UNIFORM_LOCATION (cross_fade, progress);
diff --git a/gsk/gl/gskglrenderopsprivate.h b/gsk/gl/gskglrenderopsprivate.h
index 46355239c6..9011d4aaa3 100644
--- a/gsk/gl/gskglrenderopsprivate.h
+++ b/gsk/gl/gskglrenderopsprivate.h
@@ -47,8 +47,7 @@ struct _Program
   int viewport_location;
   int projection_location;
   int modelview_location;
-  int clip_rect_bounds_location;
-  int clip_rect_corners_location;
+  int clip_rect_location;
   union {
     struct {
       int color_location;
@@ -76,16 +75,13 @@ struct _Program
       int color_location;
       int spread_location;
       int offset_location;
-      int outline_rect_bounds_location;
-      int outline_rect_corners_location;
+      int outline_rect_location;
     } inset_shadow;
     struct {
-      int outline_rect_bounds_location;
-      int outline_rect_corners_location;
+      int outline_rect_location;
     } outset_shadow;
     struct {
-      int outline_rect_bounds_location;
-      int outline_rect_corners_location;
+      int outline_rect_location;
       int color_location;
       int spread_location;
       int offset_location;
@@ -93,8 +89,7 @@ struct _Program
     struct {
       int color_location;
       int widths_location;
-      int outline_rect_bounds_location;
-      int outline_rect_corners_location;
+      int outline_rect_location;
     } border;
     struct {
       int source2_location;
diff --git a/gsk/resources/glsl/blur.glsl b/gsk/resources/glsl/blur.glsl
index 4b0109bbfc..e3aecb867c 100644
--- a/gsk/resources/glsl/blur.glsl
+++ b/gsk/resources/glsl/blur.glsl
@@ -26,14 +26,14 @@ void main() {
 
   vec2 pixel_step = vec2(1.0) / u_blur_size;
 
-  float coefficientSum = 0;
+  float coefficientSum = 0.0;
   vec4 sum = Texture(u_source, vUv) * incrementalGaussian.x;
   coefficientSum += incrementalGaussian.x;
   incrementalGaussian.xy *= incrementalGaussian.yz;
 
   int pixels_per_side = int(floor(blur_radius / 2.0));
   for (int i = 1; i <= pixels_per_side; i++) {
-    vec2 p = i * pixel_step * u_blur_dir;
+    vec2 p = float(i) * pixel_step * u_blur_dir;
 
     sum += Texture(u_source, vUv - p) * incrementalGaussian.x;
     sum += Texture(u_source, vUv + p) * incrementalGaussian.x;
diff --git a/gsk/resources/glsl/border.glsl b/gsk/resources/glsl/border.glsl
index e919461cce..b791dceb4f 100644
--- a/gsk/resources/glsl/border.glsl
+++ b/gsk/resources/glsl/border.glsl
@@ -9,17 +9,18 @@ void main() {
 // FRAGMENT_SHADER:
 uniform vec4 u_color;
 uniform vec4 u_widths;
-uniform RoundedRect u_outline_rect;
+uniform vec4[3] u_outline_rect;
 
 void main() {
   vec4 f = gl_FragCoord;
   f.x += u_viewport.x;
   f.y = (u_viewport.y + u_viewport.w) - f.y;
 
-  RoundedRect rinside = rounded_rect_shrink (u_outline_rect, u_widths);
+  RoundedRect outside = create_rect(u_outline_rect);
+  RoundedRect inside = rounded_rect_shrink (outside, u_widths);
 
-  float alpha = clamp (rounded_rect_coverage (u_outline_rect, f.xy) -
-                       rounded_rect_coverage (rinside, f.xy),
+  float alpha = clamp (rounded_rect_coverage (outside, f.xy) -
+                       rounded_rect_coverage (inside, f.xy),
                        0.0, 1.0);
 
   /* Pre-multiply */
diff --git a/gsk/resources/glsl/color_matrix.glsl b/gsk/resources/glsl/color_matrix.glsl
index 7904eae70c..bd621432fd 100644
--- a/gsk/resources/glsl/color_matrix.glsl
+++ b/gsk/resources/glsl/color_matrix.glsl
@@ -20,7 +20,7 @@ void main() {
     color.rgb /= color.a;
 
   color = u_color_matrix * color + u_color_offset;
-  color = clamp(color, 0.0f, 1.0f);
+  color = clamp(color, 0.0, 1.0);
 
   color.rgb *= color.a;
 
diff --git a/gsk/resources/glsl/inset_shadow.glsl b/gsk/resources/glsl/inset_shadow.glsl
index fa0e46769b..c6518f1aa1 100644
--- a/gsk/resources/glsl/inset_shadow.glsl
+++ b/gsk/resources/glsl/inset_shadow.glsl
@@ -9,7 +9,7 @@ void main() {
 uniform float u_spread;
 uniform vec4 u_color;
 uniform vec2 u_offset;
-uniform RoundedRect u_outline_rect;
+uniform vec4[3] u_outline_rect;
 
 void main() {
   vec4 f = gl_FragCoord;
@@ -17,10 +17,11 @@ void main() {
   f.x += u_viewport.x;
   f.y = (u_viewport.y + u_viewport.w) - f.y;
 
-  RoundedRect inside = rounded_rect_shrink(u_outline_rect, vec4(u_spread));
+  RoundedRect outside = create_rect(u_outline_rect);
+  RoundedRect inside = rounded_rect_shrink(outside, vec4(u_spread));
   vec2 offset = vec2(u_offset.x, - u_offset.y);
   vec4 color = vec4(u_color.rgb * u_color.a, u_color.a);
-  color = color * clamp (rounded_rect_coverage (u_outline_rect, f.xy) -
+  color = color * clamp (rounded_rect_coverage (outside, f.xy) -
                          rounded_rect_coverage (inside, f.xy - offset),
                          0.0, 1.0);
   setOutputColor(color * u_alpha);
diff --git a/gsk/resources/glsl/outset_shadow.glsl b/gsk/resources/glsl/outset_shadow.glsl
index 150b5aafce..d052049c2d 100644
--- a/gsk/resources/glsl/outset_shadow.glsl
+++ b/gsk/resources/glsl/outset_shadow.glsl
@@ -6,7 +6,7 @@ void main() {
 }
 
 // FRAGMENT_SHADER:
-uniform RoundedRect u_outline_rect;
+uniform vec4[3] u_outline_rect;
 
 void main() {
   vec4 f = gl_FragCoord;
@@ -14,7 +14,8 @@ void main() {
   f.x += u_viewport.x;
   f.y = (u_viewport.y + u_viewport.w) - f.y;
 
+  RoundedRect outline = create_rect(u_outline_rect);
   vec4 color = Texture(u_source, vUv);
-  color = color * (1.0 -  clamp(rounded_rect_coverage (u_outline_rect, f.xy), 0.0, 1.0));
+  color = color * (1.0 -  clamp(rounded_rect_coverage(outline, f.xy), 0.0, 1.0));
   setOutputColor(color * u_alpha);
 }
diff --git a/gsk/resources/glsl/preamble.fs.glsl b/gsk/resources/glsl/preamble.fs.glsl
index 81ee188ef5..2c53b3d019 100644
--- a/gsk/resources/glsl/preamble.fs.glsl
+++ b/gsk/resources/glsl/preamble.fs.glsl
@@ -1,21 +1,26 @@
+#ifdef GSK_GL3
+precision highp float;
+#endif
 
-#if GDK_GL3
+#ifdef GSK_GLES
 precision highp float;
 #endif
 
+
 uniform sampler2D u_source;
 uniform mat4 u_projection;
 uniform mat4 u_modelview;
-uniform float u_alpha = 1.0;
+uniform float u_alpha;// = 1.0;
 uniform vec4 u_viewport;
 
 struct RoundedRect
 {
   vec4 bounds;
-  vec2 corners[4];
+  vec4 corner_widths;
+  vec4 corner_heights;
 };
 
-uniform RoundedRect u_clip_rect;
+uniform vec4[3] u_clip_rect;
 
 #if GSK_GLES
 varying vec2 vUv;
@@ -27,6 +32,16 @@ in vec2 vUv;
 out vec4 outputColor;
 #endif
 
+// Transform from a GskRoundedRect to a RoundedRect as we need it.
+RoundedRect
+create_rect(vec4 data[3])
+{
+  vec4 bounds = vec4(data[0].xy, data[0].xy + data[0].zw);
+  vec4 widths = vec4(data[1].x, data[1].z, data[2].x, data[2].z);
+  vec4 heights = vec4(data[1].y, data[1].w, data[2].y, data[2].w);
+  return RoundedRect(bounds, widths, heights);
+}
+
 float
 ellipsis_dist (vec2 p, vec2 radius)
 {
@@ -50,18 +65,18 @@ float
 rounded_rect_coverage (RoundedRect r, vec2 p)
 {
   if (p.x < r.bounds.x || p.y < r.bounds.y ||
-      p.x >= (r.bounds.x + r.bounds.z) || p.y >= (r.bounds.y + r.bounds.w))
+      p.x >= r.bounds.z || p.y >= r.bounds.w)
     return 0.0;
 
-  vec2 rad_tl = r.corners[0];
-  vec2 rad_tr = r.corners[1];
-  vec2 rad_br = r.corners[2];
-  vec2 rad_bl = r.corners[3];
+  vec2 rad_tl = vec2(r.corner_widths.x, r.corner_heights.x);
+  vec2 rad_tr = vec2(r.corner_widths.y, r.corner_heights.y);
+  vec2 rad_br = vec2(r.corner_widths.z, r.corner_heights.z);
+  vec2 rad_bl = vec2(r.corner_widths.w, r.corner_heights.w);
 
-  vec2 ref_tl = r.bounds.xy + r.corners[0];
-  vec2 ref_tr = vec2(r.bounds.x + r.bounds.z, r.bounds.y) + (r.corners[1] * vec2(-1, 1));
-  vec2 ref_br = vec2(r.bounds.x + r.bounds.z, r.bounds.y + r.bounds.w) - r.corners[2];
-  vec2 ref_bl = vec2(r.bounds.x, r.bounds.y + r.bounds.w) + (r.corners[3] * vec2(1, -1));
+  vec2 ref_tl = r.bounds.xy + vec2( r.corner_widths.x,  r.corner_heights.x);
+  vec2 ref_tr = r.bounds.zy + vec2(-r.corner_widths.y,  r.corner_heights.y);
+  vec2 ref_br = r.bounds.zw + vec2(-r.corner_widths.z, -r.corner_heights.z);
+  vec2 ref_bl = r.bounds.xw + vec2( r.corner_widths.w, -r.corner_heights.w);
 
   float d_tl = ellipsis_coverage(p, ref_tl, rad_tl);
   float d_tr = ellipsis_coverage(p, ref_tr, rad_tr);
@@ -82,39 +97,34 @@ rounded_rect_coverage (RoundedRect r, vec2 p)
 RoundedRect
 rounded_rect_shrink (RoundedRect r, vec4 amount)
 {
-  vec4 new_bounds = r.bounds;
-  vec2 new_corners[4];
-
-  new_bounds.xy += amount.wx;
-  new_bounds.zw -= amount.wx + amount.yz;
-
-  new_corners[0] = vec2(0);
-  new_corners[1] = vec2(0);
-  new_corners[2] = vec2(0);
-  new_corners[3] = vec2(0);
+  vec4 new_bounds = r.bounds + vec4(1.0,1.0,-1.0,-1.0) * amount.wxyz;
+  vec4 new_widths = vec4(0);
+  vec4 new_heights = vec4(0);
 
   // Left top
-  if (r.corners[0].x > 0 || r.corners[0].y > 0)
-    new_corners[0] = r.corners[0] - amount.wx;
+  if (r.corner_widths.x  > 0.0) new_widths.x = r.corner_widths.x - amount.w;
+  if (r.corner_heights.x > 0.0) new_heights.x = r.corner_heights.x - amount.x;
 
-  // top right
-  if (r.corners[1].x > 0 || r.corners[1].y > 0)
-    new_corners[1] = r.corners[1] - amount.yx;
+  // Top right
+  if (r.corner_widths.y  > 0.0) new_widths.y = r.corner_widths.y - amount.y;
+  if (r.corner_heights.y > 0.0) new_heights.y = r.corner_heights.y - amount.x;
 
   // Bottom right
-  if (r.corners[2].x > 0 || r.corners[2].y > 0)
-    new_corners[2] = r.corners[2] - amount.yz;
+  if (r.corner_widths.z  > 0.0) new_widths.z = r.corner_widths.z - amount.y;
+  if (r.corner_heights.z > 0.0) new_heights.z = r.corner_heights.z - amount.z;
 
   // Bottom left
-  if (r.corners[3].x > 0 || r.corners[3].y > 0)
-    new_corners[3] = r.corners[3] - amount.wz;
+  if (r.corner_widths.w  > 0.0) new_widths.w = r.corner_widths.w - amount.w;
+  if (r.corner_heights.w > 0.0) new_heights.w = r.corner_heights.w - amount.z;
 
-  return RoundedRect (new_bounds, new_corners);
+  return RoundedRect (new_bounds, new_widths, new_heights);
 }
 
 vec4 Texture(sampler2D sampler, vec2 texCoords) {
 #if GSK_GLES
   return texture2D(sampler, texCoords);
+#elif GSK_LEGACY
+  return texture2D(sampler, texCoords);
 #else
   return texture(sampler, texCoords);
 #endif
@@ -127,9 +137,11 @@ void setOutputColor(vec4 color) {
   f.y = (u_viewport.y + u_viewport.w) - f.y;
 
 #if GSK_GLES
-  gl_FragColor = color * rounded_rect_coverage(u_clip_rect, f.xy);
+  gl_FragColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy);
+#elif GSK_LEGACY
+  gl_FragColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy);
 #else
-  outputColor = color * rounded_rect_coverage(u_clip_rect, f.xy);
+  outputColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy);
 #endif
   /*outputColor = color;*/
 }
diff --git a/gsk/resources/glsl/unblurred_outset_shadow.glsl b/gsk/resources/glsl/unblurred_outset_shadow.glsl
index fa14f11629..e50db29cd3 100644
--- a/gsk/resources/glsl/unblurred_outset_shadow.glsl
+++ b/gsk/resources/glsl/unblurred_outset_shadow.glsl
@@ -9,7 +9,7 @@ void main() {
 uniform float u_spread;
 uniform vec4 u_color;
 uniform vec2 u_offset;
-uniform RoundedRect u_outline_rect;
+uniform vec4[3] u_outline_rect;
 
 void main() {
   vec4 f = gl_FragCoord;
@@ -17,12 +17,14 @@ void main() {
   f.x += u_viewport.x;
   f.y = (u_viewport.y + u_viewport.w) - f.y;
 
-  RoundedRect outline = rounded_rect_shrink(u_outline_rect, vec4(- u_spread));
+
+  RoundedRect inside = create_rect(u_outline_rect);
+  RoundedRect outside = rounded_rect_shrink(inside, vec4(- u_spread));
 
   vec2 offset = vec2(u_offset.x, - u_offset.y);
   vec4 color = vec4(u_color.rgb * u_color.a, u_color.a);
-  color = color * clamp (rounded_rect_coverage (outline, f.xy - offset) -
-                         rounded_rect_coverage (u_outline_rect, f.xy),
+  color = color * clamp (rounded_rect_coverage (outside, f.xy - offset) -
+                         rounded_rect_coverage (inside, f.xy),
                          0.0, 1.0);
   setOutputColor(color * u_alpha);
 }


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