@swf2es/render 0.0.0-stage → 0.1.0

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.
Files changed (143) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +17 -2
  3. package/dist/commands.d.ts +67 -0
  4. package/dist/commands.d.ts.map +1 -0
  5. package/dist/commands.js +93 -0
  6. package/dist/commands.js.map +1 -0
  7. package/dist/filter-plan.d.ts +110 -0
  8. package/dist/filter-plan.d.ts.map +1 -0
  9. package/dist/filter-plan.js +480 -0
  10. package/dist/filter-plan.js.map +1 -0
  11. package/dist/filter-shaders.d.ts +63 -0
  12. package/dist/filter-shaders.d.ts.map +1 -0
  13. package/dist/filter-shaders.js +350 -0
  14. package/dist/filter-shaders.js.map +1 -0
  15. package/dist/filters.d.ts +107 -0
  16. package/dist/filters.d.ts.map +1 -0
  17. package/dist/filters.js +187 -0
  18. package/dist/filters.js.map +1 -0
  19. package/dist/geometry.d.ts +83 -0
  20. package/dist/geometry.d.ts.map +1 -0
  21. package/dist/geometry.js +93 -0
  22. package/dist/geometry.js.map +1 -0
  23. package/dist/index.d.ts +11 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +13 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/keeps.d.ts +17 -0
  28. package/dist/keeps.d.ts.map +1 -0
  29. package/dist/keeps.js +17 -0
  30. package/dist/keeps.js.map +1 -0
  31. package/dist/kernel-shaders.d.ts +74 -0
  32. package/dist/kernel-shaders.d.ts.map +1 -0
  33. package/dist/kernel-shaders.js +323 -0
  34. package/dist/kernel-shaders.js.map +1 -0
  35. package/dist/measure.d.ts +56 -0
  36. package/dist/measure.d.ts.map +1 -0
  37. package/dist/measure.js +287 -0
  38. package/dist/measure.js.map +1 -0
  39. package/dist/plan.d.ts +14 -0
  40. package/dist/plan.d.ts.map +1 -0
  41. package/dist/plan.js +247 -0
  42. package/dist/plan.js.map +1 -0
  43. package/dist/registry.d.ts +49 -0
  44. package/dist/registry.d.ts.map +1 -0
  45. package/dist/registry.js +87 -0
  46. package/dist/registry.js.map +1 -0
  47. package/dist/rows.d.ts +39 -0
  48. package/dist/rows.d.ts.map +1 -0
  49. package/dist/rows.js +60 -0
  50. package/dist/rows.js.map +1 -0
  51. package/dist/scene.d.ts +179 -0
  52. package/dist/scene.d.ts.map +1 -0
  53. package/dist/scene.js +265 -0
  54. package/dist/scene.js.map +1 -0
  55. package/dist/shelves.d.ts +23 -0
  56. package/dist/shelves.d.ts.map +1 -0
  57. package/dist/shelves.js +63 -0
  58. package/dist/shelves.js.map +1 -0
  59. package/dist/textures.d.ts +72 -0
  60. package/dist/textures.d.ts.map +1 -0
  61. package/dist/textures.js +160 -0
  62. package/dist/textures.js.map +1 -0
  63. package/dist/webgl/atlas.d.ts +63 -0
  64. package/dist/webgl/atlas.d.ts.map +1 -0
  65. package/dist/webgl/atlas.js +328 -0
  66. package/dist/webgl/atlas.js.map +1 -0
  67. package/dist/webgl/backend.d.ts +141 -0
  68. package/dist/webgl/backend.d.ts.map +1 -0
  69. package/dist/webgl/backend.js +659 -0
  70. package/dist/webgl/backend.js.map +1 -0
  71. package/dist/webgl/composite.d.ts +101 -0
  72. package/dist/webgl/composite.d.ts.map +1 -0
  73. package/dist/webgl/composite.js +293 -0
  74. package/dist/webgl/composite.js.map +1 -0
  75. package/dist/webgl/draws.d.ts +213 -0
  76. package/dist/webgl/draws.d.ts.map +1 -0
  77. package/dist/webgl/draws.js +714 -0
  78. package/dist/webgl/draws.js.map +1 -0
  79. package/dist/webgl/filters.d.ts +107 -0
  80. package/dist/webgl/filters.d.ts.map +1 -0
  81. package/dist/webgl/filters.js +351 -0
  82. package/dist/webgl/filters.js.map +1 -0
  83. package/dist/webgl/gpu-textures.d.ts +44 -0
  84. package/dist/webgl/gpu-textures.d.ts.map +1 -0
  85. package/dist/webgl/gpu-textures.js +178 -0
  86. package/dist/webgl/gpu-textures.js.map +1 -0
  87. package/dist/webgl/holds.d.ts +97 -0
  88. package/dist/webgl/holds.d.ts.map +1 -0
  89. package/dist/webgl/holds.js +453 -0
  90. package/dist/webgl/holds.js.map +1 -0
  91. package/dist/webgl/index.d.ts +2 -0
  92. package/dist/webgl/index.d.ts.map +1 -0
  93. package/dist/webgl/index.js +4 -0
  94. package/dist/webgl/index.js.map +1 -0
  95. package/dist/webgl/kernels.d.ts +64 -0
  96. package/dist/webgl/kernels.d.ts.map +1 -0
  97. package/dist/webgl/kernels.js +160 -0
  98. package/dist/webgl/kernels.js.map +1 -0
  99. package/dist/webgl/pool.d.ts +71 -0
  100. package/dist/webgl/pool.d.ts.map +1 -0
  101. package/dist/webgl/pool.js +192 -0
  102. package/dist/webgl/pool.js.map +1 -0
  103. package/dist/webgl/programs.d.ts +130 -0
  104. package/dist/webgl/programs.d.ts.map +1 -0
  105. package/dist/webgl/programs.js +582 -0
  106. package/dist/webgl/programs.js.map +1 -0
  107. package/dist/webgl/stage.d.ts +67 -0
  108. package/dist/webgl/stage.d.ts.map +1 -0
  109. package/dist/webgl/stage.js +173 -0
  110. package/dist/webgl/stage.js.map +1 -0
  111. package/dist/webgl/targets.d.ts +172 -0
  112. package/dist/webgl/targets.d.ts.map +1 -0
  113. package/dist/webgl/targets.js +323 -0
  114. package/dist/webgl/targets.js.map +1 -0
  115. package/package.json +35 -3
  116. package/src/commands.ts +98 -0
  117. package/src/filter-plan.ts +755 -0
  118. package/src/filter-shaders.ts +360 -0
  119. package/src/filters.ts +220 -0
  120. package/src/geometry.ts +143 -0
  121. package/src/index.ts +87 -0
  122. package/src/keeps.ts +21 -0
  123. package/src/kernel-shaders.ts +375 -0
  124. package/src/measure.ts +400 -0
  125. package/src/plan.ts +331 -0
  126. package/src/registry.ts +105 -0
  127. package/src/rows.ts +93 -0
  128. package/src/scene.ts +297 -0
  129. package/src/shelves.ts +70 -0
  130. package/src/textures.ts +198 -0
  131. package/src/webgl/atlas.ts +370 -0
  132. package/src/webgl/backend.ts +973 -0
  133. package/src/webgl/composite.ts +372 -0
  134. package/src/webgl/draws.ts +902 -0
  135. package/src/webgl/filters.ts +502 -0
  136. package/src/webgl/gpu-textures.ts +253 -0
  137. package/src/webgl/holds.ts +624 -0
  138. package/src/webgl/index.ts +3 -0
  139. package/src/webgl/kernels.ts +205 -0
  140. package/src/webgl/pool.ts +245 -0
  141. package/src/webgl/programs.ts +620 -0
  142. package/src/webgl/stage.ts +214 -0
  143. package/src/webgl/targets.ts +464 -0
