# texture.rs - source
Source of the Rust file `maplibre/src/render/resource/texture.rs`.
Keywords: rust, rustlang, rust-lang

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110

    //! Utility for a texture view which can either be created by a [`TextureView`](wgpu::TextureView)
    //! or [`SurfaceTexture`](wgpu::SurfaceTexture)

    use crate::render::settings::Msaa;
    use crate::render::util::HasChanged;
    use std::ops::Deref;

    /// Describes a [`TextureView`].
    ///
    /// May be converted from a [`TextureView`](wgpu::TextureView) or [`SurfaceTexture`](wgpu::SurfaceTexture)
    /// or dereferences to a wgpu [`TextureView`](wgpu::TextureView).
    #[derive(Debug)]
    pub enum TextureView {
        /// The value is an actual wgpu [`TextureView`](wgpu::TextureView).
        TextureView(wgpu::TextureView),

        /// The value is a wgpu [`SurfaceTexture`](wgpu::SurfaceTexture), but dereferences to
        /// a [`TextureView`](wgpu::TextureView).
        SurfaceTexture {
            // NOTE: The order of these fields is important because the view must be dropped before the
            // frame is dropped
            view: wgpu::TextureView,
            texture: wgpu::SurfaceTexture,
        },
    }

    impl TextureView {
        /// Returns the [`SurfaceTexture`](wgpu::SurfaceTexture) of the texture view if it is of that type.
        #[inline]
        pub fn take_surface_texture(self) -> Option<wgpu::SurfaceTexture> {
            match self {
                TextureView::TextureView(_) => None,
                TextureView::SurfaceTexture { texture, .. } => Some(texture),
            }
        }
    }

    impl From<wgpu::TextureView> for TextureView {
        fn from(value: wgpu::TextureView) -> Self {
            TextureView::TextureView(value)
        }
    }

    impl From<wgpu::SurfaceTexture> for TextureView {
        fn from(surface_texture: wgpu::SurfaceTexture) -> Self {
            let view = surface_texture.texture.create_view(&Default::default());

            TextureView::SurfaceTexture {
                texture: surface_texture,
                view,
            }
        }
    }

    impl Deref for TextureView {
        type Target = wgpu::TextureView;

        #[inline]
        fn deref(&self) -> &Self::Target {
            match &self {
                TextureView::TextureView(value) => value,
                TextureView::SurfaceTexture { view, .. } => view,
            }
        }
    }

    pub struct Texture {
        pub size: (u32, u32),
        pub texture: wgpu::Texture,
        pub view: TextureView,
    }

    impl Texture {
        pub fn new(
            label: wgpu::Label,
            device: &wgpu::Device,
            format: wgpu::TextureFormat,
            width: u32,
            height: u32,
            msaa: Msaa,
        ) -> Texture {
            let texture = device.create_texture(&wgpu::TextureDescriptor {
                label,
                size: wgpu::Extent3d {
                    width,
                    height,
                    depth_or_array_layers: 1,
                },
                mip_level_count: 1,
                sample_count: msaa.samples,
                dimension: wgpu::TextureDimension::D2,
                format,
                usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
            });
            let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
            Self {
                size: (width, height),
                texture,
                view: TextureView::TextureView(view),
            }
        }
    }

    impl HasChanged for Texture {
        type Criteria = (u32, u32);

        fn has_changed(&self, criteria: &Self::Criteria) -> bool {
            !self.size.eq(criteria)
        }
    }