gl renderer: Make RoundedRect work in gles

Which can't return struct types containing arrays. So let's revert to
the previous version but still send the rect along as a vec4[3];
This commit is contained in:
Timm Bäder 2019-12-16 06:16:26 +01:00
parent cc909b160f
commit 1243174e53
9 changed files with 88 additions and 95 deletions

View File

@ -53,30 +53,12 @@
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,
@ -2521,19 +2503,22 @@ static inline void
apply_clip_op (const Program *program,
const OpClip *op)
{
glUniform4fv (program->clip_rect_bounds_location, 1, (float *)&op->clip.bounds);
int count;
if (op->send_corners)
{
OP_PRINT (" -> Clip: %s", gsk_rounded_rect_to_string (&op->clip));
glUniform2fv (program->clip_rect_corners_location, 4, (float *)&op->clip.corner);
count = 3;
}
else
{
OP_PRINT (" -> clip: %f, %f, %f, %f",
op->clip.bounds.origin.x, op->clip.bounds.origin.y,
op->clip.bounds.size.width, op->clip.bounds.size.height);
count = 1;
}
glUniform4fv (program->clip_rect_location, count, (float *)&op->clip.bounds);
}
static inline void
@ -2549,8 +2534,7 @@ apply_inset_shadow_op (const Program *program,
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_rect_bounds_location, 1, (float *)&op->outline.bounds);
glUniform2fv (program->inset_shadow.outline_rect_corners_location, 4, (float *)&op->outline.corner);
glUniform4fv (program->inset_shadow.outline_rect_location, 3, (float *)&op->outline.bounds);
}
static inline void
@ -2561,8 +2545,7 @@ apply_unblurred_outset_shadow_op (const Program *program,
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_rect_bounds_location, 1, (float *)&op->outline.bounds);
glUniform2fv (program->unblurred_outset_shadow.outline_rect_corners_location, 4, (float *)&op->outline.corner);
glUniform4fv (program->unblurred_outset_shadow.outline_rect_location, 3, (float *)&op->outline.bounds);
}
static inline void
@ -2570,8 +2553,7 @@ apply_outset_shadow_op (const Program *program,
const OpShadow *op)
{
OP_PRINT (" -> outset shadow");
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);
glUniform4fv (program->outset_shadow.outline_rect_location, 3, (float *)&op->outline.bounds);
}
static inline void
@ -2599,8 +2581,7 @@ apply_border_op (const Program *program,
{
OP_PRINT (" -> Border Outline");
glUniform4fv (program->border.outline_rect_bounds_location, 1, (float *)&op->outline.bounds);
glUniform2fv (program->border.outline_rect_corners_location, 4, (float *)&op->outline.corner);
glUniform4fv (program->border.outline_rect_location, 3, (float *)&op->outline.bounds);
}
static inline void
@ -2751,7 +2732,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
INIT_COMMON_UNIFORM_LOCATION (prog, alpha);
INIT_COMMON_UNIFORM_LOCATION (prog, source);
INIT_COMMON_UNIFORM_RECT_LOCATION (prog, clip_rect);
INIT_COMMON_UNIFORM_LOCATION (prog, clip_rect);
INIT_COMMON_UNIFORM_LOCATION (prog, viewport);
INIT_COMMON_UNIFORM_LOCATION (prog, projection);
INIT_COMMON_UNIFORM_LOCATION (prog, modelview);
@ -2782,21 +2763,21 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, color);
INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, spread);
INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, offset);
INIT_PROGRAM_UNIFORM_RECT_LOCATION (inset_shadow, outline_rect);
INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, outline_rect);
/* outset shadow */
INIT_PROGRAM_UNIFORM_RECT_LOCATION (outset_shadow, outline_rect);
INIT_PROGRAM_UNIFORM_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_RECT_LOCATION (unblurred_outset_shadow, outline_rect);
INIT_PROGRAM_UNIFORM_LOCATION (unblurred_outset_shadow, outline_rect);
/* border */
INIT_PROGRAM_UNIFORM_LOCATION (border, color);
INIT_PROGRAM_UNIFORM_LOCATION (border, widths);
INIT_PROGRAM_UNIFORM_RECT_LOCATION (border, outline_rect);
INIT_PROGRAM_UNIFORM_LOCATION (border, outline_rect);
/* cross fade */
INIT_PROGRAM_UNIFORM_LOCATION (cross_fade, progress);

View File

