download method

Future<Uint8List> download()

Implementation

Future<Uint8List> download() async {
  if (_disposed) return Uint8List(0);
  final wgpu = WebgpuRend.instance.wgpu;
  wgpu.wgpuQueueSubmit(WebgpuRend.instance.queue, 0, nullptr);

  final size = width * height * 4;
  final int bytesPerRow = (width * 4 + 255) & ~255;
  final int paddedSize = bytesPerRow * height;

  final buffer = GpuBuffer.create(
      size: paddedSize,
      usage: WGPUBufferUsage_MapRead | WGPUBufferUsage_CopyDst);

  final encoder = CommandEncoder();
  using((arena) {
    final src = arena<WGPUTexelCopyTextureInfo>();
    src.ref.texture = texture;
    src.ref.mipLevel = 0;
    src.ref.origin.x = 0;
    src.ref.origin.y = 0;
    src.ref.origin.z = 0;
    src.ref.aspect = WGPUTextureAspect.WGPUTextureAspect_All;

    final dst = arena<WGPUTexelCopyBufferInfo>();
    dst.ref.buffer = buffer.handle.cast();
    dst.ref.layout.offset = 0;
    dst.ref.layout.bytesPerRow = bytesPerRow;
    dst.ref.layout.rowsPerImage = height;

    final copySize = arena<WGPUExtent3D>();
    copySize.ref.width = width;
    copySize.ref.height = height;
    copySize.ref.depthOrArrayLayers = 1;

    wgpu.wgpuCommandEncoderCopyTextureToBuffer(
        encoder._handle, src, dst, copySize);
  });

  beginAccess();
  encoder.submit();
  endAccess();

  final paddedData = await buffer.mapRead();
  final compactData = Uint8List(size);

  for (int y = 0; y < height; y++) {
    final srcOffset = y * bytesPerRow;
    final dstOffset = y * (width * 4);
    for (int i = 0; i < (width * 4); i++) {
      compactData[dstOffset + i] = paddedData[srcOffset + i];
    }
  }

  buffer.dispose();
  return compactData;
}