diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-03-13 17:54:15 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-03-14 16:49:31 -0400 |
commit | c1f98d6837f37a13925c55872e01faca1e99fda7 (patch) | |
tree | 2b5f9c54f9742fc1a9cc52572c7aef165482bea1 | |
parent | 3f60c39de4e39a4d10c7ad813739331e7d2abebd (diff) | |
download | gtk+-c1f98d6837f37a13925c55872e01faca1e99fda7.tar.gz |
ngl: Improve the gradient shaders
Use a define for MAX_COLOR_STOPS, and give the loop
a fixed limit.
-rw-r--r-- | gsk/ngl/resources/conic_gradient.glsl | 26 | ||||
-rw-r--r-- | gsk/ngl/resources/linear_gradient.glsl | 26 | ||||
-rw-r--r-- | 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)); } |