gl renderer: Fix clipped borders
Stop abusing the clip rect for borders.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
vec4 bounds = u_outline;
|
||||
|
||||
bounds.z = bounds.x + bounds.z;
|
||||
bounds.w = bounds.y + bounds.w;
|
||||
|
||||
RoundedRect routside = RoundedRect (bounds, u_clip_corner_widths, u_clip_corner_heights);
|
||||
vec4 f = gl_FragCoord;
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
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) -
|
||||
|
||||
Reference in New Issue
Block a user