diff options
Diffstat (limited to 'app/surface/io_surface_support_mac.cc')
-rw-r--r-- | app/surface/io_surface_support_mac.cc | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/app/surface/io_surface_support_mac.cc b/app/surface/io_surface_support_mac.cc new file mode 100644 index 0000000..fed66602 --- /dev/null +++ b/app/surface/io_surface_support_mac.cc @@ -0,0 +1,242 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <dlfcn.h> + +#include "base/singleton.h" +#include "app/surface/io_surface_support_mac.h" + +typedef CFTypeRef (*IOSurfaceCreateProcPtr)(CFDictionaryRef properties); +typedef uint32 (*IOSurfaceGetIDProcPtr)(CFTypeRef io_surface); +typedef CFTypeRef (*IOSurfaceLookupProcPtr)(uint32 io_surface_id); +typedef mach_port_t (*IOSurfaceCreateMachPortProcPtr)(CFTypeRef io_surface); +typedef CFTypeRef (*IOSurfaceLookupFromMachPortProcPtr)(mach_port_t port); +typedef CGLError (*CGLTexImageIOSurface2DProcPtr)(CGLContextObj ctx, + GLenum target, + GLenum internal_format, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + CFTypeRef io_surface, + GLuint plane); + +class IOSurfaceSupportImpl : public IOSurfaceSupport { + public: + static IOSurfaceSupportImpl* Initialize(); + + bool InitializedSuccessfully() { + return initialized_successfully_; + } + + virtual CFStringRef GetKIOSurfaceWidth(); + virtual CFStringRef GetKIOSurfaceHeight(); + virtual CFStringRef GetKIOSurfaceBytesPerElement(); + virtual CFStringRef GetKIOSurfaceIsGlobal(); + + virtual CFTypeRef IOSurfaceCreate(CFDictionaryRef properties); + virtual uint32 IOSurfaceGetID(CFTypeRef io_surface); + virtual CFTypeRef IOSurfaceLookup(uint32 io_surface_id); + virtual mach_port_t IOSurfaceCreateMachPort(CFTypeRef io_surface); + virtual CFTypeRef IOSurfaceLookupFromMachPort(mach_port_t port); + + virtual CGLError CGLTexImageIOSurface2D(CGLContextObj ctx, + GLenum target, + GLenum internal_format, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + CFTypeRef io_surface, + GLuint plane); + + private: + IOSurfaceSupportImpl(); + ~IOSurfaceSupportImpl(); + + void* iosurface_handle_; + void* opengl_handle_; + CFStringRef k_io_surface_width_; + CFStringRef k_io_surface_height_; + CFStringRef k_io_surface_bytes_per_element_; + CFStringRef k_io_surface_is_global_; + IOSurfaceCreateProcPtr io_surface_create_; + IOSurfaceGetIDProcPtr io_surface_get_id_; + IOSurfaceLookupProcPtr io_surface_lookup_; + IOSurfaceCreateMachPortProcPtr io_surface_create_mach_port_; + IOSurfaceLookupFromMachPortProcPtr io_surface_lookup_from_mach_port_; + CGLTexImageIOSurface2DProcPtr cgl_tex_image_io_surface_2d_; + bool initialized_successfully_; + + friend struct DefaultSingletonTraits<IOSurfaceSupportImpl>; + DISALLOW_EVIL_CONSTRUCTORS(IOSurfaceSupportImpl); +}; + +static Singleton<IOSurfaceSupportImpl> sole_instance_; + +IOSurfaceSupportImpl* IOSurfaceSupportImpl::Initialize() { + IOSurfaceSupportImpl* impl = sole_instance_.get(); + if (impl->InitializedSuccessfully()) + return impl; + return NULL; +} + +CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceWidth() { + return k_io_surface_width_; +} + +CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceHeight() { + return k_io_surface_height_; +} + +CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceBytesPerElement() { + return k_io_surface_bytes_per_element_; +} + +CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceIsGlobal() { + return k_io_surface_is_global_; +} + +CFTypeRef IOSurfaceSupportImpl::IOSurfaceCreate(CFDictionaryRef properties) { + return io_surface_create_(properties); +} + +uint32 IOSurfaceSupportImpl::IOSurfaceGetID( + CFTypeRef io_surface) { + return io_surface_get_id_(io_surface); +} + +CFTypeRef IOSurfaceSupportImpl::IOSurfaceLookup(uint32 io_surface_id) { + return io_surface_lookup_(io_surface_id); +} + +mach_port_t IOSurfaceSupportImpl::IOSurfaceCreateMachPort( + CFTypeRef io_surface) { + return io_surface_create_mach_port_(io_surface); +} + +CFTypeRef IOSurfaceSupportImpl::IOSurfaceLookupFromMachPort(mach_port_t port) { + return io_surface_lookup_from_mach_port_(port); +} + +CGLError IOSurfaceSupportImpl::CGLTexImageIOSurface2D(CGLContextObj ctx, + GLenum target, + GLenum internal_format, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + CFTypeRef io_surface, + GLuint plane) { + return cgl_tex_image_io_surface_2d_(ctx, + target, + internal_format, + width, + height, + format, + type, + io_surface, + plane); +} + +IOSurfaceSupportImpl::IOSurfaceSupportImpl() + : iosurface_handle_(NULL), + opengl_handle_(NULL), + k_io_surface_width_(NULL), + k_io_surface_height_(NULL), + k_io_surface_bytes_per_element_(NULL), + k_io_surface_is_global_(NULL), + io_surface_create_(NULL), + io_surface_get_id_(NULL), + io_surface_lookup_(NULL), + io_surface_create_mach_port_(NULL), + io_surface_lookup_from_mach_port_(NULL), + cgl_tex_image_io_surface_2d_(NULL), + initialized_successfully_(false) { + iosurface_handle_ = dlopen( + "/System/Library/Frameworks/IOSurface.framework/IOSurface", + RTLD_LAZY | RTLD_LOCAL); + if (!iosurface_handle_) + return; + opengl_handle_ = dlopen( + "/System/Library/Frameworks/OpenGL.framework/OpenGL", + RTLD_LAZY | RTLD_LOCAL); + if (!opengl_handle_) { + dlclose(iosurface_handle_); + iosurface_handle_ = NULL; + return; + } + + void* surface_width_ptr = dlsym(iosurface_handle_, "kIOSurfaceWidth"); + void* surface_height_ptr = dlsym(iosurface_handle_, "kIOSurfaceHeight"); + void* surface_bytes_per_element_ptr = + dlsym(iosurface_handle_, "kIOSurfaceBytesPerElement"); + void* surface_is_global_ptr = + dlsym(iosurface_handle_, "kIOSurfaceIsGlobal"); + void* surface_create_ptr = dlsym(iosurface_handle_, "IOSurfaceCreate"); + void* surface_get_id_ptr = dlsym(iosurface_handle_, "IOSurfaceGetID"); + void* surface_lookup_ptr = dlsym(iosurface_handle_, "IOSurfaceLookup"); + void* surface_create_mach_port_ptr = + dlsym(iosurface_handle_, "IOSurfaceCreateMachPort"); + void* surface_lookup_from_mach_port_ptr = + dlsym(iosurface_handle_, "IOSurfaceLookupFromMachPort"); + void* tex_image_io_surface_2d_ptr = + dlsym(opengl_handle_, "CGLTexImageIOSurface2D"); + if (!surface_width_ptr || + !surface_height_ptr || + !surface_bytes_per_element_ptr || + !surface_is_global_ptr || + !surface_create_ptr || + !surface_get_id_ptr || + !surface_lookup_ptr || + !surface_create_mach_port_ptr || + !surface_lookup_from_mach_port_ptr || + !tex_image_io_surface_2d_ptr) { + dlclose(iosurface_handle_); + iosurface_handle_ = NULL; + dlclose(opengl_handle_); + opengl_handle_ = NULL; + return; + } + + k_io_surface_width_ = *static_cast<CFStringRef*>(surface_width_ptr); + k_io_surface_height_ = *static_cast<CFStringRef*>(surface_height_ptr); + k_io_surface_bytes_per_element_ = + *static_cast<CFStringRef*>(surface_bytes_per_element_ptr); + k_io_surface_is_global_ = *static_cast<CFStringRef*>(surface_is_global_ptr); + io_surface_create_ = reinterpret_cast<IOSurfaceCreateProcPtr>( + surface_create_ptr); + io_surface_get_id_ = + reinterpret_cast<IOSurfaceGetIDProcPtr>(surface_get_id_ptr); + io_surface_lookup_ = + reinterpret_cast<IOSurfaceLookupProcPtr>(surface_lookup_ptr); + io_surface_create_mach_port_ = + reinterpret_cast<IOSurfaceCreateMachPortProcPtr>( + surface_create_mach_port_ptr); + io_surface_lookup_from_mach_port_ = + reinterpret_cast<IOSurfaceLookupFromMachPortProcPtr>( + surface_lookup_from_mach_port_ptr); + cgl_tex_image_io_surface_2d_ = + reinterpret_cast<CGLTexImageIOSurface2DProcPtr>( + tex_image_io_surface_2d_ptr); + initialized_successfully_ = true; +} + +IOSurfaceSupportImpl::~IOSurfaceSupportImpl() { + if (iosurface_handle_) + dlclose(iosurface_handle_); + if (opengl_handle_) + dlclose(opengl_handle_); +} + +IOSurfaceSupport* IOSurfaceSupport::Initialize() { + return IOSurfaceSupportImpl::Initialize(); +} + +IOSurfaceSupport::IOSurfaceSupport() { +} + +IOSurfaceSupport::~IOSurfaceSupport() { +} + |