[gtk/ngl-less-shaders: 7/13] ngl: Improve the gradient shaders




commit b8993bfef480d464d5583c25a74f88995a13bb9c
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Mar 13 17:54:15 2021 -0500

    ngl: Improve the gradient shaders
    
    Use a define for MAX_COLOR_STOPS, and give the loop
    a fixed limit.

 gsk/ngl/resources/conic_gradient.glsl  | 26 ++++++++++++++++----------
 gsk/ngl/resources/linear_gradient.glsl | 26 ++++++++++++++++----------
 gsk/ngl/resources/radial_gradient.glsl | 26 ++++++++++++++++----------
 3 files changed, 48 insertions(+), 30 deletions(-)
---
diff --git a/gsk/ngl/resources/conic_gradient.glsl b/gsk/ngl/resources/conic_gradient.glsl
index afb427bb15..758efe1e1e 100644
--- a/gsk/ngl/resources/conic_gradient.glsl
+++ b/gsk/ngl/resources/conic_gradient.glsl
@@ -18,6 +18,8 @@ void main() {
 // FRAGMENT_SHADER:
 // conic_gradient.glsl
 
+#define MAX_COLOR_STOPS 6
+
 #ifdef GSK_LEGACY
 uniform int u_num_color_stops;
 #else
@@ -25,7 +27,7 @@ uniform highp int u_num_color_stops; // Why? Because it works like this.
 #endif
 
 uniform vec4 u_geometry;
-uniform float u_color_stops[6 * 5];
+uniform float u_color_stops[MAX_COLOR_STOPS * 5];
 
 _NOPERSPECTIVE_ _IN_ vec2 coord;
 
@@ -50,27 +52,31 @@ void main() {
   // fract() does the modulo here, so now we have progress
   // into the current conic
   float offset = fract(angle * u_geometry.z + u_geometry.w);
+  float curr_offset;
+  float next_offset;
 
-  if (offset < get_offset(0)) {
+  next_offset = get_offset(0);
+  if (offset < next_offset) {
     gskSetOutputColor(gsk_scaled_premultiply(get_color(0), u_alpha));
     return;
   }
 
-  int n = u_num_color_stops - 1;
-  for (int i = 0; i < n; i++) {
-    float curr_offset = get_offset(i);
-    float next_offset = get_offset(i + 1);
+  if (offset >= get_offset(u_num_color_stops - 1)) {
+    gskSetOutputColor(gsk_scaled_premultiply(get_color(u_num_color_stops - 1), u_alpha));
+    return;
+  }
+
+  for (int i = 0; i < MAX_COLOR_STOPS; i++) {
+    curr_offset = next_offset;
+    next_offset = get_offset(i + 1);
 
-    if (offset >= curr_offset && offset < next_offset) {
+    if (offset < next_offset) {
       float f = (offset - curr_offset) / (next_offset - curr_offset);
       vec4 curr_color = gsk_premultiply(get_color(i));
       vec4 next_color = gsk_premultiply(get_color(i + 1));
       vec4 color = mix(curr_color, next_color, f);
-
       gskSetOutputColor(color * u_alpha);
       return;
     }
   }
-
-  gskSetOutputColor(gsk_scaled_premultiply(get_color(n), u_alpha));
 }
diff --git a/gsk/ngl/resources/linear_gradient.glsl b/gsk/ngl/resources/linear_gradient.glsl
index 1a2f2675e0..d5c1d962f4 100644
--- a/gsk/ngl/resources/linear_gradient.glsl
+++ b/gsk/ngl/resources/linear_gradient.glsl
@@ -42,13 +42,15 @@ void main() {
 // FRAGMENT_SHADER:
 // linear_gradient.glsl
 
+#define MAX_COLOR_STOPS 6
+
 #ifdef GSK_LEGACY
 uniform int u_num_color_stops;
 #else
 uniform highp int u_num_color_stops; // Why? Because it works like this.
 #endif
 
-uniform float u_color_stops[6 * 5];
+uniform float u_color_stops[MAX_COLOR_STOPS * 5];
 uniform bool u_repeat;
 
 _NOPERSPECTIVE_ _IN_ vec4 info;
@@ -68,31 +70,35 @@ vec4 get_color(int index) {
 
 void main() {
   float offset = dot(info.xy, info.zw);
+  float curr_offset;
+  float next_offset;
 
   if (u_repeat) {
     offset = fract(offset);
   }
 
-  if (offset < get_offset(0)) {
+  next_offset = get_offset(0);
+  if (offset < next_offset) {
     gskSetOutputColor(gsk_scaled_premultiply(get_color(0), u_alpha));
     return;
   }
 
-  int n = u_num_color_stops - 1;
-  for (int i = 0; i < n; i++) {
-    float curr_offset = get_offset(i);
-    float next_offset = get_offset(i + 1);
+  if (offset >= get_offset(u_num_color_stops - 1)) {
+    gskSetOutputColor(gsk_scaled_premultiply(get_color(u_num_color_stops - 1), u_alpha));
+    return;
+  }
+
+  for (int i = 0; i < MAX_COLOR_STOPS; i++) {
+    curr_offset = next_offset;
+    next_offset = get_offset(i + 1);
 
-    if (offset >= curr_offset && offset < next_offset) {
+    if (offset < next_offset) {
       float f = (offset - curr_offset) / (next_offset - curr_offset);
       vec4 curr_color = gsk_premultiply(get_color(i));
       vec4 next_color = gsk_premultiply(get_color(i + 1));
       vec4 color = mix(curr_color, next_color, f);
-
       gskSetOutputColor(color * u_alpha);
       return;
     }
   }
-
-  gskSetOutputColor(gsk_scaled_premultiply(get_color(n), u_alpha));
 }
diff --git a/gsk/ngl/resources/radial_gradient.glsl b/gsk/ngl/resources/radial_gradient.glsl
index e8b57ef635..1a6774dff5 100644
--- a/gsk/ngl/resources/radial_gradient.glsl
+++ b/gsk/ngl/resources/radial_gradient.glsl
@@ -20,6 +20,8 @@ void main() {
 // FRAGMENT_SHADER:
 // radial_gradient.glsl
 
+#define MAX_COLOR_STOPS 6
+
 #ifdef GSK_LEGACY
 uniform int u_num_color_stops;
 #else
@@ -28,7 +30,7 @@ uniform highp int u_num_color_stops;
 
 uniform bool u_repeat;
 uniform vec2 u_range;
-uniform float u_color_stops[6 * 5];
+uniform float u_color_stops[MAX_COLOR_STOPS * 5];
 
 _NOPERSPECTIVE_ _IN_ vec2 coord;
 
@@ -48,31 +50,35 @@ vec4 get_color(int index) {
 void main() {
   // Reverse scale
   float offset = length(coord) * u_range.x + u_range.y;
+  float curr_offset;
+  float next_offset;
 
   if (u_repeat) {
     offset = fract(offset);
   }
 
-  if (offset < get_offset(0)) {
+  next_offset = get_offset(0);
+  if (offset < next_offset) {
     gskSetOutputColor(gsk_scaled_premultiply(get_color(0), u_alpha));
     return;
   }
 
-  int n = u_num_color_stops - 1;
-  for (int i = 0; i < n; i++) {
-    float curr_offset = get_offset(i);
-    float next_offset = get_offset(i + 1);
+  if (offset >= get_offset(u_num_color_stops - 1)) {
+    gskSetOutputColor(gsk_scaled_premultiply(get_color(u_num_color_stops - 1), u_alpha));
+    return;
+  }
+
+  for (int i = 0; i < MAX_COLOR_STOPS; i++) {
+    curr_offset = next_offset;
+    next_offset = get_offset(i + 1);
 
-    if (offset >= curr_offset && offset < next_offset) {
+    if (offset < next_offset) {
       float f = (offset - curr_offset) / (next_offset - curr_offset);
       vec4 curr_color = gsk_premultiply(get_color(i));
       vec4 next_color = gsk_premultiply(get_color(i + 1));
       vec4 color = mix(curr_color, next_color, f);
-
       gskSetOutputColor(color * u_alpha);
       return;
     }
   }
-
-  gskSetOutputColor(gsk_scaled_premultiply(get_color(n), u_alpha));
 }


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