1/* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5#include shared,clip_shared 6 7varying vec3 vLocalPos; 8varying vec2 vUv; 9flat varying vec4 vUvBounds; 10flat varying float vLayer; 11flat varying vec4 vEdge; 12flat varying vec4 vUvBounds_NoClamp; 13flat varying float vClipMode; 14 15#define MODE_STRETCH 0 16#define MODE_SIMPLE 1 17 18#ifdef WR_VERTEX_SHADER 19 20struct BoxShadowData { 21 vec2 src_rect_size; 22 float clip_mode; 23 int stretch_mode_x; 24 int stretch_mode_y; 25 RectWithSize dest_rect; 26}; 27 28BoxShadowData fetch_data(ivec2 address) { 29 vec4 data[3] = fetch_from_gpu_cache_3_direct(address); 30 RectWithSize dest_rect = RectWithSize(data[2].xy, data[2].zw); 31 BoxShadowData bs_data = BoxShadowData( 32 data[0].xy, 33 data[0].z, 34 int(data[1].x), 35 int(data[1].y), 36 dest_rect 37 ); 38 return bs_data; 39} 40 41void main(void) { 42 ClipMaskInstance cmi = fetch_clip_item(); 43 ClipArea area = fetch_clip_area(cmi.render_task_address); 44 Transform clip_transform = fetch_transform(cmi.clip_transform_id); 45 Transform prim_transform = fetch_transform(cmi.prim_transform_id); 46 BoxShadowData bs_data = fetch_data(cmi.clip_data_address); 47 ImageResource res = fetch_image_resource_direct(cmi.resource_address); 48 49 RectWithSize dest_rect = bs_data.dest_rect; 50 dest_rect.p0 += cmi.local_pos; 51 52 ClipVertexInfo vi = write_clip_tile_vertex( 53 dest_rect, 54 prim_transform, 55 clip_transform, 56 area, 57 cmi.sub_rect, 58 cmi.snap_offsets 59 ); 60 vLocalPos = vi.local_pos; 61 vLayer = res.layer; 62 vClipMode = bs_data.clip_mode; 63 64 vec2 uv0 = res.uv_rect.p0; 65 vec2 uv1 = res.uv_rect.p1; 66 67 vec2 texture_size = vec2(textureSize(sColor0, 0)); 68 vec2 local_pos = vLocalPos.xy / vLocalPos.z; 69 70 switch (bs_data.stretch_mode_x) { 71 case MODE_STRETCH: { 72 vEdge.x = 0.5; 73 vEdge.z = (dest_rect.size.x / bs_data.src_rect_size.x) - 0.5; 74 vUv.x = (local_pos.x - dest_rect.p0.x) / bs_data.src_rect_size.x; 75 break; 76 } 77 case MODE_SIMPLE: 78 default: { 79 vEdge.xz = vec2(1.0); 80 vUv.x = (local_pos.x - dest_rect.p0.x) / dest_rect.size.x; 81 break; 82 } 83 } 84 85 switch (bs_data.stretch_mode_y) { 86 case MODE_STRETCH: { 87 vEdge.y = 0.5; 88 vEdge.w = (dest_rect.size.y / bs_data.src_rect_size.y) - 0.5; 89 vUv.y = (local_pos.y - dest_rect.p0.y) / bs_data.src_rect_size.y; 90 break; 91 } 92 case MODE_SIMPLE: 93 default: { 94 vEdge.yw = vec2(1.0); 95 vUv.y = (local_pos.y - dest_rect.p0.y) / dest_rect.size.y; 96 break; 97 } 98 } 99 100 vUvBounds = vec4(uv0 + vec2(0.5), uv1 - vec2(0.5)) / texture_size.xyxy; 101 vUvBounds_NoClamp = vec4(uv0, uv1) / texture_size.xyxy; 102} 103#endif 104 105#ifdef WR_FRAGMENT_SHADER 106void main(void) { 107 vec2 local_pos = vLocalPos.xy / vLocalPos.z; 108 109 vec2 uv = clamp(vUv.xy, vec2(0.0), vEdge.xy); 110 uv += max(vec2(0.0), vUv.xy - vEdge.zw); 111 uv = mix(vUvBounds_NoClamp.xy, vUvBounds_NoClamp.zw, uv); 112 uv = clamp(uv, vUvBounds.xy, vUvBounds.zw); 113 114 float in_shadow_rect = init_transform_rough_fs(local_pos); 115 116 float texel = TEX_SAMPLE(sColor0, vec3(uv, vLayer)).r; 117 118 float alpha = mix(texel, 1.0 - texel, vClipMode); 119 120 oFragColor = vec4(mix(vClipMode, alpha, in_shadow_rect)); 121} 122#endif 123