1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "base/memory/singleton.h"
8 #include "ui/gl/io_surface_support_mac.h"
10 typedef CFTypeRef (*IOSurfaceCreateProcPtr
)(CFDictionaryRef properties
);
11 typedef uint32 (*IOSurfaceGetIDProcPtr
)(CFTypeRef io_surface
);
12 typedef CFTypeRef (*IOSurfaceLookupProcPtr
)(uint32 io_surface_id
);
13 typedef mach_port_t (*IOSurfaceCreateMachPortProcPtr
)(CFTypeRef io_surface
);
14 typedef CFTypeRef (*IOSurfaceLookupFromMachPortProcPtr
)(mach_port_t port
);
15 typedef size_t (*IOSurfaceGetWidthPtr
)(CFTypeRef io_surface
);
16 typedef size_t (*IOSurfaceGetHeightPtr
)(CFTypeRef io_surface
);
17 typedef size_t (*IOSurfaceGetBytesPerRowPtr
)(CFTypeRef io_surface
);
18 typedef void* (*IOSurfaceGetBaseAddressPtr
)(CFTypeRef io_surface
);
19 typedef IOReturn (*IOSurfaceLockPtr
)(CFTypeRef io_surface
,
22 typedef IOReturn (*IOSurfaceUnlockPtr
)(CFTypeRef io_surface
,
26 typedef CGLError (*CGLTexImageIOSurface2DProcPtr
)(CGLContextObj ctx
,
28 GLenum internal_format
,
35 typedef CFTypeRef (*CVPixelBufferGetIOSurfaceProcPtr
)(
36 CVPixelBufferRef pixel_buffer
);
38 class IOSurfaceSupportImpl
: public IOSurfaceSupport
{
40 static IOSurfaceSupportImpl
* GetInstance();
42 bool InitializedSuccessfully() {
43 return initialized_successfully_
;
46 virtual CFStringRef
GetKIOSurfaceWidth() OVERRIDE
;
47 virtual CFStringRef
GetKIOSurfaceHeight() OVERRIDE
;
48 virtual CFStringRef
GetKIOSurfaceBytesPerElement() OVERRIDE
;
49 virtual CFStringRef
GetKIOSurfacePixelFormat() OVERRIDE
;
50 virtual CFStringRef
GetKIOSurfaceIsGlobal() OVERRIDE
;
52 virtual CFTypeRef
IOSurfaceCreate(CFDictionaryRef properties
) OVERRIDE
;
53 virtual uint32
IOSurfaceGetID(CFTypeRef io_surface
) OVERRIDE
;
54 virtual CFTypeRef
IOSurfaceLookup(uint32 io_surface_id
) OVERRIDE
;
55 virtual mach_port_t
IOSurfaceCreateMachPort(CFTypeRef io_surface
) OVERRIDE
;
56 virtual CFTypeRef
IOSurfaceLookupFromMachPort(mach_port_t port
) OVERRIDE
;
58 virtual size_t IOSurfaceGetWidth(CFTypeRef io_surface
) OVERRIDE
;
59 virtual size_t IOSurfaceGetHeight(CFTypeRef io_surface
) OVERRIDE
;
60 virtual size_t IOSurfaceGetBytesPerRow(CFTypeRef io_surface
) OVERRIDE
;
61 virtual void* IOSurfaceGetBaseAddress(CFTypeRef io_surface
) OVERRIDE
;
63 virtual IOReturn
IOSurfaceLock(CFTypeRef io_surface
,
65 uint32
* seed
) OVERRIDE
;
66 virtual IOReturn
IOSurfaceUnlock(CFTypeRef io_surface
,
68 uint32
* seed
) OVERRIDE
;
70 virtual CGLError
CGLTexImageIOSurface2D(CGLContextObj ctx
,
72 GLenum internal_format
,
78 GLuint plane
) OVERRIDE
;
80 virtual CFTypeRef
CVPixelBufferGetIOSurface(
81 CVPixelBufferRef pixel_buffer
) OVERRIDE
;
84 IOSurfaceSupportImpl();
85 virtual ~IOSurfaceSupportImpl();
87 void CloseLibraryHandles();
89 void* iosurface_handle_
;
91 void* core_video_handle_
;
92 CFStringRef k_io_surface_width_
;
93 CFStringRef k_io_surface_height_
;
94 CFStringRef k_io_surface_bytes_per_element_
;
95 CFStringRef k_io_surface_pixel_format_
;
96 CFStringRef k_io_surface_is_global_
;
97 IOSurfaceCreateProcPtr io_surface_create_
;
98 IOSurfaceGetIDProcPtr io_surface_get_id_
;
99 IOSurfaceLookupProcPtr io_surface_lookup_
;
100 IOSurfaceCreateMachPortProcPtr io_surface_create_mach_port_
;
101 IOSurfaceLookupFromMachPortProcPtr io_surface_lookup_from_mach_port_
;
102 IOSurfaceGetWidthPtr io_surface_get_width_
;
103 IOSurfaceGetHeightPtr io_surface_get_height_
;
104 IOSurfaceGetBytesPerRowPtr io_surface_get_bytes_per_row_
;
105 IOSurfaceGetBaseAddressPtr io_surface_get_base_address_
;
106 IOSurfaceLockPtr io_surface_lock_
;
107 IOSurfaceUnlockPtr io_surface_unlock_
;
108 CGLTexImageIOSurface2DProcPtr cgl_tex_image_io_surface_2d_
;
109 CVPixelBufferGetIOSurfaceProcPtr cv_pixel_buffer_get_io_surface_
;
110 bool initialized_successfully_
;
112 friend struct DefaultSingletonTraits
<IOSurfaceSupportImpl
>;
113 DISALLOW_COPY_AND_ASSIGN(IOSurfaceSupportImpl
);
116 IOSurfaceSupportImpl
* IOSurfaceSupportImpl::GetInstance() {
117 IOSurfaceSupportImpl
* impl
= Singleton
<IOSurfaceSupportImpl
>::get();
118 if (impl
->InitializedSuccessfully())
123 CFStringRef
IOSurfaceSupportImpl::GetKIOSurfaceWidth() {
124 return k_io_surface_width_
;
127 CFStringRef
IOSurfaceSupportImpl::GetKIOSurfaceHeight() {
128 return k_io_surface_height_
;
131 CFStringRef
IOSurfaceSupportImpl::GetKIOSurfaceBytesPerElement() {
132 return k_io_surface_bytes_per_element_
;
135 CFStringRef
IOSurfaceSupportImpl::GetKIOSurfacePixelFormat() {
136 return k_io_surface_pixel_format_
;
139 CFStringRef
IOSurfaceSupportImpl::GetKIOSurfaceIsGlobal() {
140 return k_io_surface_is_global_
;
143 CFTypeRef
IOSurfaceSupportImpl::IOSurfaceCreate(CFDictionaryRef properties
) {
144 return io_surface_create_(properties
);
147 uint32
IOSurfaceSupportImpl::IOSurfaceGetID(
148 CFTypeRef io_surface
) {
149 return io_surface_get_id_(io_surface
);
152 CFTypeRef
IOSurfaceSupportImpl::IOSurfaceLookup(uint32 io_surface_id
) {
153 return io_surface_lookup_(io_surface_id
);
156 mach_port_t
IOSurfaceSupportImpl::IOSurfaceCreateMachPort(
157 CFTypeRef io_surface
) {
158 return io_surface_create_mach_port_(io_surface
);
161 CFTypeRef
IOSurfaceSupportImpl::IOSurfaceLookupFromMachPort(mach_port_t port
) {
162 return io_surface_lookup_from_mach_port_(port
);
165 size_t IOSurfaceSupportImpl::IOSurfaceGetWidth(CFTypeRef io_surface
) {
166 return io_surface_get_width_(io_surface
);
169 size_t IOSurfaceSupportImpl::IOSurfaceGetHeight(CFTypeRef io_surface
) {
170 return io_surface_get_height_(io_surface
);
173 size_t IOSurfaceSupportImpl::IOSurfaceGetBytesPerRow(CFTypeRef io_surface
) {
174 return io_surface_get_bytes_per_row_(io_surface
);
177 void* IOSurfaceSupportImpl::IOSurfaceGetBaseAddress(CFTypeRef io_surface
) {
178 return io_surface_get_base_address_(io_surface
);
181 IOReturn
IOSurfaceSupportImpl::IOSurfaceLock(CFTypeRef io_surface
,
184 return io_surface_lock_(io_surface
, options
, seed
);
187 IOReturn
IOSurfaceSupportImpl::IOSurfaceUnlock(CFTypeRef io_surface
,
190 return io_surface_unlock_(io_surface
, options
, seed
);
193 CGLError
IOSurfaceSupportImpl::CGLTexImageIOSurface2D(CGLContextObj ctx
,
195 GLenum internal_format
,
200 CFTypeRef io_surface
,
202 return cgl_tex_image_io_surface_2d_(ctx
,
213 CFTypeRef
IOSurfaceSupportImpl::CVPixelBufferGetIOSurface(
214 CVPixelBufferRef pixel_buffer
) {
215 return cv_pixel_buffer_get_io_surface_(pixel_buffer
);
218 IOSurfaceSupportImpl::IOSurfaceSupportImpl()
219 : iosurface_handle_(NULL
),
220 opengl_handle_(NULL
),
221 core_video_handle_(NULL
),
222 k_io_surface_width_(NULL
),
223 k_io_surface_height_(NULL
),
224 k_io_surface_bytes_per_element_(NULL
),
225 k_io_surface_pixel_format_(NULL
),
226 k_io_surface_is_global_(NULL
),
227 io_surface_create_(NULL
),
228 io_surface_get_id_(NULL
),
229 io_surface_lookup_(NULL
),
230 io_surface_create_mach_port_(NULL
),
231 io_surface_lookup_from_mach_port_(NULL
),
232 io_surface_get_width_(NULL
),
233 io_surface_get_height_(NULL
),
234 io_surface_get_bytes_per_row_(NULL
),
235 io_surface_get_base_address_(NULL
),
236 io_surface_lock_(NULL
),
237 io_surface_unlock_(NULL
),
238 cgl_tex_image_io_surface_2d_(NULL
),
239 cv_pixel_buffer_get_io_surface_(NULL
),
240 initialized_successfully_(false) {
241 iosurface_handle_
= dlopen(
242 "/System/Library/Frameworks/IOSurface.framework/IOSurface",
243 RTLD_LAZY
| RTLD_LOCAL
);
244 opengl_handle_
= dlopen(
245 "/System/Library/Frameworks/OpenGL.framework/OpenGL",
246 RTLD_LAZY
| RTLD_LOCAL
);
247 core_video_handle_
= dlopen(
248 "/System/Library/Frameworks/CoreVideo.framework/CoreVideo",
249 RTLD_LAZY
| RTLD_LOCAL
);
250 if (!iosurface_handle_
||
252 !core_video_handle_
) {
253 CloseLibraryHandles();
257 void* surface_width_ptr
= dlsym(iosurface_handle_
, "kIOSurfaceWidth");
258 void* surface_height_ptr
= dlsym(iosurface_handle_
, "kIOSurfaceHeight");
259 void* surface_bytes_per_element_ptr
=
260 dlsym(iosurface_handle_
, "kIOSurfaceBytesPerElement");
261 void* surface_pixel_format_ptr
=
262 dlsym(iosurface_handle_
, "kIOSurfacePixelFormat");
263 void* surface_is_global_ptr
=
264 dlsym(iosurface_handle_
, "kIOSurfaceIsGlobal");
265 void* surface_create_ptr
= dlsym(iosurface_handle_
, "IOSurfaceCreate");
266 void* surface_get_id_ptr
= dlsym(iosurface_handle_
, "IOSurfaceGetID");
267 void* surface_lookup_ptr
= dlsym(iosurface_handle_
, "IOSurfaceLookup");
268 void* surface_create_mach_port_ptr
=
269 dlsym(iosurface_handle_
, "IOSurfaceCreateMachPort");
270 void* surface_lookup_from_mach_port_ptr
=
271 dlsym(iosurface_handle_
, "IOSurfaceLookupFromMachPort");
272 void* io_surface_get_width_ptr
=
273 dlsym(iosurface_handle_
, "IOSurfaceGetWidth");
274 void* io_surface_get_height_ptr
=
275 dlsym(iosurface_handle_
, "IOSurfaceGetHeight");
276 void* io_surface_get_bytes_per_row_ptr
=
277 dlsym(iosurface_handle_
, "IOSurfaceGetBytesPerRow");
278 void* io_surface_get_base_address_ptr
=
279 dlsym(iosurface_handle_
, "IOSurfaceGetBaseAddress");
280 void* io_surface_lock_ptr
= dlsym(iosurface_handle_
, "IOSurfaceLock");
281 void* io_surface_unlock_ptr
= dlsym(iosurface_handle_
, "IOSurfaceUnlock");
282 void* tex_image_io_surface_2d_ptr
=
283 dlsym(opengl_handle_
, "CGLTexImageIOSurface2D");
284 void* cv_pixel_buffer_get_io_surface
=
285 dlsym(core_video_handle_
, "CVPixelBufferGetIOSurface");
286 if (!surface_width_ptr
||
287 !surface_height_ptr
||
288 !surface_bytes_per_element_ptr
||
289 !surface_pixel_format_ptr
||
290 !surface_is_global_ptr
||
291 !surface_create_ptr
||
292 !surface_get_id_ptr
||
293 !surface_lookup_ptr
||
294 !surface_create_mach_port_ptr
||
295 !surface_lookup_from_mach_port_ptr
||
296 !io_surface_get_width_ptr
||
297 !io_surface_get_height_ptr
||
298 !io_surface_get_bytes_per_row_ptr
||
299 !io_surface_get_base_address_ptr
||
300 !io_surface_lock_ptr
||
301 !io_surface_unlock_ptr
||
302 !tex_image_io_surface_2d_ptr
||
303 !cv_pixel_buffer_get_io_surface
) {
304 CloseLibraryHandles();
308 k_io_surface_width_
= *static_cast<CFStringRef
*>(surface_width_ptr
);
309 k_io_surface_height_
= *static_cast<CFStringRef
*>(surface_height_ptr
);
310 k_io_surface_bytes_per_element_
=
311 *static_cast<CFStringRef
*>(surface_bytes_per_element_ptr
);
312 k_io_surface_pixel_format_
=
313 *static_cast<CFStringRef
*>(surface_pixel_format_ptr
);
314 k_io_surface_is_global_
= *static_cast<CFStringRef
*>(surface_is_global_ptr
);
315 io_surface_create_
= reinterpret_cast<IOSurfaceCreateProcPtr
>(
318 reinterpret_cast<IOSurfaceGetIDProcPtr
>(surface_get_id_ptr
);
320 reinterpret_cast<IOSurfaceLookupProcPtr
>(surface_lookup_ptr
);
321 io_surface_create_mach_port_
=
322 reinterpret_cast<IOSurfaceCreateMachPortProcPtr
>(
323 surface_create_mach_port_ptr
);
324 io_surface_lookup_from_mach_port_
=
325 reinterpret_cast<IOSurfaceLookupFromMachPortProcPtr
>(
326 surface_lookup_from_mach_port_ptr
);
327 io_surface_get_width_
=
328 reinterpret_cast<IOSurfaceGetWidthPtr
>(
329 io_surface_get_width_ptr
);
330 io_surface_get_height_
=
331 reinterpret_cast<IOSurfaceGetHeightPtr
>(
332 io_surface_get_height_ptr
);
333 io_surface_get_bytes_per_row_
=
334 reinterpret_cast<IOSurfaceGetBytesPerRowPtr
>(
335 io_surface_get_bytes_per_row_ptr
);
336 io_surface_get_base_address_
=
337 reinterpret_cast<IOSurfaceGetBaseAddressPtr
>(
338 io_surface_get_base_address_ptr
);
339 io_surface_lock_
= reinterpret_cast<IOSurfaceLockPtr
>(io_surface_lock_ptr
);
340 io_surface_unlock_
= reinterpret_cast<IOSurfaceUnlockPtr
>(
341 io_surface_unlock_ptr
);
342 cgl_tex_image_io_surface_2d_
=
343 reinterpret_cast<CGLTexImageIOSurface2DProcPtr
>(
344 tex_image_io_surface_2d_ptr
);
345 cv_pixel_buffer_get_io_surface_
=
346 reinterpret_cast<CVPixelBufferGetIOSurfaceProcPtr
>(
347 cv_pixel_buffer_get_io_surface
);
348 initialized_successfully_
= true;
351 IOSurfaceSupportImpl::~IOSurfaceSupportImpl() {
352 CloseLibraryHandles();
355 void IOSurfaceSupportImpl::CloseLibraryHandles() {
356 if (iosurface_handle_
) {
357 dlclose(iosurface_handle_
);
358 iosurface_handle_
= NULL
;
360 if (opengl_handle_
) {
361 dlclose(opengl_handle_
);
362 opengl_handle_
= NULL
;
364 if (core_video_handle_
) {
365 dlclose(core_video_handle_
);
366 core_video_handle_
= NULL
;
370 IOSurfaceSupport
* IOSurfaceSupport::Initialize() {
371 return IOSurfaceSupportImpl::GetInstance();
374 IOSurfaceSupport::IOSurfaceSupport() {
377 IOSurfaceSupport::~IOSurfaceSupport() {