From 1243174e5370f258dbd963895be430adbd708490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Mon, 16 Dec 2019 06:16:26 +0100 Subject: [PATCH] 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]; --- gsk/gl/gskglrenderer.c | 47 ++++------- gsk/gl/gskglrenderopsprivate.h | 15 ++-- gsk/resources/glsl/blur.glsl | 4 +- gsk/resources/glsl/border.glsl | 9 +- gsk/resources/glsl/color_matrix.glsl | 2 +- gsk/resources/glsl/inset_shadow.glsl | 7 +- gsk/resources/glsl/outset_shadow.glsl | 5 +- gsk/resources/glsl/preamble.fs.glsl | 84 +++++++++++-------- .../glsl/unblurred_outset_shadow.glsl | 10 ++- 9 files changed, 88 insertions(+), 95 deletions(-) diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c index 999120cb01..ee52e72c77 100644 --- a/gsk/gl/gskglrenderer.c +++ b/gsk/gl/gskglrenderer.c @@ -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); diff --git a/gsk/gl/gskglrenderopsprivate.h b/gsk/gl/gskglrenderopsprivate.h index 46355239c6..9011d4aaa3 100644 --- a/gsk/gl/gskglrenderopsprivate.h +++ b/gsk/gl/gskglrenderopsprivate.h @@ -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; diff --git a/gsk/resources/glsl/blur.glsl b/gsk/resources/glsl/blur.glsl index 4b0109bbfc..e3aecb867c 100644 --- a/gsk/resources/glsl/blur.glsl +++ b/gsk/resources/glsl/blur.glsl @@ -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; diff --git a/gsk/resources/glsl/border.glsl b/gsk/resources/glsl/border.glsl index e919461cce..b791dceb4f 100644 --- a/gsk/resources/glsl/border.glsl +++ b/gsk/resources/glsl/border.glsl @@ -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 */ diff --git a/gsk/resources/glsl/color_matrix.glsl b/gsk/resources/glsl/color_matrix.glsl index 7904eae70c..bd621432fd 100644 --- a/gsk/resources/glsl/color_matrix.glsl +++ b/gsk/resources/glsl/color_matrix.glsl @@ -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; diff --git a/gsk/resources/glsl/inset_shadow.glsl b/gsk/resources/glsl/inset_shadow.glsl index fa0e46769b..c6518f1aa1 100644 --- a/gsk/resources/glsl/inset_shadow.glsl +++ b/gsk/resources/glsl/inset_shadow.glsl @@ -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); diff --git a/gsk/resources/glsl/outset_shadow.glsl b/gsk/resources/glsl/outset_shadow.glsl index 150b5aafce..d052049c2d 100644 --- a/gsk/resources/glsl/outset_shadow.glsl +++ b/gsk/resources/glsl/outset_shadow.glsl @@ -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); } diff --git a/gsk/resources/glsl/preamble.fs.glsl b/gsk/resources/glsl/preamble.fs.glsl index 81ee188ef5..2c53b3d019 100644 --- a/gsk/resources/glsl/preamble.fs.glsl +++ b/gsk/resources/glsl/preamble.fs.glsl @@ -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;*/ } diff --git a/gsk/resources/glsl/unblurred_outset_shadow.glsl b/gsk/resources/glsl/unblurred_outset_shadow.glsl index fa14f11629..e50db29cd3 100644 --- a/gsk/resources/glsl/unblurred_outset_shadow.glsl +++ b/gsk/resources/glsl/unblurred_outset_shadow.glsl @@ -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); }