1#![deprecated = "use the objc2-io-surface crate instead"]
12#![crate_name = "io_surface"]
13#![crate_type = "rlib"]
14
15use cgl::{kCGLNoError, CGLErrorString, CGLGetCurrentContext, CGLTexImageIOSurface2D, GLenum};
18use core::ffi::{c_int, c_void};
19use core_foundation::base::{CFRelease, CFRetain, CFType, CFTypeID, CFTypeRef, TCFType};
20use core_foundation::dictionary::{CFDictionary, CFDictionaryRef};
21use core_foundation::string::{CFString, CFStringRef};
22use core_foundation_sys::base::mach_port_t;
23use leaky_cow::LeakyCow;
24use std::ffi::CStr;
25use std::slice;
26
27const BGRA: GLenum = 0x80E1;
28const RGBA: GLenum = 0x1908;
29const RGB: GLenum = 0x1907;
30const TEXTURE_RECTANGLE_ARB: GLenum = 0x84F5;
31const UNSIGNED_INT_8_8_8_8_REV: GLenum = 0x8367;
32
33#[allow(non_snake_case, non_upper_case_globals)]
34pub mod IOSurfaceLockOptions {
35 pub const kIOSurfaceLockReadOnly: u32 = 0x00000001;
36 pub const kIOSurfaceLockAvoidSync: u32 = 0x00000002;
37}
38
39type IOReturn = c_int;
40
41#[repr(C)]
42pub struct __IOSurface(c_void);
43
44pub type IOSurfaceRef = *const __IOSurface;
45
46pub struct IOSurface {
47 pub obj: IOSurfaceRef,
48}
49
50impl Drop for IOSurface {
51 fn drop(&mut self) {
52 unsafe { CFRelease(self.as_CFTypeRef()) }
53 }
54}
55
56pub type IOSurfaceID = u32;
57
58impl Clone for IOSurface {
59 #[inline]
60 fn clone(&self) -> IOSurface {
61 unsafe { TCFType::wrap_under_get_rule(self.obj) }
62 }
63}
64
65impl TCFType for IOSurface {
66 type Ref = IOSurfaceRef;
67
68 #[inline]
69 fn as_concrete_TypeRef(&self) -> IOSurfaceRef {
70 self.obj
71 }
72
73 #[inline]
74 unsafe fn wrap_under_create_rule(obj: IOSurfaceRef) -> IOSurface {
75 assert!(!obj.is_null(), "Attempted to create a NULL object.");
76 IOSurface { obj }
77 }
78
79 #[inline]
80 fn type_id() -> CFTypeID {
81 unsafe { IOSurfaceGetTypeID() }
82 }
83
84 #[inline]
85 fn as_CFTypeRef(&self) -> CFTypeRef {
86 self.as_concrete_TypeRef() as CFTypeRef
87 }
88
89 #[inline]
90 unsafe fn wrap_under_get_rule(reference: IOSurfaceRef) -> IOSurface {
91 assert!(!reference.is_null(), "Attempted to create a NULL object.");
92 let reference = CFRetain(reference as *const c_void) as IOSurfaceRef;
93 TCFType::wrap_under_create_rule(reference)
94 }
95}
96
97pub fn new(properties: &CFDictionary<CFString, CFType>) -> IOSurface {
98 unsafe { TCFType::wrap_under_create_rule(IOSurfaceCreate(properties.as_concrete_TypeRef())) }
99}
100
101pub fn lookup(csid: IOSurfaceID) -> IOSurface {
105 unsafe { TCFType::wrap_under_create_rule(IOSurfaceLookup(csid)) }
106}
107
108impl IOSurface {
109 pub fn get_id(&self) -> IOSurfaceID {
110 unsafe { IOSurfaceGetID(self.as_concrete_TypeRef()) }
111 }
112
113 pub fn bind_to_gl_texture(&self, width: i32, height: i32, has_alpha: bool) {
115 unsafe {
116 let context = CGLGetCurrentContext();
117 let gl_error = CGLTexImageIOSurface2D(
118 context,
119 TEXTURE_RECTANGLE_ARB,
120 if has_alpha {
121 RGBA as GLenum
122 } else {
123 RGB as GLenum
124 },
125 width,
126 height,
127 BGRA as GLenum,
128 UNSIGNED_INT_8_8_8_8_REV,
129 self.as_concrete_TypeRef() as *mut c_void,
130 0,
131 );
132
133 if gl_error != kCGLNoError {
134 let error_msg = CStr::from_ptr(CGLErrorString(gl_error));
135 let error_msg = error_msg.to_string_lossy();
136 panic!("{}", error_msg.leak());
139 }
140 }
141 }
142
143 pub fn upload(&self, data: &[u8]) {
144 unsafe {
145 let surface = self.as_concrete_TypeRef();
146 let mut seed = 0;
147
148 IOSurfaceLock(surface, 0, &mut seed);
149
150 let height = IOSurfaceGetHeight(surface);
151 let stride = IOSurfaceGetBytesPerRow(surface);
152 let size = height * stride;
153 let address = IOSurfaceGetBaseAddress(surface) as *mut u8;
154 let dest: &mut [u8] = slice::from_raw_parts_mut(address, size);
155 dest.clone_from_slice(data);
156
157 IOSurfaceUnlock(surface, 0, &mut seed);
159 }
160 }
161}
162
163#[cfg_attr(feature = "link", link(name = "IOSurface", kind = "framework"))]
164extern "C" {
165 pub static kIOSurfaceAllocSize: CFStringRef;
166 pub static kIOSurfaceWidth: CFStringRef;
167 pub static kIOSurfaceHeight: CFStringRef;
168 pub static kIOSurfaceBytesPerRow: CFStringRef;
169 pub static kIOSurfaceBytesPerElement: CFStringRef;
170 pub static kIOSurfaceElementWidth: CFStringRef;
171 pub static kIOSurfaceElementHeight: CFStringRef;
172 pub static kIOSurfaceOffset: CFStringRef;
173
174 pub static kIOSurfacePlaneInfo: CFStringRef;
175 pub static kIOSurfacePlaneWidth: CFStringRef;
176 pub static kIOSurfacePlaneHeight: CFStringRef;
177 pub static kIOSurfacePlaneBytesPerRow: CFStringRef;
178 pub static kIOSurfacePlaneOffset: CFStringRef;
179 pub static kIOSurfacePlaneSize: CFStringRef;
180
181 pub static kIOSurfacePlaneBase: CFStringRef;
182 pub static kIOSurfacePlaneBytesPerElement: CFStringRef;
183 pub static kIOSurfacePlaneElementWidth: CFStringRef;
184 pub static kIOSurfacePlaneElementHeight: CFStringRef;
185
186 pub static kIOSurfaceCacheMode: CFStringRef;
187 pub static kIOSurfaceIsGlobal: CFStringRef;
188 pub static kIOSurfacePixelFormat: CFStringRef;
189
190 pub fn IOSurfaceCreate(properties: CFDictionaryRef) -> IOSurfaceRef;
191 pub fn IOSurfaceLookup(csid: IOSurfaceID) -> IOSurfaceRef;
192 pub fn IOSurfaceGetID(buffer: IOSurfaceRef) -> IOSurfaceID;
193
194 pub fn IOSurfaceGetTypeID() -> CFTypeID;
195
196 pub fn IOSurfaceLock(buffer: IOSurfaceRef, options: u32, seed: *mut u32) -> IOReturn;
197 pub fn IOSurfaceUnlock(buffer: IOSurfaceRef, options: u32, seed: *mut u32) -> IOReturn;
198 pub fn IOSurfaceGetSeed(buffer: IOSurfaceRef) -> u32;
199
200 pub fn IOSurfaceGetHeight(buffer: IOSurfaceRef) -> usize;
201 pub fn IOSurfaceGetWidth(buffer: IOSurfaceRef) -> usize;
202 pub fn IOSurfaceGetBytesPerRow(buffer: IOSurfaceRef) -> usize;
203 pub fn IOSurfaceGetBaseAddress(buffer: IOSurfaceRef) -> *mut c_void;
204 pub fn IOSurfaceGetElementHeight(buffer: IOSurfaceRef) -> usize;
205 pub fn IOSurfaceGetElementWidth(buffer: IOSurfaceRef) -> usize;
206 pub fn IOSurfaceGetBytesPerElement(buffer: IOSurfaceRef) -> usize;
207 pub fn IOSurfaceGetAllocSize(buffer: IOSurfaceRef) -> usize;
208
209 pub fn IOSurfaceGetPixelFormat(buffer: IOSurfaceRef) -> i32;
210
211 pub fn IOSurfaceGetUseCount(buffer: IOSurfaceRef) -> i32;
212 pub fn IOSurfaceIncrementUseCount(buffer: IOSurfaceRef);
213 pub fn IOSurfaceDecrementUseCount(buffer: IOSurfaceRef);
214 pub fn IOSurfaceIsInUse(buffer: IOSurfaceRef) -> bool;
215
216 pub fn IOSurfaceCreateMachPort(buffer: IOSurfaceRef) -> mach_port_t;
217 pub fn IOSurfaceLookupFromMachPort(port: mach_port_t) -> IOSurfaceRef;
218
219 pub fn IOSurfaceGetPropertyAlignment(property: CFStringRef) -> usize;
220 pub fn IOSurfaceGetPropertyMaximum(property: CFStringRef) -> usize;
221
222 pub fn IOSurfaceCopyValue(buffer: IOSurfaceRef, key: CFStringRef) -> CFTypeRef;
223 pub fn IOSurfaceRemoveValue(buffer: IOSurfaceRef, key: CFStringRef);
224 pub fn IOSurfaceSetValue(buffer: IOSurfaceRef, key: CFStringRef, value: CFTypeRef);
225
226 pub fn IOSurfaceGetBaseAddressOfPlane(buffer: IOSurfaceRef, plane_index: usize) -> *mut c_void;
227 pub fn IOSurfaceGetBytesPerElementOfPlane(buffer: IOSurfaceRef, plane_index: usize) -> usize;
228 pub fn IOSurfaceGetBytesPerRowOfPlane(buffer: IOSurfaceRef, plane_index: usize) -> usize;
229 pub fn IOSurfaceGetElementHeightOfPlane(buffer: IOSurfaceRef, plane_index: usize) -> usize;
230 pub fn IOSurfaceGetElementWidthOfPlane(buffer: IOSurfaceRef, plane_index: usize) -> usize;
231 pub fn IOSurfaceGetHeightOfPlane(buffer: IOSurfaceRef, plane_index: usize) -> usize;
232 pub fn IOSurfaceGetWidthOfPlane(buffer: IOSurfaceRef, plane_index: usize) -> usize;
233}