MCPcopy
hub / github.com/processing/p5.js / readFramebufferRegion

Method readFramebufferRegion

src/webgpu/p5.RendererWebGPU.js:3871–3936  ·  view source on GitHub ↗
(framebuffer, x, y, w, h)

Source from the content-addressed store, hash-verified

3869 }
3870
3871 async readFramebufferRegion(framebuffer, x, y, w, h) {
3872 this.flushDraw();
3873 // await this.finishDraw();
3874 // const wasActive = this.activeFramebuffer() === framebuffer;
3875 // if (wasActive) {
3876 // framebuffer.end();
3877 // this.flushDraw()
3878 // }
3879 // Ensure all pending GPU work is complete before reading pixels
3880 // await this.queue.onSubmittedWorkDone();
3881
3882 const width = w * framebuffer.density;
3883 const height = h * framebuffer.density;
3884 const bytesPerPixel = 4;
3885 const unalignedBytesPerRow = width * bytesPerPixel;
3886 const alignedBytesPerRow = this._alignBytesPerRow(unalignedBytesPerRow);
3887 const bufferSize = alignedBytesPerRow * height;
3888
3889 const stagingBuffer = this._ensurePixelReadBuffer(bufferSize);
3890
3891 const commandEncoder = this.device.createCommandEncoder();
3892 commandEncoder.copyTextureToBuffer(
3893 {
3894 texture: framebuffer.colorTexture,
3895 mipLevel: 0,
3896 origin: { x: x * framebuffer.density, y: y * framebuffer.density, z: 0 }
3897 },
3898 { buffer: stagingBuffer, bytesPerRow: alignedBytesPerRow },
3899 { width, height, depthOrArrayLayers: 1 }
3900 );
3901
3902 this.device.queue.submit([commandEncoder.finish()]);
3903
3904 await stagingBuffer.mapAsync(GPUMapMode.READ, 0, bufferSize);
3905 const mappedRange = stagingBuffer.getMappedRange(0, bufferSize);
3906
3907 let pixelData;
3908 if (alignedBytesPerRow === unalignedBytesPerRow) {
3909 pixelData = new Uint8Array(mappedRange.slice(0, width * height * bytesPerPixel));
3910 } else {
3911 // Need to extract pixel data from aligned buffer
3912 pixelData = new Uint8Array(width * height * bytesPerPixel);
3913 const mappedData = new Uint8Array(mappedRange);
3914 for (let y = 0; y < height; y++) {
3915 const srcOffset = y * alignedBytesPerRow;
3916 const dstOffset = y * unalignedBytesPerRow;
3917 pixelData.set(mappedData.subarray(srcOffset, srcOffset + unalignedBytesPerRow), dstOffset);
3918 }
3919 }
3920 this._ensurePixelsAreRGBA(framebuffer, pixelData);
3921
3922 // WebGPU doesn't need vertical flipping unlike WebGL
3923 const region = new Image(width, height);
3924 region.imageData = region.canvas.getContext('2d').createImageData(width, height);
3925 region.imageData.data.set(pixelData);
3926 region.pixels = region.imageData.data;
3927 region.updatePixels();
3928

Callers

nothing calls this directly

Calls 9

flushDrawMethod · 0.95
_alignBytesPerRowMethod · 0.95
_ensurePixelsAreRGBAMethod · 0.95
updatePixelsMethod · 0.95
pixelDensityMethod · 0.95
finishMethod · 0.80
sliceMethod · 0.80
setMethod · 0.45

Tested by

no test coverage detected