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,rect,render_task,gpu_cache,gradient
6
7varying vec2 v_pos;
8
9flat varying float v_start_radius;
10
11#ifdef WR_VERTEX_SHADER
12
13#define EXTEND_MODE_REPEAT 1
14
15PER_INSTANCE in vec4 aTaskRect;
16PER_INSTANCE in vec2 aCenter;
17PER_INSTANCE in vec2 aScale;
18PER_INSTANCE in float aStartRadius;
19PER_INSTANCE in float aEndRadius;
20PER_INSTANCE in float aXYRatio;
21PER_INSTANCE in int aExtendMode;
22PER_INSTANCE in int aGradientStopsAddress;
23
24void main(void) {
25    // Store 1/rd where rd = end_radius - start_radius
26    // If rd = 0, we can't get its reciprocal. Instead, just use a zero scale.
27    float rd = aEndRadius - aStartRadius;
28    float radius_scale = rd != 0.0 ? 1.0 / rd : 0.0;
29
30    vec2 pos = mix(aTaskRect.xy, aTaskRect.zw, aPosition.xy);
31    gl_Position = uTransform * vec4(pos, 0.0, 1.0);
32
33    v_start_radius = aStartRadius * radius_scale;
34
35    // Transform all coordinates by the y scale so the
36    // fragment shader can work with circles
37
38    // v_pos is in a coordinate space relative to the task rect
39    // (so it is independent of the task origin).
40    v_pos = ((aTaskRect.zw - aTaskRect.xy) * aPosition.xy * aScale - aCenter) * radius_scale;
41    v_pos.y *= aXYRatio;
42
43    v_gradient_repeat = float(aExtendMode == EXTEND_MODE_REPEAT);
44    v_gradient_address = aGradientStopsAddress;
45}
46#endif
47
48
49#ifdef WR_FRAGMENT_SHADER
50
51void main(void) {
52    // Solve for t in length(pd) = v_start_radius + t * rd
53    float offset = length(v_pos) - v_start_radius;
54
55    oFragColor = sample_gradient(offset);
56}
57
58#ifdef SWGL_DRAW_SPAN
59void swgl_drawSpanRGBA8() {
60    int address = swgl_validateGradient(sGpuCache, get_gpu_cache_uv(v_gradient_address),
61                                        int(GRADIENT_ENTRIES + 2.0));
62    if (address < 0) {
63        return;
64    }
65    swgl_commitRadialGradientRGBA8(sGpuCache, address, GRADIENT_ENTRIES, v_gradient_repeat != 0.0,
66                                   v_pos, v_start_radius);
67}
68#endif
69
70#endif
71