(framebuffer)
| 3772 | } |
| 3773 | |
| 3774 | async readFramebufferPixels(framebuffer) { |
| 3775 | this.flushDraw(); |
| 3776 | // await this.finishDraw(); |
| 3777 | // Ensure all pending GPU work is complete before reading pixels |
| 3778 | // await this.queue.onSubmittedWorkDone(); |
| 3779 | |
| 3780 | const width = framebuffer.width * framebuffer.density; |
| 3781 | const height = framebuffer.height * framebuffer.density; |
| 3782 | const bytesPerPixel = 4; |
| 3783 | const unalignedBytesPerRow = width * bytesPerPixel; |
| 3784 | const alignedBytesPerRow = this._alignBytesPerRow(unalignedBytesPerRow); |
| 3785 | const bufferSize = alignedBytesPerRow * height; |
| 3786 | |
| 3787 | // const stagingBuffer = this._ensurePixelReadBuffer(bufferSize); |
| 3788 | const stagingBuffer = this.device.createBuffer({ |
| 3789 | size: bufferSize, |
| 3790 | usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, |
| 3791 | }); |
| 3792 | |
| 3793 | const commandEncoder = this.device.createCommandEncoder(); |
| 3794 | commandEncoder.copyTextureToBuffer( |
| 3795 | { |
| 3796 | texture: framebuffer.colorTexture, |
| 3797 | origin: { x: 0, y: 0, z: 0 }, |
| 3798 | mipLevel: 0, |
| 3799 | aspect: 'all' |
| 3800 | }, |
| 3801 | { buffer: stagingBuffer, bytesPerRow: alignedBytesPerRow, rowsPerImage: height }, |
| 3802 | { width, height, depthOrArrayLayers: 1 } |
| 3803 | ); |
| 3804 | |
| 3805 | this.device.queue.submit([commandEncoder.finish()]); |
| 3806 | |
| 3807 | // Wait for the copy operation to complete |
| 3808 | // await this.queue.onSubmittedWorkDone(); |
| 3809 | |
| 3810 | await stagingBuffer.mapAsync(GPUMapMode.READ, 0, bufferSize); |
| 3811 | const mappedRange = stagingBuffer.getMappedRange(0, bufferSize); |
| 3812 | |
| 3813 | // If alignment was needed, extract the actual pixel data |
| 3814 | let result; |
| 3815 | if (alignedBytesPerRow === unalignedBytesPerRow) { |
| 3816 | result = new Uint8Array(mappedRange.slice(0, width * height * bytesPerPixel)); |
| 3817 | stagingBuffer.unmap(); |
| 3818 | } else { |
| 3819 | // Need to extract pixel data from aligned buffer |
| 3820 | result = new Uint8Array(width * height * bytesPerPixel); |
| 3821 | const mappedData = new Uint8Array(mappedRange); |
| 3822 | for (let y = 0; y < height; y++) { |
| 3823 | const srcOffset = y * alignedBytesPerRow; |
| 3824 | const dstOffset = y * unalignedBytesPerRow; |
| 3825 | result.set(mappedData.subarray(srcOffset, srcOffset + unalignedBytesPerRow), dstOffset); |
| 3826 | } |
| 3827 | stagingBuffer.unmap(); |
| 3828 | } |
| 3829 | |
| 3830 | this._ensurePixelsAreRGBA(framebuffer, result); |
| 3831 |
nothing calls this directly
no test coverage detected