Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion packages/troika-three-text/src/SDFGenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,22 @@ function generateSDF_JS_Worker(width, height, path, viewBox, distance, exponent,
for (let i = 0; i < textureData.length; i++) {
imageData[i * 4 + channel] = textureData[i]
}
mainThreadGenerator.webglUtils.renderImageData(canvas, imageData, x, y, width, height, 1 << (3 - channel))
// The atlas context may have been lost while the worker was generating (before the async
// webglcontextlost event has flipped atlas.contextLost), in which case this GL write would
// throw from deep inside webgl-sdf-generator as an unhandled rejection, one per in-flight
// glyph, and strand the typeset callback. Dropping the write is safe: the TextBuilder's
// webglcontextrestored handler regenerates every known glyph into the restored atlas. A null
// probe means context creation was refused under the same GPU pressure - equally benign to
// drop, and no restore event will ever fire for a context that never existed. The probe
// passes the generator's context attributes so a probe that succeeds can't stick a
// wrong-attribute context onto the atlas. Rethrow only when a healthy context proves the
// error was unrelated.
try {
mainThreadGenerator.webglUtils.renderImageData(canvas, imageData, x, y, width, height, 1 << (3 - channel))
} catch (err) {
const gl = typeof canvas.getContext === 'function' ? canvas.getContext('webgl', { premultipliedAlpha: false, preserveDrawingBuffer: true, antialias: false, depth: false }) : null
if (gl && !gl.isContextLost()) throw err
}
timing += now() - start

// clean up workers after a while
Expand Down
11 changes: 10 additions & 1 deletion packages/troika-three-text/src/TextBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,16 @@ function getTextRenderInfo(args, callback) {
if (neededHeight > currentHeight) {
// Since resizing the canvas clears its render buffer, it needs special handling to copy the old contents over
console.info(`Increasing SDF texture size ${currentHeight}->${neededHeight}`)
resizeWebGLCanvasWithoutClearing(sdfCanvas, textureWidth, neededHeight)
// If the context was lost, the canvas dimensions are still applied before the GL copy-over
// throws; drop the copy in that case - the webglcontextrestored handler regenerates every
// glyph into the resized atlas. The dispose below must still run either way so the texture
// reallocates at the new canvas size.
try {
resizeWebGLCanvasWithoutClearing(sdfCanvas, textureWidth, neededHeight)
} catch (err) {
const gl = sdfCanvas.getContext('webgl', { premultipliedAlpha: false, preserveDrawingBuffer: true, antialias: false, depth: false })
if (gl && !gl.isContextLost()) throw err
}
// As of Three r136 textures cannot be resized once they're allocated on the GPU, we must dispose to reallocate it
sdfTexture.dispose()
}
Expand Down
Loading