Skip to content

Commit

Permalink
WGPU: Changed flush_to_surface() to return a command buffer
Browse files Browse the repository at this point in the history
This allows the application to control when to submit.

Fixes femtovg#227
  • Loading branch information
tronical committed Dec 30, 2024
1 parent 33eeb09 commit 08a11bd
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 7 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Changelog
All notable changes to this project will be documented in this file.

## UNRELEASED

- WGPU renderer: Changed `flush_to_surface()` API to return a command buffer,
to let the application decide when to submit.

## [0.11.3] - 2024-12-26

- WGPU renderer: Fix crash when rendering without always calling `set_size()`. (#226)
Expand Down
10 changes: 8 additions & 2 deletions examples/helpers/wgpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use super::{run, WindowSurface};

pub struct DemoSurface {
device: Arc<wgpu::Device>,
queue: Arc<wgpu::Queue>,
surface_config: wgpu::SurfaceConfiguration,
surface: wgpu::Surface<'static>,
}
Expand All @@ -26,7 +27,9 @@ impl WindowSurface for DemoSurface {
.get_current_texture()
.expect("unable to get next texture from swapchain");

canvas.flush_to_surface(&frame.texture);
let commands = canvas.flush_to_surface(&frame.texture);

self.queue.submit(Some(commands));

frame.present();
}
Expand Down Expand Up @@ -131,13 +134,16 @@ pub async fn start_wgpu(

let device = Arc::new(device);

let queue = Arc::new(queue);

let demo_surface = DemoSurface {
device: device.clone(),
queue: queue.clone(),
surface_config,
surface,
};

let renderer = WGPURenderer::new(device, Arc::new(queue));
let renderer = WGPURenderer::new(device, queue);

let mut canvas = Canvas::new(renderer).expect("Cannot create canvas");
canvas.set_size(width, height, window.scale_factor() as f32);
Expand Down
6 changes: 4 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,8 +418,8 @@ where
/// Tells the renderer to execute all drawing commands and clears the current internal state
///
/// Call this at the end of each frame.
pub fn flush_to_surface(&mut self, surface: &T::Surface) {
self.renderer.render(
pub fn flush_to_surface(&mut self, surface: &T::Surface) -> T::CommandBuffer {
let command_buffer = self.renderer.render(
surface,
&mut self.images,
&self.verts,
Expand All @@ -431,6 +431,7 @@ where
if let Some(atlas) = self.ephemeral_glyph_atlas.take() {
atlas.clear(self);
}
command_buffer
}

/// Returns a screenshot of the current canvas.
Expand Down Expand Up @@ -1536,6 +1537,7 @@ impl Renderer for RecordingRenderer {
type Image = DummyImage;
type NativeTexture = ();
type Surface = ();
type CommandBuffer = ();

fn set_size(&mut self, _width: u32, _height: u32, _dpi: f32) {}

Expand Down
5 changes: 4 additions & 1 deletion src/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ pub trait Renderer {
/// Associated surface type.
type Surface;

/// Associated type to hold commands created via flush_to_surface.
type CommandBuffer;

/// Set the size of the renderer.
fn set_size(&mut self, width: u32, height: u32, dpi: f32);

Expand All @@ -134,7 +137,7 @@ pub trait Renderer {
images: &mut ImageStore<Self::Image>,
verts: &[Vertex],
commands: Vec<Command>,
);
) -> Self::CommandBuffer;

/// Allocate a new image with the specified image info.
fn alloc_image(&mut self, info: ImageInfo) -> Result<Self::Image, ErrorKind>;
Expand Down
1 change: 1 addition & 0 deletions src/renderer/opengl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,7 @@ impl Renderer for OpenGl {
type Image = GlTexture;
type NativeTexture = <glow::Context as glow::HasContext>::Texture;
type Surface = ();
type CommandBuffer = ();

fn set_size(&mut self, width: u32, height: u32, _dpi: f32) {
self.view[0] = width as f32;
Expand Down
1 change: 1 addition & 0 deletions src/renderer/void.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ impl Renderer for Void {
type Image = VoidImage;
type NativeTexture = ();
type Surface = ();
type CommandBuffer = ();

fn set_size(&mut self, width: u32, height: u32, dpi: f32) {}

Expand Down
7 changes: 5 additions & 2 deletions src/renderer/wgpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ impl Renderer for WGPURenderer {
type Image = Image;
type NativeTexture = wgpu::Texture;
type Surface = wgpu::Texture;
type CommandBuffer = wgpu::CommandBuffer;

fn set_size(&mut self, _width: u32, _height: u32, _dpi: f32) {}

Expand All @@ -301,7 +302,7 @@ impl Renderer for WGPURenderer {
images: &mut crate::image::ImageStore<Self::Image>,
verts: &[super::Vertex],
commands: Vec<super::Command>,
) {
) -> Self::CommandBuffer {
self.screen_view[0] = surface_texture.width() as f32;
self.screen_view[1] = surface_texture.height() as f32;

Expand Down Expand Up @@ -459,11 +460,13 @@ impl Renderer for WGPURenderer {

drop(render_pass_builder);

self.queue.submit(Some(encoder.finish()));
let command_buffer = encoder.finish();

self.pipeline_cache
.borrow_mut()
.retain(|_, cached_pipeline| std::mem::replace(&mut cached_pipeline.accessed, false));

command_buffer
}

fn alloc_image(&mut self, info: crate::ImageInfo) -> Result<Self::Image, crate::ErrorKind> {
Expand Down

0 comments on commit 08a11bd

Please sign in to comment.