diff --git a/render-wasm/src/render.rs b/render-wasm/src/render.rs index e7e77db65..094c2f912 100644 --- a/render-wasm/src/render.rs +++ b/render-wasm/src/render.rs @@ -178,7 +178,7 @@ impl RenderState { self.viewbox.set_wh(width as f32, height as f32); } - pub fn flush(&mut self) { + pub fn flush_and_submit(&mut self) { self.surfaces .flush_and_submit(&mut self.gpu_state, SurfaceId::Target); } @@ -208,8 +208,6 @@ impl RenderState { pub fn apply_drawing_to_render_canvas(&mut self, shape: Option<&Shape>) { performance::begin_measure!("apply_drawing_to_render_canvas"); - self.surfaces - .flush_and_submit(&mut self.gpu_state, SurfaceId::DropShadows); self.surfaces.draw_into( SurfaceId::DropShadows, @@ -217,9 +215,6 @@ impl RenderState { Some(&skia::Paint::default()), ); - self.surfaces - .flush_and_submit(&mut self.gpu_state, SurfaceId::Fills); - self.surfaces.draw_into( SurfaceId::Fills, SurfaceId::Current, @@ -232,9 +227,6 @@ impl RenderState { } if render_overlay_below_strokes { - self.surfaces - .flush_and_submit(&mut self.gpu_state, SurfaceId::InnerShadows); - self.surfaces.draw_into( SurfaceId::InnerShadows, SurfaceId::Current, @@ -242,9 +234,6 @@ impl RenderState { ); } - self.surfaces - .flush_and_submit(&mut self.gpu_state, SurfaceId::Strokes); - self.surfaces.draw_into( SurfaceId::Strokes, SurfaceId::Current, @@ -252,9 +241,6 @@ impl RenderState { ); if !render_overlay_below_strokes { - self.surfaces - .flush_and_submit(&mut self.gpu_state, SurfaceId::InnerShadows); - self.surfaces.draw_into( SurfaceId::InnerShadows, SurfaceId::Current, @@ -262,9 +248,6 @@ impl RenderState { ); } - self.surfaces - .flush_and_submit(&mut self.gpu_state, SurfaceId::Current); - self.surfaces.apply_mut( &[ SurfaceId::DropShadows, @@ -504,7 +487,7 @@ impl RenderState { performance::begin_measure!("process_animation_frame"); if self.render_in_progress { self.render_shape_tree(tree, modifiers, structure, timestamp)?; - self.flush(); + self.flush_and_submit(); if self.render_in_progress { if let Some(frame_id) = self.render_request_id { @@ -814,7 +797,6 @@ impl RenderState { } debug::render_wasm_label(self); - self.flush(); Ok(()) } diff --git a/render-wasm/src/render/gpu_state.rs b/render-wasm/src/render/gpu_state.rs index 9c1b87f28..6d2ff87d0 100644 --- a/render-wasm/src/render/gpu_state.rs +++ b/render-wasm/src/render/gpu_state.rs @@ -1,5 +1,5 @@ -use skia_safe as skia; -use skia_safe::gpu::{self, gl::FramebufferInfo, DirectContext}; +use skia_safe::gpu::{self, gl::FramebufferInfo, gl::TextureInfo, DirectContext}; +use skia_safe::{self as skia, ISize, Surface, SurfaceProps, SurfacePropsFlags}; pub struct GpuState { pub context: DirectContext, @@ -27,6 +27,67 @@ impl GpuState { } } + fn create_webgl_texture(&mut self, width: i32, height: i32) -> gl::types::GLuint { + let mut texture_id: gl::types::GLuint = 0; + + unsafe { + gl::GenTextures(1, &mut texture_id); + gl::BindTexture(gl::TEXTURE_2D, texture_id); + + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR as i32); + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as i32); + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as i32); + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as i32); + + gl::TexImage2D( + gl::TEXTURE_2D, + 0, + gl::RGBA8 as i32, + width, + height, + 0, + gl::RGBA, + gl::UNSIGNED_BYTE, + std::ptr::null(), + ); + } + + texture_id + } + + pub fn create_surface_with_isize(&mut self, label: String, size: ISize) -> skia::Surface { + self.create_surface_with_dimensions(label, size.width, size.height) + } + + pub fn create_surface_with_dimensions( + &mut self, + label: String, + width: i32, + height: i32, + ) -> skia::Surface { + let backend_texture = unsafe { + let texture_id = self.create_webgl_texture(width, height); + let texture_info = TextureInfo { + target: gl::TEXTURE_2D, + id: texture_id, + format: gl::RGBA8, + protected: skia::gpu::Protected::No, + }; + gpu::backend_textures::make_gl((width, height), gpu::Mipmapped::No, texture_info, label) + }; + + gpu::surfaces::wrap_backend_texture( + &mut self.context, + &backend_texture, + gpu::SurfaceOrigin::BottomLeft, + None, + skia::ColorType::RGBA8888, + None, + None, + ) + .unwrap() + } + /// Create a Skia surface that will be used for rendering. pub fn create_target_surface(&mut self, width: i32, height: i32) -> skia::Surface { let backend_render_target = diff --git a/render-wasm/src/render/surfaces.rs b/render-wasm/src/render/surfaces.rs index a1c2cb02c..09fad9ef9 100644 --- a/render-wasm/src/render/surfaces.rs +++ b/render-wasm/src/render/surfaces.rs @@ -59,13 +59,18 @@ impl Surfaces { ); let margins = skia::ISize::new(extra_tile_dims.width / 4, extra_tile_dims.height / 4); - let mut target = gpu_state.create_target_surface(width, height); - let current = target.new_surface_with_dimensions(extra_tile_dims).unwrap(); - let drop_shadows = target.new_surface_with_dimensions(extra_tile_dims).unwrap(); - let inner_shadows = target.new_surface_with_dimensions(extra_tile_dims).unwrap(); - let shape_fills = target.new_surface_with_dimensions(extra_tile_dims).unwrap(); - let shape_strokes = target.new_surface_with_dimensions(extra_tile_dims).unwrap(); - let debug = target.new_surface_with_dimensions((width, height)).unwrap(); + let target = gpu_state.create_target_surface(width, height); + + let current = gpu_state.create_surface_with_isize("current".to_string(), extra_tile_dims); + let drop_shadows = + gpu_state.create_surface_with_isize("drop_shadows".to_string(), extra_tile_dims); + let inner_shadows = + gpu_state.create_surface_with_isize("inner_shadows".to_string(), extra_tile_dims); + let shape_fills = + gpu_state.create_surface_with_isize("shape_fills".to_string(), extra_tile_dims); + let shape_strokes = + gpu_state.create_surface_with_isize("shape_strokes".to_string(), extra_tile_dims); + let debug = gpu_state.create_surface_with_dimensions("debug".to_string(), width, height); let tiles = TileTextureCache::new(); Surfaces {