BabylonJS / BabylonJS/BabylonNative
ExternalTexture::Update overwrites the per-texture layer selection on every created texture
- Dominant language
- C++
- Stars
- 919
- Forks
- 162
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 19
Description
`ExternalTexture::CreateForJavaScript(env, layerIndex)` records a layer selection per created texture, but `ExternalTexture::Update` applies the single `layerIndex` from its own call to **every** texture created from that `ExternalTexture`. The per-texture selection made at creation is therefore lost on the first update.
`ExternalTexture_Shared.h:58-66` — each created texture keeps its own selection:
```cpp
auto* texture = new Graphics::Texture{context};
texture->Attach(handle, true, ...);
texture->ViewFirstLayer(layerIndex.value_or(0));
texture->ViewNumLayers(layerIndex.has_value() ? 1 : 0);
m_textures.insert(texture);
```
`ExternalTexture_Base.h:68-89` — update overwrites all of them with one value:
```cpp
for (auto* texture : m_textures)
{
...
texture->ViewFirstLayer(layerIndex.value_or(0));
texture->ViewNumLayers(layerIndex.has_value() ? 1 : 0);
}
```
## Measured
Wrapped one 2-layer array texture as two single-slice views (`layerIndex` 0 and 1), then called `Update(newTexture, {}, 0)` and read `ViewFirstLayer` / `ViewNumLayers` off both:
```
[before] A firstLayer=0 numLayers=1
[before] B firstLayer=1 numLayers=1
[after ] A firstLayer=0 numLayers=1
[after ] B firstLayer=0 numLayers=1
```
Slice 1 became slice 0, so both views now sample the same slice.
## Why it matters
This is the NV12-per-plane shape: a host wraps one array texture once per video plane, each with its own `layerIndex`. That works until the first frame update, after which every plane reads whichever slice was passed to `Update`.
`Update`'s signature takes a single `std::optional layerIndex` (`ExternalTexture.h:48`), so there is no way to express "keep each texture on its own slice". The selection looks like it wants to be per-texture state captured at creation rather than an `Update` argument.
Pre-existing and not reachable through any in-repo caller today — the tests only ever wrap a single slice — so this is a latent API defect rather than an observed failure.
Raised by @bkaradzic-microsoft reviewing #1733.
[Filed by Copilot on behalf of @bghgary]
Contributor guide
Research direction
Start with ExternalTexture.h:48 and compare the update path in ExternalTexture_Base.h:68-89 with per-texture creation in ExternalTexture_Shared.h:58-66. Run the existing ExternalTexture tests, then add coverage for two views created with different layerIndex values and updated together. Done means each view retains its own layer selection after Update.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- backend-api-design, computer-graphics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100