Skip to content

Commit 0581433

Browse files
committed
Make anyrender fallible
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
1 parent 1fa1d03 commit 0581433

12 files changed

Lines changed: 217 additions & 123 deletions

File tree

crates/anyrender/src/lib.rs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,40 +43,54 @@ pub trait WindowRenderer {
4343
type ScenePainter<'a>: PaintScene
4444
where
4545
Self: 'a;
46-
fn resume(&mut self, window: Arc<dyn WindowHandle>, width: u32, height: u32);
46+
fn resume(
47+
&mut self,
48+
window: Arc<dyn WindowHandle>,
49+
width: u32,
50+
height: u32,
51+
) -> Result<(), Box<dyn std::error::Error>>;
4752
fn suspend(&mut self);
4853
fn is_active(&self) -> bool;
4954
fn set_size(&mut self, width: u32, height: u32);
50-
fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(&mut self, draw_fn: F);
55+
fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(
56+
&mut self,
57+
draw_fn: F,
58+
) -> Result<(), Box<dyn std::error::Error>>;
5159
}
5260

5361
/// Abstraction for rendering a scene to an image buffer
5462
pub trait ImageRenderer {
5563
type ScenePainter<'a>: PaintScene
5664
where
5765
Self: 'a;
58-
fn new(width: u32, height: u32) -> Self;
66+
fn new(width: u32, height: u32) -> Result<Self, Box<dyn std::error::Error>>
67+
where
68+
Self: Sized;
5969
fn resize(&mut self, width: u32, height: u32);
6070
fn reset(&mut self);
6171
fn render_to_vec<F: FnOnce(&mut Self::ScenePainter<'_>)>(
6272
&mut self,
6373
draw_fn: F,
6474
vec: &mut Vec<u8>,
65-
);
66-
fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(&mut self, draw_fn: F, buffer: &mut [u8]);
75+
) -> Result<(), Box<dyn std::error::Error>>;
76+
fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(
77+
&mut self,
78+
draw_fn: F,
79+
buffer: &mut [u8],
80+
) -> Result<(), Box<dyn std::error::Error>>;
6781
}
6882

6983
/// Draw a scene to a buffer using an `ImageRenderer`
7084
pub fn render_to_buffer<R: ImageRenderer, F: FnOnce(&mut R::ScenePainter<'_>)>(
7185
draw_fn: F,
7286
width: u32,
7387
height: u32,
74-
) -> Vec<u8> {
88+
) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
7589
let mut buf = Vec::with_capacity((width * height * 4) as usize);
76-
let mut renderer = R::new(width, height);
77-
renderer.render_to_vec(draw_fn, &mut buf);
90+
let mut renderer = R::new(width, height)?;
91+
renderer.render_to_vec(draw_fn, &mut buf)?;
7892

79-
buf
93+
Ok(buf)
8094
}
8195

8296
/// Abstraction for drawing a 2D scene

