Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions crates/anyrender_vello/src/window_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use vello::{
AaConfig, AaSupport, RenderParams, Renderer as VelloRenderer, RendererOptions,
Scene as VelloScene,
};
use wgpu::{Features, Limits, PresentMode, TextureFormat, TextureUsages};
use wgpu::{Features, Limits, PresentMode, SurfaceError, TextureFormat, TextureUsages};
use wgpu_context::{
DeviceHandle, SurfaceRenderer, SurfaceRendererConfiguration, TextureConfiguration, WGPUContext,
};
Expand Down Expand Up @@ -207,7 +207,19 @@ impl WindowRenderer for VelloWindowRenderer {
});
timer.record_time("cmd");

let texture_view = render_surface.target_texture_view();
match render_surface.ensure_current_surface_texture() {
Ok(_) => {}
Err(SurfaceError::Timeout | SurfaceError::Lost | SurfaceError::Outdated) => {
render_surface.clear_surface_texture();
return;
}
Err(SurfaceError::OutOfMemory) => panic!("Out of memory"),
Err(SurfaceError::Other) => panic!("Unknown error getting surface"),
};

let texture_view = render_surface
.target_texture_view()
.expect("handled errorss from ensure_current_surface_texture above");
state
.renderer
.render_to_texture(
Expand All @@ -227,7 +239,9 @@ impl WindowRenderer for VelloWindowRenderer {

drop(texture_view);

render_surface.maybe_blit_and_present();
render_surface
.maybe_blit_and_present()
.expect("handled errorss from ensure_current_surface_texture above");
timer.record_time("present");

render_surface
Expand Down
20 changes: 17 additions & 3 deletions crates/anyrender_vello_hybrid/src/window_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use vello_hybrid::{
RenderSettings, RenderSize, RenderTargetConfig, Renderer as VelloHybridRenderer,
Scene as VelloHybridScene,
};
use wgpu::{CommandEncoderDescriptor, Features, Limits, PresentMode, TextureFormat};
use wgpu::{CommandEncoderDescriptor, Features, Limits, PresentMode, SurfaceError, TextureFormat};
use wgpu_context::{DeviceHandle, SurfaceRenderer, SurfaceRendererConfiguration, WGPUContext};

use crate::{VelloHybridScenePainter, scene::ImageManager};
Expand Down Expand Up @@ -226,7 +226,19 @@ impl WindowRenderer for VelloHybridWindowRenderer {
});
timer.record_time("cmd");

let texture_view = render_surface.target_texture_view();
match render_surface.ensure_current_surface_texture() {
Ok(_) => {}
Err(SurfaceError::Timeout | SurfaceError::Lost | SurfaceError::Outdated) => {
render_surface.clear_surface_texture();
return;
}
Err(SurfaceError::OutOfMemory) => panic!("Out of memory"),
Err(SurfaceError::Other) => panic!("Unknown error getting surface"),
};

let texture_view = render_surface
.target_texture_view()
.expect("handled errorss from ensure_current_surface_texture above");

state
.renderer
Expand All @@ -247,7 +259,9 @@ impl WindowRenderer for VelloHybridWindowRenderer {

drop(texture_view);

render_surface.maybe_blit_and_present();
render_surface
.maybe_blit_and_present()
.expect("handled errorss from ensure_current_surface_texture above");
timer.record_time("present");

render_surface
Expand Down
48 changes: 33 additions & 15 deletions crates/wgpu_context/src/surface_renderer.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{DeviceHandle, WgpuContextError, util::create_texture};
use wgpu::{
CommandEncoderDescriptor, CompositeAlphaMode, Device, PresentMode, Queue, Surface,
SurfaceConfiguration, SurfaceTexture, TextureFormat, TextureUsages, TextureView,
SurfaceConfiguration, SurfaceError, SurfaceTexture, TextureFormat, TextureUsages, TextureView,
TextureViewDescriptor, util::TextureBlitter,
};

Expand Down Expand Up @@ -86,7 +86,7 @@ pub struct SurfaceRenderer<'s> {
pub surface: Surface<'s>,
pub config: SurfaceConfiguration,

current_surface_texture: Option<SurfaceTexture>,
current_surface_texture: Option<Result<SurfaceTexture, SurfaceError>>,
intermediate_texture: Option<Box<IntermediateTextureStuff>>,
}

Expand Down Expand Up @@ -189,30 +189,46 @@ impl<'s> SurfaceRenderer<'s> {
.configure(&self.device_handle.device, &self.config);
}

fn ensure_current_surface_texture(&mut self) {
pub fn clear_surface_texture(&mut self) {
self.current_surface_texture = None;
}

pub fn ensure_current_surface_texture(&mut self) -> Result<(), SurfaceError> {
if self.current_surface_texture.is_none() {
self.current_surface_texture = Some(
let tex = self.surface.get_current_texture();
if let Err(SurfaceError::Lost | SurfaceError::Outdated) = &tex {
self.surface
.get_current_texture()
.expect("failed to get surface texture"),
);
.configure(&self.device_handle.device, &self.config);
}

self.current_surface_texture = Some(tex);
}

self.current_surface_texture
.as_ref()
.unwrap()
.as_ref()
.map(|_| ())
.map_err(|err| err.clone())
}

/// Get a target texture view to render to.
///
/// If there is an intermediate texture, this is a view of that intermediate texture, otherwise
/// it is a view of the surface texture.
pub fn target_texture_view(&mut self) -> TextureView {
pub fn target_texture_view(&mut self) -> Result<TextureView, SurfaceError> {
match &self.intermediate_texture {
Some(intermediate_texture) => intermediate_texture.texture_view.clone(),
Some(intermediate_texture) => Ok(intermediate_texture.texture_view.clone()),
None => {
self.ensure_current_surface_texture();
self.current_surface_texture
self.ensure_current_surface_texture()?;
Ok(self
.current_surface_texture
.as_ref()
.unwrap()
.as_ref()
.unwrap()
.texture
.create_view(&TextureViewDescriptor::default())
.create_view(&TextureViewDescriptor::default()))
}
}
}
Expand All @@ -222,15 +238,17 @@ impl<'s> SurfaceRenderer<'s> {
///
/// Prior to calling this, [`Self::target_texture_view`] must have been called and some
/// rendering work must have been scheduled to the resulting view.
pub fn maybe_blit_and_present(&mut self) {
self.ensure_current_surface_texture();
let surface_texture = self.current_surface_texture.take().unwrap();
pub fn maybe_blit_and_present(&mut self) -> Result<(), SurfaceError> {
self.ensure_current_surface_texture()?;
let surface_texture = self.current_surface_texture.take().unwrap().unwrap();

if let Some(its) = &self.intermediate_texture {
self.blit_from_intermediate_texture_to_surface(&surface_texture, its);
}

surface_texture.present();

Ok(())
}

/// Blit from the intermediate texture to the surface texture
Expand Down