1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use core_foundation::base::{Boolean, CFTypeID, TCFType};

use crate::{
    buffer::TCVBuffer,
    image_buffer::{CVImageBufferRef, TCVImageBuffer},
    GLenum, GLuint,
};

pub type CVOpenGLTextureRef = CVImageBufferRef;

extern "C" {
    pub fn CVOpenGLTextureGetTypeID() -> CFTypeID;
    pub fn CVOpenGLTextureRetain(texture: CVOpenGLTextureRef) -> CVOpenGLTextureRef;
    pub fn CVOpenGLTextureRelease(texture: CVOpenGLTextureRef);
    pub fn CVOpenGLTextureGetTarget(image: CVOpenGLTextureRef) -> GLenum;
    pub fn CVOpenGLTextureGetName(image: CVOpenGLTextureRef) -> GLuint;
    pub fn CVOpenGLTextureIsFlipped(image: CVOpenGLTextureRef) -> Boolean;
    pub fn CVOpenGLTextureGetCleanTexCoords(
        image: CVOpenGLTextureRef,
        lowerLeft: *mut f32,
        lowerRight: *mut f32,
        upperRight: *mut f32,
        upperLeft: *mut f32,
    );
}

impl TCVBuffer for CVOpenGLTexture {}
impl TCVImageBuffer for CVOpenGLTexture {}

pub struct CVOpenGLTexture(CVOpenGLTextureRef);

impl Drop for CVOpenGLTexture {
    fn drop(&mut self) {
        unsafe { CVOpenGLTextureRelease(self.0) }
    }
}

impl_TCFType!(CVOpenGLTexture, CVOpenGLTextureRef, CVOpenGLTextureGetTypeID);
impl_CFTypeDescription!(CVOpenGLTexture);

impl CVOpenGLTexture {
    pub fn get_target(&self) -> GLenum {
        unsafe { CVOpenGLTextureGetTarget(self.as_concrete_TypeRef()) }
    }

    pub fn get_name(&self) -> GLuint {
        unsafe { CVOpenGLTextureGetName(self.as_concrete_TypeRef()) }
    }

    pub fn is_flipped(&self) -> bool {
        unsafe { CVOpenGLTextureIsFlipped(self.as_concrete_TypeRef()) != 0 }
    }

    pub fn get_clean_tex_coords(&self) -> (f32, f32, f32, f32) {
        let mut lower_left = 0.0;
        let mut lower_right = 0.0;
        let mut upper_right = 0.0;
        let mut upper_left = 0.0;
        unsafe {
            CVOpenGLTextureGetCleanTexCoords(self.as_concrete_TypeRef(), &mut lower_left, &mut lower_right, &mut upper_right, &mut upper_left);
        }
        (lower_left, lower_right, upper_right, upper_left)
    }
}