Description
When IconLayer.iconAtlas changes while an earlier load is pending, resolving the loads out of order can destroy the newer, active atlas texture, even though the older result is subsequently discarded.
All icons using that atlas become corrupted: SVG icons appear as vertical stripes, and transparent atlas cells appear as filled squares.
Originally observed during initial rendering or refresh. The issue reproduces in Firefox/Chromium using:
- @deck.gl/core and @deck.gl/layers: 9.4.0
- luma.gl: 9.4.2
The reproduction uses ordinary layer props and Deck.setProps(). Controlled promises make the completion order deterministic. A preceding BitmapLayer binds a distinctive texture to make the incorrect sampling visible.
The apparent cause is in ComponentState._watchPromise: _postProcessValue runs before _setAsyncPropValue checks the completion’s load count. Consequently, the stale completion invokes the release hook on the active texture before its result is rejected.
The proposed fix checks whether the request is still current before invoking _postProcessValue:
- if (!this.component) {
+ if (!this.component || loadCount !== asyncProp.pendingLoadCount) {
return;
}
data = this._postProcessValue(asyncProp, data);
Reproduction source and proposed fix demo. Both demos use the same scene and dependencies; the fixed bundle applies only the guard above.
Flavors
React
Expected Behavior
An older atlas completion should be ignored before resource release or transformation. The newer atlas should remain valid, the SVG should retain its appearance, and the blank cell should remain transparent.
Steps to Reproduce
I created a standalone reproduction repository containing the full source, pinned dependencies, and a proposed fix demo.
Both versions are hosted on GitHub Pages:
- Open the original reproduction with WebGL enabled.
- Click 1. Resolve newer atlas first. This completes the newer request while the older request remains pending.
- Click 2. Resolve older atlas afterwards. This completes the stale request.
- Open the proposed fix demo and repeat the same sequence.
Both demos use the same scene and dependencies. The fixed version adds the proposed guard in ComponentState._watchPromise.
Environment
- Framework version: deck.gl@9.4.0
- Browser: Chrome/Firefox
- OS: Cachy OS
Logs
No response
Description
When IconLayer.iconAtlas changes while an earlier load is pending, resolving the loads out of order can destroy the newer, active atlas texture, even though the older result is subsequently discarded.
All icons using that atlas become corrupted: SVG icons appear as vertical stripes, and transparent atlas cells appear as filled squares.
Originally observed during initial rendering or refresh. The issue reproduces in Firefox/Chromium using:
The reproduction uses ordinary layer props and
Deck.setProps(). Controlled promises make the completion order deterministic. A preceding BitmapLayer binds a distinctive texture to make the incorrect sampling visible.The apparent cause is in ComponentState._watchPromise:
_postProcessValueruns before_setAsyncPropValuechecks the completion’s load count. Consequently, the stale completion invokes the release hook on the active texture before its result is rejected.The proposed fix checks whether the request is still current before invoking
_postProcessValue:Reproduction source and proposed fix demo. Both demos use the same scene and dependencies; the fixed bundle applies only the guard above.
Flavors
React
Expected Behavior
An older atlas completion should be ignored before resource release or transformation. The newer atlas should remain valid, the SVG should retain its appearance, and the blank cell should remain transparent.
Steps to Reproduce
I created a standalone reproduction repository containing the full source, pinned dependencies, and a proposed fix demo.
Both versions are hosted on GitHub Pages:
Both demos use the same scene and dependencies. The fixed version adds the proposed guard in ComponentState._watchPromise.
Environment
Logs
No response