ailloli_ui_render_wgpu/
error.rs

1//! GPU renderer errors.
2
3use thiserror::Error;
4
5/// Rejected input to [`crate::Renderer::record_layered_to_target_scaled`].
6///
7/// These failures are detected before the encoder, atlas, or stencil cache is
8/// changed. GPU validation failures (for example, a view from another device)
9/// are reported by wgpu instead. This separate error type leaves the published
10/// [`RendererError`] variants unchanged for existing exhaustive matches.
11///
12/// # Examples
13///
14/// ```
15/// use ailloli_ui_render_wgpu::TargetRecordingError;
16/// let error = TargetRecordingError::FrameTextureUnavailable;
17/// assert!(error.to_string().contains("backing texture"));
18/// ```
19#[derive(Debug, Error)]
20#[non_exhaustive]
21pub enum TargetRecordingError {
22    /// Dimensions, format, scale, or the supplied texture violate the contract.
23    ///
24    /// The diagnostic explains which check failed; its wording is not a stable
25    /// identifier. Match the variant, not the diagnostic string.
26    #[error("wgpu: invalid borrowed render target: {0}")]
27    InvalidRenderTarget(&'static str),
28    /// A backdrop filter or destination blend needs the backing texture.
29    ///
30    /// Supply the texture corresponding to the view, with `COPY_SRC` usage.
31    #[error("wgpu: borrowed target requires a backing texture for destination effects")]
32    FrameTextureUnavailable,
33}
34
35/// Failure during adapter/device setup, surface configuration, or capture readback.
36///
37/// # Examples
38///
39/// ```
40/// use ailloli_ui_render_wgpu::RendererError;
41/// let error = RendererError::SurfaceAcquireTimeout;
42/// assert!(error.to_string().contains("Timeout"));
43/// ```
44#[derive(Debug, Error)]
45pub enum RendererError {
46    /// No adapter matching the requested backend and surface was available.
47    #[error("wgpu: request adapter failed")]
48    RequestAdapterFailed,
49    /// Device creation failed; the string contains wgpu's diagnostic.
50    #[error("wgpu: request device failed: {0}")]
51    RequestDeviceFailed(String),
52    /// The surface returned no usable capabilities for the named property.
53    #[error("wgpu: surface capabilities unavailable: {0}")]
54    SurfaceCapabilitiesUnavailable(&'static str),
55    /// A surface configuration could not be constructed.
56    #[error("wgpu: surface configuration failed")]
57    SurfaceConfigFailed,
58    /// The current renderer pipelines cannot be reused with the surface's new
59    /// preferred format. The presentation adapter must rebuild the renderer.
60    #[error("wgpu: surface presentation must be recreated: {0}")]
61    SurfaceRecreationRequired(&'static str),
62    /// No compatible adapter succeeded at `Surface::configure` (wgpu 0.20 may panic instead of returning an error).
63    #[error("wgpu: surface configure failed for every compatible adapter (try WGPU_BACKEND=gl or WINIT_UNIX_BACKEND=x11)")]
64    SurfaceConfigureExhausted,
65    /// Capture was requested from a format not handled by the RGBA readback path.
66    #[error("wgpu: capture unsupported surface format: {0:?}")]
67    CaptureUnsupportedFormat(wgpu::TextureFormat),
68    /// Mapping the GPU capture buffer failed.
69    #[error("wgpu: capture mapping failed: {0}")]
70    CaptureMapFailed(String),
71    /// A render target exposed only a view where a backing texture was required.
72    #[error("wgpu: frame texture unavailable for this render target")]
73    FrameTextureUnavailable,
74    /// The requested renderer mode has no compatible render target.
75    #[error("ailloli_ui: render target unavailable for this renderer mode ({0})")]
76    RenderTargetUnavailable(&'static str),
77    /// Frame acquisition failed with an untyped host diagnostic.
78    #[error("wgpu: failed to acquire current frame: {0}")]
79    SurfaceAcquireFailed(String),
80    /// Surface acquisition timed out; hosts may skip and retry a later frame.
81    #[error("wgpu: failed to acquire current frame: Timeout")]
82    SurfaceAcquireTimeout,
83    /// The surface was lost and should be recreated or reconfigured.
84    #[error("wgpu: failed to acquire current frame: Lost")]
85    SurfaceAcquireLost,
86    /// The surface is outdated and should be reconfigured before retrying.
87    #[error("wgpu: failed to acquire current frame: Outdated")]
88    SurfaceAcquireOutdated,
89    /// The GPU cannot allocate the frame; callers should terminate rendering.
90    #[error("wgpu: failed to acquire current frame: OutOfMemory")]
91    SurfaceAcquireOutOfMemory,
92    /// The surface exists but is not ready, commonly because one axis is zero.
93    #[error("wgpu: surface is not ready: {0}")]
94    SurfaceNotReady(String),
95}
96
97impl RendererError {
98    /// Converts wgpu's typed acquisition failure without string parsing.
99    ///
100    /// # Examples
101    ///
102    /// ```
103    /// use ailloli_ui_render_wgpu::RendererError;
104    /// let error = RendererError::from_surface_error(wgpu::SurfaceError::Lost);
105    /// assert!(matches!(error, RendererError::SurfaceAcquireLost));
106    /// ```
107    pub fn from_surface_error(error: wgpu::SurfaceError) -> Self {
108        match error {
109            wgpu::SurfaceError::Timeout => Self::SurfaceAcquireTimeout,
110            wgpu::SurfaceError::Lost => Self::SurfaceAcquireLost,
111            wgpu::SurfaceError::Outdated => Self::SurfaceAcquireOutdated,
112            wgpu::SurfaceError::OutOfMemory => Self::SurfaceAcquireOutOfMemory,
113        }
114    }
115}
116
117#[cfg(test)]
118/// Verifies typed surface-acquisition error conversion.
119mod tests {
120    use super::*;
121
122    #[test]
123    fn surface_acquire_errors_are_typed_without_string_parsing() {
124        assert!(matches!(
125            RendererError::from_surface_error(wgpu::SurfaceError::Timeout),
126            RendererError::SurfaceAcquireTimeout
127        ));
128        assert!(matches!(
129            RendererError::from_surface_error(wgpu::SurfaceError::Lost),
130            RendererError::SurfaceAcquireLost
131        ));
132        assert!(matches!(
133            RendererError::from_surface_error(wgpu::SurfaceError::Outdated),
134            RendererError::SurfaceAcquireOutdated
135        ));
136        assert!(matches!(
137            RendererError::from_surface_error(wgpu::SurfaceError::OutOfMemory),
138            RendererError::SurfaceAcquireOutOfMemory
139        ));
140    }
141}