summaryrefslogtreecommitdiff
path: root/shaders/gtk4/69.shader_test
diff options
context:
space:
mode:
Diffstat (limited to 'shaders/gtk4/69.shader_test')
-rw-r--r--shaders/gtk4/69.shader_test443
1 files changed, 443 insertions, 0 deletions
diff --git a/shaders/gtk4/69.shader_test b/shaders/gtk4/69.shader_test
new file mode 100644
index 0000000..bad2c31
--- /dev/null
+++ b/shaders/gtk4/69.shader_test
@@ -0,0 +1,443 @@
+[require]
+GLSL >= 1.50
+
+[vertex shader]
+#version 150
+#define GSK_GL3 1
+#define RECT_CLIP 1
+#ifndef GSK_LEGACY
+precision highp float;
+#endif
+
+#if defined(GSK_GLES) || defined(GSK_LEGACY)
+#define _OUT_ varying
+#define _IN_ varying
+#define _GSK_ROUNDED_RECT_UNIFORM_ vec4[3]
+#else
+#define _OUT_ out
+#define _IN_ in
+#define _GSK_ROUNDED_RECT_UNIFORM_ GskRoundedRect
+#endif
+
+
+struct GskRoundedRect
+{
+ vec4 bounds; // Top left and bottom right
+ // Look, arrays can't be in structs if you want to return the struct
+ // from a function in gles or whatever. Just kill me.
+ vec4 corner_points1; // xy = top left, zw = top right
+ vec4 corner_points2; // xy = bottom right, zw = bottom left
+};
+
+// Transform from a C GskRoundedRect to what we need.
+GskRoundedRect
+gsk_create_rect(vec4[3] data)
+{
+ vec4 bounds = vec4(data[0].xy, data[0].xy + data[0].zw);
+
+ vec4 corner_points1 = vec4(bounds.xy + data[1].xy,
+ bounds.zy + vec2(data[1].zw * vec2(-1, 1)));
+ vec4 corner_points2 = vec4(bounds.zw + (data[2].xy * vec2(-1, -1)),
+ bounds.xw + vec2(data[2].zw * vec2(1, -1)));
+
+ return GskRoundedRect(bounds, corner_points1, corner_points2);
+}
+
+vec4
+gsk_get_bounds(vec4[3] data)
+{
+ return vec4(data[0].xy, data[0].xy + data[0].zw);
+}
+
+vec4 gsk_premultiply(vec4 c) {
+ return vec4(c.rgb * c.a, c.a);
+}
+
+vec4 gsk_scaled_premultiply(vec4 c, float s) {
+ // Fast version of gsk_premultiply(c) * s
+ // 4 muls instead of 7
+ float a = s * c.a;
+
+ return vec4(c.rgb * a, a);
+}
+uniform mat4 u_projection;
+uniform mat4 u_modelview;
+uniform float u_alpha;
+
+#if defined(GSK_GLES) || defined(GSK_LEGACY)
+attribute vec2 aPosition;
+attribute vec2 aUv;
+attribute vec4 aColor;
+attribute vec4 aColor2;
+_OUT_ vec2 vUv;
+#else
+_IN_ vec2 aPosition;
+_IN_ vec2 aUv;
+_IN_ vec4 aColor;
+_IN_ vec4 aColor2;
+_OUT_ vec2 vUv;
+#endif
+
+// amount is: top, right, bottom, left
+GskRoundedRect
+gsk_rounded_rect_shrink (GskRoundedRect r, vec4 amount)
+{
+ vec4 new_bounds = r.bounds + vec4(1.0,1.0,-1.0,-1.0) * amount.wxyz;
+ vec4 new_corner_points1 = r.corner_points1;
+ vec4 new_corner_points2 = r.corner_points2;
+
+ if (r.corner_points1.xy == r.bounds.xy) new_corner_points1.xy = new_bounds.xy;
+ if (r.corner_points1.zw == r.bounds.zy) new_corner_points1.zw = new_bounds.zy;
+ if (r.corner_points2.xy == r.bounds.zw) new_corner_points2.xy = new_bounds.zw;
+ if (r.corner_points2.zw == r.bounds.xw) new_corner_points2.zw = new_bounds.xw;
+
+ return GskRoundedRect (new_bounds, new_corner_points1, new_corner_points2);
+}
+
+void
+gsk_rounded_rect_offset(inout GskRoundedRect r, vec2 offset)
+{
+ r.bounds.xy += offset;
+ r.bounds.zw += offset;
+ r.corner_points1.xy += offset;
+ r.corner_points1.zw += offset;
+ r.corner_points2.xy += offset;
+ r.corner_points2.zw += offset;
+}
+
+void gsk_rounded_rect_transform(inout GskRoundedRect r, mat4 mat)
+{
+ r.bounds.xy = (mat * vec4(r.bounds.xy, 0.0, 1.0)).xy;
+ r.bounds.zw = (mat * vec4(r.bounds.zw, 0.0, 1.0)).xy;
+
+ r.corner_points1.xy = (mat * vec4(r.corner_points1.xy, 0.0, 1.0)).xy;
+ r.corner_points1.zw = (mat * vec4(r.corner_points1.zw, 0.0, 1.0)).xy;
+
+ r.corner_points2.xy = (mat * vec4(r.corner_points2.xy, 0.0, 1.0)).xy;
+ r.corner_points2.zw = (mat * vec4(r.corner_points2.zw, 0.0, 1.0)).xy;
+}
+
+#if defined(GSK_LEGACY)
+// Can't have out or inout array parameters...
+#define gsk_rounded_rect_encode(r, uni) uni[0] = r.bounds; uni[1] = r.corner_points1; uni[2] = r.corner_points2;
+#else
+void gsk_rounded_rect_encode(GskRoundedRect r, out _GSK_ROUNDED_RECT_UNIFORM_ out_r)
+{
+#if defined(GSK_GLES)
+ out_r[0] = r.bounds;
+ out_r[1] = r.corner_points1;
+ out_r[2] = r.corner_points2;
+#else
+ out_r = r;
+#endif
+}
+
+#endif
+
+// conic_gradient.glsl
+
+uniform vec4 u_geometry;
+
+_OUT_ vec2 coord;
+
+void main() {
+ gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));
+
+ vec2 mv0 = u_modelview[0].xy;
+ vec2 mv1 = u_modelview[1].xy;
+ vec2 offset = aPosition - u_geometry.xy;
+
+ coord = vec2(dot(mv0, offset), dot(mv1, offset));
+}
+
+// FRAGMENT_SHADER:
+[fragment shader]
+#version 150
+#define GSK_GL3 1
+#define RECT_CLIP 1
+#ifndef GSK_LEGACY
+precision highp float;
+#endif
+
+#if defined(GSK_GLES) || defined(GSK_LEGACY)
+#define _OUT_ varying
+#define _IN_ varying
+#define _GSK_ROUNDED_RECT_UNIFORM_ vec4[3]
+#else
+#define _OUT_ out
+#define _IN_ in
+#define _GSK_ROUNDED_RECT_UNIFORM_ GskRoundedRect
+#endif
+
+
+struct GskRoundedRect
+{
+ vec4 bounds; // Top left and bottom right
+ // Look, arrays can't be in structs if you want to return the struct
+ // from a function in gles or whatever. Just kill me.
+ vec4 corner_points1; // xy = top left, zw = top right
+ vec4 corner_points2; // xy = bottom right, zw = bottom left
+};
+
+// Transform from a C GskRoundedRect to what we need.
+GskRoundedRect
+gsk_create_rect(vec4[3] data)
+{
+ vec4 bounds = vec4(data[0].xy, data[0].xy + data[0].zw);
+
+ vec4 corner_points1 = vec4(bounds.xy + data[1].xy,
+ bounds.zy + vec2(data[1].zw * vec2(-1, 1)));
+ vec4 corner_points2 = vec4(bounds.zw + (data[2].xy * vec2(-1, -1)),
+ bounds.xw + vec2(data[2].zw * vec2(1, -1)));
+
+ return GskRoundedRect(bounds, corner_points1, corner_points2);
+}
+
+vec4
+gsk_get_bounds(vec4[3] data)
+{
+ return vec4(data[0].xy, data[0].xy + data[0].zw);
+}
+
+vec4 gsk_premultiply(vec4 c) {
+ return vec4(c.rgb * c.a, c.a);
+}
+
+vec4 gsk_scaled_premultiply(vec4 c, float s) {
+ // Fast version of gsk_premultiply(c) * s
+ // 4 muls instead of 7
+ float a = s * c.a;
+
+ return vec4(c.rgb * a, a);
+}
+uniform sampler2D u_source;
+uniform mat4 u_projection;
+uniform mat4 u_modelview;
+uniform float u_alpha;
+uniform vec4 u_viewport;
+uniform vec4[3] u_clip_rect;
+
+#if defined(GSK_LEGACY)
+_OUT_ vec4 outputColor;
+#elif !defined(GSK_GLES)
+_OUT_ vec4 outputColor;
+#endif
+
+_IN_ vec2 vUv;
+
+
+GskRoundedRect gsk_decode_rect(_GSK_ROUNDED_RECT_UNIFORM_ r)
+{
+#if defined(GSK_GLES) || defined(GSK_LEGACY)
+ return GskRoundedRect(r[0], r[1], r[2]);
+#else
+ return r;
+#endif
+}
+
+float
+gsk_ellipsis_dist (vec2 p, vec2 radius)
+{
+ if (radius == vec2(0, 0))
+ return 0.0;
+
+ vec2 p0 = p / radius;
+ vec2 p1 = 2.0 * p0 / radius;
+
+ return (dot(p0, p0) - 1.0) / length (p1);
+}
+
+float
+gsk_ellipsis_coverage (vec2 point, vec2 center, vec2 radius)
+{
+ float d = gsk_ellipsis_dist (point - center, radius);
+ return clamp (0.5 - d, 0.0, 1.0);
+}
+
+float
+gsk_rounded_rect_coverage (GskRoundedRect r, vec2 p)
+{
+ if (p.x < r.bounds.x || p.y < r.bounds.y ||
+ p.x >= r.bounds.z || p.y >= r.bounds.w)
+ return 0.0;
+
+ vec2 ref_tl = r.corner_points1.xy;
+ vec2 ref_tr = r.corner_points1.zw;
+ vec2 ref_br = r.corner_points2.xy;
+ vec2 ref_bl = r.corner_points2.zw;
+
+ if (p.x >= ref_tl.x && p.x >= ref_bl.x &&
+ p.x <= ref_tr.x && p.x <= ref_br.x)
+ return 1.0;
+
+ if (p.y >= ref_tl.y && p.y >= ref_tr.y &&
+ p.y <= ref_bl.y && p.y <= ref_br.y)
+ return 1.0;
+
+ vec2 rad_tl = r.corner_points1.xy - r.bounds.xy;
+ vec2 rad_tr = r.corner_points1.zw - r.bounds.zy;
+ vec2 rad_br = r.corner_points2.xy - r.bounds.zw;
+ vec2 rad_bl = r.corner_points2.zw - r.bounds.xw;
+
+ float d_tl = gsk_ellipsis_coverage(p, ref_tl, rad_tl);
+ float d_tr = gsk_ellipsis_coverage(p, ref_tr, rad_tr);
+ float d_br = gsk_ellipsis_coverage(p, ref_br, rad_br);
+ float d_bl = gsk_ellipsis_coverage(p, ref_bl, rad_bl);
+
+ vec4 corner_coverages = 1.0 - vec4(d_tl, d_tr, d_br, d_bl);
+
+ bvec4 is_out = bvec4(p.x < ref_tl.x && p.y < ref_tl.y,
+ p.x > ref_tr.x && p.y < ref_tr.y,
+ p.x > ref_br.x && p.y > ref_br.y,
+ p.x < ref_bl.x && p.y > ref_bl.y);
+
+ return 1.0 - dot(vec4(is_out), corner_coverages);
+}
+
+float
+gsk_rect_coverage (vec4 r, vec2 p)
+{
+ if (p.x < r.x || p.y < r.y ||
+ p.x >= r.z || p.y >= r.w)
+ return 0.0;
+
+ return 1.0;
+}
+
+vec4 GskTexture(sampler2D sampler, vec2 texCoords) {
+#if defined(GSK_GLES) || defined(GSK_LEGACY)
+ return texture2D(sampler, texCoords);
+#else
+ return texture(sampler, texCoords);
+#endif
+}
+
+#ifdef GSK_GL3
+layout(origin_upper_left) in vec4 gl_FragCoord;
+#endif
+
+vec2 gsk_get_frag_coord() {
+ vec2 fc = gl_FragCoord.xy;
+
+#ifdef GSK_GL3
+ fc += u_viewport.xy;
+#else
+ fc.x += u_viewport.x;
+ fc.y = (u_viewport.y + u_viewport.w) - fc.y;
+#endif
+
+ return fc;
+}
+
+void gskSetOutputColor(vec4 color) {
+ vec4 result;
+
+#if defined(NO_CLIP)
+ result = color;
+#elif defined(RECT_CLIP)
+ float coverage = gsk_rect_coverage(gsk_get_bounds(u_clip_rect),
+ gsk_get_frag_coord());
+ result = color * coverage;
+#else
+ float coverage = gsk_rounded_rect_coverage(gsk_create_rect(u_clip_rect),
+ gsk_get_frag_coord());
+ result = color * coverage;
+#endif
+
+#if defined(GSK_GLES) || defined(GSK_LEGACY)
+ gl_FragColor = result;
+#else
+ outputColor = result;
+#endif
+}
+
+void gskSetScaledOutputColor(vec4 color, float alpha) {
+ vec4 result;
+
+#if defined(NO_CLIP)
+ result = color * alpha;
+#elif defined(RECT_CLIP)
+ float coverage = gsk_rect_coverage(gsk_get_bounds(u_clip_rect),
+ gsk_get_frag_coord());
+ result = color * (alpha * coverage);
+#else
+ float coverage = gsk_rounded_rect_coverage(gsk_create_rect(u_clip_rect),
+ gsk_get_frag_coord());
+ result = color * (alpha * coverage);
+#endif
+
+#if defined(GSK_GLES) || defined(GSK_LEGACY)
+ gl_FragColor = result;
+#else
+ outputColor = result;
+#endif
+}
+
+// conic_gradient.glsl
+
+#define MAX_COLOR_STOPS 6
+
+#ifdef GSK_LEGACY
+uniform int u_num_color_stops;
+#else
+uniform highp int u_num_color_stops; // Why? Because it works like this.
+#endif
+
+uniform vec4 u_geometry;
+uniform float u_color_stops[MAX_COLOR_STOPS * 5];
+
+_IN_ vec2 coord;
+
+float get_offset(int index) {
+ // u_color_stops[5 * index] makes Intel Windows driver crash.
+ // See https://gitlab.gnome.org/GNOME/gtk/-/issues/3783
+ int base = 5 * index;
+ return u_color_stops[base];
+}
+
+vec4 get_color(int index) {
+ int base = 5 * index + 1;
+
+ return vec4(u_color_stops[base],
+ u_color_stops[base + 1],
+ u_color_stops[base + 2],
+ u_color_stops[base + 3]);
+}
+
+void main() {
+ // direction of point in range [-PI, PI]
+ vec2 pos = floor(coord);
+ float angle = atan(pos.y, pos.x);
+
+ // fract() does the modulo here, so now we have progress
+ // into the current conic
+ float offset = fract(angle * u_geometry.z + u_geometry.w);
+ float curr_offset;
+ float next_offset;
+
+ next_offset = get_offset(0);
+ if (offset < next_offset) {
+ gskSetOutputColor(gsk_scaled_premultiply(get_color(0), u_alpha));
+ return;
+ }
+
+ if (offset >= get_offset(u_num_color_stops - 1)) {
+ gskSetOutputColor(gsk_scaled_premultiply(get_color(u_num_color_stops - 1), u_alpha));
+ return;
+ }
+
+ for (int i = 0; i < MAX_COLOR_STOPS; i++) {
+ curr_offset = next_offset;
+ next_offset = get_offset(i + 1);
+
+ if (offset < next_offset) {
+ float f = (offset - curr_offset) / (next_offset - curr_offset);
+ vec4 curr_color = gsk_premultiply(get_color(i));
+ vec4 next_color = gsk_premultiply(get_color(i + 1));
+ vec4 color = mix(curr_color, next_color, f);
+ gskSetScaledOutputColor(color, u_alpha);
+ return;
+ }
+ }
+}
+