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,
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;
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 */
/* 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)
}
}
}
-
- if (needs_clip)
- ops_set_clip (builder, &prev_clip);
}
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
/* 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);
}
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,
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);
}
-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) -