Open Bug 1965377 Opened 14 days ago Updated 2 days ago

Expire textures returned by `GPUCanvasContext.getCurrentTexture`

Categories

(Core :: Graphics: WebGPU, defect, P1)

defect

Tracking

()

People

(Reporter: jimb, Unassigned)

References

(Blocks 1 open bug)

Details

The WebGPU specification allows implementations to promptly reclaim storage allocated for textures returned by GPUCanvasContext.getCurrentTexture before they are GC'd by enqueuing tasks to expire the current texture. Since applications are encouraged to call getCurrentTexture to obtain a fresh texture on every frame, and there is no guarantee of when the GC will get around to cleaning objects up, this is a significant opportunity to conserve GPU memory.

I believe Firefox's WebGPU implementation does not, at present, expire textures. We should expect applications to run out of memory, depending on how large the canvas they are rendering to is.

Blocks: webgpu-perf
Severity: -- → S3

Here's the spec link for the "expiry task source": https://www.w3.org/TR/webgpu/#automatic-expiry-task-source

Jeff, if you have a chance to find an example of how to run a task, could you please post the link here? I was asking for external textures rather than getCurrentTexture() which is what this bug is about, but the scheduling steps should be the same.

Flags: needinfo?(jmuizelaar)

These are just some notes. I don't understand things well enough to make any suggestions.

There may be no bug here after all, when we are able to present without readback: PresentationData::mRecycledInternalTextures certainly looks like the kind of data structure you'd want if you were indeed re-using canvas textures.

My first impulse here was to look for a way to recycle the same textures over and over, but that is trickier than it first seems. Suppose:

  • We record a command buffer that draws to a canvas texture.
  • The expiry task runs, expiring that texture.
  • We submit the command buffer.

The spec says that submitting that command buffer should cause an error: the expiry task sets the canvas texture's [[destroyed]] property, and then submission validates checks the [[destroyed]] property (both on the device timeline).

wgpu_core represents a destroyed texture as a wgpu_core::resource::Texture whose inner field has been snatched. Queue submission calls Texture::try_inner to decide whether each texture used by the command buffer has been destroyed.

This means that if Firefox wants to recycle textures, it can't just retain a TextureId or Arc<wgpu_core::resource::Texture>: if such an id or pointer remained usable for Firefox to recycle it for a subsequent frame, then queue submission of a stale command buffer would see it as usable too, and not reject its submission.

I thought that a first cut might be to simply destroy the wgpu texture at expiry time. But recycling also needs to coordinate with queue processing to ensure that the GPU has finished drawing to the texture, and with presentation, to ensure that the compositor is finished reading from it.

Priority: -- → P1
You need to log in before you can comment on or make changes to this bug.