From: Timm Bäder Date: Thu, 15 Mar 2018 16:27:19 +0000 (+0100) Subject: gl renderer: Fix clipped borders X-Git-Tag: archive/raspbian/4.4.1+ds1-2+rpi1^2~18^2~22^2~973 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=0a7880110ed78bec6f2dcf78d180d74b4952e129;p=gtk4.git gl renderer: Fix clipped borders Stop abusing the clip rect for borders. --- diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c index 7afc34879c..b82c2e53c3 100644 --- a/gsk/gl/gskglrenderer.c +++ b/gsk/gl/gskglrenderer.c @@ -242,28 +242,6 @@ struct _GskGLRendererClass G_DEFINE_TYPE (GskGLRenderer, gsk_gl_renderer, GSK_TYPE_RENDERER) -static inline void -rounded_rect_intersect (GskGLRenderer *self, - RenderOpBuilder *builder, - const GskRoundedRect *rect, - GskRoundedRect *dest) -{ - graphene_rect_t transformed_rect; - graphene_rect_t intersection; - int i; - - graphene_matrix_transform_bounds (&builder->current_modelview, &rect->bounds, &transformed_rect); - graphene_rect_intersection (&transformed_rect, &builder->current_clip.bounds, - &intersection); - - dest->bounds = intersection; - for (i = 0; i < 4; i ++) - { - dest->corner[i].width = rect->corner[i].width * self->scale_factor; - dest->corner[i].height = rect->corner[i].height * self->scale_factor; - } -} - static inline void rounded_rect_to_floats (GskGLRenderer *self, RenderOpBuilder *builder, @@ -429,10 +407,9 @@ render_border_node (GskGLRenderer *self, const GdkRGBA *colors = gsk_border_node_peek_colors (node); const GskRoundedRect *rounded_outline = gsk_border_node_peek_outline (node); const float *og_widths = gsk_border_node_peek_widths (node); + GskRoundedRect outline; float widths[4]; - const gboolean needs_clip = TRUE;/*!gsk_rounded_rect_is_rectilinear (rounded_outline);*/ int i; - GskRoundedRect prev_clip; struct { float w; float h; @@ -490,22 +467,6 @@ render_border_node (GskGLRenderer *self, for (i = 0; i < 4; i ++) widths[i] *= self->scale_factor; - if (needs_clip) - { - GskRoundedRect child_clip; - - ops_set_program (builder, &self->border_program); - - rounded_rect_intersect (self, builder, rounded_outline, &child_clip); - prev_clip = ops_set_clip (builder, &child_clip); - - ops_set_border (builder, widths); - } - else - { - ops_set_program (builder, &self->color_program); - } - { const GskQuadVertex side_data[4][6] = { /* Top */ @@ -555,6 +516,19 @@ render_border_node (GskGLRenderer *self, /* We sort them by color */ sort_border_sides (colors, indices); + /* Prepare outline */ + outline = *rounded_outline; + graphene_matrix_transform_bounds (&builder->current_modelview, + &outline.bounds, &outline.bounds); + for (i = 0; i < 4; i ++) + { + outline.corner[i].width *= self->scale_factor; + outline.corner[i].height *= self->scale_factor; + } + + ops_set_program (builder, &self->border_program); + ops_set_border (builder, widths, &outline); + for (i = 0; i < 4; i ++) { if (widths[indices[i]] > 0) @@ -564,9 +538,6 @@ render_border_node (GskGLRenderer *self, } } } - - if (needs_clip) - ops_set_clip (builder, &prev_clip); } static inline void @@ -1696,9 +1667,29 @@ static inline void apply_border_op (const Program *program, const RenderOp *op) { + const GskRoundedRect *o = &op->border.outline; + float outline[4]; + float widths[4]; + float heights[4]; + int i; OP_PRINT (" -> Border (%f, %f, %f, %f)", op->border.widths[0], op->border.widths[1], op->border.widths[2], op->border.widths[3]); + + outline[0] = o->bounds.origin.x; + outline[1] = o->bounds.origin.y; + outline[2] = o->bounds.size.width; + outline[3] = o->bounds.size.height; + + for (i = 0; i < 4; i ++) + { + widths[i] = o->corner[i].width; + heights[i] = o->corner[i].height; + } + glUniform4fv (program->border.widths_location, 1, op->border.widths); + glUniform4fv (program->border.outline_location, 1, outline); + glUniform4fv (program->border.corner_widths_location, 1, widths); + glUniform4fv (program->border.corner_heights_location, 1, heights); } static inline void @@ -1889,6 +1880,9 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self, /* border */ INIT_PROGRAM_UNIFORM_LOCATION (border, color); INIT_PROGRAM_UNIFORM_LOCATION (border, widths); + INIT_PROGRAM_UNIFORM_LOCATION (border, outline); + INIT_PROGRAM_UNIFORM_LOCATION (border, corner_widths); + INIT_PROGRAM_UNIFORM_LOCATION (border, corner_heights); /* cross fade */ INIT_PROGRAM_UNIFORM_LOCATION (cross_fade, progress); diff --git a/gsk/gl/gskglrenderops.c b/gsk/gl/gskglrenderops.c index 0520ff769b..b36c06d8d0 100644 --- a/gsk/gl/gskglrenderops.c +++ b/gsk/gl/gskglrenderops.c @@ -309,13 +309,18 @@ ops_set_color_matrix (RenderOpBuilder *builder, } void -ops_set_border (RenderOpBuilder *builder, - const float *widths) +ops_set_border (RenderOpBuilder *builder, + const float *widths, + const GskRoundedRect *outline) { RenderOp op; + /* TODO: Assert that current_program == border program? */ + if (memcmp (&builder->program_state[builder->current_program->index].border.widths, - widths, sizeof (float) * 4) == 0) + widths, sizeof (float) * 4) == 0 && + memcmp (&builder->program_state[builder->current_program->index].border.outline, + outline, sizeof (GskRoundedRect)) == 0) return; memcpy (&builder->program_state[builder->current_program->index].border.widths, @@ -326,6 +331,7 @@ ops_set_border (RenderOpBuilder *builder, op.border.widths[1] = widths[1]; op.border.widths[2] = widths[2]; op.border.widths[3] = widths[3]; + op.border.outline = *outline; g_array_append_val (builder->render_ops, op); } diff --git a/gsk/gl/gskglrenderopsprivate.h b/gsk/gl/gskglrenderopsprivate.h index b700b75f94..7d6fe8a821 100644 --- a/gsk/gl/gskglrenderopsprivate.h +++ b/gsk/gl/gskglrenderopsprivate.h @@ -106,6 +106,9 @@ typedef struct struct { int color_location; int widths_location; + int outline_location; + int corner_widths_location; + int corner_heights_location; } border; struct { int source2_location; @@ -183,6 +186,7 @@ typedef struct struct { float widths[4]; float color[4]; + GskRoundedRect outline; } border; struct { float progress; @@ -211,6 +215,7 @@ typedef struct struct { float widths[4]; float color[4]; + GskRoundedRect outline; } border; }; } program_state[GL_N_PROGRAMS]; @@ -265,7 +270,8 @@ void ops_set_color_matrix (RenderOpBuilder *builder, const graphene_vec4_t *offset); void ops_set_border (RenderOpBuilder *builder, - const float *widths); + const float *widths, + const GskRoundedRect *outline); void ops_set_border_color (RenderOpBuilder *builder, const GdkRGBA *color); diff --git a/gsk/resources/glsl/border.fs.glsl b/gsk/resources/glsl/border.fs.glsl index 59b1b816e5..970c5739ea 100644 --- a/gsk/resources/glsl/border.fs.glsl +++ b/gsk/resources/glsl/border.fs.glsl @@ -1,20 +1,21 @@ -uniform vec4 u_color;// = vec4(1, 0, 1, 1); +uniform vec4 u_color; uniform vec4 u_widths; -// For border we abuse, ehm, re-use, the global clip -// as rounded rect and shrink it by u_widths +uniform vec4 u_outline; +uniform vec4 u_corner_widths; +uniform vec4 u_corner_heights; + void main() { - vec4 bounds = u_clip; - vec4 f = gl_FragCoord; + vec4 bounds = u_outline; + bounds.z = bounds.x + bounds.z; + bounds.w = bounds.y + bounds.w; + vec4 f = gl_FragCoord; f.x += u_viewport.x; f.y = (u_viewport.y + u_viewport.w) - f.y; - bounds.z = bounds.x + bounds.z; - bounds.w = bounds.y + bounds.w; - - RoundedRect routside = RoundedRect (bounds, u_clip_corner_widths, u_clip_corner_heights); + RoundedRect routside = RoundedRect (bounds, u_corner_widths, u_corner_heights); RoundedRect rinside = rounded_rect_shrink (routside, u_widths); float alpha = clamp (rounded_rect_coverage (routside, f.xy) -