core_video/
metal_texture.rs1use 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}