dispose method

  1. @override
void dispose()

Releases everything: the textures and buffers handed out, the arenas, the caches, the canvas's configuration and the device itself.

This backend can finish the job, and the WebGL2 one cannot. There the canvas is the drawing surface and the platform view registry pins it for the life of the application; the most that backend can do is remove the element and ask WEBGL_lose_context to free the context behind it. Here the canvas is a copy target, the factory holds an emptiable slot rather than the element, unconfigure gives back the swap chain and GPUDevice.destroy gives back the device — so what is left afterwards is a closure over a null.

A second call does nothing, as on every backend: a renderer and the owner that opened the device can both let go of it, and the conformance check "a second dispose does nothing" holds each backend to that. It threw a StateError before.

Implementation

@override
void dispose() {
  if (_disposed) return;
  _disposed = true;
  if (!_isLost) {
    _isLost = true;
    _lost.add(
      const DeviceLoss(
        reason: DeviceLossReason.destroyed,
        message: 'the WebGPU device was disposed',
      ),
    );
  }
  unawaited(_lost.close());
  unawaited(_deviceErrors.close());
  unawaited(_timings.close());
  webgpuDisposePersistentResources(_textures, _buffers);
  _blanks.clear();
  _uniformArena.dispose();
  _staging.dispose();
  _vertexArena.dispose();
  _indexArena.dispose();
  _zeroBlock.destroy();
  // Pipelines, layouts, samplers and bind groups have no `destroy` of their
  // own: they belong to the device and die with it. Forgetting them is what
  // makes the resource count fall to zero, and what stops a caller holding
  // this device from holding them too.
  _pipelines.clear();
  _holders.clear();
  _drawStates.clear();
  _bindingLayouts.clear();
  _layoutRefusals.clear();
  _samplers.clear();
  _bindGroups.clear();
  _conversionLayouts.clear();
  _conversionPipelines.clear();
  _library.forget();

  _context.unconfigure();
  _canvas.remove();
  _slot.element = null;
  _gpuDevice.destroy();
}