crates/anyrender/src/null_backend.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,14 @@ impl WindowRenderer for NullWindowRenderer {
2020
where
2121
Self: 'a;
2222

23-
fn resume(&mut self, _window: Arc<dyn WindowHandle>, _width: u32, _height: u32) {
23+
fn resume(
24+
&mut self,
25+
_window: Arc<dyn WindowHandle>,
26+
_width: u32,
27+
_height: u32,
28+
) -> Result<(), Box<dyn std::error::Error>> {
2429
self.is_active = true;
30+
Ok(())
2531
}
2632

2733
fn suspend(&mut self) {
@@ -34,7 +40,12 @@ impl WindowRenderer for NullWindowRenderer {
3440

3541
fn set_size(&mut self, _width: u32, _height: u32) {}
3642

37-
fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(&mut self, _draw_fn: F) {}
43+
fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(
44+
&mut self,
45+
_draw_fn: F,
46+
) -> Result<(), Box<dyn std::error::Error>> {
47+
Ok(())
48+
}
3849
}
3950

4051
#[derive(Copy, Clone, Default)]
@@ -52,8 +63,8 @@ impl ImageRenderer for NullImageRenderer {
5263
where
5364
Self: 'a;
5465

55-
fn new(_width: u32, _height: u32) -> Self {
56-
Self
66+
fn new(_width: u32, _height: u32) -> Result<Self, Box<dyn std::error::Error>> {
67+
Ok(Self)
5768
}
5869

5970
fn resize(&mut self, _width: u32, _height: u32) {}
@@ -64,10 +75,17 @@ impl ImageRenderer for NullImageRenderer {
6475
&mut self,
6576
_draw_fn: F,
6677
_vec: &mut Vec<u8>,
67-
) {
78+
) -> Result<(), Box<dyn std::error::Error>> {
79+
Ok(())
6880
}
6981

70-
fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(&mut self, _draw_fn: F, _buffer: &mut [u8]) {}
82+
fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(
83+
&mut self,
84+
_draw_fn: F,
85+
_buffer: &mut [u8],
86+
) -> Result<(), Box<dyn std::error::Error>> {
87+
Ok(())
88+
}
7189
}
7290

7391
#[derive(Copy, Clone, Default)]

crates/anyrender_skia/src/image_renderer.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ impl ImageRenderer for SkiaImageRenderer {
1616
where
1717
Self: 'a;
1818

19-
fn new(width: u32, height: u32) -> Self {
19+
fn new(width: u32, height: u32) -> Result<Self, Box<dyn std::error::Error>> {
2020
graphics::set_font_cache_count_limit(100);
2121
graphics::set_typeface_cache_count_limit(100);
2222
graphics::set_resource_cache_total_bytes_limit(10485760);
2323

24-
Self {
24+
Ok(Self {
2525
image_info: ImageInfo::new(
2626
(width as i32, height as i32),
2727
ColorType::RGBA8888,
@@ -30,7 +30,7 @@ impl ImageRenderer for SkiaImageRenderer {
3030
),
3131
surface_props: SurfaceProps::default(),
3232
scene_cache: SkiaSceneCache::default(),
33-
}
33+
})
3434
}
3535

3636
fn resize(&mut self, width: u32, height: u32) {
@@ -48,7 +48,7 @@ impl ImageRenderer for SkiaImageRenderer {
4848
&mut self,
4949
draw_fn: F,
5050
buffer: &mut Vec<u8>,
51-
) {
51+
) -> Result<(), Box<dyn std::error::Error>> {
5252
debug_timer!(timer, feature = "log_frame_times");
5353

5454
let mut surface = surfaces::wrap_pixels(
@@ -57,7 +57,7 @@ impl ImageRenderer for SkiaImageRenderer {
5757
None,
5858
Some(&self.surface_props),
5959
)
60-
.unwrap();
60+
.ok_or("Invalid surface parameters")?;
6161

6262
surface.canvas().clear(Color::WHITE);
6363

@@ -71,9 +71,14 @@ impl ImageRenderer for SkiaImageRenderer {
7171
timer.record_time("cache next gen");
7272

7373
timer.print_times("skia_raster: ");
74+
Ok(())
7475
}
7576

76-
fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(&mut self, draw_fn: F, buffer: &mut [u8]) {
77+
fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(
78+
&mut self,
79+
draw_fn: F,
80+
buffer: &mut [u8],
81+
) -> Result<(), Box<dyn std::error::Error>> {
7782
debug_timer!(timer, feature = "log_frame_times");
7883

7984
let mut surface = surfaces::wrap_pixels(
@@ -82,7 +87,7 @@ impl ImageRenderer for SkiaImageRenderer {
8287
None,
8388
Some(&self.surface_props),
8489
)
85-
.unwrap();
90+
.ok_or("Invalid surface parameters")?;
8691

8792
surface.canvas().clear(Color::WHITE);
8893

@@ -96,5 +101,6 @@ impl ImageRenderer for SkiaImageRenderer {
96101
timer.record_time("cache next gen");
97102

98103
timer.print_times("skia_raster: ");
104+
Ok(())
99105
}
100106
}

crates/anyrender_skia/src/window_renderer.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,12 @@ impl WindowRenderer for SkiaWindowRenderer {
4949
where
5050
Self: 'a;
5151

52-
fn resume(&mut self, window: Arc<dyn anyrender::WindowHandle>, width: u32, height: u32) {
52+
fn resume(
53+
&mut self,
54+
window: Arc<dyn anyrender::WindowHandle>,
55+
width: u32,
56+
height: u32,
57+
) -> Result<(), Box<dyn std::error::Error>> {
5358
graphics::set_font_cache_count_limit(100);
5459
graphics::set_typeface_cache_count_limit(100);
5560
graphics::set_resource_cache_total_bytes_limit(10485760);
@@ -62,7 +67,9 @@ impl WindowRenderer for SkiaWindowRenderer {
6267
self.render_state = RenderState::Active(Box::new(ActiveRenderState {
6368
backend: Box::new(backend),
6469
scene_cache: SkiaSceneCache::default(),
65-
}))
70+
}));
71+
72+
Ok(())
6673
}
6774

6875
fn suspend(&mut self) {
@@ -79,16 +86,19 @@ impl WindowRenderer for SkiaWindowRenderer {
7986
}
8087
}
8188

82-
fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(&mut self, draw_fn: F) {
89+
fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(
90+
&mut self,
91+
draw_fn: F,
92+
) -> Result<(), Box<dyn std::error::Error>> {
8393
let RenderState::Active(state) = &mut self.render_state else {
84-
return;
94+
return Ok(());
8595
};
8696

8797
debug_timer!(timer, feature = "log_frame_times");
8898

8999
let mut surface = match state.backend.prepare() {
90100
Some(it) => it,
91-
None => return,
101+
None => return Ok(()),
92102
};
93103

94104
surface.canvas().restore_to_count(1);
@@ -107,6 +117,7 @@ impl WindowRenderer for SkiaWindowRenderer {
107117
timer.record_time("cache next gen");
108118

109119
timer.print_times("skia: ");
120+
Ok(())
110121
}
111122
}
112123

crates/anyrender_vello/src/image_renderer.rs

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ impl ImageRenderer for VelloImageRenderer {
1818
where
1919
Self: 'a;
2020

21-
fn new(width: u32, height: u32) -> Self {
21+
fn new(width: u32, height: u32) -> Result<Self, Box<dyn std::error::Error>> {
2222
// Create WGPUContext
2323
let mut context = WGPUContext::new();
2424

@@ -28,8 +28,7 @@ impl ImageRenderer for VelloImageRenderer {
2828
width,
2929
height,
3030
usage: TextureUsages::STORAGE_BINDING,
31-
}))
32-
.expect("No compatible device found");
31+
}))?;
3332

3433
// Create vello::Renderer
3534
let vello_renderer = VelloRenderer::new(
@@ -40,14 +39,13 @@ impl ImageRenderer for VelloImageRenderer {
4039
antialiasing_support: vello::AaSupport::area_only(),
4140
pipeline_cache: None,
4241
},
43-
)
44-
.expect("Got non-Send/Sync error from creating renderer");
42+
)?;
4543

46-
Self {
44+
Ok(Self {
4745
buffer_renderer,
4846
vello_renderer,
4947
scene: VelloScene::new(),
50-
}
48+
})
5149
}
5250

5351
fn resize(&mut self, width: u32, height: u32) {
@@ -62,45 +60,43 @@ impl ImageRenderer for VelloImageRenderer {
6260
&mut self,
6361
draw_fn: F,
6462
cpu_buffer: &mut Vec<u8>,
65-
) {
63+
) -> Result<(), Box<dyn std::error::Error>> {
6664
let size = self.buffer_renderer.size();
6765
cpu_buffer.clear();
6866
cpu_buffer.reserve((size.width * size.height * 4) as usize);
69-
self.render(draw_fn, cpu_buffer);
67+
self.render(draw_fn, cpu_buffer)
7068
}
7169

7270
fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(
7371
&mut self,
7472
draw_fn: F,
7573
cpu_buffer: &mut [u8],
76-
) {
74+
) -> Result<(), Box<dyn std::error::Error>> {
7775
draw_fn(&mut VelloScenePainter {
7876
inner: &mut self.scene,
7977
renderer: Some(&mut self.vello_renderer),
8078
custom_paint_sources: Some(&mut FxHashMap::default()),
8179
});
8280

8381
let size = self.buffer_renderer.size();
84-
self.vello_renderer
85-
.render_to_texture(
86-
self.buffer_renderer.device(),
87-
self.buffer_renderer.queue(),
88-
&self.scene,
89-
&self.buffer_renderer.target_texture_view(),
90-
&vello::RenderParams {
91-
base_color: vello::peniko::Color::TRANSPARENT,
92-
width: size.width,
93-
height: size.height,
94-
antialiasing_method: vello::AaConfig::Area,
95-
},
96-
)
97-
.expect("Got non-Send/Sync error from rendering");
82+
self.vello_renderer.render_to_texture(
83+
self.buffer_renderer.device(),
84+
self.buffer_renderer.queue(),
85+
&self.scene,
86+
&self.buffer_renderer.target_texture_view(),
87+
&vello::RenderParams {
88+
base_color: vello::peniko::Color::TRANSPARENT,
89+
width: size.width,
90+
height: size.height,
91+
antialiasing_method: vello::AaConfig::Area,
92+
},
93+
)?;
9894

99-
self.buffer_renderer
100-
.copy_texture_to_buffer(cpu_buffer)
101-
.unwrap();
95+
self.buffer_renderer.copy_texture_to_buffer(cpu_buffer)?;
10296

10397
// Empty the Vello scene (memory optimisation)
10498
self.scene.reset();
99+
100+
Ok(())
105101
}
106102
}

0 commit comments

Comments
 (0)