Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wgpu without a window for web #528

Open
adamgerhant opened this issue Feb 2, 2024 · 0 comments
Open

Wgpu without a window for web #528

adamgerhant opened this issue Feb 2, 2024 · 0 comments

Comments

@adamgerhant
Copy link

adamgerhant commented Feb 2, 2024

The current Wgpu without a window code example does not work when compiling to wasm and running in a browser. Specially, copying data from the buffer using futures_intrusive::channel::shared::oneshot_channel() seems to cause the error. To solve this, I used the code in another wgpu example which uses flume::bounded. This fixed the problem and allowed me to copy data from the buffer and return it to Javascript.

l should probably make a pull request, but I think its unnecessary for a very simple change. Here's the old code compared to the new

Old

{
    let buffer_slice = output_buffer.slice(..);

    // NOTE: We have to create the mapping THEN device.poll() before await
    // the future. Otherwise the application will freeze.
    let (tx, rx) = futures_intrusive::channel::shared::oneshot_channel();
    buffer_slice.map_async(wgpu::MapMode::Read, move |result| {
        tx.send(result).unwrap();
    });
    device.poll(wgpu::Maintain::Wait);
    rx.receive().await.unwrap().unwrap();

    let data = buffer_slice.get_mapped_range();

    use image::{ImageBuffer, Rgba};
    let buffer =
        ImageBuffer::<Rgba<u8>, _>::from_raw(texture_size, texture_size, data).unwrap();
    buffer.save("image.png").unwrap();

}
output_buffer.unmap();

New

let mut pixel_data = Vec::<u8>::new();

let buffer_slice = output_buffer.slice(..);
let (sender, receiver) = flume::bounded(1);
buffer_slice.map_async(wgpu::MapMode::Read, move |r| sender.send(r).unwrap());
device.poll(wgpu::Maintain::wait()).panic_on_timeout();
receiver.recv_async().await.unwrap().unwrap();
{
    let view = buffer_slice.get_mapped_range();
    texture_data.extend_from_slice(&view[..]);
}
output_buffer.unmap();

let img = DynamicImage::ImageRgba8(ImageBuffer::from_raw(texture_size, texture_size, pixel_data).unwrap());

//img can be saved to disk, or returned as a byte stream with the following
let mut png_data = Cursor::new(Vec::<u8>::new());
img.write_to(&mut png_data, ImageFormat::Png).unwrap();

let png_bytes = png_data.into_inner();
png_bytes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant