diff --git a/Cargo.lock b/Cargo.lock index 08217cf93..c849f4c8d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2980,6 +2980,7 @@ dependencies = [ name = "ruffle_render_webgl" version = "0.1.0" dependencies = [ + "bytemuck", "fnv", "jpeg-decoder", "js-sys", diff --git a/render/webgl/Cargo.toml b/render/webgl/Cargo.toml index 8168d8b57..0e23a45a5 100644 --- a/render/webgl/Cargo.toml +++ b/render/webgl/Cargo.toml @@ -14,6 +14,7 @@ png = "0.16.8" ruffle_render_common_tess = { path = "../common_tess" } ruffle_web_common = { path = "../../web/common" } wasm-bindgen = "=0.2.69" +bytemuck = { version = "1.5.1", features = ["derive"] } [dependencies.jpeg-decoder] version = "0.1.22" diff --git a/render/webgl/src/lib.rs b/render/webgl/src/lib.rs index 6ea000ae8..78add2273 100644 --- a/render/webgl/src/lib.rs +++ b/render/webgl/src/lib.rs @@ -1,3 +1,4 @@ +use bytemuck::{Pod, Zeroable}; use ruffle_core::backend::render::{ Bitmap, BitmapFormat, BitmapHandle, BitmapInfo, Color, MovieLibrary, RenderBackend, ShapeHandle, Transform, @@ -33,8 +34,8 @@ enum MaskState { ClearMaskStencil, } -#[derive(Clone, Debug)] #[repr(C)] +#[derive(Copy, Clone, Debug, Pod, Zeroable)] struct Vertex { position: [f32; 2], color: u32, @@ -256,49 +257,37 @@ impl WebGlRenderBackend { let vertex_buffer = self.gl.create_buffer().unwrap(); self.gl.bind_buffer(Gl::ARRAY_BUFFER, Some(&vertex_buffer)); + self.gl.buffer_data_with_u8_array( + Gl::ARRAY_BUFFER, + bytemuck::cast_slice(&[ + Vertex { + position: [0.0, 0.0], + color: 0xffff_ffff, + }, + Vertex { + position: [1.0, 0.0], + color: 0xffff_ffff, + }, + Vertex { + position: [1.0, 1.0], + color: 0xffff_ffff, + }, + Vertex { + position: [0.0, 1.0], + color: 0xffff_ffff, + }, + ]), + Gl::STATIC_DRAW, + ); - let verts = [ - Vertex { - position: [0.0, 0.0], - color: 0xffff_ffff, - }, - Vertex { - position: [1.0, 0.0], - color: 0xffff_ffff, - }, - Vertex { - position: [1.0, 1.0], - color: 0xffff_ffff, - }, - Vertex { - position: [0.0, 1.0], - color: 0xffff_ffff, - }, - ]; - let (vertex_buffer, index_buffer) = unsafe { - let verts_bytes = std::slice::from_raw_parts( - verts.as_ptr() as *const u8, - std::mem::size_of_val(&verts), - ); - self.gl - .buffer_data_with_u8_array(Gl::ARRAY_BUFFER, verts_bytes, Gl::STATIC_DRAW); - - let index_buffer = self.gl.create_buffer().unwrap(); - self.gl - .bind_buffer(Gl::ELEMENT_ARRAY_BUFFER, Some(&index_buffer)); - let indices = [0u32, 1, 2, 0, 2, 3]; - let indices_bytes = std::slice::from_raw_parts( - indices.as_ptr() as *const u8, - std::mem::size_of::() * indices.len(), - ); - self.gl.buffer_data_with_u8_array( - Gl::ELEMENT_ARRAY_BUFFER, - indices_bytes, - Gl::STATIC_DRAW, - ); - - (vertex_buffer, index_buffer) - }; + let index_buffer = self.gl.create_buffer().unwrap(); + self.gl + .bind_buffer(Gl::ELEMENT_ARRAY_BUFFER, Some(&index_buffer)); + self.gl.buffer_data_with_u8_array( + Gl::ELEMENT_ARRAY_BUFFER, + bytemuck::cast_slice(&[0u32, 1, 2, 0, 2, 3]), + Gl::STATIC_DRAW, + ); if program.vertex_position_location != 0xffff_ffff { self.gl.vertex_attrib_pointer_with_i32( @@ -511,29 +500,21 @@ impl WebGlRenderBackend { let vertex_buffer = self.gl.create_buffer().unwrap(); self.gl.bind_buffer(Gl::ARRAY_BUFFER, Some(&vertex_buffer)); - let (vertex_buffer, index_buffer) = unsafe { - let vertices: Vec<_> = draw.vertices.into_iter().map(Vertex::from).collect(); - let verts_bytes = std::slice::from_raw_parts( - vertices.as_ptr() as *const u8, - vertices.len() * std::mem::size_of::(), - ); - self.gl - .buffer_data_with_u8_array(Gl::ARRAY_BUFFER, verts_bytes, Gl::STATIC_DRAW); + let vertices: Vec<_> = draw.vertices.into_iter().map(Vertex::from).collect(); + self.gl.buffer_data_with_u8_array( + Gl::ARRAY_BUFFER, + bytemuck::cast_slice(&vertices), + Gl::STATIC_DRAW, + ); - let index_buffer = self.gl.create_buffer().unwrap(); - self.gl - .bind_buffer(Gl::ELEMENT_ARRAY_BUFFER, Some(&index_buffer)); - let indices_bytes = std::slice::from_raw_parts( - draw.indices.as_ptr() as *const u8, - draw.indices.len() * std::mem::size_of::(), - ); - self.gl.buffer_data_with_u8_array( - Gl::ELEMENT_ARRAY_BUFFER, - indices_bytes, - Gl::STATIC_DRAW, - ); - (vertex_buffer, index_buffer) - }; + let index_buffer = self.gl.create_buffer().unwrap(); + self.gl + .bind_buffer(Gl::ELEMENT_ARRAY_BUFFER, Some(&index_buffer)); + self.gl.buffer_data_with_u8_array( + Gl::ELEMENT_ARRAY_BUFFER, + bytemuck::cast_slice(&draw.indices), + Gl::STATIC_DRAW, + ); let program = match draw.draw_type { TessDrawType::Color => &self.color_program, @@ -1134,13 +1115,11 @@ impl RenderBackend for WebGlRenderBackend { gradient.gradient_type, ); program.uniform1fv(&self.gl, ShaderUniform::GradientRatios, &gradient.ratios); - let colors = unsafe { - std::slice::from_raw_parts( - gradient.colors[0].as_ptr(), - MAX_GRADIENT_COLORS * 4, - ) - }; - program.uniform4fv(&self.gl, ShaderUniform::GradientColors, &colors); + program.uniform4fv( + &self.gl, + ShaderUniform::GradientColors, + &bytemuck::cast_slice(&gradient.colors), + ); program.uniform1i( &self.gl, ShaderUniform::GradientNumColors, @@ -1565,7 +1544,7 @@ impl ShaderProgram { gl.uniform_matrix3fv_with_f32_array( self.uniforms[uniform as usize].as_ref(), false, - unsafe { std::slice::from_raw_parts(values[0].as_ptr(), 9) }, + bytemuck::cast_slice(values), ); } @@ -1573,7 +1552,7 @@ impl ShaderProgram { gl.uniform_matrix4fv_with_f32_array( self.uniforms[uniform as usize].as_ref(), false, - unsafe { std::slice::from_raw_parts(values[0].as_ptr(), 16) }, + bytemuck::cast_slice(values), ); } }