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 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 304