summaryrefslogtreecommitdiffstats
path: root/gfx/wr/webrender/res/cs_clip_image.glsl
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /gfx/wr/webrender/res/cs_clip_image.glsl
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/wr/webrender/res/cs_clip_image.glsl')
-rw-r--r--gfx/wr/webrender/res/cs_clip_image.glsl117
1 files changed, 117 insertions, 0 deletions
diff --git a/gfx/wr/webrender/res/cs_clip_image.glsl b/gfx/wr/webrender/res/cs_clip_image.glsl
new file mode 100644
index 0000000000..94d5d87cbe
--- /dev/null
+++ b/gfx/wr/webrender/res/cs_clip_image.glsl
@@ -0,0 +1,117 @@
+/* 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/. */
+
+#include shared,clip_shared
+
+varying vec2 vLocalPos;
+varying vec2 vClipMaskImageUv;
+
+flat varying vec4 vClipMaskUvInnerRect;
+
+#ifdef WR_VERTEX_SHADER
+
+PER_INSTANCE in vec4 aClipTileRect;
+PER_INSTANCE in ivec2 aClipDataResourceAddress;
+PER_INSTANCE in vec4 aClipLocalRect;
+
+struct ClipMaskInstanceImage {
+ ClipMaskInstanceCommon base;
+ RectWithEndpoint tile_rect;
+ ivec2 resource_address;
+ RectWithEndpoint local_rect;
+};
+
+ClipMaskInstanceImage fetch_clip_item() {
+ ClipMaskInstanceImage cmi;
+
+ cmi.base = fetch_clip_item_common();
+
+ cmi.tile_rect = RectWithEndpoint(aClipTileRect.xy, aClipTileRect.zw);
+ cmi.resource_address = aClipDataResourceAddress;
+ cmi.local_rect = RectWithEndpoint(aClipLocalRect.xy, aClipLocalRect.zw);
+
+ return cmi;
+}
+
+struct ClipImageVertexInfo {
+ vec2 local_pos;
+ vec4 world_pos;
+};
+
+// This differs from write_clip_tile_vertex in that we forward transform the
+// primitive's local-space tile rect into the target space. We use scissoring
+// to ensure that the primitive does not draw outside the target bounds.
+ClipImageVertexInfo write_clip_image_vertex(RectWithEndpoint tile_rect,
+ RectWithEndpoint local_clip_rect,
+ Transform prim_transform,
+ Transform clip_transform,
+ RectWithEndpoint sub_rect,
+ vec2 task_origin,
+ vec2 screen_origin,
+ float device_pixel_scale) {
+ vec2 local_pos = rect_clamp(local_clip_rect, mix(tile_rect.p0, tile_rect.p1, aPosition.xy));
+ vec4 world_pos = prim_transform.m * vec4(local_pos, 0.0, 1.0);
+ vec4 final_pos = vec4(
+ world_pos.xy * device_pixel_scale + (task_origin - screen_origin) * world_pos.w,
+ 0.0,
+ world_pos.w
+ );
+ gl_Position = uTransform * final_pos;
+
+ init_transform_vs(
+ clip_transform.is_axis_aligned
+ ? vec4(vec2(-1.0e16), vec2(1.0e16))
+ : vec4(local_clip_rect.p0, local_clip_rect.p1));
+
+ ClipImageVertexInfo vi = ClipImageVertexInfo(local_pos, world_pos);
+ return vi;
+}
+
+void main(void) {
+ ClipMaskInstanceImage cmi = fetch_clip_item();
+ Transform clip_transform = fetch_transform(cmi.base.clip_transform_id);
+ Transform prim_transform = fetch_transform(cmi.base.prim_transform_id);
+ ImageSource res = fetch_image_source_direct(cmi.resource_address);
+
+ ClipImageVertexInfo vi = write_clip_image_vertex(
+ cmi.tile_rect,
+ cmi.local_rect,
+ prim_transform,
+ clip_transform,
+ cmi.base.sub_rect,
+ cmi.base.task_origin,
+ cmi.base.screen_origin,
+ cmi.base.device_pixel_scale
+ );
+ vLocalPos = vi.local_pos;
+ vec2 uv = (vi.local_pos - cmi.tile_rect.p0) / rect_size(cmi.tile_rect);
+
+ vec2 texture_size = vec2(TEX_SIZE(sColor0));
+ vec4 uv_rect = vec4(res.uv_rect.p0, res.uv_rect.p1);
+ vClipMaskImageUv = mix(uv_rect.xy, uv_rect.zw, uv) / texture_size;
+
+ // applying a half-texel offset to the UV boundaries to prevent linear samples from the outside
+ vClipMaskUvInnerRect = (uv_rect + vec4(0.5, 0.5, -0.5, -0.5)) / texture_size.xyxy;
+}
+#endif
+
+#ifdef WR_FRAGMENT_SHADER
+void main(void) {
+ float alpha = init_transform_rough_fs(vLocalPos);
+ vec2 source_uv = clamp(vClipMaskImageUv, vClipMaskUvInnerRect.xy, vClipMaskUvInnerRect.zw);
+ float clip_alpha = texture(sColor0, source_uv).r; //careful: texture has type A8
+ oFragColor = vec4(mix(1.0, clip_alpha, alpha), 0.0, 0.0, 1.0);
+}
+
+#ifdef SWGL_DRAW_SPAN
+void swgl_drawSpanR8() {
+ if (has_valid_transform_bounds()) {
+ return;
+ }
+
+ swgl_commitTextureLinearR8(sColor0, vClipMaskImageUv, vClipMaskUvInnerRect);
+}
+#endif
+
+#endif