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/surface/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 CGLError (*CGLTexImageIOSurface2DProcPtr)(CGLContextObj ctx, | |
18 GLenum target, | |
19 GLenum internal_format, | |
20 GLsizei width, | |
21 GLsizei height, | |
22 GLenum format, | |
23 GLenum type, | |
24 CFTypeRef io_surface, | |
25 GLuint plane); | |
26 typedef CFTypeRef (*CVPixelBufferGetIOSurfaceProcPtr)( | |
27 CVPixelBufferRef pixel_buffer); | |
28 | |
29 class IOSurfaceSupportImpl : public IOSurfaceSupport { | |
30 public: | |
31 static IOSurfaceSupportImpl* GetInstance(); | |
32 | |
33 bool InitializedSuccessfully() { | |
34 return initialized_successfully_; | |
35 } | |
36 | |
37 virtual CFStringRef GetKIOSurfaceWidth() OVERRIDE; | |
38 virtual CFStringRef GetKIOSurfaceHeight() OVERRIDE; | |
39 virtual CFStringRef GetKIOSurfaceBytesPerElement() OVERRIDE; | |
40 virtual CFStringRef GetKIOSurfaceIsGlobal() OVERRIDE; | |
41 | |
42 virtual CFTypeRef IOSurfaceCreate(CFDictionaryRef properties) OVERRIDE; | |
43 virtual uint32 IOSurfaceGetID(CFTypeRef io_surface) OVERRIDE; | |
44 virtual CFTypeRef IOSurfaceLookup(uint32 io_surface_id) OVERRIDE; | |
45 virtual mach_port_t IOSurfaceCreateMachPort(CFTypeRef io_surface) OVERRIDE; | |
46 virtual CFTypeRef IOSurfaceLookupFromMachPort(mach_port_t port) OVERRIDE; | |
47 | |
48 virtual size_t IOSurfaceGetWidth(CFTypeRef io_surface) OVERRIDE; | |
49 virtual size_t IOSurfaceGetHeight(CFTypeRef io_surface) OVERRIDE; | |
50 | |
51 virtual CGLError CGLTexImageIOSurface2D(CGLContextObj ctx, | |
52 GLenum target, | |
53 GLenum internal_format, | |
54 GLsizei width, | |
55 GLsizei height, | |
56 GLenum format, | |
57 GLenum type, | |
58 CFTypeRef io_surface, | |
59 GLuint plane) OVERRIDE; | |
60 | |
61 virtual CFTypeRef CVPixelBufferGetIOSurface( | |
62 CVPixelBufferRef pixel_buffer) OVERRIDE; | |
63 | |
64 private: | |
65 IOSurfaceSupportImpl(); | |
66 virtual ~IOSurfaceSupportImpl(); | |
67 | |
68 void CloseLibraryHandles(); | |
69 | |
70 void* iosurface_handle_; | |
71 void* opengl_handle_; | |
72 void* core_video_handle_; | |
73 CFStringRef k_io_surface_width_; | |
74 CFStringRef k_io_surface_height_; | |
75 CFStringRef k_io_surface_bytes_per_element_; | |
76 CFStringRef k_io_surface_is_global_; | |
77 IOSurfaceCreateProcPtr io_surface_create_; | |
78 IOSurfaceGetIDProcPtr io_surface_get_id_; | |
79 IOSurfaceLookupProcPtr io_surface_lookup_; | |
80 IOSurfaceCreateMachPortProcPtr io_surface_create_mach_port_; | |
81 IOSurfaceLookupFromMachPortProcPtr io_surface_lookup_from_mach_port_; | |
82 IOSurfaceGetWidthPtr io_surface_get_width_; | |
83 IOSurfaceGetHeightPtr io_surface_get_height_; | |
84 CGLTexImageIOSurface2DProcPtr cgl_tex_image_io_surface_2d_; | |
85 CVPixelBufferGetIOSurfaceProcPtr cv_pixel_buffer_get_io_surface_; | |
86 bool initialized_successfully_; | |
87 | |
88 friend struct DefaultSingletonTraits<IOSurfaceSupportImpl>; | |
89 DISALLOW_COPY_AND_ASSIGN(IOSurfaceSupportImpl); | |
90 }; | |
91 | |
92 IOSurfaceSupportImpl* IOSurfaceSupportImpl::GetInstance() { | |
93 IOSurfaceSupportImpl* impl = Singleton<IOSurfaceSupportImpl>::get(); | |
94 if (impl->InitializedSuccessfully()) | |
95 return impl; | |
96 return NULL; | |
97 } | |
98 | |
99 CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceWidth() { | |
100 return k_io_surface_width_; | |
101 } | |
102 | |
103 CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceHeight() { | |
104 return k_io_surface_height_; | |
105 } | |
106 | |
107 CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceBytesPerElement() { | |
108 return k_io_surface_bytes_per_element_; | |
109 } | |
110 | |
111 CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceIsGlobal() { | |
112 return k_io_surface_is_global_; | |
113 } | |
114 | |
115 CFTypeRef IOSurfaceSupportImpl::IOSurfaceCreate(CFDictionaryRef properties) { | |
116 return io_surface_create_(properties); | |
117 } | |
118 | |
119 uint32 IOSurfaceSupportImpl::IOSurfaceGetID( | |
120 CFTypeRef io_surface) { | |
121 return io_surface_get_id_(io_surface); | |
122 } | |
123 | |
124 CFTypeRef IOSurfaceSupportImpl::IOSurfaceLookup(uint32 io_surface_id) { | |
125 return io_surface_lookup_(io_surface_id); | |
126 } | |
127 | |
128 mach_port_t IOSurfaceSupportImpl::IOSurfaceCreateMachPort( | |
129 CFTypeRef io_surface) { | |
130 return io_surface_create_mach_port_(io_surface); | |
131 } | |
132 | |
133 CFTypeRef IOSurfaceSupportImpl::IOSurfaceLookupFromMachPort(mach_port_t port) { | |
134 return io_surface_lookup_from_mach_port_(port); | |
135 } | |
136 | |
137 size_t IOSurfaceSupportImpl::IOSurfaceGetWidth(CFTypeRef io_surface) { | |
138 return io_surface_get_width_(io_surface); | |
139 } | |
140 | |
141 size_t IOSurfaceSupportImpl::IOSurfaceGetHeight(CFTypeRef io_surface) { | |
142 return io_surface_get_height_(io_surface); | |
143 } | |
144 | |
145 | |
146 CGLError IOSurfaceSupportImpl::CGLTexImageIOSurface2D(CGLContextObj ctx, | |
147 GLenum target, | |
148 GLenum internal_format, | |
149 GLsizei width, | |
150 GLsizei height, | |
151 GLenum format, | |
152 GLenum type, | |
153 CFTypeRef io_surface, | |
154 GLuint plane) { | |
155 return cgl_tex_image_io_surface_2d_(ctx, | |
156 target, | |
157 internal_format, | |
158 width, | |
159 height, | |
160 format, | |
161 type, | |
162 io_surface, | |
163 plane); | |
164 } | |
165 | |
166 CFTypeRef IOSurfaceSupportImpl::CVPixelBufferGetIOSurface( | |
167 CVPixelBufferRef pixel_buffer) { | |
168 return cv_pixel_buffer_get_io_surface_(pixel_buffer); | |
169 } | |
170 | |
171 IOSurfaceSupportImpl::IOSurfaceSupportImpl() | |
172 : iosurface_handle_(NULL), | |
173 opengl_handle_(NULL), | |
174 core_video_handle_(NULL), | |
175 k_io_surface_width_(NULL), | |
176 k_io_surface_height_(NULL), | |
177 k_io_surface_bytes_per_element_(NULL), | |
178 k_io_surface_is_global_(NULL), | |
179 io_surface_create_(NULL), | |
180 io_surface_get_id_(NULL), | |
181 io_surface_lookup_(NULL), | |
182 io_surface_create_mach_port_(NULL), | |
183 io_surface_lookup_from_mach_port_(NULL), | |
184 io_surface_get_width_(NULL), | |
185 io_surface_get_height_(NULL), | |
186 cgl_tex_image_io_surface_2d_(NULL), | |
187 cv_pixel_buffer_get_io_surface_(NULL), | |
188 initialized_successfully_(false) { | |
189 iosurface_handle_ = dlopen( | |
190 "/System/Library/Frameworks/IOSurface.framework/IOSurface", | |
191 RTLD_LAZY | RTLD_LOCAL); | |
192 opengl_handle_ = dlopen( | |
193 "/System/Library/Frameworks/OpenGL.framework/OpenGL", | |
194 RTLD_LAZY | RTLD_LOCAL); | |
195 core_video_handle_ = dlopen( | |
196 "/System/Library/Frameworks/CoreVideo.framework/CoreVideo", | |
197 RTLD_LAZY | RTLD_LOCAL); | |
198 if (!iosurface_handle_ || | |
199 !opengl_handle_ || | |
200 !core_video_handle_) { | |
201 CloseLibraryHandles(); | |
202 return; | |
203 } | |
204 | |
205 void* surface_width_ptr = dlsym(iosurface_handle_, "kIOSurfaceWidth"); | |
206 void* surface_height_ptr = dlsym(iosurface_handle_, "kIOSurfaceHeight"); | |
207 void* surface_bytes_per_element_ptr = | |
208 dlsym(iosurface_handle_, "kIOSurfaceBytesPerElement"); | |
209 void* surface_is_global_ptr = | |
210 dlsym(iosurface_handle_, "kIOSurfaceIsGlobal"); | |
211 void* surface_create_ptr = dlsym(iosurface_handle_, "IOSurfaceCreate"); | |
212 void* surface_get_id_ptr = dlsym(iosurface_handle_, "IOSurfaceGetID"); | |
213 void* surface_lookup_ptr = dlsym(iosurface_handle_, "IOSurfaceLookup"); | |
214 void* surface_create_mach_port_ptr = | |
215 dlsym(iosurface_handle_, "IOSurfaceCreateMachPort"); | |
216 void* surface_lookup_from_mach_port_ptr = | |
217 dlsym(iosurface_handle_, "IOSurfaceLookupFromMachPort"); | |
218 void* io_surface_get_width_ptr = | |
219 dlsym(iosurface_handle_, "IOSurfaceGetWidth"); | |
220 void* io_surface_get_height_ptr = | |
221 dlsym(iosurface_handle_, "IOSurfaceGetHeight"); | |
222 void* tex_image_io_surface_2d_ptr = | |
223 dlsym(opengl_handle_, "CGLTexImageIOSurface2D"); | |
224 void* cv_pixel_buffer_get_io_surface = | |
225 dlsym(core_video_handle_, "CVPixelBufferGetIOSurface"); | |
226 if (!surface_width_ptr || | |
227 !surface_height_ptr || | |
228 !surface_bytes_per_element_ptr || | |
229 !surface_is_global_ptr || | |
230 !surface_create_ptr || | |
231 !surface_get_id_ptr || | |
232 !surface_lookup_ptr || | |
233 !surface_create_mach_port_ptr || | |
234 !surface_lookup_from_mach_port_ptr || | |
235 !io_surface_get_width_ptr || | |
236 !io_surface_get_height_ptr || | |
237 !tex_image_io_surface_2d_ptr || | |
238 !cv_pixel_buffer_get_io_surface) { | |
239 CloseLibraryHandles(); | |
240 return; | |
241 } | |
242 | |
243 k_io_surface_width_ = *static_cast<CFStringRef*>(surface_width_ptr); | |
244 k_io_surface_height_ = *static_cast<CFStringRef*>(surface_height_ptr); | |
245 k_io_surface_bytes_per_element_ = | |
246 *static_cast<CFStringRef*>(surface_bytes_per_element_ptr); | |
247 k_io_surface_is_global_ = *static_cast<CFStringRef*>(surface_is_global_ptr); | |
248 io_surface_create_ = reinterpret_cast<IOSurfaceCreateProcPtr>( | |
249 surface_create_ptr); | |
250 io_surface_get_id_ = | |
251 reinterpret_cast<IOSurfaceGetIDProcPtr>(surface_get_id_ptr); | |
252 io_surface_lookup_ = | |
253 reinterpret_cast<IOSurfaceLookupProcPtr>(surface_lookup_ptr); | |
254 io_surface_create_mach_port_ = | |
255 reinterpret_cast<IOSurfaceCreateMachPortProcPtr>( | |
256 surface_create_mach_port_ptr); | |
257 io_surface_lookup_from_mach_port_ = | |
258 reinterpret_cast<IOSurfaceLookupFromMachPortProcPtr>( | |
259 surface_lookup_from_mach_port_ptr); | |
260 io_surface_get_width_ = | |
261 reinterpret_cast<IOSurfaceGetWidthPtr>( | |
262 io_surface_get_width_ptr); | |
263 io_surface_get_height_ = | |
264 reinterpret_cast<IOSurfaceGetHeightPtr>( | |
265 io_surface_get_height_ptr); | |
266 cgl_tex_image_io_surface_2d_ = | |
267 reinterpret_cast<CGLTexImageIOSurface2DProcPtr>( | |
268 tex_image_io_surface_2d_ptr); | |
269 cv_pixel_buffer_get_io_surface_ = | |
270 reinterpret_cast<CVPixelBufferGetIOSurfaceProcPtr>( | |
271 cv_pixel_buffer_get_io_surface); | |
272 initialized_successfully_ = true; | |
273 } | |
274 | |
275 IOSurfaceSupportImpl::~IOSurfaceSupportImpl() { | |
276 CloseLibraryHandles(); | |
277 } | |
278 | |
279 void IOSurfaceSupportImpl::CloseLibraryHandles() { | |
280 if (iosurface_handle_) { | |
281 dlclose(iosurface_handle_); | |
282 iosurface_handle_ = NULL; | |
283 } | |
284 if (opengl_handle_) { | |
285 dlclose(opengl_handle_); | |
286 opengl_handle_ = NULL; | |
287 } | |
288 if (core_video_handle_) { | |
289 dlclose(core_video_handle_); | |
290 core_video_handle_ = NULL; | |
291 } | |
292 } | |
293 | |
294 IOSurfaceSupport* IOSurfaceSupport::Initialize() { | |
295 return IOSurfaceSupportImpl::GetInstance(); | |
296 } | |
297 | |
298 IOSurfaceSupport::IOSurfaceSupport() { | |
299 } | |
300 | |
301 IOSurfaceSupport::~IOSurfaceSupport() { | |
302 } | |
303 | |
OLD | NEW |