diff options
author | tcmal <me@aria.rip> | 2024-08-25 17:44:24 +0100 |
---|---|---|
committer | tcmal <me@aria.rip> | 2024-08-25 17:44:24 +0100 |
commit | 3b21e4c9d1d72a2ba71e4e4c1a2f60fb51f67205 (patch) | |
tree | cb83a9aae70b397c8e5504f889d71787e7f99f18 /stockton-skeleton | |
parent | 9b4edc67d315a640a9d22f84919b0dd81e201f1d (diff) |
fix(render): handle_surface_change
Diffstat (limited to 'stockton-skeleton')
-rw-r--r-- | stockton-skeleton/src/draw_passes/cons.rs | 22 | ||||
-rw-r--r-- | stockton-skeleton/src/draw_passes/mod.rs | 8 | ||||
-rw-r--r-- | stockton-skeleton/src/lib.rs | 14 |
3 files changed, 32 insertions, 12 deletions
diff --git a/stockton-skeleton/src/draw_passes/cons.rs b/stockton-skeleton/src/draw_passes/cons.rs index 51c06a6..dea42af 100644 --- a/stockton-skeleton/src/draw_passes/cons.rs +++ b/stockton-skeleton/src/draw_passes/cons.rs @@ -32,12 +32,26 @@ macro_rules! cons_shared_impl { } fn handle_surface_change( - &mut self, + mut self, session: &Session, context: &mut RenderingContext, - ) -> Result<()> { - self.a.handle_surface_change(session, context)?; - self.b.handle_surface_change(session, context) + ) -> Result<Self> { + match self.a.handle_surface_change(session, context) { + Ok(a) => self.a = a, + Err(e) => { + self.b.deactivate(context)?; + return Err(e); + } + } + match self.b.handle_surface_change(session, context) { + Ok(b) => self.b = b, + Err(e) => { + self.a.deactivate(context)?; + return Err(e); + } + } + + Ok(self) } }; } diff --git a/stockton-skeleton/src/draw_passes/mod.rs b/stockton-skeleton/src/draw_passes/mod.rs index cdc983f..5b138c2 100644 --- a/stockton-skeleton/src/draw_passes/mod.rs +++ b/stockton-skeleton/src/draw_passes/mod.rs @@ -27,11 +27,15 @@ pub trait DrawPass<P: PassPosition> { ) -> Result<()>; /// Called just after the surface changes (probably a resize). + /// This takes ownership and returns itself to ensure that the `DrawPass` is not called again if it fails. + /// This means you should deactivate as much as possible in case of an error. fn handle_surface_change( - &mut self, + self, session: &Session, context: &mut RenderingContext, - ) -> Result<()>; + ) -> Result<Self> + where + Self: Sized; /// Deactivate any vulkan parts that need to be deactivated fn deactivate(self, context: &mut RenderingContext) -> Result<()>; diff --git a/stockton-skeleton/src/lib.rs b/stockton-skeleton/src/lib.rs index 6260753..2b6fe70 100644 --- a/stockton-skeleton/src/lib.rs +++ b/stockton-skeleton/src/lib.rs @@ -35,7 +35,7 @@ pub struct Renderer<DP> { context: ManuallyDrop<RenderingContext>, /// The draw pass we're using - draw_pass: DP, + draw_pass: ManuallyDrop<DP>, } impl<DP: DrawPass<Singular>> Renderer<DP> { @@ -54,7 +54,7 @@ impl<DP: DrawPass<Singular>> Renderer<DP> { Ok(Renderer { context: ManuallyDrop::new(context), - draw_pass, + draw_pass: ManuallyDrop::new(draw_pass), }) } @@ -65,7 +65,7 @@ impl<DP: DrawPass<Singular>> Renderer<DP> { // Hence, we can always take from the ManuallyDrop unsafe { match ManuallyDrop::take(&mut self.context) - .draw_next_frame(session, &mut self.draw_pass) + .draw_next_frame(session, &mut *self.draw_pass) { Ok(c) => { self.context = ManuallyDrop::new(c); @@ -74,7 +74,7 @@ impl<DP: DrawPass<Singular>> Renderer<DP> { Err((_e, c)) => { // TODO: Try to detect if the error is actually surface related. let c = c.attempt_recovery()?; - match c.draw_next_frame(session, &mut self.draw_pass) { + match c.draw_next_frame(session, &mut *self.draw_pass) { Ok(c) => { self.context = ManuallyDrop::new(c); Ok(self) @@ -94,9 +94,11 @@ impl<DP: DrawPass<Singular>> Renderer<DP> { unsafe { let ctx = ManuallyDrop::take(&mut self.context).recreate_surface()?; self.context = ManuallyDrop::new(ctx); + + let dp = ManuallyDrop::take(&mut self.draw_pass) + .handle_surface_change(session, &mut self.context)?; + self.draw_pass = ManuallyDrop::new(dp); } - self.draw_pass - .handle_surface_change(session, &mut self.context)?; Ok(self) } |