Skip to content

Commit

Permalink
chore: updates
Browse files Browse the repository at this point in the history
  • Loading branch information
triniwiz committed Dec 12, 2024
1 parent 4083f02 commit a4a8104
Show file tree
Hide file tree
Showing 15 changed files with 1,078 additions and 119 deletions.
26 changes: 13 additions & 13 deletions crates/canvas-c/src/webgpu/gpu_canvas_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,21 @@ use super::{
//use wgpu_core::gfx_select;

#[derive(Copy, Clone, Debug)]
struct TextureData {
usage: wgt::TextureUsages,
dimension: wgt::TextureDimension,
size: wgt::Extent3d,
format: wgt::TextureFormat,
mip_level_count: u32,
sample_count: u32,
pub struct TextureData {
pub usage: wgt::TextureUsages,
pub dimension: wgt::TextureDimension,
pub size: wgt::Extent3d,
pub format: wgt::TextureFormat,
pub mip_level_count: u32,
pub sample_count: u32,
}

#[derive(Debug)]
pub struct SurfaceData {
device: Arc<CanvasGPUDevice>,
error_sink: ErrorSink,
texture_data: TextureData,
previous_configuration: wgt::SurfaceConfiguration<Vec<wgt::TextureFormat>>,
pub(crate) device: Arc<CanvasGPUDevice>,
pub(crate) error_sink: ErrorSink,
pub texture_data: TextureData,
pub(crate) previous_configuration: wgt::SurfaceConfiguration<Vec<wgt::TextureFormat>>,
}

#[derive(Copy, Clone, Debug)]
Expand All @@ -46,8 +46,8 @@ pub struct ViewData {

#[derive(Copy, Clone, Debug)]
pub struct ReadBackTexture {
texture: wgpu_core::id::TextureId,
data: TextureData,
pub(crate) texture: wgpu_core::id::TextureId,
pub(crate) data: TextureData,
}

pub struct CanvasGPUCanvasContext {
Expand Down
148 changes: 126 additions & 22 deletions crates/canvas-c/src/webgpu/gpu_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ use crate::webgpu::enums::CanvasGPUTextureFormat;
//use wgpu_core::gfx_select;
use crate::webgpu::error::{handle_error, handle_error_fatal};
use crate::webgpu::prelude::label_to_ptr;
use crate::webgpu::structs::{CanvasImageCopyCanvasRenderingContext2D, CanvasImageCopyImageAsset, CanvasImageCopyWebGL};
use crate::webgpu::structs::{
CanvasImageCopyCanvasRenderingContext2D, CanvasImageCopyGPUContext, CanvasImageCopyImageAsset,
CanvasImageCopyWebGL,
};
use canvas_webgl::utils::gl::bytes_per_pixel;
use std::borrow::Cow;
use std::os::raw::{c_char, c_void};
Expand Down Expand Up @@ -40,7 +43,9 @@ pub struct CanvasGPUQueue {
unsafe impl Send for CanvasGPUQueue {}

#[no_mangle]
pub unsafe extern "C" fn canvas_native_webgpu_queue_get_label(queue: *const CanvasGPUQueue) -> *mut c_char {
pub unsafe extern "C" fn canvas_native_webgpu_queue_get_label(
queue: *const CanvasGPUQueue,
) -> *mut c_char {
if queue.is_null() {
return std::ptr::null_mut();
}
Expand Down Expand Up @@ -89,7 +94,6 @@ fn get_offset_image(
break;
}


let src_start = (src_y * img_width + x_offset) * bytes_per_pixel;
let src_end = src_start + width * bytes_per_pixel;

Expand All @@ -99,8 +103,7 @@ fn get_offset_image(
let dst_start = row * width * bytes_per_pixel;
let copy_len = src_row_data.len().min(width * bytes_per_pixel);

result[dst_start..dst_start + copy_len]
.copy_from_slice(&src_row_data[0..copy_len]);
result[dst_start..dst_start + copy_len].copy_from_slice(&src_row_data[0..copy_len]);
}

result
Expand All @@ -123,12 +126,10 @@ pub unsafe extern "C" fn canvas_native_webgpu_queue_copy_webgl_to_texture(
}
let webgl = &*source.source;


webgl.0.make_current();
let width = webgl.0.get_drawing_buffer_width();
let height = webgl.0.get_drawing_buffer_height();


let row_size = bytes_per_pixel(gl_bindings::RGBA as u32, gl_bindings::RGBA as u32) as i32;

let mut bytes = vec![0u8; (width * height * row_size) as usize];
Expand Down Expand Up @@ -156,7 +157,6 @@ pub unsafe extern "C" fn canvas_native_webgpu_queue_copy_webgl_to_texture(
}
}


let ext_source = CanvasImageCopyExternalImage {
source: bytes.as_ptr(),
source_size: bytes.len(),
Expand All @@ -166,7 +166,12 @@ pub unsafe extern "C" fn canvas_native_webgpu_queue_copy_webgl_to_texture(
height: height as u32,
};

canvas_native_webgpu_queue_copy_external_image_to_texture(queue, &ext_source, destination, size);
canvas_native_webgpu_queue_copy_external_image_to_texture(
queue,
&ext_source,
destination,
size,
);
}

#[no_mangle]
Expand All @@ -180,7 +185,6 @@ pub unsafe extern "C" fn canvas_native_webgpu_queue_copy_context_to_texture(
return;
}


let source = &*source;
let destination = &*destination;

Expand All @@ -191,7 +195,6 @@ pub unsafe extern "C" fn canvas_native_webgpu_queue_copy_context_to_texture(

let (width, height) = context.context.dimensions();


let queue = &*queue;
let queue_id = queue.queue.id;

Expand All @@ -203,10 +206,17 @@ pub unsafe extern "C" fn canvas_native_webgpu_queue_copy_context_to_texture(

match destination_texture.format {
CanvasGPUTextureFormat::Bgra8Unorm | CanvasGPUTextureFormat::Bgra8UnormSrgb => {
context.context.get_pixels_format(data.as_mut_slice(), (0, 0), (width as i32, height as i32), canvas_2d::context::ColorType::BGRA8888);
context.context.get_pixels_format(
data.as_mut_slice(),
(0, 0),
(width as i32, height as i32),
canvas_2d::context::ColorType::BGRA8888,
);
}
_ => {
context.context.get_pixels(data.as_mut_slice(), (0, 0), (width as i32, height as i32));
context
.context
.get_pixels(data.as_mut_slice(), (0, 0), (width as i32, height as i32));
}
}

Expand Down Expand Up @@ -267,7 +277,6 @@ pub unsafe extern "C" fn canvas_native_webgpu_queue_copy_context_to_texture(
}
}


#[no_mangle]
pub unsafe extern "C" fn canvas_native_webgpu_queue_copy_image_asset_to_texture(
queue: *const CanvasGPUQueue,
Expand Down Expand Up @@ -300,14 +309,26 @@ pub unsafe extern "C" fn canvas_native_webgpu_queue_copy_image_asset_to_texture(
match texture.format {
CanvasGPUTextureFormat::Bgra8Unorm | CanvasGPUTextureFormat::Bgra8UnormSrgb => {
let mut bytes = bytes.to_vec();
canvas_core::image_asset::ImageAsset::rgba_to_bgra_in_place(bytes.as_mut_slice());
canvas_core::image_asset::ImageAsset::rgba_to_bgra_in_place(
bytes.as_mut_slice(),
);

ext_source.source = bytes.as_ptr();

canvas_native_webgpu_queue_copy_external_image_to_texture(queue, &ext_source, destination, size);
canvas_native_webgpu_queue_copy_external_image_to_texture(
queue,
&ext_source,
destination,
size,
);
}
_ => {
canvas_native_webgpu_queue_copy_external_image_to_texture(queue, &ext_source, destination, size);
canvas_native_webgpu_queue_copy_external_image_to_texture(
queue,
&ext_source,
destination,
size,
);
}
}
}
Expand Down Expand Up @@ -394,6 +415,90 @@ pub unsafe extern "C" fn canvas_native_webgpu_queue_copy_external_image_to_textu
}
}

#[no_mangle]
pub unsafe extern "C" fn canvas_native_webgpu_queue_copy_gpu_context_to_texture(
queue: *const CanvasGPUQueue,
source: *const CanvasImageCopyGPUContext,
destination: *const CanvasImageCopyTexture,
size: *const CanvasExtent3d,
) {
if queue.is_null() || source.is_null() || destination.is_null() || size.is_null() {
return;
}

let source = &*source;
let destination = &*destination;

if source.source.is_null() || destination.texture.is_null() {
return;
}
let context =
&mut *(source.source as *mut crate::webgpu::gpu_canvas_context::CanvasGPUCanvasContext);

let mut texture = None;
if let Some(current_texture) = context.current_texture.lock().as_ref() {
texture = Some(current_texture.texture);
} else if let Some(read_back_texture) = context.read_back_texture.lock().as_ref() {
texture = Some(read_back_texture.texture);
}

if let Some(texture) = texture {
let queue = &*queue;

let global = queue.queue.instance.global();

if let Some(data) = context.data.lock().as_ref() {
let label = Cow::Borrowed("copyExternalImageToTexture:Encoder");
let (encoder, error) = global.device_create_command_encoder(
data.device.device,
&wgt::CommandEncoderDescriptor {
label: wgpu_core::Label::from(label),
},
None,
);
if let Some(error) = error {
// todo log error
return;
}

let source = wgt::TexelCopyTextureInfo {
texture,
mip_level: data.texture_data.mip_level_count,
origin: wgt::Origin3d {
x: source.origin.x,
y: source.origin.y,
z: 0,
},
aspect: Default::default(),
};
let destination_texture = unsafe { &*destination.texture };
let dest = wgt::TexelCopyTextureInfo {
texture: destination_texture.texture,
mip_level: destination.mip_level,
origin: destination.origin.into(),
aspect: destination.aspect.into(),
};

let size = *size;

let size: wgt::Extent3d = size.into();

if let Err(cause) =
global.command_encoder_copy_texture_to_texture(encoder, &source, &dest, &size)
{
handle_error(
global,
queue.error_sink.as_ref(),
cause,
"",
None,
"canvas_native_webgpu_queue_copy_gpu_context_to_texture",
);
}
}
}
}

#[no_mangle]
pub unsafe extern "C" fn canvas_native_webgpu_queue_on_submitted_work_done(
queue: *const CanvasGPUQueue,
Expand Down Expand Up @@ -447,8 +552,7 @@ pub unsafe extern "C" fn canvas_native_webgpu_queue_submit(
})
.collect::<Vec<_>>();

if let Err((_, cause)) = global.queue_submit(queue_id, &command_buffer_ids)
{
if let Err((_, cause)) = global.queue_submit(queue_id, &command_buffer_ids) {
handle_error_fatal(global, cause, "canvas_native_webgpu_queue_submit");
}

Expand Down Expand Up @@ -488,8 +592,7 @@ pub unsafe extern "C" fn canvas_native_webgpu_queue_write_buffer(
None => &data[data_offset..],
};

if let Err(cause) = global.queue_write_buffer(queue_id, buffer_id, buffer_offset, data)
{
if let Err(cause) = global.queue_write_buffer(queue_id, buffer_id, buffer_offset, data) {
handle_error(
global,
queue.error_sink.as_ref(),
Expand Down Expand Up @@ -541,7 +644,8 @@ pub unsafe extern "C" fn canvas_native_webgpu_queue_write_texture(

let size: wgt::Extent3d = size.into();

if let Err(cause) = global.queue_write_texture(queue_id, &destination, data, &data_layout, &size)
if let Err(cause) =
global.queue_write_texture(queue_id, &destination, data, &data_layout, &size)
{
handle_error(
global,
Expand Down
20 changes: 20 additions & 0 deletions crates/canvas-c/src/webgpu/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,26 @@ pub struct CanvasImageCopyExternalImage {
pub height: u32,
}

#[repr(C)]
#[derive(Debug)]
pub struct CanvasImageCopyGPUContext {
/// The texture to be copied from. The copy source data is captured at the moment
/// the copy is issued.
pub source: *const crate::webgpu::gpu_canvas_context::CanvasGPUCanvasContext,
/// The base texel used for copying from the external image. Together
/// with the `copy_size` argument to copy functions, defines the
/// sub-region of the image to copy.
///
/// Relative to the top left of the image.
///
/// Must be [`Origin2d::ZERO`] if [`DownlevelFlags::UNRESTRICTED_EXTERNAL_TEXTURE_COPIES`] is not supported.
pub origin: CanvasOrigin2d,
/// If the Y coordinate of the image should be flipped. Even if this is
/// true, `origin` is still relative to the top left.
pub flip_y: bool,
}



#[repr(C)]
#[derive(Debug)]
Expand Down
Loading

0 comments on commit a4a8104

Please sign in to comment.