Home | History | Annotate | Download | only in gl
      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 
    380