xref: /aosp_15_r20/external/mesa3d/src/gallium/frontends/rusticl/mesa/util/disk_cache.rs (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 use libc_rust_gen::free;
2 use mesa_rust_gen::*;
3 
4 use std::ffi::{c_void, CString};
5 use std::ops::Deref;
6 use std::ptr;
7 use std::ptr::NonNull;
8 use std::slice;
9 
10 pub struct DiskCacheBorrowed {
11     cache: NonNull<disk_cache>,
12 }
13 
14 pub struct DiskCache {
15     inner: DiskCacheBorrowed,
16 }
17 
18 // disk_cache is thread safe
19 unsafe impl Sync for DiskCacheBorrowed {}
20 
21 impl DiskCacheBorrowed {
from_ptr(cache: *mut disk_cache) -> Option<Self>22     pub fn from_ptr(cache: *mut disk_cache) -> Option<Self> {
23         NonNull::new(cache).map(|c| Self { cache: c })
24     }
25 
put(&self, data: &[u8], key: &mut cache_key)26     pub fn put(&self, data: &[u8], key: &mut cache_key) {
27         unsafe {
28             disk_cache_put(
29                 self.cache.as_ptr(),
30                 key,
31                 data.as_ptr().cast(),
32                 data.len(),
33                 ptr::null_mut(),
34             );
35         }
36     }
37 
get(&self, key: &mut cache_key) -> Option<DiskCacheEntry>38     pub fn get(&self, key: &mut cache_key) -> Option<DiskCacheEntry> {
39         let mut size = 0;
40 
41         unsafe {
42             let data = disk_cache_get(self.cache.as_ptr(), key, &mut size);
43             if data.is_null() {
44                 None
45             } else {
46                 Some(DiskCacheEntry {
47                     data: slice::from_raw_parts_mut(data.cast(), size),
48                 })
49             }
50         }
51     }
52 
gen_key(&self, data: &[u8]) -> cache_key53     pub fn gen_key(&self, data: &[u8]) -> cache_key {
54         let mut key = cache_key::default();
55 
56         unsafe {
57             disk_cache_compute_key(
58                 self.cache.as_ptr(),
59                 data.as_ptr().cast(),
60                 data.len(),
61                 &mut key,
62             );
63         }
64 
65         key
66     }
67 
as_ptr(s: &Option<Self>) -> *mut disk_cache68     pub fn as_ptr(s: &Option<Self>) -> *mut disk_cache {
69         if let Some(s) = s {
70             s.cache.as_ptr()
71         } else {
72             ptr::null_mut()
73         }
74     }
75 }
76 
77 impl DiskCache {
new(name: &str, func_ptrs: &[*mut c_void], flags: u64) -> Option<Self>78     pub fn new(name: &str, func_ptrs: &[*mut c_void], flags: u64) -> Option<Self> {
79         let c_name = CString::new(name).unwrap();
80         let mut sha_ctx = SHA1_CTX::default();
81         let mut sha = [0; SHA1_DIGEST_LENGTH as usize];
82         let mut cache_id = [0; SHA1_DIGEST_STRING_LENGTH as usize];
83 
84         let cache = unsafe {
85             SHA1Init(&mut sha_ctx);
86 
87             for &func_ptr in func_ptrs {
88                 if !disk_cache_get_function_identifier(func_ptr, &mut sha_ctx) {
89                     return None;
90                 }
91             }
92             SHA1Final(&mut sha, &mut sha_ctx);
93             mesa_bytes_to_hex(cache_id.as_mut_ptr(), sha.as_ptr(), sha.len() as u32);
94             disk_cache_create(c_name.as_ptr(), cache_id.as_ptr(), flags)
95         };
96 
97         DiskCacheBorrowed::from_ptr(cache).map(|c| Self { inner: c })
98     }
99 }
100 
101 impl Deref for DiskCache {
102     type Target = DiskCacheBorrowed;
103 
deref(&self) -> &Self::Target104     fn deref(&self) -> &Self::Target {
105         &self.inner
106     }
107 }
108 
109 impl Drop for DiskCache {
drop(&mut self)110     fn drop(&mut self) {
111         unsafe {
112             disk_cache_destroy(self.cache.as_ptr());
113         }
114     }
115 }
116 
117 pub struct DiskCacheEntry<'a> {
118     data: &'a mut [u8],
119 }
120 
121 impl<'a> Deref for DiskCacheEntry<'a> {
122     type Target = [u8];
123 
deref(&self) -> &Self::Target124     fn deref(&self) -> &Self::Target {
125         self.data
126     }
127 }
128 
129 impl<'a> Drop for DiskCacheEntry<'a> {
drop(&mut self)130     fn drop(&mut self) {
131         unsafe {
132             free(self.data.as_mut_ptr().cast());
133         }
134     }
135 }
136