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 {}