@swf2es/render 0.1.20 → 0.1.21

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.
@@ -19,6 +19,13 @@ export const TINT_AT = 7;
19
19
  export const DRAW_AT = 8;
20
20
  /** The most cutoff table entries a text's draw takes, as the player's text/saffron.ts builds them. */
21
21
  export const TABLE_ENTRIES = 48;
22
+ /**
23
+ * Texels a text's slot in the glyph tables' texture (GlyphTables): its mode,
24
+ * then its table's entries; and texels a line of it. Powers of two, which
25
+ * the vertex shader splits a slot's texel into column and line with.
26
+ */
27
+ export const TABLE_SLOT = 64;
28
+ export const TABLE_LINE = 1024;
22
29
  /** Segments a row of the outlines' texture, as the player's text/saffron.ts stores them. */
23
30
  export const OUTLINE_ROW = 1024;
24
31
  /**
@@ -52,6 +59,8 @@ export const RUN_UNIT = FILL_UNIT + FILL_TEXTURES;
52
59
  export const MERGED_UNIT = RUN_UNIT + 1;
53
60
  /** The merged fills' rows a line of their integer texture: a power of two, as for RUN_MOST. */
54
61
  export const MERGED_LINE = 1024;
62
+ /** The glyph tables' unit (GlyphTables), past the merged fills' rows. */
63
+ export const TABLE_UNIT = MERGED_UNIT + 1;
55
64
  /**
56
65
  * Places a vertex by its row's transform, on a quarter of a pixel of
57
66
  * Flash's (uUnit of them a stage pixel, from the stage's origin) where it
@@ -268,11 +277,14 @@ void main(void) {
268
277
  * pixels to Flash's, uUnit of them a stage pixel, on their grid from the
269
278
  * stage's origin, a BitmapData's in a draw. A glyph's pen stands where its
270
279
  * text's origin, at a whole pixel, puts it, snapped as its grid fits it
271
- * (uMode: gridFitType 0 none, 1 pixel, 2 subpixel, thickness, sharpness),
272
- * and its quad reaches out past its outline by the furthest cutoff. Its
273
- * colour is drawn under the row's colour transform, light or dark as adl
274
- * chooses its table. aOrigin: the pen, and its light and dark tables, each
275
- * its first entry plus 64 times its entries; aGlyph: a corner of its
280
+ * (its mode: gridFitType 0 none, 1 pixel, 2 subpixel, thickness,
281
+ * sharpness), and its quad reaches out past its outline by the furthest
282
+ * cutoff. Its colour is drawn under the row's colour transform, light or
283
+ * dark as adl chooses its table. The text's mode and tables are in its slot
284
+ * of uTables (uTable; GlyphTables), read by texelFetch: not a uniform array
285
+ * indexed by each glyph's table start, the access that hung Intel's GPUs
286
+ * in the fill program's run table. aOrigin: the pen, and its light and dark tables,
287
+ * each its first entry plus 64 times its entries; aGlyph: a corner of its
276
288
  * outline's bounds and the way out from it; aRun: its segments, first and
277
289
  * count, the pixels of a unit of its outline, and its size.
278
290
  */
@@ -287,8 +299,8 @@ uniform highp sampler2D uRows;
287
299
  uniform int uRow;
288
300
  uniform vec4 uView;
289
301
  uniform float uUnit;
290
- uniform vec4 uMode;
291
- uniform vec4 uTable[${TABLE_ENTRIES}];
302
+ uniform highp sampler2D uTables;
303
+ uniform int uTable;
292
304
  out vec2 vPixel;
293
305
  flat out vec2 vPen;
294
306
  flat out vec4 vToGlyph;
@@ -296,10 +308,16 @@ flat out vec4 vToPixel;
296
308
  flat out vec4 vCut;
297
309
  flat out vec4 vShown;
298
310
 
311
+ // Texel i of the text's slot: its mode, then its tables' entries.
312
+ vec4 slot(int i) {
313
+ int at = uTable * ${TABLE_SLOT} + i;
314
+ return texelFetch(uTables, ivec2(at & ${TABLE_LINE - 1}, at >> ${Math.log2(TABLE_LINE)}), 0);
315
+ }
316
+
299
317
  // The cutoffs at ppem by the table of entries start to start + count, as text/csm.ts' cutoffs.
