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