Backed out 5 changesets (bug 1866429, bug 1866421, bug 1865046, bug 1866462, bug...
[gecko.git] / gfx / wr / swgl / README.md
blob2c43ed881957398548ce9658f018a9ea7eb8855f
1 # swgl
3 Software OpenGL implementation for WebRender
5 ## Overview
6 This is a relatively simple single threaded software rasterizer designed
7 for use by WebRender. It will shade one quad at a time using a 4xf32 vector
8 with one vertex per lane. It rasterizes quads usings spans and shades that
9 span 4 pixels at a time.
11 ## Building
12 clang-cl is required to build on Windows. This can be done by installing
13 the llvm binaries from https://releases.llvm.org/ and adding the installation
14 to the path with something like `set PATH=%PATH%;C:\Program Files\LLVM\bin`.
15 Then `set CC=clang-cl` and `set CXX=clang-cl`. That should be sufficient
16 for `cc-rs` to use `clang-cl` instead of `cl`.
18 ## Extensions
19 SWGL contains a number of OpenGL and GLSL extensions designed to both ease
20 integration with WebRender and to help accelerate span rasterization.
22 GLSL extension intrinsics are generally prefixed with `swgl_` to distinguish
23 them from other items in the GLSL namespace.
25 Inside GLSL, the `SWGL` preprocessor token is defined so that usage of SWGL
26 extensions may be conditionally compiled.
28 ```
29 void swgl_drawSpanRGBA8();
30 void swgl_drawSpanR8();
32 int swgl_SpanLength;
33 int swgl_StepSize;
35 mixed swgl_interpStep(mixed varying_input);
36 void swgl_stepInterp();
37 ```
39 SWGL's default fragment processing calls a fragment shader's `main` function
40 on groups of fragments in units of `swgl_StepSize`. On return, the value of
41 gl_FragColor is read, packed to an appropriate pixel format, and sent to the
42 blend stage for output to the destination framebuffer. This can be inefficient
43 for some types of fragment shaders, such as those that must lookup from a
44 texture and immediately output it, unpacking the texels only to subsequently
45 repack them at cost. Also, various per-fragment conditions in the shader might
46 need to be repeatedly checked, even though they are actually constant over
47 the entire primitive.
49 To work around this inefficiency, SWGL allows fragments to optionally be
50 processed over entire spans. This can both side-step the packing inefficiency
51 as well as more efficiently deal with conditions that remain constant over an
52 entire span. SWGL also introduces various specialized intrinsics for more
53 efficiently dealing with certain types of primitive spans with optimal
54 fixed-function processing.
56 Inside a fragment shader, a `swgl_drawSpan` function may be defined to override
57 the normal fragment processing for that fragment shader. The function must then
58 call some form of `swgl_commit` intrinsic to actually output to the destination
59 framebuffer via the blend stage, as normal fragment processing does not take
60 place otherwise as would have happened in `main`. This function is used by the
61 rasterizer to process an entire span of fragments that have passed the depth
62 test (if applicable) and clipping, but have not yet been output to the blend
63 stage.
65 The amount of fragments within the span to be processed is designated by
66 `swgl_SpanLength` and is always aligned to units of `swgl_StepSize`.
67 The size of a group of fragments in terms of which `swgl_commit` intrinsics
68 process and output fragments is designated by `swgl_StepSize`. The
69 `swgl_commit` intrinsics will deduct accordingly from `swgl_SpanLength` in
70 units of `swgl_StepSize` to reflect the fragments actually processed, which
71 may be less than the entire span or up to the entire span.
73 Fragments should be output until `swgl_SpanLength` becomes zero to process the
74 entire span. If `swgl_drawSpan` returns while leaving any fragments unprocessed,
75 the remaining fragments will be processed as normal by the fragment shader's
76 `main` function. This can be used to conditionally handle certain fast-paths
77 in a fragment shader by otherwise defaulting to the `main` function if
78 `swgl_drawSpan` can't appropriately process some or all of the fragments.
80 The values of any varying inputs to the fragment shader will be set to their
81 values for the start of the span, but do not automatically update over the
82 the course of a span within a given call to `swgl_drawSpan`. The
83 `swgl_interpStep` intrinsic may be used to get the derivative per `swgl_StepSize`
84 group of fragments of a varying input so that the caller may update such
85 variables manually if desired or otherwise use that information for processing.
86 The `swgl_stepInterp` intrinsic forces all such varying inputs to advance by
87 a single step.
89 The RGBA8 version will be used when the destination framebuffer is RGBA8 format,
90 and the R8 version will be used when the destination framebuffer is R8. Various
91 other intrinsics described below may have restrictions on whether they can be
92 used only with a certain destination framebuffer format and are noted as such if
93 so.
95 ```
96 void swgl_clipMask(sampler2D mask, vec2 offset, vec2 bb_origin, vec2 bb_size);
97 ```
99 When called from the the vertex shader, this specifies a clip mask texture to
100 be used to mask the currently drawn primitive while blending is enabled. This
101 mask will only apply to the current primitive.
103 The mask must be an R8 texture that will be interpreted as alpha weighting
104 applied to the source pixel prior to the blend stage. It is sampled 1:1 with
105 nearest filtering without any applied transform. The given offset specifies
106 the positioning of the clip mask relative to the framebuffer's viewport.
108 The supplied bounding box constrains sampling of the clip mask to only fall
109 within the given rectangle, specified relative to the clip mask offset.
110 Anything falling outside this rectangle will be clipped entirely. If the
111 rectangle is empty, then the clip mask will be ignored.
114 void swgl_antiAlias(int edgeMask);
117 When called from the vertex shader, this enables anti-aliasing for the
118 currently drawn primitive while blending is enabled. This setting will only
119 apply to the current primitive. Anti-aliasing will be applied only to the
120 edges corresponding to bits supplied in the mask. For simple use-cases,
121 the edge mask can be set to all 1 bits to enable AA for the entire quad.
123 The order of the bits in the edge mask must match the winding order in which
124 the vertices are output in the vertex shader if processed as a quad, so that
125 the edge ends on that vertex. The easiest way to understand this ordering
126 is that for a rectangle (x0,y0,x1,y1) then the edge Nth edge bit corresponds
127 to the edge where Nth coordinate in the rectangle is constant.
129 SWGL tries to use an anti-aliasing method that is reasonably close to WR's
130 signed-distance field approximation. WR would normally try to discern the
131 2D local-space coordinates of a given destination pixel relative to the
132 2D local-space bounding rectangle of a primitive. It then uses the screen-
133 space derivative to try to determine the how many local-space units equate
134 to a distance of around one screen-space pixel. A distance approximation
135 of coverage is then used based on the distance in local-space from the
136 the current pixel's center, roughly at half-intensity at pixel center
137 and ranging to zero or full intensity within a radius of half a pixel
138 away from the center. To account for AAing going outside the normal geometry
139 boundaries of the primitive, WR has to extrude the primitive by a local-space
140 estimate to allow some AA to happen within the extruded region.
142 SWGL can ultimately do this approximation more simply and get around the
143 extrusion limitations by just ensuring spans encompass any pixel that is
144 partially covered when computing span boundaries. Further, since SWGL already
145 knows the slope of an edge and the coordinate of the span relative to the span
146 boundaries, finding the partial coverage of a given span becomes easy to do
147 without requiring any extra interpolants to track against local-space bounds.
148 Essentially, SWGL just performs anti-aliasing on the actual geometry bounds,
149 but when the pixels on a span's edge are determined to be partially covered
150 during span rasterization, it uses the same distance field method as WR on
151 those span boundary pixels to estimate the coverage based on edge slope.
154 void swgl_commitTextureLinearRGBA8(sampler, vec2 uv, vec4 uv_bounds);
155 void swgl_commitTextureLinearR8(sampler, vec2 uv, vec4 uv_bounds);
156 void swgl_commitTextureLinearR8ToRGBA8(sampler, vec2 uv, vec4 uv_bounds);
158 void swgl_commitTextureLinearColorRGBA8(sampler, vec2 uv, vec4 uv_bounds, vec4|float color);
159 void swgl_commitTextureLinearColorR8(sampler, vec2 uv, vec4 uv_bounds, vec4|float color);
160 void swgl_commitTextureLinearColorR8ToRGBA8(sampler, vec2 uv, vec4 uv_bounds, vec4|float color);
162 void swgl_commitTextureLinearRepeatRGBA8(sampler, vec2 uv, vec2 tile_repeat, vec4 uv_repeat, vec4 uv_bounds);
163 void swgl_commitTextureLinearRepeatColorRGBA8(sampler, vec2 uv, vec2 tile_repeat, vec4 uv_repeat, vec4 uv_bounds, vec4|float color);
165 void swgl_commitTextureNearestRGBA8(sampler, vec2 uv, vec4 uv_bounds);
166 void swgl_commitTextureNearestColorRGBA8(sampler, vec2 uv, vec4 uv_bounds, vec4|float color);
168 void swgl_commitTextureNearestRepeatRGBA8(sampler, vec2 uv, vec2 tile_repeat, vec4 uv_repeat, vec4 uv_bounds);
169 void swgl_commitTextureNearestRepeatColorRGBA8(sampler, vec2 uv, vec2 tile_repeat, vec4 uv_repeat, vec4 uv_bounds, vec4|float color);
171 void swgl_commitTextureRGBA8(sampler, vec2 uv, vec4 uv_bounds);
172 void swgl_commitTextureColorRGBA8(sampler, vec2 uv, vec4 uv_bounds, vec4|float color);
174 void swgl_commitTextureRepeatRGBA8(sampler, vec2 uv, vec2 tile_repeat, vec4 uv_repeat, vec4 uv_bounds);
175 void swgl_commitTextureRepeatColorRGBA8(sampler, vec2 uv, vec2 tile_repeat, vec4 uv_repeat, vec4 uv_bounds, vec4|float color);
177 void swgl_commitPartialTextureLinearR8(int len, sampler, vec2 uv, vec4 uv_bounds);
178 void swgl_commitPartialTextureLinearInvertR8(int len, sampler, vec2 uv, vec4 uv_bounds);
181 Samples and commits an entire span of texture starting at the given uv and
182 within the supplied uv bounds. The color variations also accept a supplied color
183 that modulates the result.
185 The RGBA8 versions may only be used to commit within `swgl_drawSpanRGBA8`, and
186 the R8 versions may only be used to commit within `swgl_drawSpanR8`. The R8ToRGBA8
187 versions may be used to sample from an R8 source while committing to an RGBA8
188 framebuffer.
190 The Linear variations use a linear filter that bilinearly interpolates between
191 the four samples near the pixel. The Nearest variations use a nearest filter
192 that chooses the closest aliased sample to the center of the pixel. If neither
193 Linear nor Nearest is specified in the `swgl_commitTexture` variation name, then
194 it will automatically select either the Linear or Nearest variation depending
195 on the sampler's specified filter.
197 The Repeat variations require an optional repeat rect that specifies how to
198 scale and offset the UVs, assuming the UVs are normalized to repeat in the
199 range 0 to 1. For NearestRepeat variations, it is assumed the repeat rect is
200 always within the bounds. The tile repeat limit, if non-zero, specifies the
201 maximum number of repetitions allowed.
203 The Partial variations allow committing only a sub-span rather the entire
204 remaining span. These are currently only implemented in linear R8 variants
205 for optimizing clip shaders in WebRender. The Invert variant of these is
206 useful for implementing clip-out modes by inverting the source texture value.
209 // Premultiplied alpha over blend, but with source color set to source alpha modulated with a constant color.
210 void swgl_blendDropShadow(vec4 color);
211 // Premultiplied alpha over blend, but treats the source as a subpixel mask modulated with a constant color.
212 void swgl_blendSubpixelText(vec4 color);
215 SWGL allows overriding the blend mode per-primitive by calling `swgl_blend`
216 intrinsics in the vertex shader. The existing blend mode set by the GL is
217 replaced with the one specified by the intrinsic for the current primitive.
218 The blend mode will be reset to the blend mode set by the GL for the next
219 primitive after the current one, even within the same draw call.