300
- vec2 cutoffs(int start, int count, float ppem) {
301
- vec4 first = uTable[start];
302
- vec4 last = uTable[start + count - 1];
318
+ vec2 cutoffs(vec4 mode, int start, int count, float ppem) {
319
+ vec4 first = slot(1 + start);
320
+ vec4 last = slot(start + count);
303
321
  vec2 c = first.yz;
304
322
  if (ppem >= last.x) {
305
323
  c = last.yz;
@@ -309,9 +327,9 @@ vec2 cutoffs(int start, int count, float ppem) {
309
327
  break;
310
328
  }
311
329
 
312
- vec4 b = uTable[start + i];
330
+ vec4 b = slot(1 + start + i);
313
331
  if (ppem <= b.x) {
314
- vec4 a = uTable[start + i - 1];
332
+ vec4 a = slot(start + i);
315
333
  c = mix(a.yz, b.yz, (ppem - a.x) / (b.x - a.x));
316
334
  break;
317
335
  }
@@ -319,8 +337,8 @@ vec2 cutoffs(int start, int count, float ppem) {
319
337
  }
320
338
 
321
339
  float unit = 0.0001 * ppem;
322
- float t = clamp(uMode.y, -200.0, 200.0);
323
- float s = clamp(uMode.z, -400.0, 400.0);
340
+ float t = clamp(mode.y, -200.0, 200.0);
341
+ float s = clamp(mode.z, -400.0, 400.0);
324
342
  c -= unit * vec2(t + s * 0.5, t - s * 0.5);
325
343
  if (c.x < c.y) {
326
344
  c = vec2((c.x + c.y) * 0.5);
@@ -335,6 +353,7 @@ void main(void) {
335
353
  vec4 t = texelFetch(uRows, at + ivec2(1, 0), 0);
336
354
  vec4 mul = texelFetch(uRows, at + ivec2(2, 0), 0);
337
355
  vec4 add = texelFetch(uRows, at + ivec2(3, 0), 0);
356
+ vec4 mode = slot(0);
338
357
  // The text's pixels to Flash's.
339
358
  mat2 linear = mat2(m.xy, m.zw) * uUnit;
340
359
  vec2 origin = t.xy * uUnit;
@@ -342,9 +361,9 @@ void main(void) {
342
361
  float across = max(abs(linear[0][1]), abs(linear[1][0]));
343
362
  if (across > max(abs(linear[0][0]), abs(linear[1][1])) / 65536.0) {
344
363
  // Turned or skewed: no grid.
345
- } else if (uMode.x == 1.0) {
364
+ } else if (mode.x == 1.0) {
346
365
  pen = vec2(roundEven(pen.x * 8.0) / 8.0 + 0.5, roundEven(pen.y));
347
- } else if (uMode.x == 2.0) {
366
+ } else if (mode.x == 2.0) {
348
367
  pen = vec2(roundEven(pen.x * 4.0) / 4.0 + 0.5, roundEven(pen.y));
349
368
  } else {
350
369
  pen = roundEven(pen * 4.0) / 4.0 + vec2(0.5, 0.0);
@@ -355,7 +374,7 @@ void main(void) {
355
374
  vec4 shown = clamp(aColor * mul + add, 0.0, 1.0);
356
375
  bool light = dot(floor(shown.rgb * 255.0 + 0.5), vec3(30.0, 59.0, 11.0)) > 20000.0;
357
376
  int table = int(light ? aOrigin.z : aOrigin.w);
358
- vec2 cut = cutoffs(table & 63, table >> 6, ppem);
377
+ vec2 cut = cutoffs(mode, table & 63, table >> 6, ppem);
359
378
  mat2 toPixel = linear * aRun.z;
360
379
  float margin = max(abs(cut.x), abs(cut.y)) + 1.0;
361
380
  float det = determinant(toPixel);
@@ -1 +1 @@
1
- {"version":3,"file":"programs.js","sourceRoot":"","sources":["../../src/webgl/programs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"programs.js","sourceRoot":"","sources":["../../src/webgl/programs.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swf2es/render",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "swf2es's own renderer: a scene list, a planner and a WebGL 2 backend (docs/renderer.md)",
5
5
  "keywords": [
6
6
  "swf",
@@ -33,6 +33,6 @@
33
33
  "src"
34
34
  ],
35
35
  "dependencies": {
36
- "@swf2es/context3d": "0.1.20"
36
+ "@swf2es/context3d": "0.1.21"
37
37
  }
38
38
  }
@@ -38,21 +38,24 @@ export const KERNEL_PASS = 10;
38
38
 
39
39
  /**
40
40
  * How a uniform's values are set: one to four floats, an array of vec4s, a
41
- * 4 by 4 matrix, an array of ivec4s, or a sampler, its value the texture of
42
- * the frame's it reads.
41
+ * 4 by 4 matrix, an array of ivec4s, a sampler, its value the texture of
42
+ * the frame's it reads, or a sampler of a line of floats, its values, for a
43
+ * shader that reads them at a varying index (as a uniform array read so
44
+ * hangs some GPUs).
43
45
  */
44
46
  export const FLOATS = 1;
45
47
  export const VEC4S = 2;
46
48
  export const MATRIX4 = 3;
47
49
  export const IVEC4S = 4;
48
50
  export const SAMPLER = 5;
51
+ export const FLOAT_LINE = 6;
49
52
 
50
53
  /** A pass's blurred input (FilterPass.blurred): none read, or the pass's input itself. */
51
54
  export const NO_BLUR = -2;
52
55
  export const INPUT_BLUR = -1;
53
56
 
54
- /** The most floats a convolution's matrix takes in its shader: 57 vec4s. */
55
- const CONVOLUTION_FLOATS = 57 * 4;
57
+ /** The most floats a convolution's matrix takes in its shader: 15 by 15. */
58
+ const CONVOLUTION_FLOATS = 15 * 15;
56
59
 
57
60
  /** One pass: a program drawn from slot `input` into slot `output`, its uniforms in its plan's. */
58
61
  export interface FilterPass {
@@ -468,7 +471,7 @@ function colorMatrix(
468
471
  return out;
469
472
  }
470
473
 
471
- /** A convolution's weights, its matrix by rows padded to the shader's array. */
474
+ /** A convolution's weights, its matrix by rows padded to the shader's line. */
472
475
  const weights = new Float32Array(CONVOLUTION_FLOATS);
473
476
 
474
477
  function convolution(
@@ -485,7 +488,7 @@ function convolution(
485
488
  weights.set(v.subarray(at + 12, at + 12 + Math.min(columns * rows, weights.length)));
486
489
  const out = plan.slot(width, height);
487
490
  plan.pass(CONVOLUTION_PASS, input, width, height, out, width, height);
488
- plan.uniformFrom("uMatrix", VEC4S, weights, 0, weights.length);
491
+ plan.uniformFrom("uWeights", FLOAT_LINE, weights, 0, weights.length);
489
492
  plan.uniform("uSize", 2, columns, rows);
490
493
  plan.uniformFrom("uEdge", FLOATS, v, at + 2, 4);
491
494
  plan.uniform("uDivisor", 1, v[at + 6]);
@@ -312,7 +312,7 @@ export const CONVOLUTION = `in vec2 vTextureCoord;
312
312
  out vec4 finalColor;
313
313
  uniform sampler2D uTexture;
314
314
  uniform highp vec4 uInputSize;
315
- uniform vec4 uMatrix[57];
315
+ uniform highp sampler2D uWeights;
316
316
  uniform vec2 uSize;
317
317
  uniform vec4 uBox;
318
318
  uniform vec4 uEdge;
@@ -342,10 +342,10 @@ void main(void) {
342
342
  int cols = int(uSize.x);
343
343
  int count = cols * int(uSize.y);
344
344
  vec4 sum = vec4(0.0);
345
- // One loop, its index alone indexing the weights, as GLSL ES 1 allows.
346
345
  for (int k = 0; k < 225; k++) {
347
346
  if (k >= count) { break; }
348
- float w = dot(uMatrix[k / 4], vec4(equal(vec4(float(k - k / 4 * 4)), vec4(0.0, 1.0, 2.0, 3.0))));
347
+ // From a texture: a uniform array indexed so is what hung Intel's GPUs in other programs.
348
+ float w = texelFetch(uWeights, ivec2(k, 0), 0).r;
349
349
  if (w != 0.0) {
350
350
  int j = k / cols;
351
351
  vec2 at = vec2(float(k - j * cols), float(j)) - reach;
@@ -1,5 +1,6 @@
1
1
  import type { GlState } from "@swf2es/context3d/device";
2
2
  import { type Geometries, type GeometryData, GLYPH_FLOATS } from "../geometry.js";
3
+ import { GlyphTables } from "./glyph-tables.js";
3
4
  import {
4
5
  COLOR_AT,
5
6
  DEPTH_AT,
@@ -67,13 +68,16 @@ function interleave(
67
68
  }
68
69
  }
69
70
 
70
- /** Where a geometry lies in the atlas, or the glyph atlas with its text's mode and table. */
71
+ /**
72
+ * Where a geometry lies in the atlas, or the glyph atlas with its text's
73
+ * mode and table, and their slot in the glyph tables (-1 past their room).
74
+ */
71
75
  export interface Place {
72
76
  vertexStart: number;
73
77
  vertices: number;
74
78
  indexStart: number;
75
79
  indices: number;
76
- glyphs: { mode: Float32Array; table: Float32Array } | null;
80
+ glyphs: { mode: Float32Array; table: Float32Array; slot: number } | null;
77
81
  /** Its geometry's flat (GeometryData.flat). */
78
82
  flat: boolean;
79
83
  /** Small, unchanged geometries may be copied into a run's streaming buffer. */
@@ -122,10 +126,13 @@ export class GeometryAtlas {
122
126
  live: 0,
123
127
  holes: 0,
124
128
  };
129
+ /** The texts' modes and tables, which the glyph program reads. */
130
+ readonly tables: GlyphTables;
125
131
 
126
132
  constructor(gl: WebGL2RenderingContext, state: GlState) {
127
133
  this.gl = gl;
128
134
  this.state = state;
135
+ this.tables = new GlyphTables(gl, state);
129
136
  }
130
137
 
131
138
  /** The buffers and vertex arrays made, both atlases empty, as the context comes or comes back. */
@@ -177,6 +184,7 @@ export class GeometryAtlas {
177
184
  this.stagedVertices = 0;
178
185
  this.stagedIndexCount = 0;
179
186
  this.places = [];
187
+ this.tables.setUp();
180
188
  }
181
189
 
182
190
  /**
@@ -254,7 +262,8 @@ export class GeometryAtlas {
254
262
  const texts =
255
263
  g.top + glyphVertices > g.capacity ||
256
264
  g.indexTop + glyphIndices > g.indexCapacity ||
257
- (g.holes > GLYPHS_LEAST && g.holes > g.live);
265
+ (g.holes > GLYPHS_LEAST && g.holes > g.live) ||
266
+ this.tables.full;
258
267
  if (shapes) {
259
268
  this.repack(geometries);
260
269
  }
@@ -272,6 +281,7 @@ export class GeometryAtlas {
272
281
 
273
282
  geometries.added.length = 0;
274
283
  this.flush();
284
+ this.tables.upload();
275
285
  }
276
286
 
277
287
  /** Every live shape's geometry copied into new buffers, with room for twice what is live. */
@@ -336,12 +346,16 @@ export class GeometryAtlas {
336
346
  g.indexTop = 0;
337
347
  g.live = 0;
338
348
  g.holes = 0;
349
+ // Only the live texts' tables kept.
350
+ this.tables.reset();
339
351
  for (const id of ids) {
340
352
  const data = geometries.get(id) as GeometryData;
341
353
  if (data.glyphs) {
342
354
  this.copyGlyphs(id, data);
343
355
  }
344
356
  }
357
+
358
+ this.tables.upload();
345
359
  }
346
360
 
347
361
  /** `data` copied in at the top of the atlas, its indices made absolute. */
@@ -483,7 +497,11 @@ export class GeometryAtlas {
483
497
  vertices: count,
484
498
  indexStart: g.indexTop,
485
499
  indices: indices.length,
486
- glyphs: { mode: glyphs.mode, table: glyphs.table },
500
+ glyphs: {
501
+ mode: glyphs.mode,
502
+ table: glyphs.table,
503
+ slot: this.tables.slot(glyphs.mode, glyphs.table),
504
+ },
487
505
  flat: false,
488
506
  batch: null,
489
507
  };
@@ -501,5 +519,6 @@ export class GeometryAtlas {
501
519
  gl.deleteVertexArray(this.glyphArray);
502
520
  gl.deleteBuffer(this.glyphBuffer);
503
521
  gl.deleteBuffer(this.glyphIndexBuffer);
522
+ this.tables.destroy();
504
523
  }
505
524
  }
@@ -37,6 +37,7 @@ import {
37
37
  RUN_MOST,
38
38
  RUN_UNIT,
39
39
  SNAP_BIT,
40
+ TABLE_UNIT,
40
41
  TEXTURE_UNIT,
41
42
  } from "./programs.js";
42
43
  import { framebufferOf, type Open, type Target, type TargetPool } from "./targets.js";
@@ -166,15 +167,17 @@ export class Draws {
166
167
  private meshMode = -1;
167
168
  /**
168
169
  * Advanced text's program (GeometryData.glyphs), where it takes its row, view, Flash's
169
- * pixels a stage pixel, mode and table; its vertices are in an atlas of their own.
170
+ * pixels a stage pixel and its text's slot in the glyph tables (GlyphTables), and the row
171
+ * and slot told it last, -1 for none; its vertices are in an atlas of their own.
170
172
  */
171
173
  private glyphProgram!: WebGLProgram;
172
174
  private glyphRowLocation: WebGLUniformLocation | null = null;
173
175
  private glyphViewLocation: WebGLUniformLocation | null = null;
174
176
  private glyphUnitLocation: WebGLUniformLocation | null = null;
175
- private glyphModeLocation: WebGLUniformLocation | null = null;
176
177
  private glyphTableLocation: WebGLUniformLocation | null = null;
177
178
  private glyphStale = true;
179
+ private glyphRow = -1;
180
+ private glyphTable = -1;
178
181
  /** Flash's pixels a stage pixel: the target's pixels a stage pixel over those a pixel of Flash's. */
179
182
  private unit = 1;
180
183
  /**
@@ -279,12 +282,14 @@ export class Draws {
279
282
  this.glyphRowLocation = gl.getUniformLocation(this.glyphProgram, "uRow");
280
283
  this.glyphViewLocation = gl.getUniformLocation(this.glyphProgram, "uView");
281
284
  this.glyphUnitLocation = gl.getUniformLocation(this.glyphProgram, "uUnit");
282
- this.glyphModeLocation = gl.getUniformLocation(this.glyphProgram, "uMode");
283
285
  this.glyphTableLocation = gl.getUniformLocation(this.glyphProgram, "uTable");
284
286
  this.state.useProgram(this.glyphProgram);
285
287
  gl.uniform1i(gl.getUniformLocation(this.glyphProgram, "uRows"), 0);
286
288
  gl.uniform1i(gl.getUniformLocation(this.glyphProgram, "uSegments"), OUTLINE_UNIT);
289
+ gl.uniform1i(gl.getUniformLocation(this.glyphProgram, "uTables"), TABLE_UNIT);
287
290
  this.glyphStale = true;
291
+ this.glyphRow = -1;
292
+ this.glyphTable = -1;
288
293
  this.lastRow = -1;
289
294
  }
290
295
 
@@ -846,7 +851,8 @@ export class Draws {
846
851
  /**
847
852
  * Entry `i`, advanced text's glyph quads (GeometryData.glyphs), drawn by the glyph
848
853
  * program from its atlas, which is told the view as it changed, and its
849
- * text's mode and table; the glyph program left in use.
854
+ * row and its text's slot in the glyph tables as they change; the glyph
855
+ * program left in use.
850
856
  */
851
857
  private drawGlyphs(scene: SceneList, i: number, place: Place): void {
852
858
  const gl = this.gl;
@@ -860,11 +866,23 @@ export class Draws {
860
866
  this.glyphStale = false;
861
867
  }
862
868
 
863
- gl.uniform1i(this.glyphRowLocation, scene.row[i]);
864
- gl.uniform4fv(this.glyphModeLocation, glyphs.mode);
865
- gl.uniform4fv(this.glyphTableLocation, glyphs.table);
869
+ const row = scene.row[i];
870
+ if (row !== this.glyphRow) {
871
+ gl.uniform1i(this.glyphRowLocation, row);
872
+ this.glyphRow = row;
873
+ }
874
+
875
+ const tables = this.atlas.tables;
876
+ const slot = glyphs.slot >= 0 ? glyphs.slot : tables.scratch(glyphs.mode, glyphs.table);
877
+ if (slot !== this.glyphTable) {
878
+ gl.uniform1i(this.glyphTableLocation, slot);
879
+ this.glyphTable = slot;
880
+ }
881
+
866
882
  state.bindTexture(OUTLINE_UNIT, this.gpu.outlines);
867
883
  state.bindSampler(OUTLINE_UNIT, null);
884
+ state.bindTexture(TABLE_UNIT, tables.texture);
885
+ state.bindSampler(TABLE_UNIT, null);
868
886
  gl.drawElements(gl.TRIANGLES, place.indices, gl.UNSIGNED_INT, place.indexStart * 4);
869
887
  }
870
888
 
@@ -5,6 +5,7 @@ import {
5
5
  CONVOLUTION_PASS,
6
6
  DISPLACE_PASS,
7
7
  FilterPlan,
8
+ FLOAT_LINE,
8
9
  FLOATS,
9
10
  GLOW_PASS,
10
11
  GRADIENT_PASS,
@@ -59,6 +60,8 @@ export interface FilterHost<T extends FilterTarget> {
59
60
  const INPUT_UNIT = 4;
60
61
  const BLURRED_UNIT = 5;
61
62
  const EXTRA_UNIT = 6;
63
+ /** A pass's line of floats (FLOAT_LINE): a convolution's weights, which reads no gradient nor map. */
64
+ const LINE_UNIT = EXTRA_UNIT;
62
65
 
63
66
  /**
64
67
  * A triangle over the output's frame, the viewport, reading its input
@@ -146,6 +149,10 @@ export class FilterRunner<T extends FilterTarget> {
146
149
  private readonly hasTexture = (id: number) => id >= 0 && this.host.texture(id) !== null;
147
150
  /** The target's pixels a unit of its own, for the chain running. */
148
151
  private resolution = 1;
152
+ /** The texture of a pass's line of floats (FLOAT_LINE), its width, and the floats' bits it holds. */
153
+ private line: WebGLTexture | null = null;
154
+ private lineWidth = 0;
155
+ private lineBits = new Uint32Array(0);
149
156
 
150
157
  constructor(
151
158
  gl: WebGL2RenderingContext,
@@ -356,6 +363,10 @@ export class FilterRunner<T extends FilterTarget> {
356
363
  // As many as KERNEL_IMAGES, which the plan holds a kernel to.
357
364
  this.kernels.bindImage(location, this.samplers++, values[at], this.host);
358
365
  break;
366
+ case FLOAT_LINE:
367
+ gl.uniform1i(location, LINE_UNIT);
368
+ this.bindLine(values, at, count);
369
+ break;
359
370
  case FLOATS:
360
371
  this.set(
361
372
  pass,
@@ -369,6 +380,45 @@ export class FilterRunner<T extends FilterTarget> {
369
380
  }
370
381
  }
371
382
 
383
+ /**
384
+ * `count` of `values` from `at` bound on LINE_UNIT as a line of floats,
385
+ * uploaded where they are not the ones it holds: a frame's filters alike
386
+ * take the same.
387
+ */
388
+ private bindLine(values: Float32Array, at: number, count: number): void {
389
+ const gl = this.gl;
390
+ const bits = new Uint32Array(values.buffer, values.byteOffset + at * 4, count);
391
+ let same = this.line !== null && count === this.lineBits.length;
392
+ for (let k = 0; same && k < count; k++) {
393
+ same = bits[k] === this.lineBits[k];
394
+ }
395
+
396
+ if (!same) {
397
+ if (!this.line || count > this.lineWidth) {
398
+ if (this.line) {
399
+ this.state.dropTexture(this.line);
400
+ gl.deleteTexture(this.line);
401
+ }
402
+
403
+ this.line = gl.createTexture() as WebGLTexture;
404
+ this.lineWidth = count;
405
+ this.state.bindTexture(LINE_UNIT, this.line);
406
+ this.state.activeTexture(LINE_UNIT);
407
+ gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32F, count, 1);
408
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
409
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
410
+ }
411
+
412
+ this.state.bindTexture(LINE_UNIT, this.line);
413
+ this.state.activeTexture(LINE_UNIT);
414
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, count, 1, gl.RED, gl.FLOAT, values, at);
415
+ this.lineBits = bits.slice();
416
+ }
417
+
418
+ this.state.bindTexture(LINE_UNIT, this.line);
419
+ this.state.bindSampler(LINE_UNIT, null);
420
+ }
421
+
372
422
  /** The pass of program `id` (filter-plan.ts), in use. */
373
423
  private program(id: number): Pass {
374
424
  switch (id) {
@@ -498,5 +548,10 @@ export class FilterRunner<T extends FilterTarget> {
498
548
  }
499
549
 
500
550
  this.passes.clear();
551
+ if (this.line) {
552
+ this.state.dropTexture(this.line);
553
+ this.gl.deleteTexture(this.line);
554
+ this.line = null;
555
+ }
501
556
  }
502
557
  }