Repository navigation
fix(windows): cache compiled WebGL programs; WebGPU canvases no longer freeze on resize - #184
Merged
Merged
Conversation
ANGLE only reuses linked programs when the app installs EGL_ANDROID_blob_cache callbacks; its own cache size defaults to 0. Without them every new context recompiled every shader through the HLSL compiler, which blocked large scenes for about a second on each visit. Programs are now kept in memory and under %LOCALAPPDATA%\<exe>\canvas\program-cache (CANVAS_PROGRAM_CACHE_DIR overrides it; empty keeps it in memory only).
Configuring the surface from the layout pass waited for the GPU without a
limit, while the last presented frame waited on the compositor, which waits
on the UI thread. The resize is now applied from the next getCurrentTexture,
once that frame is done, drawing offscreen until then.
Resizing gets a fresh swapchain, since ResizeBuffers fails while the page
still holds a texture of the old one ("window is in use"). getCurrentTexture
falls back to the offscreen texture instead of returning null.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
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 |
linkProgram queried ACTIVE_UNIFORM_BLOCKS straight after glLinkProgram, which waits for the link to finish, so ANGLE could never link in the background. The count is now queried (and cached) the first time uniformBlockBinding needs it.
ANGLE compiles and links on worker threads once a context enables it, and COMPLETION_STATUS_KHR lets the page poll without waiting (three.js's compileAsync, for example).
Exposed when the driver reports GL_KHR_parallel_shader_compile. The GL default for MAX_SHADER_COMPILER_THREADS_KHR already lets the driver use its own maximum, so nothing else has to be set. COMPLETION_STATUS_KHR reads back as a boolean.
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.
WebGL: compiled programs are cached
ANGLE only reuses linked programs when the app installs
EGL_ANDROID_blob_cachecallbacks (its built-in cache size is 0), so every new context recompiled every shader through the HLSL compiler. A page with a large physically based scene blocked the UI thread for about a second on every visit.Programs are now kept in memory and on disk under
%LOCALAPPDATA%\<exe>\canvas\program-cache(packaged apps get it redirected into their package data).CANVAS_PROGRAM_CACHE_DIRoverrides the location; an empty value keeps the cache in memory only. Memory is capped at 32 MB and disk at 64 MB.Revisits within a session are fast too. The very first visit on a fresh install still compiles once.
WebGL: links run in the background
linkProgramqueriedACTIVE_UNIFORM_BLOCKSstraight afterglLinkProgram, which waits for the link to finish, so ANGLE could never link off-thread. The count is now queried the first timeuniformBlockBindingneeds it.KHR_parallel_shader_compileis exposed on Windows. Once a page enables it, ANGLE compiles and links on worker threads, andCOMPLETION_STATUS_KHRcan be polled without waiting (three.js'scompileAsyncuses it).The same three.js scene (PMREM room environment, physical and standard materials), first open with an empty shader cache, measured as time the JS thread is blocked:
compileAsyncrender()), ~1,000 ms (compileAsync)WebGPU: resizing a canvas no longer freezes the app
getCurrentTexture, once that frame has finished, and frames draw offscreen until then. Nothing blocks.ResizeBuffersfailed while the page still held a texture of the old one (window is in use), and the canvas stayed at its old size.getCurrentTexturefalls back to the offscreen texture instead of returning null (context may not be configured).Tested on Windows x64 (Intel Iris Xe) by resizing the window 6 times on a compute + render page: 9 runs in a row stayed responsive and kept animating, with no
ResizeBufferserrors. Before the change, nearly every run froze.Binaries
canvasnative.noderebuilt for x64 and arm64. The arm64 build has not been run on a device.Note for local builds:
Cargo.lockis ignored, and a fresh resolve picks napi 3.14 / napi-sys 3.4. That silently bypasses the[patch.crates-io]napi-sys, and the module aborts on load in a NativeScript Windows host. These binaries were built against napi 3.13.0.