core_video/
metal_texture.rs

1use core_foundation::{
2    base::{Boolean, CFTypeID, TCFType},
3    string::{CFString, CFStringRef},
4};
5use metal::{foreign_types::ForeignType, MTLTexture, Texture};
6
7use crate::{
8    buffer::TCVBuffer,
9    image_buffer::{CVImageBufferRef, TCVImageBuffer},
10};
11
12pub type CVMetalTextureRef = CVImageBufferRef;
13
14extern "C" {
15    pub fn CVMetalTextureGetTypeID() -> CFTypeID;
16    pub fn CVMetalTextureGetTexture(image: CVMetalTextureRef) -> *mut MTLTexture;
17    pub fn CVMetalTextureIsFlipped(image: CVMetalTextureRef) -> Boolean;
18    pub fn CVMetalTextureGetCleanTexCoords(
19        image: CVMetalTextureRef,
20        lowerLeft: *mut f32,
21        lowerRight: *mut f32,
22        upperRight: *mut f32,
23        upperLeft: *mut f32,
24    );
25
26    pub static kCVMetalTextureUsage: CFStringRef;
27    pub static kCVMetalTextureStorageMode: CFStringRef;
28}
29
30pub enum CVMetalTextureKeys {
31    Usage,
32    StorageMode,
33}
34
35impl From<CVMetalTextureKeys> for CFStringRef {
36    fn from(key: CVMetalTextureKeys) -> Self {
37        unsafe {
38            match key {
39                CVMetalTextureKeys::Usage => kCVMetalTextureUsage,
40                CVMetalTextureKeys::StorageMode => kCVMetalTextureStorageMode,
41            }
42        }
43    }
44}
45
46impl From<CVMetalTextureKeys> for CFString {
47    fn from(key: CVMetalTextureKeys) -> Self {
48        unsafe { CFString::wrap_under_get_rule(CFStringRef::from(key)) }
49    }
50}
51
52impl TCVBuffer for CVMetalTexture {}
53impl TCVImageBuffer for CVMetalTexture {}
54
55declare_TCFType! {
56    CVMetalTexture, CVMetalTextureRef
57}
58impl_TCFType!(CVMetalTexture, CVMetalTextureRef, CVMetalTextureGetTypeID);
59impl_CFTypeDescription!(CVMetalTexture);
60
61impl CVMetalTexture {
62    #[inline]
63    pub fn get_texture(&self) -> Option<Texture> {
64        unsafe {
65            let texture = CVMetalTextureGetTexture(self.as_concrete_TypeRef());
66            if texture.is_null() {
67                None
68            } else {
69                Some(Texture::from_ptr(texture))
70            }
71        }
72    }
73
74    #[inline]
75    pub fn is_flipped(&self) -> bool {
76        unsafe { CVMetalTextureIsFlipped(self.as_concrete_TypeRef()) != 0 }
77    }
78
79    #[inline]
80    pub fn get_clean_tex_coords(&self) -> (f32, f32, f32, f32) {
81        let mut lower_left = 0.0;
82        let mut lower_right = 0.0;
83        let mut upper_right = 0.0;
84        let mut upper_left = 0.0;
85        unsafe {
86            CVMetalTextureGetCleanTexCoords(self.as_concrete_TypeRef(), &mut lower_left, &mut lower_right, &mut upper_right, &mut upper_left);
87        }
88        (lower_left, lower_right, upper_right, upper_left)
89    }
90}