summaryrefslogtreecommitdiffstats
path: root/gfx/wr/webrender/res/ps_split_composite.glsl
blob: c07eca137127b00a040e1adcf0a1750c7fd9f110 (plain)
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
/* 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 highp vec2 vUv;

// Flag to allow perspective interpolation of UV.
// Packed in to a vector to work around bug 1630356.
flat varying mediump vec2 vPerspective;

flat varying highp 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