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