@ -47,8 +47,7 @@ struct _Program
int viewport_location;
int projection_location;
int modelview_location;
int clip_rect_bounds_location;
int clip_rect_corners_location;
int clip_rect_location;
union {
struct {
int color_location;
@ -76,16 +75,13 @@ struct _Program
int color_location;
int spread_location;
int offset_location;
int outline_rect_bounds_location;
int outline_rect_corners_location;
int outline_rect_location;
} inset_shadow;
struct {
int outline_rect_bounds_location;
int outline_rect_corners_location;
int outline_rect_location;
} outset_shadow;
struct {
int outline_rect_bounds_location;
int outline_rect_corners_location;
int outline_rect_location;
int color_location;
int spread_location;
int offset_location;
@ -93,8 +89,7 @@ struct _Program
struct {
int color_location;
int widths_location;
int outline_rect_bounds_location;
int outline_rect_corners_location;
int outline_rect_location;
} border;
struct {
int source2_location;

View File

@ -26,14 +26,14 @@ void main() {
vec2 pixel_step = vec2(1.0) / u_blur_size;
float coefficientSum = 0;
float coefficientSum = 0.0;
vec4 sum = Texture(u_source, vUv) * incrementalGaussian.x;
coefficientSum += incrementalGaussian.x;
incrementalGaussian.xy *= incrementalGaussian.yz;
int pixels_per_side = int(floor(blur_radius / 2.0));
for (int i = 1; i <= pixels_per_side; i++) {
vec2 p = i * pixel_step * u_blur_dir;
vec2 p = float(i) * pixel_step * u_blur_dir;
sum += Texture(u_source, vUv - p) * incrementalGaussian.x;
sum += Texture(u_source, vUv + p) * incrementalGaussian.x;

View File

@ -9,17 +9,18 @@ void main() {
// FRAGMENT_SHADER:
uniform vec4 u_color;
uniform vec4 u_widths;
uniform RoundedRect u_outline_rect;
uniform vec4[3] u_outline_rect;
void main() {
vec4 f = gl_FragCoord;
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
RoundedRect rinside = rounded_rect_shrink (u_outline_rect, u_widths);
RoundedRect outside = create_rect(u_outline_rect);
RoundedRect inside = rounded_rect_shrink (outside, u_widths);
float alpha = clamp (rounded_rect_coverage (u_outline_rect, f.xy) -
rounded_rect_coverage (rinside, f.xy),
float alpha = clamp (rounded_rect_coverage (outside, f.xy) -
rounded_rect_coverage (inside, f.xy),
0.0, 1.0);
/* Pre-multiply */

View File

@ -20,7 +20,7 @@ void main() {
color.rgb /= color.a;
color = u_color_matrix * color + u_color_offset;
color = clamp(color, 0.0f, 1.0f);
color = clamp(color, 0.0, 1.0);
color.rgb *= color.a;

View File

@ -9,7 +9,7 @@ void main() {
uniform float u_spread;
uniform vec4 u_color;
uniform vec2 u_offset;
uniform RoundedRect u_outline_rect;
uniform vec4[3] u_outline_rect;
void main() {
vec4 f = gl_FragCoord;
@ -17,10 +17,11 @@ void main() {
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
RoundedRect inside = rounded_rect_shrink(u_outline_rect, vec4(u_spread));
RoundedRect outside = create_rect(u_outline_rect);
RoundedRect inside = rounded_rect_shrink(outside, vec4(u_spread));
vec2 offset = vec2(u_offset.x, - u_offset.y);
vec4 color = vec4(u_color.rgb * u_color.a, u_color.a);
color = color * clamp (rounded_rect_coverage (u_outline_rect, f.xy) -
color = color * clamp (rounded_rect_coverage (outside, f.xy) -
rounded_rect_coverage (inside, f.xy - offset),
0.0, 1.0);
setOutputColor(color * u_alpha);

View File

@ -6,7 +6,7 @@ void main() {
}
// FRAGMENT_SHADER:
uniform RoundedRect u_outline_rect;
uniform vec4[3] u_outline_rect;
void main() {
vec4 f = gl_FragCoord;
@ -14,7 +14,8 @@ void main() {
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
RoundedRect outline = create_rect(u_outline_rect);
vec4 color = Texture(u_source, vUv);
color = color * (1.0 - clamp(rounded_rect_coverage (u_outline_rect, f.xy), 0.0, 1.0));
color = color * (1.0 - clamp(rounded_rect_coverage(outline, f.xy), 0.0, 1.0));
setOutputColor(color * u_alpha);
}

View File

@ -1,21 +1,26 @@
#if GDK_GL3
#ifdef GSK_GL3
precision highp float;
#endif
#ifdef GSK_GLES
precision highp float;
#endif
uniform sampler2D u_source;
uniform mat4 u_projection;
uniform mat4 u_modelview;
uniform float u_alpha = 1.0;
uniform float u_alpha;// = 1.0;
uniform vec4 u_viewport;
struct RoundedRect
{
vec4 bounds;
vec2 corners[4];
vec4 corner_widths;
vec4 corner_heights;
};
uniform RoundedRect u_clip_rect;
uniform vec4[3] u_clip_rect;
#if GSK_GLES
varying vec2 vUv;
@ -27,6 +32,16 @@ in vec2 vUv;
out vec4 outputColor;
#endif
// Transform from a GskRoundedRect to a RoundedRect as we need it.
RoundedRect
create_rect(vec4 data[3])
{
vec4 bounds = vec4(data[0].xy, data[0].xy + data[0].zw);
vec4 widths = vec4(data[1].x, data[1].z, data[2].x, data[2].z);
vec4 heights = vec4(data[1].y, data[1].w, data[2].y, data[2].w);
return RoundedRect(bounds, widths, heights);
}
float
ellipsis_dist (vec2 p, vec2 radius)
{
@ -50,18 +65,18 @@ float
rounded_rect_coverage (RoundedRect r, vec2 p)
{
if (p.x < r.bounds.x || p.y < r.bounds.y ||
p.x >= (r.bounds.x + r.bounds.z) || p.y >= (r.bounds.y + r.bounds.w))
p.x >= r.bounds.z || p.y >= r.bounds.w)
return 0.0;
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 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 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));
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);
float d_tl = ellipsis_coverage(p, ref_tl, rad_tl);
float d_tr = ellipsis_coverage(p, ref_tr, rad_tr);
@ -82,39 +97,34 @@ rounded_rect_coverage (RoundedRect r, vec2 p)
RoundedRect
rounded_rect_shrink (RoundedRect r, vec4 amount)
{
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);
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);
// Left top
if (r.corners[0].x > 0 || r.corners[0].y > 0)
new_corners[0] = r.corners[0] - amount.wx;
if (r.corner_widths.x > 0.0) new_widths.x = r.corner_widths.x - amount.w;
if (r.corner_heights.x > 0.0) new_heights.x = r.corner_heights.x - amount.x;
// top right
if (r.corners[1].x > 0 || r.corners[1].y > 0)
new_corners[1] = r.corners[1] - amount.yx;
// Top right
if (r.corner_widths.y > 0.0) new_widths.y = r.corner_widths.y - amount.y;
if (r.corner_heights.y > 0.0) new_heights.y = r.corner_heights.y - amount.x;
// Bottom right
if (r.corners[2].x > 0 || r.corners[2].y > 0)
new_corners[2] = r.corners[2] - amount.yz;
if (r.corner_widths.z > 0.0) new_widths.z = r.corner_widths.z - amount.y;
if (r.corner_heights.z > 0.0) new_heights.z = r.corner_heights.z - amount.z;
// Bottom left
if (r.corners[3].x > 0 || r.corners[3].y > 0)
new_corners[3] = r.corners[3] - amount.wz;
if (r.corner_widths.w > 0.0) new_widths.w = r.corner_widths.w - amount.w;
if (r.corner_heights.w > 0.0) new_heights.w = r.corner_heights.w - amount.z;
return RoundedRect (new_bounds, new_corners);
return RoundedRect (new_bounds, new_widths, new_heights);
}
vec4 Texture(sampler2D sampler, vec2 texCoords) {
#if GSK_GLES
return texture2D(sampler, texCoords);
#elif GSK_LEGACY
return texture2D(sampler, texCoords);
#else
return texture(sampler, texCoords);
#endif
@ -127,9 +137,11 @@ void setOutputColor(vec4 color) {
f.y = (u_viewport.y + u_viewport.w) - f.y;
#if GSK_GLES
gl_FragColor = color * rounded_rect_coverage(u_clip_rect, f.xy);
gl_FragColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy);
#elif GSK_LEGACY
gl_FragColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy);
#else
outputColor = color * rounded_rect_coverage(u_clip_rect, f.xy);
outputColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy);
#endif
/*outputColor = color;*/
}

View File

@ -9,7 +9,7 @@ void main() {
uniform float u_spread;
uniform vec4 u_color;
uniform vec2 u_offset;
uniform RoundedRect u_outline_rect;
uniform vec4[3] u_outline_rect;
void main() {
vec4 f = gl_FragCoord;
@ -17,12 +17,14 @@ void main() {
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
RoundedRect outline = rounded_rect_shrink(u_outline_rect, vec4(- u_spread));
RoundedRect inside = create_rect(u_outline_rect);
RoundedRect outside = rounded_rect_shrink(inside, vec4(- u_spread));
vec2 offset = vec2(u_offset.x, - u_offset.y);
vec4 color = vec4(u_color.rgb * u_color.a, u_color.a);
color = color * clamp (rounded_rect_coverage (outline, f.xy - offset) -
rounded_rect_coverage (u_outline_rect, f.xy),
color = color * clamp (rounded_rect_coverage (outside, f.xy - offset) -
rounded_rect_coverage (inside, f.xy),
0.0, 1.0);
setOutputColor(color * u_alpha);
}