summaryrefslogtreecommitdiffstats
path: root/gfx/wr/webrender/res/ps_split_composite.glsl
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/wr/webrender/res/ps_split_composite.glsl')
-rw-r--r--gfx/wr/webrender/res/ps_split_composite.glsl134
1 files changed, 134 insertions, 0 deletions
diff --git a/gfx/wr/webrender/res/ps_split_composite.glsl b/gfx/wr/webrender/res/ps_split_composite.glsl
new file mode 100644
index 0000000000..4b134950f5
--- /dev/null
+++ b/gfx/wr/webrender/res/ps_split_composite.glsl
@@ -0,0 +1,134 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#define WR_FEATURE_TEXTURE_2D
+
+#include shared,prim_shared
+
+// interpolated UV coordinates to sample.
+varying vec2 vUv;
+
+// Flag to allow perspective interpolation of UV.
+// Packed in to a vector to work around bug 1630356.
+flat varying vec2 vPerspective;
+
+flat varying vec4 vUvSampleBounds;
+
+#ifdef WR_VERTEX_SHADER
+struct SplitGeometry {
+ vec2 local[4];
+};
+
+SplitGeometry fetch_split_geometry(int address) {
+ ivec2 uv = get_gpu_cache_uv(address);
+
+ vec4 data0 = TEXEL_FETCH(sGpuCache, uv, 0, ivec2(0, 0));
+ vec4 data1 = TEXEL_FETCH(sGpuCache, uv, 0, ivec2(1, 0));
+
+ SplitGeometry geo;
+ geo.local = vec2[4](
+ data0.xy,
+ data0.zw,
+ data1.xy,
+ data1.zw
+ );
+
+ return geo;
+}
+
+vec2 bilerp(vec2 a, vec2 b, vec2 c, vec2 d, float s, float t) {
+ vec2 x = mix(a, b, t);
+ vec2 y = mix(c, d, t);
+ return mix(x, y, s);
+}
+
+struct SplitCompositeInstance {
+ int prim_header_index;
+ int polygons_address;
+ float z;
+ int render_task_index;
+};
+
+SplitCompositeInstance fetch_composite_instance() {
+ SplitCompositeInstance ci;
+
+ ci.prim_header_index = aData.x;
+ ci.polygons_address = aData.y;
+ ci.z = float(aData.z);
+ ci.render_task_index = aData.w;
+
+ return ci;
+}
+
+void main(void) {
+ SplitCompositeInstance ci = fetch_composite_instance();
+ SplitGeometry geometry = fetch_split_geometry(ci.polygons_address);
+ PrimitiveHeader ph = fetch_prim_header(ci.prim_header_index);
+ PictureTask dest_task = fetch_picture_task(ci.render_task_index);
+ Transform transform = fetch_transform(ph.transform_id);
+ ImageSource res = fetch_image_source(ph.user_data.x);
+ ClipArea clip_area = fetch_clip_area(ph.user_data.w);
+
+ vec2 dest_origin = dest_task.task_rect.p0 -
+ dest_task.content_origin;
+
+ vec2 local_pos = bilerp(geometry.local[0], geometry.local[1],
+ geometry.local[3], geometry.local[2],
+ aPosition.y, aPosition.x);
+ vec4 world_pos = transform.m * vec4(local_pos, 0.0, 1.0);
+
+ vec4 final_pos = vec4(
+ dest_origin * world_pos.w + world_pos.xy * dest_task.device_pixel_scale,
+ world_pos.w * ci.z,
+ world_pos.w
+ );
+
+ write_clip(
+ world_pos,
+ clip_area,
+ dest_task
+ );
+
+ gl_Position = uTransform * final_pos;
+
+ vec2 texture_size = vec2(TEX_SIZE(sColor0));
+ vec2 uv0 = res.uv_rect.p0;
+ vec2 uv1 = res.uv_rect.p1;
+
+ vec2 min_uv = min(uv0, uv1);
+ vec2 max_uv = max(uv0, uv1);
+
+ vUvSampleBounds = vec4(
+ min_uv + vec2(0.5),
+ max_uv - vec2(0.5)
+ ) / texture_size.xyxy;
+
+ vec2 f = (local_pos - ph.local_rect.p0) / rect_size(ph.local_rect);
+ f = get_image_quad_uv(ph.user_data.x, f);
+ vec2 uv = mix(uv0, uv1, f);
+ float perspective_interpolate = float(ph.user_data.y);
+
+ vUv = uv / texture_size * mix(gl_Position.w, 1.0, perspective_interpolate);
+ vPerspective.x = perspective_interpolate;
+}
+#endif
+
+#ifdef WR_FRAGMENT_SHADER
+void main(void) {
+ float alpha = do_clip();
+ float perspective_divisor = mix(gl_FragCoord.w, 1.0, vPerspective.x);
+ vec2 uv = clamp(vUv * perspective_divisor, vUvSampleBounds.xy, vUvSampleBounds.zw);
+ write_output(alpha * texture(sColor0, uv));
+}
+
+#ifdef SWGL_DRAW_SPAN
+void swgl_drawSpanRGBA8() {
+ float perspective_divisor = mix(swgl_forceScalar(gl_FragCoord.w), 1.0, vPerspective.x);
+ vec2 uv = vUv * perspective_divisor;
+
+ swgl_commitTextureRGBA8(sColor0, uv, vUvSampleBounds);
+}
+#endif
+
+#endif