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,prim_shared 6 7// interpolated UV coordinates to sample. 8varying vec2 vUv; 9// X = layer index to sample, Y = flag to allow perspective interpolation of UV. 10flat varying vec2 vLayerAndPerspective; 11flat varying vec4 vUvSampleBounds; 12 13#ifdef WR_VERTEX_SHADER 14struct SplitGeometry { 15 vec2 local[4]; 16}; 17 18SplitGeometry fetch_split_geometry(int address) { 19 ivec2 uv = get_gpu_cache_uv(address); 20 21 vec4 data0 = TEXEL_FETCH(sGpuCache, uv, 0, ivec2(0, 0)); 22 vec4 data1 = TEXEL_FETCH(sGpuCache, uv, 0, ivec2(1, 0)); 23 24 SplitGeometry geo; 25 geo.local = vec2[4]( 26 data0.xy, 27 data0.zw, 28 data1.xy, 29 data1.zw 30 ); 31 32 return geo; 33} 34 35vec2 bilerp(vec2 a, vec2 b, vec2 c, vec2 d, float s, float t) { 36 vec2 x = mix(a, b, t); 37 vec2 y = mix(c, d, t); 38 return mix(x, y, s); 39} 40 41struct SplitCompositeInstance { 42 int prim_header_index; 43 int polygons_address; 44 float z; 45}; 46 47SplitCompositeInstance fetch_composite_instance() { 48 SplitCompositeInstance ci; 49 50 ci.prim_header_index = aData.x; 51 ci.polygons_address = aData.y; 52 ci.z = float(aData.z); 53 54 return ci; 55} 56 57void main(void) { 58 SplitCompositeInstance ci = fetch_composite_instance(); 59 SplitGeometry geometry = fetch_split_geometry(ci.polygons_address); 60 PrimitiveHeader ph = fetch_prim_header(ci.prim_header_index); 61 PictureTask dest_task = fetch_picture_task(ph.render_task_index); 62 Transform transform = fetch_transform(ph.transform_id); 63 ImageResource res = fetch_image_resource(ph.user_data.x); 64 ClipArea clip_area = fetch_clip_area(ph.clip_task_index); 65 66 vec2 dest_origin = dest_task.common_data.task_rect.p0 - 67 dest_task.content_origin; 68 69 vec2 local_pos = bilerp(geometry.local[0], geometry.local[1], 70 geometry.local[3], geometry.local[2], 71 aPosition.y, aPosition.x); 72 vec4 world_pos = transform.m * vec4(local_pos, 0.0, 1.0); 73 74 vec4 final_pos = vec4( 75 dest_origin * world_pos.w + world_pos.xy * dest_task.common_data.device_pixel_scale, 76 world_pos.w * ci.z, 77 world_pos.w 78 ); 79 80 write_clip( 81 world_pos, 82 vec2(0.0), 83 clip_area 84 ); 85 86 gl_Position = uTransform * final_pos; 87 88 vec2 texture_size = vec2(textureSize(sPrevPassColor, 0)); 89 vec2 uv0 = res.uv_rect.p0; 90 vec2 uv1 = res.uv_rect.p1; 91 92 vec2 min_uv = min(uv0, uv1); 93 vec2 max_uv = max(uv0, uv1); 94 95 vUvSampleBounds = vec4( 96 min_uv + vec2(0.5), 97 max_uv - vec2(0.5) 98 ) / texture_size.xyxy; 99 100 vec2 f = (local_pos - ph.local_rect.p0) / ph.local_rect.size; 101 f = get_image_quad_uv(ph.user_data.x, f); 102 vec2 uv = mix(uv0, uv1, f); 103 float perspective_interpolate = float(ph.user_data.y); 104 105 vUv = uv / texture_size * mix(gl_Position.w, 1.0, perspective_interpolate); 106 vLayerAndPerspective = vec2(res.layer, perspective_interpolate); 107} 108#endif 109 110#ifdef WR_FRAGMENT_SHADER 111void main(void) { 112 float alpha = do_clip(); 113 float perspective_divisor = mix(gl_FragCoord.w, 1.0, vLayerAndPerspective.y); 114 vec2 uv = clamp(vUv * perspective_divisor, vUvSampleBounds.xy, vUvSampleBounds.zw); 115 oFragColor = alpha * textureLod(sPrevPassColor, vec3(uv, vLayerAndPerspective.x), 0.0); 116} 117#endif 118