mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-02-18 01:43:27 +00:00
Safe error handling for swap chain
This commit is contained in:
parent
a753f578be
commit
314074d13c
@ -194,6 +194,7 @@ impl GlobalPlay for wgc::hub::Global<IdentityPassThroughFactory> {
|
||||
A::GetSwapChainTexture { id, parent_id } => {
|
||||
if let Some(id) = id {
|
||||
self.swap_chain_get_current_texture_view::<B>(parent_id, id)
|
||||
.unwrap()
|
||||
.view_id
|
||||
.unwrap();
|
||||
}
|
||||
|
@ -41,7 +41,11 @@ use crate::{
|
||||
resource, span, LifeGuard, PrivateFeatures, Stored, SubmissionIndex,
|
||||
};
|
||||
|
||||
use hal::{self, device::Device as _, queue::CommandQueue as _, window::PresentationSurface as _};
|
||||
use hal::{
|
||||
self, device::Device as _, queue::CommandQueue as _, window::PresentError,
|
||||
window::PresentationSurface as _,
|
||||
};
|
||||
use thiserror::Error;
|
||||
use wgt::{SwapChainDescriptor, SwapChainStatus};
|
||||
|
||||
const FRAME_TIMEOUT_MS: u64 = 1000;
|
||||
@ -104,7 +108,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
swap_chain_id: SwapChainId,
|
||||
view_id_in: Input<G, TextureViewId>,
|
||||
) -> SwapChainOutput {
|
||||
) -> Result<SwapChainOutput, SwapChainError> {
|
||||
span!(_guard, INFO, "SwapChain::get_next_texture");
|
||||
|
||||
let hub = B::hub(self);
|
||||
@ -135,7 +139,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
),
|
||||
};
|
||||
|
||||
let view_id = image.map(|image| {
|
||||
let view_id = image
|
||||
.map(|image| {
|
||||
let view = resource::TextureView {
|
||||
inner: resource::TextureViewInner::SwapChain {
|
||||
image,
|
||||
@ -164,18 +169,18 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
.texture_views
|
||||
.register_identity(view_id_in, view, &mut token);
|
||||
|
||||
assert!(
|
||||
sc.acquired_view_id.is_none(),
|
||||
"Swap chain image is already acquired"
|
||||
);
|
||||
if sc.acquired_view_id.is_some() {
|
||||
return Err(SwapChainError::AlreadyAcquired);
|
||||
}
|
||||
|
||||
sc.acquired_view_id = Some(Stored {
|
||||
value: id,
|
||||
ref_count,
|
||||
});
|
||||
|
||||
id
|
||||
});
|
||||
Ok(id)
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
match device.trace {
|
||||
@ -186,10 +191,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
None => (),
|
||||
};
|
||||
|
||||
SwapChainOutput { status, view_id }
|
||||
Ok(SwapChainOutput { status, view_id })
|
||||
}
|
||||
|
||||
pub fn swap_chain_present<B: GfxBackend>(&self, swap_chain_id: SwapChainId) {
|
||||
pub fn swap_chain_present<B: GfxBackend>(
|
||||
&self,
|
||||
swap_chain_id: SwapChainId,
|
||||
) -> Result<(), SwapChainError> {
|
||||
span!(_guard, INFO, "SwapChain::present");
|
||||
|
||||
let hub = B::hub(self);
|
||||
@ -211,24 +219,21 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let view_id = sc
|
||||
.acquired_view_id
|
||||
.take()
|
||||
.expect("Swap chain image is not acquired");
|
||||
.ok_or(SwapChainError::AlreadyAcquired)?;
|
||||
let (view, _) = hub.texture_views.unregister(view_id.value, &mut token);
|
||||
let image = match view.inner {
|
||||
resource::TextureViewInner::Native { .. } => unreachable!(),
|
||||
resource::TextureViewInner::SwapChain { image, .. } => image,
|
||||
};
|
||||
|
||||
let err = {
|
||||
let sem = if sc.active_submission_index > device.last_completed_submission_index() {
|
||||
Some(&sc.semaphore)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let queue = &mut device.queue_group.queues[0];
|
||||
unsafe { queue.present_surface(B::get_surface_mut(surface), image, sem) }
|
||||
};
|
||||
if let Err(e) = err {
|
||||
log::warn!("present failed: {:?}", e);
|
||||
unsafe {
|
||||
queue.present_surface(B::get_surface_mut(surface), image, sem)?;
|
||||
}
|
||||
|
||||
tracing::debug!(trace = true, "Presented. End of Frame");
|
||||
@ -238,5 +243,15 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
device.raw.destroy_framebuffer(fbo);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
pub enum SwapChainError {
|
||||
#[error("swap chain image is already acquired")]
|
||||
AlreadyAcquired,
|
||||
#[error(transparent)]
|
||||
PresentError(#[from] PresentError),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user