1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
/* 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.
flat varying float 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);
ImageResource res = fetch_image_resource(ph.user_data.x);
ClipArea clip_area = fetch_clip_area(ph.user_data.w);
vec2 dest_origin = dest_task.common_data.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(textureSize(sColor0, 0));
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) / ph.local_rect.size;
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 = perspective_interpolate;
}
#endif
#ifdef WR_FRAGMENT_SHADER
void main(void) {
float alpha = do_clip();
float perspective_divisor = mix(gl_FragCoord.w, 1.0, vPerspective);
vec2 uv = clamp(vUv * perspective_divisor, vUvSampleBounds.xy, vUvSampleBounds.zw);
write_output(alpha * texture(sColor0, uv));
}
#ifdef SWGL
void swgl_drawSpanRGBA8() {
if (!swgl_isTextureRGBA8(sColor0) || !swgl_isTextureLinear(sColor0)) {
return;
}
float perspective_divisor = mix(swgl_forceScalar(gl_FragCoord.w), 1.0, vPerspective);
vec2 uv = vUv * perspective_divisor;
if (swgl_allowTextureNearest(sColor0, uv)) {
swgl_commitTextureNearestRGBA8(sColor0, uv, vUvSampleBounds, 0);
return;
}
uv = swgl_linearQuantize(sColor0, uv);
vec2 min_uv = swgl_linearQuantize(sColor0, vUvSampleBounds.xy);
vec2 max_uv = swgl_linearQuantize(sColor0, vUvSampleBounds.zw);
vec2 step_uv = swgl_linearQuantizeStep(sColor0, swgl_interpStep(vUv)) * perspective_divisor;
while (swgl_SpanLength > 0) {
swgl_commitTextureLinearRGBA8(sColor0, clamp(uv, min_uv, max_uv), 0);
uv += step_uv;
}
}
#endif
#endif
|