iOS: threaded WebGL on a CAEAGLLayer, deleteProgram fix - #176
Merged
Merged
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
triniwiz
force-pushed
the
feat/offscreen-canvas-threaded
branch
from
September 30, 2026 20:58
a50f6c8 to
0c9b9b3
Compare
triniwiz
force-pushed
the
feat/ios-threaded-webgl
branch
from
September 30, 2026 21:02
fef3426 to
885ffe1
Compare
Both deleteProgram bindings called canvas_native_webgl_delete_framebuffer, so programs were never deleted, and a framebuffer sharing the program's name was deleted in its place. On iOS that is the canvas's own framebuffer when it and the program both got name 1: three.js disposing its PMREM programs left the canvas drawing into nothing. The spec deletes a fresh context's first program and checks it is gone and the canvas still takes a clear.
iOS WebGL drew through a GLKView, whose display (the per-frame present)
only runs on the main thread, which is the JS thread: a heavy scene held
the UI to the GPU's pace.
The GLKView is replaced by a view backed by a CAEAGLLayer. The context
owns its drawing buffer: a framebuffer whose color buffer is stored in the
layer (renderbufferStorage:fromDrawable:) and presented with
presentRenderbuffer:, both of which run on any thread, plus a packed
depth/stencil buffer from the context attributes. An offscreen context
gets plain renderbuffers instead of an unshown GLKView.
That lets an iOS context be threaded as on Android (the default;
getContext(..., { threaded: false }) opts out): it is created, drawn,
presented and dropped on the shared WebGL thread, and requestAnimationFrame
is held back while a canvas is behind.
- Resizing reallocates the drawing buffer, queued behind earlier calls;
a GL-backed 2D context reallocates its own as it resizes.
- Snapshots read the drawing buffer on the context's thread.
- The texImage helpers and video frame uploads (NSCRender) run on the
context's thread; NSCRender makes its GL objects on first use there.
- Depth and stencil are discarded after each present unless
preserveDrawingBuffer is set, as GLKView did.
triniwiz
force-pushed
the
feat/ios-threaded-webgl
branch
from
September 30, 2026 21:15
885ffe1 to
88984e6
Compare
This was referenced Sep 30, 2026
triniwiz
added a commit
that referenced
this pull request
Sep 30, 2026
* fix(canvas-core): require glutin 0.32.3 The Android GL context asks for a low priority with ContextAttributesBuilder::with_priority, which glutin 0.32.0 does not have. A lockfile still on 0.32.0 fails to build canvas-core. * chore: rebuild Android and Apple native libraries canvas-release.aar and CanvasNative.xcframework, canvassvg-release.aar and CanvasSVG.xcframework, rebuilt from f5424ba with the steps of build-native.yml, for #174, #175, #176 and #177. canvas_native.h catches up with declarations already in the source. * chore: 3.0.0-beta.0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Runs iOS WebGL contexts on the shared WebGL thread, as #174 does on Android, by replacing the GLKView with a view backed by a
CAEAGLLayer. Also fixesdeleteProgram, which deleted a framebuffer instead of the program on every platform.Threaded WebGL on iOS
display, the per-frame present, only runs on the main thread, which is also the JS thread, so a heavy scene held the UI to the GPU's pace.renderbufferStorage:fromDrawable:) and presented withpresentRenderbuffer:. Both work from any thread. Depth/stencil is a packed renderbuffer taken from the context attributes. An offscreen context gets plain renderbuffers instead of a GLKView that is never shown.getContext(..., { threaded: false })opts out. It is created, drawn, presented and dropped on thensc-webglthread, andrequestAnimationFrameis held back while a canvas is behind (Canvas.threadedWebGL,NSCCanvas.threadedWebGL).forceGL) reallocates its own as it resizes.toDataURLand friends), thetexImagehelpers, and video frame uploads.NSCRendergainsdrawFrame/drawFrameTexImage3D/drawFrameTexSubImage3Doverloads that take the context, and makes its GL objects on first use there.@nativescript/canvas-mediapasses the context.preserveDrawingBufferis set, as GLKView did.CanvasGLKViewbecomesCanvasGLView, andNSCCanvas.getGlViewPtr()becomesgetGlLayerPtr().deleteProgramfixdeleteProgrambindings (the slow path and the fast-API path) calledcanvas_native_webgl_delete_framebufferwith the program's name.Testing
deleteProgram deletes the program and nothing else(WebGL 1 and 2). It fails without the fix (the program should be gone: expected false, got true).nsc-webglthread busy.forceGL2D canvas on iOS;