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 CGLError (*CGLTexImageIOSurface2DProcPtr)(CGLContextObj ctx,
19 GLenum internal_format,
26 typedef CFTypeRef (*CVPixelBufferGetIOSurfaceProcPtr)(
27 CVPixelBufferRef pixel_buffer);
29 class IOSurfaceSupportImpl : public IOSurfaceSupport {
31 static IOSurfaceSupportImpl* GetInstance();
33 bool InitializedSuccessfully() {
34 return initialized_successfully_;
37 virtual CFStringRef GetKIOSurfaceWidth() OVERRIDE;
38 virtual CFStringRef GetKIOSurfaceHeight() OVERRIDE;
39 virtual CFStringRef GetKIOSurfaceBytesPerElement() OVERRIDE;
40 virtual CFStringRef GetKIOSurfaceIsGlobal() OVERRIDE;
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;
48 virtual size_t IOSurfaceGetWidth(CFTypeRef io_surface) OVERRIDE;
49 virtual size_t IOSurfaceGetHeight(CFTypeRef io_surface) OVERRIDE;
51 virtual CGLError CGLTexImageIOSurface2D(CGLContextObj ctx,
53 GLenum internal_format,
59 GLuint plane) OVERRIDE;
61 virtual CFTypeRef CVPixelBufferGetIOSurface(
62 CVPixelBufferRef pixel_buffer) OVERRIDE;
65 IOSurfaceSupportImpl();
66 virtual ~IOSurfaceSupportImpl();
68 void CloseLibraryHandles();
70 void* iosurface_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_;
88 friend struct DefaultSingletonTraits<IOSurfaceSupportImpl>;
89 DISALLOW_COPY_AND_ASSIGN(IOSurfaceSupportImpl);
92 IOSurfaceSupportImpl* IOSurfaceSupportImpl::GetInstance() {
93 IOSurfaceSupportImpl* impl = Singleton<IOSurfaceSupportImpl>::get();
94 if (impl->InitializedSuccessfully())
99 CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceWidth() {
100 return k_io_surface_width_;
103 CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceHeight() {
104 return k_io_surface_height_;
107 CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceBytesPerElement() {
108 return k_io_surface_bytes_per_element_;
111 CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceIsGlobal() {
112 return k_io_surface_is_global_;
115 CFTypeRef IOSurfaceSupportImpl::IOSurfaceCreate(CFDictionaryRef properties) {
116 return io_surface_create_(properties);
119 uint32 IOSurfaceSupportImpl::IOSurfaceGetID(
120 CFTypeRef io_surface) {
121 return io_surface_get_id_(io_surface);
124 CFTypeRef IOSurfaceSupportImpl::IOSurfaceLookup(uint32 io_surface_id) {
125 return io_surface_lookup_(io_surface_id);
128 mach_port_t IOSurfaceSupportImpl::IOSurfaceCreateMachPort(
129 CFTypeRef io_surface) {
130 return io_surface_create_mach_port_(io_surface);
133 CFTypeRef IOSurfaceSupportImpl::IOSurfaceLookupFromMachPort(mach_port_t port) {
134 return io_surface_lookup_from_mach_port_(port);
137 size_t IOSurfaceSupportImpl::IOSurfaceGetWidth(CFTypeRef io_surface) {
138 return io_surface_get_width_(io_surface);
141 size_t IOSurfaceSupportImpl::IOSurfaceGetHeight(CFTypeRef io_surface) {
142 return io_surface_get_height_(io_surface);
146 CGLError IOSurfaceSupportImpl::CGLTexImageIOSurface2D(CGLContextObj ctx,
148 GLenum internal_format,
153 CFTypeRef io_surface,
155 return cgl_tex_image_io_surface_2d_(ctx,
166 CFTypeRef IOSurfaceSupportImpl::CVPixelBufferGetIOSurface(
167 CVPixelBufferRef pixel_buffer) {
168 return cv_pixel_buffer_get_io_surface_(pixel_buffer);
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_ ||
200 !core_video_handle_) {
201 CloseLibraryHandles();
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();
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>(
251 reinterpret_cast<IOSurfaceGetIDProcPtr>(surface_get_id_ptr);
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;
275 IOSurfaceSupportImpl::~IOSurfaceSupportImpl() {
276 CloseLibraryHandles();
279 void IOSurfaceSupportImpl::CloseLibraryHandles() {
280 if (iosurface_handle_) {
281 dlclose(iosurface_handle_);
282 iosurface_handle_ = NULL;
284 if (opengl_handle_) {
285 dlclose(opengl_handle_);
286 opengl_handle_ = NULL;
288 if (core_video_handle_) {
289 dlclose(core_video_handle_);
290 core_video_handle_ = NULL;
294 IOSurfaceSupport* IOSurfaceSupport::Initialize() {
295 return IOSurfaceSupportImpl::GetInstance();
298 IOSurfaceSupport::IOSurfaceSupport() {
301 IOSurfaceSupport::~IOSurfaceSupport() {