wgpu/api/
surface_texture.rs

1use std::{error, fmt, thread};
2
3use crate::*;
4
5/// Surface texture that can be rendered to.
6/// Result of a successful call to [`Surface::get_current_texture`].
7///
8/// This type is unique to the Rust API of `wgpu`. In the WebGPU specification,
9/// the [`GPUCanvasContext`](https://gpuweb.github.io/gpuweb/#canvas-context) provides
10/// a texture without any additional information.
11#[derive(Debug, Clone)]
12pub struct SurfaceTexture {
13    /// Accessible view of the frame.
14    pub texture: Texture,
15    /// `true` if the acquired buffer can still be used for rendering,
16    /// but should be recreated for maximum performance.
17    pub suboptimal: bool,
18    pub(crate) presented: bool,
19    pub(crate) detail: dispatch::DispatchSurfaceOutputDetail,
20}
21#[cfg(send_sync)]
22static_assertions::assert_impl_all!(SurfaceTexture: Send, Sync);
23
24crate::cmp::impl_eq_ord_hash_proxy!(SurfaceTexture => .texture.inner);
25
26impl SurfaceTexture {
27    /// Schedule this texture to be presented on the owning surface.
28    ///
29    /// Needs to be called after any work on the texture is scheduled via [`Queue::submit`].
30    ///
31    /// # Platform dependent behavior
32    ///
33    /// On Wayland, `present` will attach a `wl_buffer` to the underlying `wl_surface` and commit the new surface
34    /// state. If it is desired to do things such as request a frame callback, scale the surface using the viewporter
35    /// or synchronize other double buffered state, then these operations should be done before the call to `present`.
36    pub fn present(mut self) {
37        self.presented = true;
38        self.detail.present();
39    }
40}
41
42impl Drop for SurfaceTexture {
43    fn drop(&mut self) {
44        if !self.presented && !thread::panicking() {
45            self.detail.texture_discard();
46        }
47    }
48}
49
50/// Result of an unsuccessful call to [`Surface::get_current_texture`].
51#[derive(Clone, PartialEq, Eq, Debug)]
52pub enum SurfaceError {
53    /// A timeout was encountered while trying to acquire the next frame.
54    Timeout,
55    /// The underlying surface has changed, and therefore the swap chain must be updated.
56    Outdated,
57    /// The swap chain has been lost and needs to be recreated.
58    Lost,
59    /// There is no more memory left to allocate a new frame.
60    OutOfMemory,
61    /// Acquiring a texture failed with a generic error. Check error callbacks for more information.
62    Other,
63}
64static_assertions::assert_impl_all!(SurfaceError: Send, Sync);
65
66impl fmt::Display for SurfaceError {
67    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68        write!(f, "{}", match self {
69            Self::Timeout => "A timeout was encountered while trying to acquire the next frame",
70            Self::Outdated => "The underlying surface has changed, and therefore the swap chain must be updated",
71            Self::Lost =>  "The swap chain has been lost and needs to be recreated",
72            Self::OutOfMemory => "There is no more memory left to allocate a new frame",
73            Self::Other => "Acquiring a texture failed with a generic error. Check error callbacks for more information",
74        })
75    }
76}
77
78impl error::Error for SurfaceError {}