From 976a05f6eb55bc37ebb58a1d52f8e015701fe667 Mon Sep 17 00:00:00 2001 From: Fabio Lagalla Date: Tue, 26 Jan 2021 12:46:22 +0100 Subject: [PATCH] gskglrenderer: First class support of repeating-linear-gradient --- gsk/gl/gskglrenderer.c | 6 +++++- gsk/gl/gskglrenderops.c | 2 ++ gsk/gl/gskglrenderopsprivate.h | 2 ++ gsk/gl/opbuffer.h | 1 + gsk/resources/glsl/linear_gradient.glsl | 5 +++++ 5 files changed, 15 insertions(+), 1 deletion(-) diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c index 4807dbfba1..026c827ab5 100644 --- a/gsk/gl/gskglrenderer.c +++ b/gsk/gl/gskglrenderer.c @@ -1452,6 +1452,7 @@ render_linear_gradient_node (GskGLRenderer *self, ops_set_linear_gradient (builder, n_color_stops, stops, + gsk_render_node_get_node_type (node) == GSK_REPEATING_LINEAR_GRADIENT_NODE, builder->dx + start->x, builder->dy + start->y, builder->dx + end->x, @@ -3044,6 +3045,7 @@ apply_linear_gradient_op (const Program *program, glUniform4f (program->linear_gradient.points_location, op->start_point[0], op->start_point[1], op->end_point[0] - op->start_point[0], op->end_point[1] - op->start_point[1]); + glUniform1i (program->linear_gradient.repeat_location, op->repeat); } static inline void @@ -3385,6 +3387,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self, /* linear gradient */ INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient, color_stops); INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient, num_color_stops); + INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient, repeat); INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient, points); /* radial gradient */ @@ -3742,6 +3745,8 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self, break; case GSK_LINEAR_GRADIENT_NODE: + /* Intentional fall-through */ + case GSK_REPEATING_LINEAR_GRADIENT_NODE: render_linear_gradient_node (self, node, builder); break; @@ -3812,7 +3817,6 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self, render_gl_shader_node (self, node, builder); break; - case GSK_REPEATING_LINEAR_GRADIENT_NODE: case GSK_REPEATING_RADIAL_GRADIENT_NODE: case GSK_CAIRO_NODE: default: diff --git a/gsk/gl/gskglrenderops.c b/gsk/gl/gskglrenderops.c index 8bd420e7bd..ec14be1e13 100644 --- a/gsk/gl/gskglrenderops.c +++ b/gsk/gl/gskglrenderops.c @@ -859,6 +859,7 @@ void ops_set_linear_gradient (RenderOpBuilder *self, guint n_color_stops, const GskColorStop *color_stops, + bool repeat, float start_x, float start_y, float end_x, @@ -912,6 +913,7 @@ ops_set_linear_gradient (RenderOpBuilder *self, sizeof (GskColorStop) * real_n_color_stops); } + op->repeat = repeat; op->start_point[0] = start_x; op->start_point[1] = start_y; op->end_point[0] = end_x; diff --git a/gsk/gl/gskglrenderopsprivate.h b/gsk/gl/gskglrenderopsprivate.h index ada8ed43b2..ccc63ab074 100644 --- a/gsk/gl/gskglrenderopsprivate.h +++ b/gsk/gl/gskglrenderopsprivate.h @@ -119,6 +119,7 @@ struct _Program int num_color_stops_location; int color_stops_location; int points_location; + int repeat_location; } linear_gradient; struct { int num_color_stops_location; @@ -315,6 +316,7 @@ void ops_set_unblurred_outset_shadow (RenderOpBuilder *se void ops_set_linear_gradient (RenderOpBuilder *self, guint n_color_stops, const GskColorStop *color_stops, + bool repeat, float start_x, float start_y, float end_x, diff --git a/gsk/gl/opbuffer.h b/gsk/gl/opbuffer.h index db9b5c9425..4241214a37 100644 --- a/gsk/gl/opbuffer.h +++ b/gsk/gl/opbuffer.h @@ -146,6 +146,7 @@ typedef struct IntUniformValue n_color_stops; float start_point[2]; float end_point[2]; + bool repeat; } OpLinearGradient; typedef struct diff --git a/gsk/resources/glsl/linear_gradient.glsl b/gsk/resources/glsl/linear_gradient.glsl index aa90b846e0..cc90392c06 100644 --- a/gsk/resources/glsl/linear_gradient.glsl +++ b/gsk/resources/glsl/linear_gradient.glsl @@ -46,6 +46,7 @@ uniform highp int u_num_color_stops; // Why? Because it works like this. #endif uniform float u_color_stops[6 * 5]; +uniform bool u_repeat; _NOPERSPECTIVE_ _IN_ vec4 info; @@ -65,6 +66,10 @@ vec4 get_color(int index) { void main() { float offset = dot(info.xy, info.zw); + if (u_repeat) { + offset = fract(offset); + } + if (offset < get_offset(0)) { gskSetOutputColor(gsk_scaled_premultiply(get_color(0), u_alpha)); return;