Fix correctness bugs in TextureManager and image worker#11
Merged
Conversation
- ImageWorker: fix duplicate `supportsOptionsCreateImageBitmap === false` check that caused modern browsers to fall through to the no-options createImageBitmap branch. - ImageWorker: return computed `withAlphaChannel` instead of raw input so the worker path matches the main thread. - ImageWorker: treat `null` like `undefined` so withAlphaChannel falls back to mime detection, matching the main thread's nullish coalesce. - ImageWorker: reject (instead of hanging) when no worker is available and wire `onerror` / `onmessageerror` so a crashed worker rejects all outstanding requests. - ImageWorker: revoke the worker-script blob URL after workers spawn; replace `minLoad = 99` with `Infinity`; drop the unused `imageWorkersEnabled` field. - ImageTexture: revoke the object URL created from a Blob in the non-createImageBitmap fallback path on both success and error. - ImageTexture: add delimiters between sx/sy/sw/sh in `makeCacheKey` to prevent cache-key collisions (e.g. sx=1,sy=23 vs sx=12,sy=3). - ImageTexture: compute `isBase64Image(src)` once in `loadImage`. - CoreTextureManager: introduce `TEXTURE_UPLOAD_FAILED` error code and use it for upload failures (previously misreported as `TEXTURE_DATA_NULL`); propagate the underlying message. - CoreTextureManager: drop the unreachable `coreContext !== null` check around `loadCtxTexture()` (return type is non-nullable). - CoreTextureManager: skip `failed`/`freed` textures pulled from the upload queue in `processSome`, and reject them in `enqueueUploadTexture` so the queue never holds dead entries. - CoreTextureManager: drain `uploadTextureQueue` when initialization completes so textures enqueued before init don't sit waiting for a frame tick. - CoreTextureManager: fix typo in the no-image-worker warning. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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
Reviewed
CoreTextureManager,ImageTexture, andImageWorkerfor bugs and lower-risk issues, and fixed them in this PR. Larger optimizations (in-flight dedup, parallelgetTextureDatainprocessSome, lazyresolveDefaultson cache miss, replacing XHR withfetch+AbortController) are intentionally not included here and tracked separately.What changed
ImageWorker
supportsOptionsCreateImageBitmap === false && supportsOptionsCreateImageBitmap === falsebranch that caused modern browsers to silently fall through to the no-optionscreateImageBitmap(blob)path. The fallback now requires both options and full support to befalse.withAlphaChannelinstead of echoing the raw input — previously the worker path returnednull/undefinedfor PNGs while the main-thread path returnedtrue, leading to inconsistent GL uploads.withAlphaChannelnow treatsnullthe same asundefined, matching the main thread's nullish-coalesce behavior.getImagenow rejects when no worker is available instead of leaving the promise hanging.worker.onerror/worker.onmessageerror: a crashed worker now rejects all outstanding pending requests rather than hanging the entire load pipeline.let minLoad = 99→Infinityso we always pick the genuinely least-loaded worker.imageWorkersEnabledfield.ImageTexture
loadImageFallbackis now revoked on bothonloadandonerror, fixing a per-image leak on the non-createImageBitmapfallback path.makeCacheKeynow inserts delimiters betweensx/sy/sw/shso values like(sx=1, sy=23)and(sx=12, sy=3)no longer collide.loadImagecomputesisBase64Image(src)once.CoreTextureManager
TEXTURE_UPLOAD_FAILEDerror code; upload failures no longer masquerade asTEXTURE_DATA_NULL, and the underlying error message is propagated.coreContext !== nullcheck aroundloadCtxTexture()(return type is non-nullable; the check shadowed an actual NPE risk that didn't exist).processSomeskipsfailed/freedtextures pulled from the queue instead of wasting a fetch/decode on dead entries.enqueueUploadTexturerejectsfailed/freedtextures so the queue never holds dead entries in the first place.processSome.TextureError
TEXTURE_UPLOAD_FAILEDto the enum and default-messages map.Why this matters
The two most impactful items: the duplicate-variable bug was silently disabling the optimal
createImageBitmapcode path on every modern browser, and the worker-crash / no-worker cases could hang load promises indefinitely. The rest are smaller correctness fixes and resource leaks.Test plan
pnpm test)TEXTURE_UPLOAD_FAILEDwith a meaningful message instead ofTEXTURE_DATA_NULL🤖 Generated with Claude Code