@swf2es/render 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +17 -2
- package/dist/commands.d.ts +67 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +93 -0
- package/dist/commands.js.map +1 -0
- package/dist/filter-plan.d.ts +110 -0
- package/dist/filter-plan.d.ts.map +1 -0
- package/dist/filter-plan.js +480 -0
- package/dist/filter-plan.js.map +1 -0
- package/dist/filter-shaders.d.ts +63 -0
- package/dist/filter-shaders.d.ts.map +1 -0
- package/dist/filter-shaders.js +350 -0
- package/dist/filter-shaders.js.map +1 -0
- package/dist/filters.d.ts +107 -0
- package/dist/filters.d.ts.map +1 -0
- package/dist/filters.js +187 -0
- package/dist/filters.js.map +1 -0
- package/dist/geometry.d.ts +83 -0
- package/dist/geometry.d.ts.map +1 -0
- package/dist/geometry.js +93 -0
- package/dist/geometry.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/keeps.d.ts +17 -0
- package/dist/keeps.d.ts.map +1 -0
- package/dist/keeps.js +17 -0
- package/dist/keeps.js.map +1 -0
- package/dist/kernel-shaders.d.ts +74 -0
- package/dist/kernel-shaders.d.ts.map +1 -0
- package/dist/kernel-shaders.js +323 -0
- package/dist/kernel-shaders.js.map +1 -0
- package/dist/measure.d.ts +56 -0
- package/dist/measure.d.ts.map +1 -0
- package/dist/measure.js +287 -0
- package/dist/measure.js.map +1 -0
- package/dist/plan.d.ts +14 -0
- package/dist/plan.d.ts.map +1 -0
- package/dist/plan.js +247 -0
- package/dist/plan.js.map +1 -0
- package/dist/registry.d.ts +49 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +87 -0
- package/dist/registry.js.map +1 -0
- package/dist/rows.d.ts +39 -0
- package/dist/rows.d.ts.map +1 -0
- package/dist/rows.js +60 -0
- package/dist/rows.js.map +1 -0
- package/dist/scene.d.ts +179 -0
- package/dist/scene.d.ts.map +1 -0
- package/dist/scene.js +265 -0
- package/dist/scene.js.map +1 -0
- package/dist/shelves.d.ts +23 -0
- package/dist/shelves.d.ts.map +1 -0
- package/dist/shelves.js +63 -0
- package/dist/shelves.js.map +1 -0
- package/dist/textures.d.ts +72 -0
- package/dist/textures.d.ts.map +1 -0
- package/dist/textures.js +160 -0
- package/dist/textures.js.map +1 -0
- package/dist/webgl/atlas.d.ts +63 -0
- package/dist/webgl/atlas.d.ts.map +1 -0
- package/dist/webgl/atlas.js +328 -0
- package/dist/webgl/atlas.js.map +1 -0
- package/dist/webgl/backend.d.ts +141 -0
- package/dist/webgl/backend.d.ts.map +1 -0
- package/dist/webgl/backend.js +659 -0
- package/dist/webgl/backend.js.map +1 -0
- package/dist/webgl/composite.d.ts +101 -0
- package/dist/webgl/composite.d.ts.map +1 -0
- package/dist/webgl/composite.js +293 -0
- package/dist/webgl/composite.js.map +1 -0
- package/dist/webgl/draws.d.ts +213 -0
- package/dist/webgl/draws.d.ts.map +1 -0
- package/dist/webgl/draws.js +714 -0
- package/dist/webgl/draws.js.map +1 -0
- package/dist/webgl/filters.d.ts +107 -0
- package/dist/webgl/filters.d.ts.map +1 -0
- package/dist/webgl/filters.js +351 -0
- package/dist/webgl/filters.js.map +1 -0
- package/dist/webgl/gpu-textures.d.ts +44 -0
- package/dist/webgl/gpu-textures.d.ts.map +1 -0
- package/dist/webgl/gpu-textures.js +178 -0
- package/dist/webgl/gpu-textures.js.map +1 -0
- package/dist/webgl/holds.d.ts +97 -0
- package/dist/webgl/holds.d.ts.map +1 -0
- package/dist/webgl/holds.js +453 -0
- package/dist/webgl/holds.js.map +1 -0
- package/dist/webgl/index.d.ts +2 -0
- package/dist/webgl/index.d.ts.map +1 -0
- package/dist/webgl/index.js +4 -0
- package/dist/webgl/index.js.map +1 -0
- package/dist/webgl/kernels.d.ts +64 -0
- package/dist/webgl/kernels.d.ts.map +1 -0
- package/dist/webgl/kernels.js +160 -0
- package/dist/webgl/kernels.js.map +1 -0
- package/dist/webgl/pool.d.ts +71 -0
- package/dist/webgl/pool.d.ts.map +1 -0
- package/dist/webgl/pool.js +192 -0
- package/dist/webgl/pool.js.map +1 -0
- package/dist/webgl/programs.d.ts +130 -0
- package/dist/webgl/programs.d.ts.map +1 -0
- package/dist/webgl/programs.js +582 -0
- package/dist/webgl/programs.js.map +1 -0
- package/dist/webgl/stage.d.ts +67 -0
- package/dist/webgl/stage.d.ts.map +1 -0
- package/dist/webgl/stage.js +173 -0
- package/dist/webgl/stage.js.map +1 -0
- package/dist/webgl/targets.d.ts +172 -0
- package/dist/webgl/targets.d.ts.map +1 -0
- package/dist/webgl/targets.js +323 -0
- package/dist/webgl/targets.js.map +1 -0
- package/package.json +35 -3
- package/src/commands.ts +98 -0
- package/src/filter-plan.ts +755 -0
- package/src/filter-shaders.ts +360 -0
- package/src/filters.ts +220 -0
- package/src/geometry.ts +143 -0
- package/src/index.ts +87 -0
- package/src/keeps.ts +21 -0
- package/src/kernel-shaders.ts +375 -0
- package/src/measure.ts +400 -0
- package/src/plan.ts +331 -0
- package/src/registry.ts +105 -0
- package/src/rows.ts +93 -0
- package/src/scene.ts +297 -0
- package/src/shelves.ts +70 -0
- package/src/textures.ts +198 -0
- package/src/webgl/atlas.ts +370 -0
- package/src/webgl/backend.ts +973 -0
- package/src/webgl/composite.ts +372 -0
- package/src/webgl/draws.ts +902 -0
- package/src/webgl/filters.ts +502 -0
- package/src/webgl/gpu-textures.ts +253 -0
- package/src/webgl/holds.ts +624 -0
- package/src/webgl/index.ts +3 -0
- package/src/webgl/kernels.ts +205 -0
- package/src/webgl/pool.ts +245 -0
- package/src/webgl/programs.ts +620 -0
- package/src/webgl/stage.ts +214 -0
- package/src/webgl/targets.ts +464 -0
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
import { ROWS_A_LINE } from "../rows.js";
|
|
2
|
+
import { ADD, ALPHA, DARKEN, DIFFERENCE, ERASE, HARDLIGHT, INVERT, LAYER, LIGHTEN, MULTIPLY, NORMAL, OVERLAY, SCREEN, SUBTRACT, } from "../scene.js";
|
|
3
|
+
/** Texels a row (ROW_FLOATS over four). */
|
|
4
|
+
export const ROW_TEXELS = 4;
|
|
5
|
+
/**
|
|
6
|
+
* The vertex atlas' attributes, where both the fill and the mesh programs
|
|
7
|
+
* read them: a mesh's depth is the four bytes of its colour, as a float.
|
|
8
|
+
*/
|
|
9
|
+
export const POSITION_AT = 0;
|
|
10
|
+
export const TEXEL_AT = 1;
|
|
11
|
+
export const COLOR_AT = 2;
|
|
12
|
+
export const DEPTH_AT = 3;
|
|
13
|
+
/** Advanced text's glyph quads' attributes past their position (GeometryData.glyphs), in theirs. */
|
|
14
|
+
export const ORIGIN_AT = 4;
|
|
15
|
+
export const GLYPH_AT = 5;
|
|
16
|
+
export const RUN_AT = 6;
|
|
17
|
+
export const TINT_AT = 7;
|
|
18
|
+
/** The most cutoff table entries a text's draw takes, as the player's text/saffron.ts builds them. */
|
|
19
|
+
export const TABLE_ENTRIES = 48;
|
|
20
|
+
/** Segments a row of the outlines' texture, as the player's text/saffron.ts stores them. */
|
|
21
|
+
export const OUTLINE_ROW = 1024;
|
|
22
|
+
/**
|
|
23
|
+
* The most draws a multi-draw of the fill program makes, their rows in its
|
|
24
|
+
* integer texture, a line of it. A power of two: the vertex shader splits a
|
|
25
|
+
* draw's place in the table into column and line with a mask and a shift.
|
|
26
|
+
*/
|
|
27
|
+
export const RUN_MOST = 256;
|
|
28
|
+
/** Textures the fill program samples in one draw call, each on a unit of its own. */
|
|
29
|
+
export const FILL_TEXTURES = 8;
|
|
30
|
+
/**
|
|
31
|
+
* A fill draw's row and how it is drawn, in one int: the row in the bits
|
|
32
|
+
* below FILL_SLOT, then which of the fill program's textures it samples, one
|
|
33
|
+
* past its index or 0 for none, then SNAP_BIT where it snaps (SNAP). Rows
|
|
34
|
+
* are fewer: ROWS_A_LINE to a line of a texture of at most 16384 lines.
|
|
35
|
+
*/
|
|
36
|
+
export const FILL_SLOT = 24;
|
|
37
|
+
export const SNAP_BIT = 1 << 28;
|
|
38
|
+
/** The texture unit a mesh's texture is bound to, and textures are uploaded on; the rows are on 0. */
|
|
39
|
+
export const TEXTURE_UNIT = 1;
|
|
40
|
+
/** The units a composite reads its layer and what is below from. */
|
|
41
|
+
export const LAYER_UNIT = 2;
|
|
42
|
+
export const BACK_UNIT = 3;
|
|
43
|
+
/** The unit advanced text's outlines are on (uploadOutlines); the filters take 4 to 6. */
|
|
44
|
+
export const OUTLINE_UNIT = 7;
|
|
45
|
+
/** The first of the units the fill program's textures are bound to (FILL_TEXTURES). */
|
|
46
|
+
export const FILL_UNIT = 8;
|
|
47
|
+
/** The multi-draw row table's unit, past the fill textures. */
|
|
48
|
+
export const RUN_UNIT = FILL_UNIT + FILL_TEXTURES;
|
|
49
|
+
/**
|
|
50
|
+
* Places a vertex by its row's transform, on a quarter of a pixel of
|
|
51
|
+
* Flash's (uUnit of them a stage pixel, from the stage's origin) where it
|
|
52
|
+
* snaps (SNAP), then on the target by uView (scale and offset into clip
|
|
53
|
+
* space), and passes on its straight colour, the row's colour transform
|
|
54
|
+
* and the texture it samples. uRow names the draw's row (FILL_SLOT); with
|
|
55
|
+
* `multi` (WEBGL_multi_draw), uRunTable names each draw's of a multi-draw by
|
|
56
|
+
* gl_DrawID, which is 0 in a draw of its own.
|
|
57
|
+
*/
|
|
58
|
+
export const fillVertex = (multi) => `#version 300 es
|
|
59
|
+
${multi ? "#extension GL_ANGLE_multi_draw : require" : ""}
|
|
60
|
+
precision highp float;
|
|
61
|
+
layout(location = ${POSITION_AT}) in vec2 aPosition;
|
|
62
|
+
layout(location = ${TEXEL_AT}) in vec2 aTexel;
|
|
63
|
+
layout(location = ${COLOR_AT}) in vec4 aColor;
|
|
64
|
+
uniform highp sampler2D uRows;
|
|
65
|
+
${multi ? "uniform highp isampler2D uRunTable;\nuniform int uRunBase;" : "uniform int uRow;"}
|
|
66
|
+
uniform vec4 uView;
|
|
67
|
+
uniform float uUnit;
|
|
68
|
+
out vec4 vColor;
|
|
69
|
+
out vec2 vTexel;
|
|
70
|
+
flat out vec4 vMul;
|
|
71
|
+
flat out vec4 vAdd;
|
|
72
|
+
flat out int vSlot;
|
|
73
|
+
|
|
74
|
+
void main(void) {
|
|
75
|
+
int draw = ${multi ? `texelFetch(uRunTable, ivec2((uRunBase + gl_DrawID) & ${RUN_MOST - 1}, (uRunBase + gl_DrawID) >> ${Math.log2(RUN_MOST)}), 0).r` : "uRow"};
|
|
76
|
+
int row = draw & ${(1 << FILL_SLOT) - 1};
|
|
77
|
+
vSlot = (draw >> ${FILL_SLOT}) & 15;
|
|
78
|
+
ivec2 at = ivec2((row & ${ROWS_A_LINE - 1}) * ${ROW_TEXELS}, row >> ${Math.log2(ROWS_A_LINE)});
|
|
79
|
+
vec4 m = texelFetch(uRows, at, 0);
|
|
80
|
+
vec4 t = texelFetch(uRows, at + ivec2(1, 0), 0);
|
|
81
|
+
vMul = texelFetch(uRows, at + ivec2(2, 0), 0);
|
|
82
|
+
vAdd = texelFetch(uRows, at + ivec2(3, 0), 0);
|
|
83
|
+
vec2 p = vec2(m.x * aPosition.x + m.z * aPosition.y + t.x, m.y * aPosition.x + m.w * aPosition.y + t.y);
|
|
84
|
+
if ((draw & ${SNAP_BIT}) != 0) {
|
|
85
|
+
p = roundEven(p * uUnit * 4.0) / (uUnit * 4.0);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
gl_Position = vec4(p * uView.xy + uView.zw, 0.0, 1.0);
|
|
89
|
+
vColor = aColor;
|
|
90
|
+
vTexel = aTexel;
|
|
91
|
+
}
|
|
92
|
+
`;
|
|
93
|
+
/**
|
|
94
|
+
* Texel `at` of the texture vSlot names, as only a constant may index the
|
|
95
|
+
* samplers. At level 0: the textures have no mipmaps and sample alike up
|
|
96
|
+
* close and far off, and so no derivatives are taken in the switch.
|
|
97
|
+
*/
|
|
98
|
+
const slotTexel = Array.from({ length: FILL_TEXTURES }, (_, k) => ` case ${k + 1}:
|
|
99
|
+
return textureLod(uTextures[${k}], at / vec2(textureSize(uTextures[${k}], 0)), 0.0);`).join("\n");
|
|
100
|
+
/**
|
|
101
|
+
* Flash's colour transform on the straight colour, clamped, then
|
|
102
|
+
* premultiplied for blending: the vertex' colour, or with a texture the
|
|
103
|
+
* texel's (premultiplied in the texture) times it, as the colour batcher
|
|
104
|
+
* did, a clear texel staying clear.
|
|
105
|
+
*/
|
|
106
|
+
export const fillFragment = `#version 300 es
|
|
107
|
+
precision highp float;
|
|
108
|
+
in vec4 vColor;
|
|
109
|
+
in vec2 vTexel;
|
|
110
|
+
flat in vec4 vMul;
|
|
111
|
+
flat in vec4 vAdd;
|
|
112
|
+
flat in int vSlot;
|
|
113
|
+
uniform sampler2D uTextures[${FILL_TEXTURES}];
|
|
114
|
+
out vec4 finalColor;
|
|
115
|
+
|
|
116
|
+
vec4 texel(vec2 at) {
|
|
117
|
+
switch (vSlot) {
|
|
118
|
+
${slotTexel}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return vec4(0.0);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
void main(void) {
|
|
125
|
+
vec4 straight = vColor;
|
|
126
|
+
if (vSlot != 0) {
|
|
127
|
+
vec4 t = texel(vTexel);
|
|
128
|
+
if (t.a == 0.0) {
|
|
129
|
+
finalColor = vec4(0.0);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
straight = vec4(t.rgb / t.a * vColor.rgb, t.a * vColor.a);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
vec4 c = clamp(straight * vMul + vAdd, 0.0, 1.0);
|
|
137
|
+
finalColor = vec4(c.rgb * c.a, c.a);
|
|
138
|
+
}
|
|
139
|
+
`;
|
|
140
|
+
/**
|
|
141
|
+
* drawTriangles' textured triangles (MESH), placed as fills are, their u
|
|
142
|
+
* and v carried times their depth t, and t, which the GPU interpolates
|
|
143
|
+
* straight across the screen for each pixel to divide.
|
|
144
|
+
*/
|
|
145
|
+
export const meshVertex = `#version 300 es
|
|
146
|
+
precision highp float;
|
|
147
|
+
layout(location = ${POSITION_AT}) in vec2 aPosition;
|
|
148
|
+
layout(location = ${TEXEL_AT}) in vec2 aTexel;
|
|
149
|
+
layout(location = ${DEPTH_AT}) in float aDepth;
|
|
150
|
+
uniform highp sampler2D uRows;
|
|
151
|
+
uniform int uRow;
|
|
152
|
+
uniform vec4 uView;
|
|
153
|
+
out vec3 vUVT;
|
|
154
|
+
flat out vec4 vMul;
|
|
155
|
+
flat out vec4 vAdd;
|
|
156
|
+
|
|
157
|
+
void main(void) {
|
|
158
|
+
ivec2 at = ivec2((uRow & ${ROWS_A_LINE - 1}) * ${ROW_TEXELS}, uRow >> ${Math.log2(ROWS_A_LINE)});
|
|
159
|
+
vec4 m = texelFetch(uRows, at, 0);
|
|
160
|
+
vec4 t = texelFetch(uRows, at + ivec2(1, 0), 0);
|
|
161
|
+
vMul = texelFetch(uRows, at + ivec2(2, 0), 0);
|
|
162
|
+
vAdd = texelFetch(uRows, at + ivec2(3, 0), 0);
|
|
163
|
+
vec2 p = vec2(m.x * aPosition.x + m.z * aPosition.y + t.x, m.y * aPosition.x + m.w * aPosition.y + t.y);
|
|
164
|
+
gl_Position = vec4(p * uView.xy + uView.zw, 0.0, 1.0);
|
|
165
|
+
vUVT = vec3(aTexel * aDepth, aDepth);
|
|
166
|
+
}
|
|
167
|
+
`;
|
|
168
|
+
/**
|
|
169
|
+
* drawTriangles' bitmap as adl samples it: u and v from 0 to 1 onto the first
|
|
170
|
+
* texel's centre to the last's, wrapped into that or clamped to it, read
|
|
171
|
+
* once a pixel of Flash's, at its top left corner; not smoothed, the nearer
|
|
172
|
+
* texel, the lower of two as near; smoothed, the four around, weighed.
|
|
173
|
+
* uFrag takes a fragment to the target's pixels from the stage's origin,
|
|
174
|
+
* down (x + uFrag.x, uFrag.y + uFrag.z * y), and is a pixel of Flash's
|
|
175
|
+
* that many of them (w). uMode: whether it repeats, whether it is smoothed,
|
|
176
|
+
* and whether it is a 3D object's quad (PLANE), which reads its bitmap
|
|
177
|
+
* otherwise. The colour transform then as on a fill.
|
|
178
|
+
*/
|
|
179
|
+
export const meshFragment = `#version 300 es
|
|
180
|
+
precision highp float;
|
|
181
|
+
in vec3 vUVT;
|
|
182
|
+
flat in vec4 vMul;
|
|
183
|
+
flat in vec4 vAdd;
|
|
184
|
+
uniform sampler2D uTexture;
|
|
185
|
+
uniform vec4 uFrag;
|
|
186
|
+
uniform ivec3 uMode;
|
|
187
|
+
out vec4 finalColor;
|
|
188
|
+
|
|
189
|
+
vec4 texel(ivec2 at) {
|
|
190
|
+
return texelFetch(uTexture, at, 0);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
void main(void) {
|
|
194
|
+
float pixel = uFrag.w;
|
|
195
|
+
vec2 f = vec2(gl_FragCoord.x + uFrag.x, uFrag.y + uFrag.z * gl_FragCoord.y);
|
|
196
|
+
vec2 size = vec2(textureSize(uTexture, 0));
|
|
197
|
+
if (uMode.z != 0) {
|
|
198
|
+
// A 3D object's quad (PLANE): its bitmap read smoothed at the pixel's centre, in its texels.
|
|
199
|
+
vec2 centre = (floor(f / pixel) + 0.5) * pixel;
|
|
200
|
+
vec3 at = vUVT + dFdx(vUVT) * (centre.x - f.x) + dFdy(vUVT) * ((centre.y - f.y) * uFrag.z);
|
|
201
|
+
vec4 shown = texture(uTexture, (at.z != 0.0 ? at.xy / at.z : vec2(0.0)) / size);
|
|
202
|
+
if (shown.a == 0.0) {
|
|
203
|
+
finalColor = vec4(0.0);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
vec4 s = clamp(vec4(shown.rgb / shown.a, shown.a) * vMul + vAdd, 0.0, 1.0);
|
|
208
|
+
finalColor = vec4(s.rgb * s.a, s.a);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
vec2 corner = floor(f / pixel) * pixel;
|
|
213
|
+
vec3 uvt = vUVT + dFdx(vUVT) * (corner.x - f.x) + dFdy(vUVT) * ((corner.y - f.y) * uFrag.z);
|
|
214
|
+
vec2 uv = uvt.z != 0.0 ? uvt.xy / uvt.z : vec2(0.0);
|
|
215
|
+
// As adl draws one, a bitmap a texel high shows its first texel throughout.
|
|
216
|
+
if (size.y == 1.0) {
|
|
217
|
+
uv = vec2(0.0);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// A hair nearer 0, as adl's come out, stepped across the triangle in fixed point: 1 wraps to
|
|
221
|
+
// the last texel, not the first, and a corner halfway between texels takes the one nearer 0.
|
|
222
|
+
uv -= sign(uv) / 16384.0;
|
|
223
|
+
uv = uMode.x != 0 ? fract(uv) : clamp(uv, 0.0, 1.0);
|
|
224
|
+
vec2 p = uv * (size - 1.0);
|
|
225
|
+
vec4 color;
|
|
226
|
+
if (uMode.y != 0) {
|
|
227
|
+
vec2 below = floor(p);
|
|
228
|
+
vec2 w = p - below;
|
|
229
|
+
ivec2 a = ivec2(below);
|
|
230
|
+
ivec2 b = min(a + 1, ivec2(size) - 1);
|
|
231
|
+
color = mix(
|
|
232
|
+
mix(texel(a), texel(ivec2(b.x, a.y)), w.x),
|
|
233
|
+
mix(texel(ivec2(a.x, b.y)), texel(b), w.x),
|
|
234
|
+
w.y
|
|
235
|
+
);
|
|
236
|
+
} else {
|
|
237
|
+
color = texel(ivec2(floor(p + 0.5)));
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (color.a == 0.0) {
|
|
241
|
+
finalColor = vec4(0.0);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
vec4 c = clamp(vec4(color.rgb / color.a, color.a) * vMul + vAdd, 0.0, 1.0);
|
|
246
|
+
finalColor = vec4(c.rgb * c.a, c.a);
|
|
247
|
+
}
|
|
248
|
+
`;
|
|
249
|
+
/**
|
|
250
|
+
* Advanced text's glyph quads (player's text/saffron.ts), placed by the
|
|
251
|
+
* row's transform: the text's
|
|
252
|
+
* pixels to Flash's, uUnit of them a stage pixel, on their grid from the
|
|
253
|
+
* stage's origin, a BitmapData's in a draw. A glyph's pen stands where its
|
|
254
|
+
* text's origin, at a whole pixel, puts it, snapped as its grid fits it
|
|
255
|
+
* (uMode: gridFitType 0 none, 1 pixel, 2 subpixel, thickness, sharpness),
|
|
256
|
+
* and its quad reaches out past its outline by the furthest cutoff. Its
|
|
257
|
+
* colour is drawn under the row's colour transform, light or dark as adl
|
|
258
|
+
* chooses its table. aOrigin: the pen, and its light and dark tables, each
|
|
259
|
+
* its first entry plus 64 times its entries; aGlyph: a corner of its
|
|
260
|
+
* outline's bounds and the way out from it; aRun: its segments, first and
|
|
261
|
+
* count, the pixels of a unit of its outline, and its size.
|
|
262
|
+
*/
|
|
263
|
+
export const glyphsVertex = `#version 300 es
|
|
264
|
+
precision highp float;
|
|
265
|
+
layout(location = ${POSITION_AT}) in vec2 aPosition;
|
|
266
|
+
layout(location = ${ORIGIN_AT}) in vec4 aOrigin;
|
|
267
|
+
layout(location = ${GLYPH_AT}) in vec4 aGlyph;
|
|
268
|
+
layout(location = ${RUN_AT}) in vec4 aRun;
|
|
269
|
+
layout(location = ${TINT_AT}) in vec4 aColor;
|
|
270
|
+
uniform highp sampler2D uRows;
|
|
271
|
+
uniform int uRow;
|
|
272
|
+
uniform vec4 uView;
|
|
273
|
+
uniform float uUnit;
|
|
274
|
+
uniform vec4 uMode;
|
|
275
|
+
uniform vec4 uTable[${TABLE_ENTRIES}];
|
|
276
|
+
out vec2 vPixel;
|
|
277
|
+
flat out vec2 vPen;
|
|
278
|
+
flat out vec4 vToGlyph;
|
|
279
|
+
flat out vec4 vToPixel;
|
|
280
|
+
flat out vec4 vCut;
|
|
281
|
+
flat out vec4 vShown;
|
|
282
|
+
|
|
283
|
+
// The cutoffs at ppem by the table of entries start to start + count, as text/csm.ts' cutoffs.
|
|
284
|
+
vec2 cutoffs(int start, int count, float ppem) {
|
|
285
|
+
vec4 first = uTable[start];
|
|
286
|
+
vec4 last = uTable[start + count - 1];
|
|
287
|
+
vec2 c = first.yz;
|
|
288
|
+
if (ppem >= last.x) {
|
|
289
|
+
c = last.yz;
|
|
290
|
+
} else if (ppem > first.x) {
|
|
291
|
+
for (int i = 1; i < ${TABLE_ENTRIES}; i++) {
|
|
292
|
+
if (i >= count) {
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
vec4 b = uTable[start + i];
|
|
297
|
+
if (ppem <= b.x) {
|
|
298
|
+
vec4 a = uTable[start + i - 1];
|
|
299
|
+
c = mix(a.yz, b.yz, (ppem - a.x) / (b.x - a.x));
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
float unit = 0.0001 * ppem;
|
|
306
|
+
float t = clamp(uMode.y, -200.0, 200.0);
|
|
307
|
+
float s = clamp(uMode.z, -400.0, 400.0);
|
|
308
|
+
c -= unit * vec2(t + s * 0.5, t - s * 0.5);
|
|
309
|
+
if (c.x < c.y) {
|
|
310
|
+
c = vec2((c.x + c.y) * 0.5);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return c;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
void main(void) {
|
|
317
|
+
ivec2 at = ivec2((uRow & ${ROWS_A_LINE - 1}) * ${ROW_TEXELS}, uRow >> ${Math.log2(ROWS_A_LINE)});
|
|
318
|
+
vec4 m = texelFetch(uRows, at, 0);
|
|
319
|
+
vec4 t = texelFetch(uRows, at + ivec2(1, 0), 0);
|
|
320
|
+
vec4 mul = texelFetch(uRows, at + ivec2(2, 0), 0);
|
|
321
|
+
vec4 add = texelFetch(uRows, at + ivec2(3, 0), 0);
|
|
322
|
+
// The text's pixels to Flash's.
|
|
323
|
+
mat2 linear = mat2(m.xy, m.zw) * uUnit;
|
|
324
|
+
vec2 origin = t.xy * uUnit;
|
|
325
|
+
vec2 pen = linear * aOrigin.xy + roundEven(origin);
|
|
326
|
+
float across = max(abs(linear[0][1]), abs(linear[1][0]));
|
|
327
|
+
if (across > max(abs(linear[0][0]), abs(linear[1][1])) / 65536.0) {
|
|
328
|
+
// Turned or skewed: no grid.
|
|
329
|
+
} else if (uMode.x == 1.0) {
|
|
330
|
+
pen = vec2(roundEven(pen.x * 8.0) / 8.0 + 0.5, roundEven(pen.y));
|
|
331
|
+
} else if (uMode.x == 2.0) {
|
|
332
|
+
pen = vec2(roundEven(pen.x * 4.0) / 4.0 + 0.5, roundEven(pen.y));
|
|
333
|
+
} else {
|
|
334
|
+
pen = roundEven(pen * 4.0) / 4.0 + vec2(0.5, 0.0);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
float ppem = aRun.w * sqrt(abs(determinant(linear)));
|
|
338
|
+
// The colour as drawn, straight: light or dark by it, as adl chooses.
|
|
339
|
+
vec4 shown = clamp(aColor * mul + add, 0.0, 1.0);
|
|
340
|
+
bool light = dot(floor(shown.rgb * 255.0 + 0.5), vec3(30.0, 59.0, 11.0)) > 20000.0;
|
|
341
|
+
int table = int(light ? aOrigin.z : aOrigin.w);
|
|
342
|
+
vec2 cut = cutoffs(table & 63, table >> 6, ppem);
|
|
343
|
+
mat2 toPixel = linear * aRun.z;
|
|
344
|
+
float margin = max(abs(cut.x), abs(cut.y)) + 1.0;
|
|
345
|
+
float det = determinant(toPixel);
|
|
346
|
+
mat2 inverse = det != 0.0
|
|
347
|
+
? mat2(toPixel[1][1], -toPixel[0][1], -toPixel[1][0], toPixel[0][0]) / det
|
|
348
|
+
: mat2(0.0);
|
|
349
|
+
// Out in the glyph's space, so that the margin stays outside under reflections and turns: each
|
|
350
|
+
// row of the inverse gives the glyph's units a pixel across that edge takes.
|
|
351
|
+
vec2 reach = vec2(length(vec2(inverse[0][0], inverse[1][0])),
|
|
352
|
+
length(vec2(inverse[0][1], inverse[1][1]))) * margin;
|
|
353
|
+
vec2 p = pen + toPixel * (aGlyph.xy + aGlyph.zw * reach);
|
|
354
|
+
vPixel = p;
|
|
355
|
+
vPen = pen;
|
|
356
|
+
vToGlyph = vec4(inverse[0], inverse[1]);
|
|
357
|
+
vToPixel = vec4(toPixel[0], toPixel[1]);
|
|
358
|
+
vCut = vec4(cut, aRun.xy);
|
|
359
|
+
vShown = shown;
|
|
360
|
+
gl_Position = vec4((p / uUnit) * uView.xy + uView.zw, 0.0, 1.0);
|
|
361
|
+
}
|
|
362
|
+
`;
|
|
363
|
+
/**
|
|
364
|
+
* Each pixel of Flash's a glyph's quad covers, by its signed distance to
|
|
365
|
+
* the glyph's outline (the segments of its run in uSegments, the nearest
|
|
366
|
+
* and, by parity, whether it is inside), between the cutoffs, as Saffron
|
|
367
|
+
* covers it. Nothing outside: in a mask, which
|
|
368
|
+
* writes the stencil wherever it draws, a glyph is its shape.
|
|
369
|
+
*/
|
|
370
|
+
export const glyphsFragment = `#version 300 es
|
|
371
|
+
precision highp float;
|
|
372
|
+
precision highp int;
|
|
373
|
+
in vec2 vPixel;
|
|
374
|
+
flat in vec2 vPen;
|
|
375
|
+
flat in vec4 vToGlyph;
|
|
376
|
+
flat in vec4 vToPixel;
|
|
377
|
+
flat in vec4 vCut;
|
|
378
|
+
flat in vec4 vShown;
|
|
379
|
+
out vec4 finalColor;
|
|
380
|
+
uniform highp sampler2D uSegments;
|
|
381
|
+
|
|
382
|
+
void main(void) {
|
|
383
|
+
vec2 centre = floor(vPixel) + 0.5;
|
|
384
|
+
mat2 toGlyph = mat2(vToGlyph.xy, vToGlyph.zw);
|
|
385
|
+
mat2 toPixel = mat2(vToPixel.xy, vToPixel.zw);
|
|
386
|
+
vec2 g = toGlyph * (centre - vPen);
|
|
387
|
+
int start = int(vCut.z);
|
|
388
|
+
int count = int(vCut.w);
|
|
389
|
+
float nearest = 3.4e38;
|
|
390
|
+
vec2 along = vec2(1.0, 0.0);
|
|
391
|
+
bool inside = false;
|
|
392
|
+
for (int i = 0; i < count; i++) {
|
|
393
|
+
int k = start + i;
|
|
394
|
+
vec4 s = texelFetch(uSegments, ivec2(k & ${OUTLINE_ROW - 1}, k >> ${Math.log2(OUTLINE_ROW)}), 0);
|
|
395
|
+
vec2 a = s.xy;
|
|
396
|
+
vec2 e = s.zw - a;
|
|
397
|
+
vec2 w = g - a;
|
|
398
|
+
float t = clamp(dot(w, e) / max(dot(e, e), 1e-20), 0.0, 1.0);
|
|
399
|
+
vec2 off = w - e * t;
|
|
400
|
+
float d = dot(off, off);
|
|
401
|
+
if (d < nearest) {
|
|
402
|
+
nearest = d;
|
|
403
|
+
along = e;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
if ((a.y > g.y) != (s.w > g.y) && a.x + (g.y - a.y) * e.x / e.y > g.x) {
|
|
407
|
+
inside = !inside;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// In Flash's pixels, across the nearest edge as the transform stretches it.
|
|
412
|
+
float stretch = length(toPixel * along);
|
|
413
|
+
float d = stretch > 0.0
|
|
414
|
+
? sqrt(nearest) * abs(determinant(toPixel)) * length(along) / stretch
|
|
415
|
+
: 0.0;
|
|
416
|
+
d = inside ? d : -d;
|
|
417
|
+
float coverage = vCut.x > vCut.y
|
|
418
|
+
? clamp((d - vCut.y) / (vCut.x - vCut.y), 0.0, 1.0)
|
|
419
|
+
: step(vCut.x, d);
|
|
420
|
+
if (coverage <= 0.0) {
|
|
421
|
+
discard;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
finalColor = vec4(vShown.rgb * vShown.a, vShown.a) * coverage;
|
|
425
|
+
}
|
|
426
|
+
`;
|
|
427
|
+
/**
|
|
428
|
+
* Two triangles over a layer's rectangle of the target, uRect its corners
|
|
429
|
+
* in clip space: a rasteriser then steps over those pixels alone, as a
|
|
430
|
+
* software one does not for a triangle over the whole target cut by the
|
|
431
|
+
* scissor.
|
|
432
|
+
*/
|
|
433
|
+
export const compositeVertex = `#version 300 es
|
|
434
|
+
uniform vec4 uRect;
|
|
435
|
+
void main(void) {
|
|
436
|
+
int k = gl_VertexID;
|
|
437
|
+
vec2 p = vec2(k == 1 || k == 2 || k == 4 ? 1.0 : 0.0, k == 2 || k == 4 || k == 5 ? 1.0 : 0.0);
|
|
438
|
+
gl_Position = vec4(mix(uRect.xy, uRect.zw, p), 0.0, 1.0);
|
|
439
|
+
}
|
|
440
|
+
`;
|
|
441
|
+
/**
|
|
442
|
+
* A composited layer's pixel, `front`, coloured by its row's colour
|
|
443
|
+
* transform where it has one (`row` not -1).
|
|
444
|
+
*/
|
|
445
|
+
const layerColor = (row) => ` if (${row} >= 0 && front.a > 0.0) {
|
|
446
|
+
ivec2 row = ivec2((${row} & ${ROWS_A_LINE - 1}) * ${ROW_TEXELS}, ${row} >> ${Math.log2(ROWS_A_LINE)});
|
|
447
|
+
vec4 mul = texelFetch(uRows, row + ivec2(2, 0), 0);
|
|
448
|
+
vec4 add = texelFetch(uRows, row + ivec2(3, 0), 0);
|
|
449
|
+
vec4 c = clamp(vec4(front.rgb / front.a, front.a) * mul + add, 0.0, 1.0);
|
|
450
|
+
front = vec4(c.rgb * c.a, c.a);
|
|
451
|
+
}
|
|
452
|
+
`;
|
|
453
|
+
/** A composited layer's pixel, `front`, coloured by its row's colour transform where it has one (uRow not -1). */
|
|
454
|
+
export const LAYER_COLOR = layerColor("uRow");
|
|
455
|
+
/**
|
|
456
|
+
* `front`, premultiplied, blended in mode uMode onto what is below it
|
|
457
|
+
* (uBack, a copy of it, whose texel at the fragment is uBackOffset short of
|
|
458
|
+
* it) into finalColor: normal, layer, add and screen as `front` alone, GL's
|
|
459
|
+
* blending computing them; the separable modes blend straight colours and
|
|
460
|
+
* composite source over, the others have formulas of their own.
|
|
461
|
+
*/
|
|
462
|
+
const BLEND_FRONT = ` if (uMode == ${NORMAL} || uMode == ${LAYER} || uMode == ${SCREEN} || uMode == ${ADD}) {
|
|
463
|
+
finalColor = front;
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
vec4 back = texelFetch(uBack, ivec2(gl_FragCoord.xy) - uBackOffset, 0);
|
|
468
|
+
vec3 cb = straight(back);
|
|
469
|
+
vec3 cf = straight(front);
|
|
470
|
+
vec3 b;
|
|
471
|
+
switch (uMode) {
|
|
472
|
+
case ${MULTIPLY}: b = cb * cf; break;
|
|
473
|
+
case ${LIGHTEN}: b = max(cb, cf); break;
|
|
474
|
+
case ${DARKEN}: b = min(cb, cf); break;
|
|
475
|
+
case ${DIFFERENCE}: b = abs(cb - cf); break;
|
|
476
|
+
case ${OVERLAY}: b = hardlight(cf, cb); break;
|
|
477
|
+
case ${HARDLIGHT}: b = hardlight(cb, cf); break;
|
|
478
|
+
case ${SUBTRACT}:
|
|
479
|
+
finalColor = vec4(max(back.rgb - front.rgb, 0.0), front.a + back.a * (1.0 - front.a));
|
|
480
|
+
return;
|
|
481
|
+
case ${INVERT}:
|
|
482
|
+
finalColor = vec4((back.a - back.rgb) * front.a + back.rgb * (1.0 - front.a), back.a);
|
|
483
|
+
return;
|
|
484
|
+
case ${ALPHA}:
|
|
485
|
+
finalColor = front.a > 0.0 ? back * front.a : back;
|
|
486
|
+
return;
|
|
487
|
+
case ${ERASE}:
|
|
488
|
+
finalColor = back * (1.0 - front.a);
|
|
489
|
+
return;
|
|
490
|
+
default:
|
|
491
|
+
finalColor = front + back * (1.0 - front.a);
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
vec3 co = front.rgb * (1.0 - back.a) + back.rgb * (1.0 - front.a) + front.a * back.a * b;
|
|
496
|
+
finalColor = vec4(co, front.a + back.a * (1.0 - front.a));
|
|
497
|
+
`;
|
|
498
|
+
/** BLEND_FRONT's helpers. */
|
|
499
|
+
const BLEND_HELPERS = `vec3 straight(vec4 c) { return c.a > 0.0 ? c.rgb / c.a : vec3(0.0); }
|
|
500
|
+
vec3 hardlight(vec3 cb, vec3 cf) {
|
|
501
|
+
vec3 multiply = 2.0 * cb * cf;
|
|
502
|
+
vec3 screen = 1.0 - 2.0 * (1.0 - cb) * (1.0 - cf);
|
|
503
|
+
return mix(multiply, screen, step(0.5, cf));
|
|
504
|
+
}
|
|
505
|
+
`;
|
|
506
|
+
/**
|
|
507
|
+
* A layer composited onto what is below over its rectangle, pixel for
|
|
508
|
+
* pixel: its rows run down, as the filters read them, and the target's up
|
|
509
|
+
* where it is the canvas (uFlip), from uOffset in its framebuffer. Coloured
|
|
510
|
+
* by its row's colour transform where it has one (uRow not -1), on its
|
|
511
|
+
* straight colour where it covers anything; then blended by its mode
|
|
512
|
+
* (BLEND_FRONT).
|
|
513
|
+
*/
|
|
514
|
+
export const compositeFragment = `#version 300 es
|
|
515
|
+
precision highp float;
|
|
516
|
+
uniform sampler2D uLayer;
|
|
517
|
+
uniform sampler2D uBack;
|
|
518
|
+
uniform highp sampler2D uRows;
|
|
519
|
+
uniform int uRow;
|
|
520
|
+
uniform int uMode;
|
|
521
|
+
uniform ivec2 uOffset;
|
|
522
|
+
uniform bool uFlip;
|
|
523
|
+
uniform ivec2 uBackOffset;
|
|
524
|
+
out vec4 finalColor;
|
|
525
|
+
|
|
526
|
+
${BLEND_HELPERS}
|
|
527
|
+
void main(void) {
|
|
528
|
+
ivec2 frag = ivec2(gl_FragCoord.xy);
|
|
529
|
+
ivec2 at = ivec2(frag.x - uOffset.x, uFlip ? uOffset.y - frag.y : frag.y - uOffset.y);
|
|
530
|
+
vec4 front = texelFetch(uLayer, at, 0);
|
|
531
|
+
${LAYER_COLOR}
|
|
532
|
+
${BLEND_FRONT}}
|
|
533
|
+
`;
|
|
534
|
+
/**
|
|
535
|
+
* A fill drawn straight onto what is below it in a blend mode, where its
|
|
536
|
+
* layer would hold it alone (a flat fill, GeometryData.flat): its pixel as
|
|
537
|
+
* fillFragment has it, then as compositeFragment composites its layer's,
|
|
538
|
+
* coloured by the layer's row (uLayerRow, -1 for none) and blended by uMode.
|
|
539
|
+
*/
|
|
540
|
+
export const blendFillFragment = `#version 300 es
|
|
541
|
+
precision highp float;
|
|
542
|
+
in vec4 vColor;
|
|
543
|
+
in vec2 vTexel;
|
|
544
|
+
flat in vec4 vMul;
|
|
545
|
+
flat in vec4 vAdd;
|
|
546
|
+
flat in int vSlot;
|
|
547
|
+
uniform sampler2D uTextures[${FILL_TEXTURES}];
|
|
548
|
+
uniform sampler2D uBack;
|
|
549
|
+
uniform highp sampler2D uRows;
|
|
550
|
+
uniform int uLayerRow;
|
|
551
|
+
uniform int uMode;
|
|
552
|
+
uniform ivec2 uBackOffset;
|
|
553
|
+
out vec4 finalColor;
|
|
554
|
+
|
|
555
|
+
${BLEND_HELPERS}
|
|
556
|
+
vec4 texel(vec2 at) {
|
|
557
|
+
switch (vSlot) {
|
|
558
|
+
${slotTexel}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
return vec4(0.0);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
void main(void) {
|
|
565
|
+
vec4 front = vec4(0.0);
|
|
566
|
+
vec4 fill = vColor;
|
|
567
|
+
bool clear = false;
|
|
568
|
+
if (vSlot != 0) {
|
|
569
|
+
vec4 t = texel(vTexel);
|
|
570
|
+
clear = t.a == 0.0;
|
|
571
|
+
fill = clear ? fill : vec4(t.rgb / t.a * vColor.rgb, t.a * vColor.a);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
if (!clear) {
|
|
575
|
+
vec4 c = clamp(fill * vMul + vAdd, 0.0, 1.0);
|
|
576
|
+
front = vec4(c.rgb * c.a, c.a);
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
${layerColor("uLayerRow")}
|
|
580
|
+
${BLEND_FRONT}}
|
|
581
|
+
`;
|
|
582
|
+
//# sourceMappingURL=programs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"programs.js","sourceRoot":"","sources":["../../src/webgl/programs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { GlState } from "@swf2es/context3d/device";
|
|
2
|
+
import { type Layer, type Multisampled, type TargetPool } from "./targets.js";
|
|
3
|
+
/**
|
|
4
|
+
* The stage's own targets and their way onto the canvas: multisampled
|
|
5
|
+
* buffers the canvas's size and the texture they resolve into, the layer a
|
|
6
|
+
* frame that clears the stage is drawn into before an opaque canvas, and
|
|
7
|
+
* the copies onto the canvas.
|
|
8
|
+
*/
|
|
9
|
+
export declare class Stage {
|
|
10
|
+
private readonly gl;
|
|
11
|
+
private readonly state;
|
|
12
|
+
private readonly pool;
|
|
13
|
+
/** The most samples the GPU takes, and whether the canvas has alpha, asked once. */
|
|
14
|
+
private maxSamples;
|
|
15
|
+
private hasAlpha;
|
|
16
|
+
/**
|
|
17
|
+
* The stage's multisampled buffers, and the texture they resolve into before a canvas they may
|
|
18
|
+
* not be resolved onto (present), made as first needed.
|
|
19
|
+
*/
|
|
20
|
+
private stageMsaa;
|
|
21
|
+
private stageResolved;
|
|
22
|
+
/**
|
|
23
|
+
* Whether the driver resolves the stage straight onto a canvas with alpha, found as it first does
|
|
24
|
+
* (present): null till then. SwiftShader refuses it.
|
|
25
|
+
*/
|
|
26
|
+
private directResolve;
|
|
27
|
+
/** The layer a frame that clears the stage is drawn into before an opaque canvas (stageAlpha). */
|
|
28
|
+
private stageLayer;
|
|
29
|
+
constructor(gl: WebGL2RenderingContext, state: GlState, pool: TargetPool);
|
|
30
|
+
/** Whether the canvas has alpha, as asked of the context in setUp. */
|
|
31
|
+
get canvasAlpha(): boolean;
|
|
32
|
+
/** Nothing made yet, and the GPU and the canvas asked again, as the context comes or comes back. */
|
|
33
|
+
setUp(): void;
|
|
34
|
+
/**
|
|
35
|
+
* The stage's multisampled pixels onto the canvas: resolved straight onto one with alpha where
|
|
36
|
+
* the driver lets a resolve go there, else into a texture first, as an opaque canvas's must be, a
|
|
37
|
+
* resolve keeping its format. Whether the driver lets it is found once, by the error it raises.
|
|
38
|
+
*/
|
|
39
|
+
present(msaa: Multisampled): void;
|
|
40
|
+
/** The texture the stage resolves into before the canvas (present), made as first needed. */
|
|
41
|
+
private resolveTarget;
|
|
42
|
+
/**
|
|
43
|
+
* The first `width` by `height` pixels of `source` copied onto the canvas,
|
|
44
|
+
* upside down where `flip`. Bound through the state cache first and as
|
|
45
|
+
* it was after, so the cache holds what is bound, whatever it held.
|
|
46
|
+
*/
|
|
47
|
+
toCanvas(source: WebGLFramebuffer, width: number, height: number, flip: boolean): void;
|
|
48
|
+
/**
|
|
49
|
+
* The layer the canvas' size a frame that clears the stage is drawn into
|
|
50
|
+
* before an opaque canvas (execute): its own, kept apart from the free
|
|
51
|
+
* layers so that none smaller takes it, made again for another size, let
|
|
52
|
+
* go of once idle as they are.
|
|
53
|
+
*/
|
|
54
|
+
stageAlpha(width: number, height: number): Layer;
|
|
55
|
+
/**
|
|
56
|
+
* The stage's multisampled buffers, made again for another size or samples, their resolve's
|
|
57
|
+
* texture let go of; none where it takes no samples.
|
|
58
|
+
*/
|
|
59
|
+
stageBuffers(width: number, height: number, wanted: number): Multisampled | null;
|
|
60
|
+
/** The stage's multisampled buffers and their resolve let go of, as samples or size change. */
|
|
61
|
+
dropStageBuffers(): void;
|
|
62
|
+
/** The stage's layer (stageAlpha) let go of, undrawn into for LAYER_IDLE_FRAMES. */
|
|
63
|
+
dropIdleLayer(): void;
|
|
64
|
+
/** What the stage made on the context, deleted. */
|
|
65
|
+
destroy(): void;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=stage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stage.d.ts","sourceRoot":"","sources":["../../src/webgl/stage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,EAGL,KAAK,KAAK,EACV,KAAK,YAAY,EACjB,KAAK,UAAU,EAChB,MAAM,cAAc,CAAC;AAEtB;;;;;GAKG;AACH,qBAAa,KAAK;IAChB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAyB;IAC5C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAChC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,oFAAoF;IACpF,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,QAAQ,CAAS;IACzB;;;OAGG;IACH,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,aAAa,CAAyE;IAC9F;;;OAGG;IACH,OAAO,CAAC,aAAa,CAAwB;IAC7C,kGAAkG;IAClG,OAAO,CAAC,UAAU,CAAsB;IAExC,YAAY,EAAE,EAAE,sBAAsB,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAIvE;IAED,sEAAsE;IACtE,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,oGAAoG;IACpG,KAAK,IAAI,IAAI,CAQZ;IAED;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAwBhC;IAED,6FAA6F;IAC7F,OAAO,CAAC,aAAa;IAsBrB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAkBrF;IAED;;;;;OAKG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,CAc/C;IAED;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAe/E;IAED,+FAA+F;IAC/F,gBAAgB,IAAI,IAAI,CAavB;IAED,oFAAoF;IACpF,aAAa,IAAI,IAAI,CAMpB;IAED,mDAAmD;IACnD,OAAO,IAAI,IAAI,CAKd;CACF"}
|