OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include <dlfcn.h> | |
6 | |
7 #include "base/memory/singleton.h" | |
8 #include "ui/gl/io_surface_support_mac.h" | |
9 | |
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, | |
20 uint32 options, | |
21 uint32* seed); | |
22 typedef IOReturn (*IOSurfaceUnlockPtr)(CFTypeRef io_surface, | |
23 uint32 options, | |
24 uint32* seed); | |
25 | |
26 typedef CGLError (*CGLTexImageIOSurface2DProcPtr)(CGLContextObj ctx, | |
27 GLenum target, | |
28 GLenum internal_format, | |
29 GLsizei width, | |
30 GLsizei height, | |
31 GLenum format, | |
32 GLenum type, | |
33 CFTypeRef io_surface, | |
34 GLuint plane); | |
35 typedef CFTypeRef (*CVPixelBufferGetIOSurfaceProcPtr)( | |
36 CVPixelBufferRef pixel_buffer); | |
37 | |
38 class IOSurfaceSupportImpl : public IOSurfaceSupport { | |
39 public: | |
40 static IOSurfaceSupportImpl* GetInstance(); | |
41 | |
42 bool InitializedSuccessfully() { | |
43 return initialized_successfully_; | |
44 } | |
45 | |
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; | |
51 | |
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; | |
57 | |
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; | |
62 | |
63 virtual IOReturn IOSurfaceLock(CFTypeRef io_surface, | |
64 uint32 options, | |
65 uint32* seed) OVERRIDE; | |
66 virtual IOReturn IOSurfaceUnlock(CFTypeRef io_surface, | |
67 uint32 options, | |
68 uint32* seed) OVERRIDE; | |
69 | |
70 virtual CGLError CGLTexImageIOSurface2D(CGLContextObj ctx, | |
71 GLenum target, | |
72 GLenum internal_format, | |
73 GLsizei width, | |
74 GLsizei height, | |
75 GLenum format, | |
76 GLenum type, | |
77 CFTypeRef io_surface, | |
78 GLuint plane) OVERRIDE; | |
79 | |
80 virtual CFTypeRef CVPixelBufferGetIOSurface( | |
81 CVPixelBufferRef pixel_buffer) OVERRIDE; | |
82 | |
83 private: | |
84 IOSurfaceSupportImpl(); | |
85 virtual ~IOSurfaceSupportImpl(); | |
86 | |
87 void CloseLibraryHandles(); | |
88 | |
89 void* iosurface_handle_; | |
90 void* opengl_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_; | |
111 | |
112 friend struct DefaultSingletonTraits<IOSurfaceSupportImpl>; | |
113 DISALLOW_COPY_AND_ASSIGN(IOSurfaceSupportImpl); | |
114 }; | |
115 | |
116 IOSurfaceSupportImpl* IOSurfaceSupportImpl::GetInstance() { | |
117 IOSurfaceSupportImpl* impl = Singleton<IOSurfaceSupportImpl>::get(); | |
118 if (impl->InitializedSuccessfully()) | |
119 return impl; | |
120 return NULL; | |
121 } | |
122 | |
123 CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceWidth() { | |
124 return k_io_surface_width_; | |
125 } | |
126 | |
127 CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceHeight() { | |
128 return k_io_surface_height_; | |
129 } | |
130 | |
131 CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceBytesPerElement() { | |
132 return k_io_surface_bytes_per_element_; | |
133 } | |
134 | |
135 CFStringRef IOSurfaceSupportImpl::GetKIOSurfacePixelFormat() { | |
136 return k_io_surface_pixel_format_; | |
137 } | |
138 | |
139 CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceIsGlobal() { | |
140 return k_io_surface_is_global_; | |
141 } | |
142 | |
143 CFTypeRef IOSurfaceSupportImpl::IOSurfaceCreate(CFDictionaryRef properties) { | |
144 return io_surface_create_(properties); | |
145 } | |
146 | |
147 uint32 IOSurfaceSupportImpl::IOSurfaceGetID( | |
148 CFTypeRef io_surface) { | |
149 return io_surface_get_id_(io_surface); | |
150 } | |
151 | |
152 CFTypeRef IOSurfaceSupportImpl::IOSurfaceLookup(uint32 io_surface_id) { | |
153 return io_surface_lookup_(io_surface_id); | |
154 } | |
155 | |
156 mach_port_t IOSurfaceSupportImpl::IOSurfaceCreateMachPort( | |
157 CFTypeRef io_surface) { | |
158 return io_surface_create_mach_port_(io_surface); | |
159 } | |
160 | |
161 CFTypeRef IOSurfaceSupportImpl::IOSurfaceLookupFromMachPort(mach_port_t port) { | |
162 return io_surface_lookup_from_mach_port_(port); | |
163 } | |
164 | |
165 size_t IOSurfaceSupportImpl::IOSurfaceGetWidth(CFTypeRef io_surface) { | |
166 return io_surface_get_width_(io_surface); | |
167 } | |
168 | |
169 size_t IOSurfaceSupportImpl::IOSurfaceGetHeight(CFTypeRef io_surface) { | |
170 return io_surface_get_height_(io_surface); | |
171 } | |
172 | |
173 size_t IOSurfaceSupportImpl::IOSurfaceGetBytesPerRow(CFTypeRef io_surface) { | |
174 return io_surface_get_bytes_per_row_(io_surface); | |
175 } | |
176 | |
177 void* IOSurfaceSupportImpl::IOSurfaceGetBaseAddress(CFTypeRef io_surface) { | |
178 return io_surface_get_base_address_(io_surface); | |
179 } | |
180 | |
181 IOReturn IOSurfaceSupportImpl::IOSurfaceLock(CFTypeRef io_surface, | |
182 uint32 options, | |
183 uint32* seed) { | |
184 return io_surface_lock_(io_surface, options, seed); | |
185 } | |
186 | |
187 IOReturn IOSurfaceSupportImpl::IOSurfaceUnlock(CFTypeRef io_surface, | |
188 uint32 options, | |
189 uint32* seed) { | |
190 return io_surface_unlock_(io_surface, options, seed); | |
191 } | |
192 | |
193 CGLError IOSurfaceSupportImpl::CGLTexImageIOSurface2D(CGLContextObj ctx, | |
194 GLenum target, | |
195 GLenum internal_format, | |
196 GLsizei width, | |
197 GLsizei height, | |
198 GLenum format, | |
199 GLenum type, | |
200 CFTypeRef io_surface, | |
201 GLuint plane) { | |
202 return cgl_tex_image_io_surface_2d_(ctx, | |
203 target, | |
204 internal_format, | |
205 width, | |
206 height, | |
207 format, | |
208 type, | |
209 io_surface, | |
210 plane); | |
211 } | |
212 | |
213 CFTypeRef IOSurfaceSupportImpl::CVPixelBufferGetIOSurface( | |
214 CVPixelBufferRef pixel_buffer) { | |
215 return cv_pixel_buffer_get_io_surface_(pixel_buffer); | |
216 } | |
217 | |
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_ || | |
251 !opengl_handle_ || | |
252 !core_video_handle_) { | |
253 CloseLibraryHandles(); | |
254 return; | |
255 } | |
256 | |
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(); | |
305 return; | |
306 } | |
307 | |
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>( | |
316 surface_create_ptr); | |
317 io_surface_get_id_ = | |
318 reinterpret_cast<IOSurfaceGetIDProcPtr>(surface_get_id_ptr); | |
319 io_surface_lookup_ = | |
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; | |
349 } | |
350 | |
351 IOSurfaceSupportImpl::~IOSurfaceSupportImpl() { | |
352 CloseLibraryHandles(); | |
353 } | |
354 | |
355 void IOSurfaceSupportImpl::CloseLibraryHandles() { | |
356 if (iosurface_handle_) { | |
357 dlclose(iosurface_handle_); | |
358 iosurface_handle_ = NULL; | |
359 } | |
360 if (opengl_handle_) { | |
361 dlclose(opengl_handle_); | |
362 opengl_handle_ = NULL; | |
363 } | |
364 if (core_video_handle_) { | |
365 dlclose(core_video_handle_); | |
366 core_video_handle_ = NULL; | |
367 } | |
368 } | |
369 | |
370 IOSurfaceSupport* IOSurfaceSupport::Initialize() { | |
371 return IOSurfaceSupportImpl::GetInstance(); | |
372 } | |
373 | |
374 IOSurfaceSupport::IOSurfaceSupport() { | |
375 } | |
376 | |
377 IOSurfaceSupport::~IOSurfaceSupport() { | |
378 } | |
379 | |
OLD | NEW |