Skip to content

Commit db0f13c

Browse files
committed
[sigma] Fixes some attachment labels issue
The issue was that hovering a node in the attachment-label example was making all edges disappear, until any re-rendering was triggered (by leaving the node, zooming, panning...). Details: - Adds regression test for the observed bug on label-attachment example - Adds gl.activeTexture() call before gl.bindTexture() in regenerateAtlas to fix the issue
1 parent 817c0e9 commit db0f13c

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* Regression test for texture unit corruption in AttachmentManager.
3+
*
4+
* When regenerateAtlas() creates a GL texture it must bind it to a dedicated
5+
* texture unit, not to whichever unit happens to be active. Otherwise, it
6+
* overwrites unrelated data-texture bindings (e.g. the edge data texture on
7+
* unit 4), causing edges to vanish until the next full render rebinds them.
8+
*/
9+
import { describe, expect, test } from "vitest";
10+
11+
import { createTestGL } from "../../../_test-helpers";
12+
import { AttachmentManager } from "./attachment-manager";
13+
14+
describe("AttachmentManager", () => {
15+
test("regenerateAtlas preserves other texture unit bindings", () => {
16+
const gl = createTestGL();
17+
18+
// Bind a sentinel texture to unit 4 (simulates the edge data texture)
19+
const sentinel = gl.createTexture();
20+
gl.activeTexture(gl.TEXTURE0 + 4);
21+
gl.bindTexture(gl.TEXTURE_2D, sentinel);
22+
23+
const manager = new AttachmentManager(gl, {}, () => {});
24+
25+
// Populate cache directly so regenerateAtlas actually creates a GL texture
26+
const canvas = document.createElement("canvas");
27+
canvas.width = 10;
28+
canvas.height = 10;
29+
canvas.getContext("2d")!.fillRect(0, 0, 10, 10);
30+
(manager as unknown as Record<string, unknown>).cache = new Map([
31+
["n:att", { image: canvas, width: 10, height: 10 }],
32+
]);
33+
(manager as unknown as Record<string, unknown>).dirty = true;
34+
35+
manager.regenerateAtlas();
36+
37+
// Unit 4 must still hold the sentinel, not the atlas texture
38+
gl.activeTexture(gl.TEXTURE0 + 4);
39+
expect(gl.getParameter(gl.TEXTURE_BINDING_2D)).toBe(sentinel);
40+
41+
gl.deleteTexture(sentinel);
42+
manager.kill();
43+
});
44+
});

packages/sigma/src/rendering/nodes/attachments/attachment-manager.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import { LabelAttachmentContext, LabelAttachmentRenderer } from "../../../primitives";
1212
import { AtlasEntry, AtlasLookup, PackableItem, ShelfCursor, packItemsOnPage } from "../../../utils";
1313
import { contentToCanvas } from "./attachment-converter";
14+
import { ATTACHMENT_TEXTURE_UNIT } from "./attachment-program";
1415

1516
const ATLAS_SIZE = 2048;
1617

@@ -127,6 +128,7 @@ export class AttachmentManager {
127128
this.deleteGLTexture();
128129
const gl = this.gl;
129130
const tex = gl.createTexture()!;
131+
gl.activeTexture(gl.TEXTURE0 + ATTACHMENT_TEXTURE_UNIT);
130132
gl.bindTexture(gl.TEXTURE_2D, tex);
131133
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
132134
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.packCanvas);

0 commit comments

Comments
 (0)