rendy_resource/sampler/
cache.rs

1//! A cache to store and retrieve samplers
2
3use {
4    super::Sampler,
5    crate::escape::Handle,
6    rendy_core::hal::{image::SamplerDesc, Backend},
7    std::{
8        collections::hash_map::{Entry, HashMap},
9        ops::{Deref, DerefMut},
10    },
11};
12
13/// Sampler cache holds handlers to created samplers.
14#[derive(Debug)]
15pub struct SamplerCache<B: Backend> {
16    samplers: HashMap<SamplerDesc, Handle<Sampler<B>>>,
17}
18
19impl<B> Default for SamplerCache<B>
20where
21    B: Backend,
22{
23    fn default() -> Self {
24        SamplerCache {
25            samplers: HashMap::default(),
26        }
27    }
28}
29
30impl<B> SamplerCache<B>
31where
32    B: Backend,
33{
34    /// Get sampler with specified paramters.
35    /// Create new one using closure provided.
36    pub fn get(
37        &mut self,
38        info: SamplerDesc,
39        create: impl FnOnce() -> Result<Handle<Sampler<B>>, rendy_core::hal::device::AllocationError>,
40    ) -> Result<Handle<Sampler<B>>, rendy_core::hal::device::AllocationError> {
41        Ok(match self.samplers.entry(info) {
42            Entry::Occupied(occupied) => occupied.get().clone(),
43            Entry::Vacant(vacant) => {
44                let sampler = create()?;
45                vacant.insert(sampler).clone()
46            }
47        })
48    }
49
50    /// Get sampler with specified paramters.
51    /// Create new one using closure provided.
52    /// Does not lock for writing if sampler exists.
53    pub fn get_with_upgradable_lock<R, W, U>(
54        read: R,
55        upgrade: U,
56        info: SamplerDesc,
57        create: impl FnOnce() -> Result<Handle<Sampler<B>>, rendy_core::hal::device::AllocationError>,
58    ) -> Result<Handle<Sampler<B>>, rendy_core::hal::device::AllocationError>
59    where
60        R: Deref<Target = Self>,
61        W: DerefMut<Target = Self>,
62        U: FnOnce(R) -> W,
63    {
64        if let Some(sampler) = read.samplers.get(&info) {
65            return Ok(sampler.clone());
66        }
67        let sampler = create()?;
68        {
69            upgrade(read).samplers.insert(info, sampler.clone());
70        }
71        Ok(sampler)
72    }
73}