@@ -0,0 +1,253 @@
1
+ import type { GlState } from "@swf2es/context3d/device";
2
+ import { ROW_FLOATS, ROWS_A_LINE, type Rows } from "../rows.js";
3
+ import { MIRROR, REPEAT, SMOOTH } from "../scene.js";
4
+ import type { Textures } from "../textures.js";
5
+ import { OUTLINE_ROW, OUTLINE_UNIT, ROW_TEXELS, TEXTURE_UNIT } from "./programs.js";
6
+
7
+ /**
8
+ * The textures the programs read: the registry's, uploaded as they are
9
+ * added or change, and the samplers they are read through; the rows, a
10
+ * float texture uploaded once a frame; and advanced text's outlines.
11
+ */
12
+ export class GpuTextures {
13
+ private readonly gl: WebGL2RenderingContext;
14
+ private readonly state: GlState;
15
+ /** The textures uploaded, by the registry's ids, and their sizes; the samplers made, by their bits. */
16
+ textures: (WebGLTexture | null)[] = [];
17
+ private sizes: number[] = [];
18
+ private samplers: (WebGLSampler | null)[] = [];
19
+ rowsTexture!: WebGLTexture;
20
+ private rowLines = 0;
21
+ /** Advanced text's outlines (uploadOutlines), on OUTLINE_UNIT for the glyph program. */
22
+ outlines: WebGLTexture | null = null;
23
+ /** The outlines uploaded: of which epoch, how many segments, and the texture's rows. */
24
+ private outlineEpoch = -1;
25
+ private outlineCount = 0;
26
+ private outlineRows = 0;
27
+
28
+ constructor(gl: WebGL2RenderingContext, state: GlState) {
29
+ this.gl = gl;
30
+ this.state = state;
31
+ }
32
+
33
+ /** The rows' texture made, and none other yet, as the context comes or comes back. */
34
+ setUp(): void {
35
+ const gl = this.gl;
36
+ this.outlines = null;
37
+ this.outlineEpoch = -1;
38
+ this.outlineCount = 0;
39
+ this.outlineRows = 0;
40
+ this.textures = [];
41
+ this.samplers = [];
42
+ this.rowsTexture = gl.createTexture() as WebGLTexture;
43
+ this.state.bindTexture(0, this.rowsTexture);
44
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
45
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
46
+ this.rowLines = 0;
47
+ }
48
+
49
+ /** Whether texture `id` of the frame's is there, for a filter that reads it. */
50
+ readonly hasTexture = (id: number) => id >= 0 && (this.textures[id] ?? null) !== null;
51
+
52
+ /**
53
+ * Advanced text's outlines (GeometryData.glyphs), `count` segments of four floats each
54
+ * in `data`, as the player's store holds them: uploaded whole for another
55
+ * `epoch` or a larger store, else the rows added since.
56
+ */
57
+ uploadOutlines(data: Float32Array, count: number, epoch: number): void {
58
+ const gl = this.gl;
59
+ if (gl.isContextLost() || count === 0) {
60
+ return;
61
+ }
62
+
63
+ const rows = data.length / 4 / OUTLINE_ROW;
64
+ let from = epoch === this.outlineEpoch ? this.outlineCount : 0;
65
+ if (!this.outlines || rows !== this.outlineRows) {
66
+ if (this.outlines) {
67
+ this.state.dropTexture(this.outlines);
68
+ gl.deleteTexture(this.outlines);
69
+ }
70
+
71
+ this.outlines = gl.createTexture() as WebGLTexture;
72
+ this.state.bindTexture(OUTLINE_UNIT, this.outlines);
73
+ this.state.activeTexture(OUTLINE_UNIT);
74
+ gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, OUTLINE_ROW, rows);
75
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
76
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
77
+ this.outlineRows = rows;
78
+ from = 0;
79
+ }
80
+
81
+ if (from < count) {
82
+ const first = Math.floor(from / OUTLINE_ROW);
83
+ const height = Math.ceil(count / OUTLINE_ROW) - first;
84
+ this.state.bindTexture(OUTLINE_UNIT, this.outlines);
85
+ this.state.activeTexture(OUTLINE_UNIT);
86
+ gl.texSubImage2D(
87
+ gl.TEXTURE_2D,
88
+ 0,
89
+ 0,
90
+ first,
91
+ OUTLINE_ROW,
92
+ height,
93
+ gl.RGBA,
94
+ gl.FLOAT,
95
+ data,
96
+ first * OUTLINE_ROW * 4,
97
+ );
98
+ }
99
+
100
+ this.outlineEpoch = epoch;
101
+ this.outlineCount = count;
102
+ }
103
+
104
+ /** The textures removed since the last frame deleted, and those added or changed uploaded, their pixels let go. */
105
+ uploadTextures(textures: Textures): void {
106
+ const gl = this.gl;
107
+ for (const id of textures.removed) {
108
+ const texture = this.textures[id];
109
+ if (texture) {
110
+ this.state.dropTexture(texture);
111
+ gl.deleteTexture(texture);
112
+ this.textures[id] = null;
113
+ }
114
+ }
115
+
116
+ textures.removed.length = 0;
117
+ for (const id of textures.pending) {
118
+ const data = textures.get(id);
119
+ if (!data?.pixels) {
120
+ continue;
121
+ }
122
+
123
+ let texture = this.textures[id];
124
+ if (!texture) {
125
+ texture = gl.createTexture() as WebGLTexture;
126
+ this.textures[id] = texture;
127
+ this.sizes[id * 2] = -1;
128
+ }
129
+
130
+ this.state.bindTexture(TEXTURE_UNIT, texture);
131
+ this.state.activeTexture(TEXTURE_UNIT);
132
+ // Floats, a kernel's image, make the texture again each time, as bytes may follow them.
133
+ if (data.pixels instanceof Float32Array) {
134
+ this.sizes[id * 2] = -1;
135
+ gl.texImage2D(
136
+ gl.TEXTURE_2D,
137
+ 0,
138
+ gl.RGBA32F,
139
+ data.width,
140
+ data.height,
141
+ 0,
142
+ gl.RGBA,
143
+ gl.FLOAT,
144
+ data.pixels,
145
+ );
146
+ data.pixels = null;
147
+ continue;
148
+ }
149
+
150
+ // Pixels of the same size go into the texture there is; another size makes it again.
151
+ if (this.sizes[id * 2] === data.width && this.sizes[id * 2 + 1] === data.height) {
152
+ gl.texSubImage2D(
153
+ gl.TEXTURE_2D,
154
+ 0,
155
+ 0,
156
+ 0,
157
+ data.width,
158
+ data.height,
159
+ gl.RGBA,
160
+ gl.UNSIGNED_BYTE,
161
+ data.pixels,
162
+ );
163
+ data.pixels = null;
164
+ continue;
165
+ }
166
+
167
+ this.sizes[id * 2] = data.width;
168
+ this.sizes[id * 2 + 1] = data.height;
169
+ gl.texImage2D(
170
+ gl.TEXTURE_2D,
171
+ 0,
172
+ gl.RGBA8,
173
+ data.width,
174
+ data.height,
175
+ 0,
176
+ gl.RGBA,
177
+ gl.UNSIGNED_BYTE,
178
+ data.pixels,
179
+ );
180
+ data.pixels = null;
181
+ }
182
+
183
+ textures.pending.length = 0;
184
+ }
185
+
186
+ /** The sampler for `bits` (SMOOTH, and REPEAT or MIRROR), made as first asked for. */
187
+ sampler(bits: number): WebGLSampler {
188
+ const known = this.samplers[bits];
189
+ if (known) {
190
+ return known;
191
+ }
192
+
193
+ const gl = this.gl;
194
+ const sampler = gl.createSampler() as WebGLSampler;
195
+ const filter = bits & SMOOTH ? gl.LINEAR : gl.NEAREST;
196
+ const wrap = bits & REPEAT ? gl.REPEAT : bits & MIRROR ? gl.MIRRORED_REPEAT : gl.CLAMP_TO_EDGE;
197
+ gl.samplerParameteri(sampler, gl.TEXTURE_MIN_FILTER, filter);
198
+ gl.samplerParameteri(sampler, gl.TEXTURE_MAG_FILTER, filter);
199
+ gl.samplerParameteri(sampler, gl.TEXTURE_WRAP_S, wrap);
200
+ gl.samplerParameteri(sampler, gl.TEXTURE_WRAP_T, wrap);
201
+ this.samplers[bits] = sampler;
202
+ return sampler;
203
+ }
204
+
205
+ /** The rows a frame wrote, uploaded in one call, the texture made taller first if they need it. */
206
+ uploadRows(rows: Rows): void {
207
+ const gl = this.gl;
208
+ const lines = Math.max(1, Math.ceil(rows.count / ROWS_A_LINE));
209
+ const width = ROWS_A_LINE * ROW_TEXELS;
210
+ this.state.bindTexture(0, this.rowsTexture);
211
+ this.state.activeTexture(0);
212
+ if (lines > this.rowLines) {
213
+ this.rowLines = Math.max(lines, this.rowLines * 2);
214
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, width, this.rowLines, 0, gl.RGBA, gl.FLOAT, null);
215
+ }
216
+
217
+ if (rows.count > 0) {
218
+ // Whole lines: the data holds ROW_FLOATS a row for as many rows as its lines hold.
219
+ gl.texSubImage2D(
220
+ gl.TEXTURE_2D,
221
+ 0,
222
+ 0,
223
+ 0,
224
+ width,
225
+ lines,
226
+ gl.RGBA,
227
+ gl.FLOAT,
228
+ rows.data.subarray(0, lines * ROWS_A_LINE * ROW_FLOATS),
229
+ );
230
+ }
231
+ }
232
+
233
+ /** The textures made on the context, deleted. */
234
+ destroy(): void {
235
+ const gl = this.gl;
236
+ gl.deleteTexture(this.rowsTexture);
237
+ if (this.outlines) {
238
+ gl.deleteTexture(this.outlines);
239
+ }
240
+
241
+ for (const texture of this.textures) {
242
+ if (texture) {
243
+ gl.deleteTexture(texture);
244
+ }
245
+ }
246
+
247
+ for (const sampler of this.samplers) {
248
+ if (sampler) {
249
+ gl.deleteSampler(sampler);
250
+ }
251
+ }
252
+ }
253
+ }