g_assert_cmpint (self->program_name ## _program.program_name.uniform_basename ## _location, >, -1); \
}G_STMT_END
+#define INIT_PROGRAM_UNIFORM_RECT_LOCATION(program_name, uniform_basename) \
+ G_STMT_START{\
+ self->program_name ## _program.program_name.uniform_basename ## _bounds_location = \
+ glGetUniformLocation(self->program_name ## _program.id, "u_" #uniform_basename ".bounds");\
+ g_assert_cmpint (self->program_name ## _program.program_name.uniform_basename ## _bounds_location, >, -1); \
+ self->program_name ## _program.program_name.uniform_basename ## _corners_location = \
+ glGetUniformLocation(self->program_name ## _program.id, "u_" #uniform_basename ".corners");\
+ g_assert_cmpint (self->program_name ## _program.program_name.uniform_basename ## _corners_location, >, -1); \
+ }G_STMT_END
+
#define INIT_COMMON_UNIFORM_LOCATION(program_ptr, uniform_basename) \
G_STMT_START{\
program_ptr->uniform_basename ## _location = \
glGetUniformLocation(program_ptr->id, "u_" #uniform_basename);\
}G_STMT_END
+#define INIT_COMMON_UNIFORM_RECT_LOCATION(program_ptr, uniform_basename) \
+ G_STMT_START{\
+ program_ptr->uniform_basename ## _bounds_location = \
+ glGetUniformLocation(program_ptr->id, "u_" #uniform_basename ".bounds");\
+ program_ptr->uniform_basename ## _corners_location = \
+ glGetUniformLocation(program_ptr->id, "u_" #uniform_basename ".corners");\
+ }G_STMT_END
+
typedef enum
{
FORCE_OFFSCREEN = 1 << 0,
rect->size.width, 1));
}
-static inline void
-rounded_rect_to_floats (GskGLRenderer *self,
- RenderOpBuilder *builder,
- const GskRoundedRect *rect,
- float *outline,
- float *corner_widths,
- float *corner_heights)
+static inline GskRoundedRect
+transform_rect (GskGLRenderer *self,
+ RenderOpBuilder *builder,
+ const GskRoundedRect *rect)
{
const float scale = ops_get_scale (builder);
+ GskRoundedRect r;
int i;
- graphene_rect_t transformed_bounds;
-
- ops_transform_bounds_modelview (builder, &rect->bounds, &transformed_bounds);
- outline[0] = transformed_bounds.origin.x;
- outline[1] = transformed_bounds.origin.y;
- outline[2] = transformed_bounds.size.width;
- outline[3] = transformed_bounds.size.height;
+ ops_transform_bounds_modelview (builder, &rect->bounds, &r.bounds);
for (i = 0; i < 4; i ++)
{
- corner_widths[i] = rect->corner[i].width * scale;
- corner_heights[i] = rect->corner[i].height * scale;
+ r.corner[i].width = rect->corner[i].width * scale;
+ r.corner[i].height = rect->corner[i].height * scale;
}
+
+ return r;
}
static inline void
ops_set_program (builder, &self->inset_shadow_program);
op = ops_begin (builder, OP_CHANGE_INSET_SHADOW);
op->color = gsk_inset_shadow_node_peek_color (node);
- rounded_rect_to_floats (self, builder,
- gsk_inset_shadow_node_peek_outline (node),
- op->outline,
- op->corner_widths,
- op->corner_heights);
+ op->outline = transform_rect (self, builder, gsk_inset_shadow_node_peek_outline (node));
op->spread = spread * scale;
op->offset[0] = dx * scale;
op->offset[1] = -dy * scale;
ops_set_program (builder, &self->inset_shadow_program);
op = ops_begin (builder, OP_CHANGE_INSET_SHADOW);
op->color = gsk_inset_shadow_node_peek_color (node);
- rounded_rect_to_floats (self, builder,
- &outline_to_blur,
- op->outline,
- op->corner_widths,
- op->corner_heights);
+ op->outline = transform_rect (self, builder, &outline_to_blur);
op->spread = spread * scale;
op->offset[0] = dx * scale;
op->offset[1] = -dy * scale;
ops_set_program (builder, &self->unblurred_outset_shadow_program);
op = ops_begin (builder, OP_CHANGE_UNBLURRED_OUTSET_SHADOW);
op->color = gsk_outset_shadow_node_peek_color (node);
-
- rounded_rect_to_floats (self, builder,
- outline,
- op->outline,
- op->corner_widths,
- op->corner_heights);
-
+ op->outline = transform_rect (self, builder, outline);
op->spread = spread * scale;
op->offset[0] = dx * scale;
op->offset[1] = - dy * scale;
ops_set_texture (builder, blurred_texture_id);
shadow = ops_begin (builder, OP_CHANGE_OUTSET_SHADOW);
- rounded_rect_to_floats (self, builder,
- outline,
- shadow->outline,
- shadow->corner_widths,
- shadow->corner_heights);
+ shadow->outline = transform_rect (self, builder, outline);
{
const float min_x = builder->dx + outline->bounds.origin.x - spread - (blur_extra / 2.0) + dx;
op->clip.corner[1].height,
op->clip.corner[2].height,
op->clip.corner[3].height);
- glUniform4f (program->clip_location,
- op->clip.bounds.origin.x, op->clip.bounds.origin.y,
- op->clip.bounds.size.width, op->clip.bounds.size.height);
-
- glUniform4f (program->clip_corner_widths_location,
- op->clip.corner[0].width,
- op->clip.corner[1].width,
- op->clip.corner[2].width,
- op->clip.corner[3].width);
- glUniform4f (program->clip_corner_heights_location,
- op->clip.corner[0].height,
- op->clip.corner[1].height,
- op->clip.corner[2].height,
- op->clip.corner[3].height);
+ glUniform4fv (program->clip_rect_bounds_location, 1, (float *)&op->clip.bounds);
+ glUniform2fv (program->clip_rect_corners_location, 4, (float *)&op->clip.corner);
}
static inline void
apply_inset_shadow_op (const Program *program,
const OpShadow *op)
{
- OP_PRINT (" -> inset shadow. Color: (%f, %f, %f, %f), Offset: (%f, %f), Spread: %f, Outline: (%f, %f, %f, %f) Corner widths: (%f, %f, %f, %f), Corner Heights: (%f, %f, %f, %f)",
+ OP_PRINT (" -> inset shadow. Color: (%f, %f, %f, %f), Offset: (%f, %f), Spread: %f, Outline: %s",
op->color[0],
op->color[1],
op->color[2],
op->offset[0],
op->offset[1],
op->spread,
- op->outline[0],
- op->outline[1],
- op->outline[2],
- op->outline[3],
- op->corner_widths[0],
- op->corner_widths[1],
- op->corner_widths[2],
- op->corner_widths[3],
- op->corner_heights[0],
- op->corner_heights[1],
- op->corner_heights[2],
- op->corner_heights[3]);
+ gsk_rounded_rect_to_string (&op->outline));
glUniform4fv (program->inset_shadow.color_location, 1, (float *)op->color);
glUniform2fv (program->inset_shadow.offset_location, 1, op->offset);
glUniform1f (program->inset_shadow.spread_location, op->spread);
- glUniform4fv (program->inset_shadow.outline_location, 1, op->outline);
- glUniform4fv (program->inset_shadow.corner_widths_location, 1, op->corner_widths);
- glUniform4fv (program->inset_shadow.corner_heights_location, 1, op->corner_heights);
+ glUniform4fv (program->inset_shadow.outline_rect_bounds_location, 1, (float *)&op->outline.bounds);
+ glUniform2fv (program->inset_shadow.outline_rect_corners_location, 4, (float *)&op->outline.corner);
}
static inline void
glUniform4fv (program->unblurred_outset_shadow.color_location, 1, (float *)op->color);
glUniform2fv (program->unblurred_outset_shadow.offset_location, 1, op->offset);
glUniform1f (program->unblurred_outset_shadow.spread_location, op->spread);
- glUniform4fv (program->unblurred_outset_shadow.outline_location, 1, op->outline);
- glUniform4fv (program->unblurred_outset_shadow.corner_widths_location, 1,
- op->corner_widths);
- glUniform4fv (program->unblurred_outset_shadow.corner_heights_location, 1,
- op->corner_heights);
+ glUniform4fv (program->unblurred_outset_shadow.outline_rect_bounds_location, 1, (float *)&op->outline.bounds);
+ glUniform2fv (program->unblurred_outset_shadow.outline_rect_corners_location, 4, (float *)&op->outline.corner);
}
static inline void
const OpShadow *op)
{
OP_PRINT (" -> outset shadow");
- glUniform4fv (program->outset_shadow.outline_location, 1, op->outline);
- glUniform4fv (program->outset_shadow.corner_widths_location, 1, op->corner_widths);
- glUniform4fv (program->outset_shadow.corner_heights_location, 1, op->corner_heights);
+ glUniform4fv (program->outset_shadow.outline_rect_bounds_location, 1, (float *)&op->outline.bounds);
+ glUniform2fv (program->outset_shadow.outline_rect_corners_location, 4, (float *)&op->outline.corner);
}
static inline void
apply_border_op (const Program *program,
const OpBorder *op)
{
- const GskRoundedRect *o = &op->outline;
OP_PRINT (" -> Border Outline");
- glUniform4fv (program->border.outline_location, 1, (float *)&o->bounds);
- glUniform2fv (program->border.corner_sizes_location, 4, (float *)&o->corner);
+ glUniform4fv (program->border.outline_rect_bounds_location, 1, (float *)&op->outline.bounds);
+ glUniform2fv (program->border.outline_rect_corners_location, 4, (float *)&op->outline.corner);
}
static inline void
INIT_COMMON_UNIFORM_LOCATION (prog, alpha);
INIT_COMMON_UNIFORM_LOCATION (prog, source);
- INIT_COMMON_UNIFORM_LOCATION (prog, clip);
- INIT_COMMON_UNIFORM_LOCATION (prog, clip_corner_widths);
- INIT_COMMON_UNIFORM_LOCATION (prog, clip_corner_heights);
+ INIT_COMMON_UNIFORM_RECT_LOCATION (prog, clip_rect);
INIT_COMMON_UNIFORM_LOCATION (prog, viewport);
INIT_COMMON_UNIFORM_LOCATION (prog, projection);
INIT_COMMON_UNIFORM_LOCATION (prog, modelview);
INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, color);
INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, spread);
INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, offset);
- INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, outline);
- INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, corner_widths);
- INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, corner_heights);
+ INIT_PROGRAM_UNIFORM_RECT_LOCATION (inset_shadow, outline_rect);
/* outset shadow */
- INIT_PROGRAM_UNIFORM_LOCATION (outset_shadow, outline);
- INIT_PROGRAM_UNIFORM_LOCATION (outset_shadow, corner_widths);
- INIT_PROGRAM_UNIFORM_LOCATION (outset_shadow, corner_heights);
+ INIT_PROGRAM_UNIFORM_RECT_LOCATION (outset_shadow, outline_rect);
/* unblurred outset shadow */
INIT_PROGRAM_UNIFORM_LOCATION (unblurred_outset_shadow, color);
INIT_PROGRAM_UNIFORM_LOCATION (unblurred_outset_shadow, spread);
INIT_PROGRAM_UNIFORM_LOCATION (unblurred_outset_shadow, offset);
- INIT_PROGRAM_UNIFORM_LOCATION (unblurred_outset_shadow, outline);
- INIT_PROGRAM_UNIFORM_LOCATION (unblurred_outset_shadow, corner_widths);
- INIT_PROGRAM_UNIFORM_LOCATION (unblurred_outset_shadow, corner_heights);
+ INIT_PROGRAM_UNIFORM_RECT_LOCATION (unblurred_outset_shadow, outline_rect);
/* 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_sizes);
+ INIT_PROGRAM_UNIFORM_RECT_LOCATION (border, outline_rect);
/* cross fade */
INIT_PROGRAM_UNIFORM_LOCATION (cross_fade, progress);
uniform float u_alpha = 1.0;
uniform vec4 u_viewport;
-// In GtkSnapshot coordinates
-uniform vec4 u_clip;
-uniform vec4 u_clip_corner_widths = vec4(0, 0, 0, 0);
-uniform vec4 u_clip_corner_heights = vec4(0, 0, 0, 0);
-
-in vec2 vUv;
-
-out vec4 outputColor;
-
-
struct RoundedRect
{
vec4 bounds;
- vec4 corner_widths;
- vec4 corner_heights;
+ vec2 corners[4];
};
+uniform RoundedRect u_clip_rect;
+
+in vec2 vUv;
+out vec4 outputColor;
+
float
ellipsis_dist (vec2 p, vec2 radius)
{
rounded_rect_coverage (RoundedRect r, vec2 p)
{
if (p.x < r.bounds.x || p.y < r.bounds.y ||
- p.x >= r.bounds.z || p.y >= r.bounds.w)
+ p.x >= (r.bounds.x + r.bounds.z) || p.y >= (r.bounds.y + r.bounds.w))
return 0.0;
- vec2 rad_tl = vec2(r.corner_widths.x, r.corner_heights.x);
- vec2 rad_tr = vec2(r.corner_widths.y, r.corner_heights.y);
- vec2 rad_br = vec2(r.corner_widths.z, r.corner_heights.z);
- vec2 rad_bl = vec2(r.corner_widths.w, r.corner_heights.w);
+ vec2 rad_tl = r.corners[0];
+ vec2 rad_tr = r.corners[1];
+ vec2 rad_br = r.corners[2];
+ vec2 rad_bl = r.corners[3];
- vec2 ref_tl = r.bounds.xy + vec2( r.corner_widths.x, r.corner_heights.x);
- vec2 ref_tr = r.bounds.zy + vec2(-r.corner_widths.y, r.corner_heights.y);
- vec2 ref_br = r.bounds.zw + vec2(-r.corner_widths.z, -r.corner_heights.z);
- vec2 ref_bl = r.bounds.xw + vec2( r.corner_widths.w, -r.corner_heights.w);
+ vec2 ref_tl = r.bounds.xy + r.corners[0];
+ vec2 ref_tr = vec2(r.bounds.x + r.bounds.z, r.bounds.y) + (r.corners[1] * vec2(-1, 1));
+ vec2 ref_br = vec2(r.bounds.x + r.bounds.z, r.bounds.y + r.bounds.w) - r.corners[2];
+ vec2 ref_bl = vec2(r.bounds.x, r.bounds.y + r.bounds.w) + (r.corners[3] * vec2(1, -1));
float d_tl = ellipsis_coverage(p, ref_tl, rad_tl);
float d_tr = ellipsis_coverage(p, ref_tr, rad_tr);
return 1.0 - dot(vec4(is_out), corner_coverages);
}
+// amount is: top, right, bottom, left
RoundedRect
rounded_rect_shrink (RoundedRect r, vec4 amount)
{
- vec4 new_bounds = r.bounds + vec4(1.0,1.0,-1.0,-1.0) * amount.wxyz;
- vec4 new_widths = vec4(0);
- vec4 new_heights = vec4(0);
+ vec4 new_bounds = r.bounds;
+ vec2 new_corners[4];
+
+ new_bounds.xy += amount.wx;
+ new_bounds.zw -= amount.wx + amount.yz;
+
+ new_corners[0] = vec2(0);
+ new_corners[1] = vec2(0);
+ new_corners[2] = vec2(0);
+ new_corners[3] = vec2(0);
// Left top
- if (r.corner_widths.x > 0) new_widths.x = r.corner_widths.x - amount.w;
- if (r.corner_heights.x > 0) new_heights.x = r.corner_heights.x - amount.x;
+ if (r.corners[0].x > 0 || r.corners[0].y > 0)
+ new_corners[0] = r.corners[0] - amount.wx;
- // Top right
- if (r.corner_widths.y > 0) new_widths.y = r.corner_widths.y - amount.y;
- if (r.corner_heights.y > 0) new_heights.y = r.corner_heights.y - amount.x;
+ // top right
+ if (r.corners[1].x > 0 || r.corners[1].y > 0)
+ new_corners[1] = r.corners[1] - amount.yx;
// Bottom right
- if (r.corner_widths.z > 0) new_widths.z = r.corner_widths.z - amount.y;
- if (r.corner_heights.z > 0) new_heights.z = r.corner_heights.z - amount.z;
+ if (r.corners[2].x > 0 || r.corners[2].y > 0)
+ new_corners[2] = r.corners[2] - amount.yz;
// Bottom left
- if (r.corner_widths.w > 0) new_widths.w = r.corner_widths.w - amount.w;
- if (r.corner_heights.w > 0) new_heights.w = r.corner_heights.w - amount.z;
+ if (r.corners[3].x > 0 || r.corners[3].y > 0)
+ new_corners[3] = r.corners[3] - amount.wz;
- return RoundedRect (new_bounds, new_widths, new_heights);
+ return RoundedRect (new_bounds, new_corners);
}
vec4 Texture(sampler2D sampler, vec2 texCoords) {
}
void setOutputColor(vec4 color) {
- vec4 clipBounds = u_clip;
vec4 f = gl_FragCoord;
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
- clipBounds.z = clipBounds.x + clipBounds.z;
- clipBounds.w = clipBounds.y + clipBounds.w;
-
- RoundedRect r = RoundedRect(clipBounds, u_clip_corner_widths, u_clip_corner_heights);
-
- outputColor = color * rounded_rect_coverage(r, f.xy);
+ outputColor = color * rounded_rect_coverage(u_clip_rect, f.xy);
/*outputColor = color;*/
}