Bug 1059066 - Add various IOSurface related methods to MacIOSurface wrapper. r=mattwoodrow
authorJean-Yves Avenard <jyavenard@mozilla.com>
Wed, 03 Sep 2014 17:09:24 +1000
changeset 227244 00a8eb0b6ee3246975b033edad77bd18706ccc29
parent 227243 b3b2792184ac6200a4abb77073c317b6d95ae531
child 227245 65cb5f911c751f25a8cfb9d94f013e6d7986b884
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1059066
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1059066 - Add various IOSurface related methods to MacIOSurface wrapper. r=mattwoodrow
gfx/2d/MacIOSurface.cpp
gfx/2d/MacIOSurface.h
--- a/gfx/2d/MacIOSurface.cpp
+++ b/gfx/2d/MacIOSurface.cpp
@@ -13,48 +13,58 @@
 
 using namespace mozilla;
 // IOSurface signatures
 #define IOSURFACE_FRAMEWORK_PATH \
   "/System/Library/Frameworks/IOSurface.framework/IOSurface"
 #define OPENGL_FRAMEWORK_PATH \
   "/System/Library/Frameworks/OpenGL.framework/OpenGL"
 #define COREGRAPHICS_FRAMEWORK_PATH \
-  "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/CoreGraphics"
-
-
+  "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/" \
+  "CoreGraphics.framework/CoreGraphics"
+#define COREVIDEO_FRAMEWORK_PATH \
+  "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/" \
+  "CoreVideo.framework/CoreVideo"
 
 #define GET_CONST(const_name) \
   ((CFStringRef*) dlsym(sIOSurfaceFramework, const_name))
 #define GET_IOSYM(dest,sym_name) \
   (typeof(dest)) dlsym(sIOSurfaceFramework, sym_name)
 #define GET_CGLSYM(dest,sym_name) \
   (typeof(dest)) dlsym(sOpenGLFramework, sym_name)
 #define GET_CGSYM(dest,sym_name) \
   (typeof(dest)) dlsym(sCoreGraphicsFramework, sym_name)
+#define GET_CVSYM(dest, sym_name) \
+  (typeof(dest)) dlsym(sCoreVideoFramework, sym_name)
 
 MacIOSurfaceLib::LibraryUnloader MacIOSurfaceLib::sLibraryUnloader;
 bool                          MacIOSurfaceLib::isLoaded = false;
 void*                         MacIOSurfaceLib::sIOSurfaceFramework;
 void*                         MacIOSurfaceLib::sOpenGLFramework;
 void*                         MacIOSurfaceLib::sCoreGraphicsFramework;
+void*                         MacIOSurfaceLib::sCoreVideoFramework;
 IOSurfaceCreateFunc           MacIOSurfaceLib::sCreate;
 IOSurfaceGetIDFunc            MacIOSurfaceLib::sGetID;
 IOSurfaceLookupFunc           MacIOSurfaceLib::sLookup;
 IOSurfaceGetBaseAddressFunc   MacIOSurfaceLib::sGetBaseAddress;
-IOSurfaceGetWidthFunc         MacIOSurfaceLib::sWidth;
-IOSurfaceGetHeightFunc        MacIOSurfaceLib::sHeight;
-IOSurfaceGetBytesPerRowFunc   MacIOSurfaceLib::sBytesPerRow;
+IOSurfaceGetBaseAddressOfPlaneFunc  MacIOSurfaceLib::sGetBaseAddressOfPlane;
+IOSurfaceSizeTFunc            MacIOSurfaceLib::sWidth;
+IOSurfaceSizeTFunc            MacIOSurfaceLib::sHeight;
+IOSurfaceSizeTFunc            MacIOSurfaceLib::sPlaneCount;
+IOSurfaceSizeTFunc            MacIOSurfaceLib::sBytesPerRow;
 IOSurfaceGetPropertyMaximumFunc   MacIOSurfaceLib::sGetPropertyMaximum;
+IOSurfaceVoidFunc             MacIOSurfaceLib::sIncrementUseCount;
+IOSurfaceVoidFunc             MacIOSurfaceLib::sDecrementUseCount;
 IOSurfaceLockFunc             MacIOSurfaceLib::sLock;
 IOSurfaceUnlockFunc           MacIOSurfaceLib::sUnlock;
 CGLTexImageIOSurface2DFunc    MacIOSurfaceLib::sTexImage;
 IOSurfaceContextCreateFunc    MacIOSurfaceLib::sIOSurfaceContextCreate;
 IOSurfaceContextCreateImageFunc   MacIOSurfaceLib::sIOSurfaceContextCreateImage;
 IOSurfaceContextGetSurfaceFunc    MacIOSurfaceLib::sIOSurfaceContextGetSurface;
+CVPixelBufferGetIOSurfaceFunc MacIOSurfaceLib::sCVPixelBufferGetIOSurface;
 unsigned int                  (*MacIOSurfaceLib::sCGContextGetTypePtr) (CGContextRef) = nullptr;
 
 CFStringRef                   MacIOSurfaceLib::kPropWidth;
 CFStringRef                   MacIOSurfaceLib::kPropHeight;
 CFStringRef                   MacIOSurfaceLib::kPropBytesPerElem;
 CFStringRef                   MacIOSurfaceLib::kPropBytesPerRow;
 CFStringRef                   MacIOSurfaceLib::kPropIsGlobal;
 
@@ -78,51 +88,72 @@ IOSurfacePtr MacIOSurfaceLib::IOSurfaceL
 IOSurfaceID MacIOSurfaceLib::IOSurfaceGetID(IOSurfacePtr aIOSurfacePtr) {
   return sGetID(aIOSurfacePtr);
 }
 
 void* MacIOSurfaceLib::IOSurfaceGetBaseAddress(IOSurfacePtr aIOSurfacePtr) {
   return sGetBaseAddress(aIOSurfacePtr);
 }
 
+void* MacIOSurfaceLib::IOSurfaceGetBaseAddressOfPlane(IOSurfacePtr aIOSurfacePtr,
+                                                      size_t planeIndex) {
+  return sGetBaseAddressOfPlane(aIOSurfacePtr, planeIndex);
+}
+
+size_t MacIOSurfaceLib::IOSurfaceGetPlaneCount(IOSurfacePtr aIOSurfacePtr) {
+  return sPlaneCount(aIOSurfacePtr);
+}
+
 size_t MacIOSurfaceLib::IOSurfaceGetWidth(IOSurfacePtr aIOSurfacePtr) {
   return sWidth(aIOSurfacePtr);
 }
 
 size_t MacIOSurfaceLib::IOSurfaceGetHeight(IOSurfacePtr aIOSurfacePtr) {
   return sHeight(aIOSurfacePtr);
 }
 
 size_t MacIOSurfaceLib::IOSurfaceGetBytesPerRow(IOSurfacePtr aIOSurfacePtr) {
   return sBytesPerRow(aIOSurfacePtr);
 }
 
 size_t MacIOSurfaceLib::IOSurfaceGetPropertyMaximum(CFStringRef property) {
   return sGetPropertyMaximum(property);
 }
 
-IOReturn MacIOSurfaceLib::IOSurfaceLock(IOSurfacePtr aIOSurfacePtr, 
-                                       uint32_t options, uint32_t *seed) {
+IOReturn MacIOSurfaceLib::IOSurfaceLock(IOSurfacePtr aIOSurfacePtr,
+                                       uint32_t options, uint32_t* seed) {
   return sLock(aIOSurfacePtr, options, seed);
 }
 
-IOReturn MacIOSurfaceLib::IOSurfaceUnlock(IOSurfacePtr aIOSurfacePtr, 
+IOReturn MacIOSurfaceLib::IOSurfaceUnlock(IOSurfacePtr aIOSurfacePtr,
                                          uint32_t options, uint32_t *seed) {
   return sUnlock(aIOSurfacePtr, options, seed);
 }
 
+void MacIOSurfaceLib::IOSurfaceIncrementUseCount(IOSurfacePtr aIOSurfacePtr) {
+  sIncrementUseCount(aIOSurfacePtr);
+}
+
+void MacIOSurfaceLib::IOSurfaceDecrementUseCount(IOSurfacePtr aIOSurfacePtr) {
+  sDecrementUseCount(aIOSurfacePtr);
+}
+
 CGLError MacIOSurfaceLib::CGLTexImageIOSurface2D(CGLContextObj ctxt,
                              GLenum target, GLenum internalFormat,
                              GLsizei width, GLsizei height,
                              GLenum format, GLenum type,
                              IOSurfacePtr ioSurface, GLuint plane) {
   return sTexImage(ctxt, target, internalFormat, width, height,
                    format, type, ioSurface, plane);
 }
 
+IOSurfacePtr MacIOSurfaceLib::CVPixelBufferGetIOSurface(CVPixelBufferRef aPixelBuffer) {
+  return sCVPixelBufferGetIOSurface(aPixelBuffer);
+}
+
 CGContextRef MacIOSurfaceLib::IOSurfaceContextCreate(IOSurfacePtr aIOSurfacePtr,
                              unsigned aWidth, unsigned aHeight,
                              unsigned aBitsPerComponent, unsigned aBytes,
                              CGColorSpaceRef aColorSpace, CGBitmapInfo bitmapInfo) {
   if (!sIOSurfaceContextCreate)
     return nullptr;
   return sIOSurfaceContextCreate(aIOSurfacePtr, aWidth, aHeight, aBitsPerComponent, aBytes, aColorSpace, bitmapInfo);
 }
@@ -154,26 +185,34 @@ void MacIOSurfaceLib::LoadLibrary() {
   isLoaded = true;
   sIOSurfaceFramework = dlopen(IOSURFACE_FRAMEWORK_PATH,
                             RTLD_LAZY | RTLD_LOCAL);
   sOpenGLFramework = dlopen(OPENGL_FRAMEWORK_PATH,
                             RTLD_LAZY | RTLD_LOCAL);
 
   sCoreGraphicsFramework = dlopen(COREGRAPHICS_FRAMEWORK_PATH,
                             RTLD_LAZY | RTLD_LOCAL);
-  if (!sIOSurfaceFramework || !sOpenGLFramework || !sCoreGraphicsFramework) {
+
+  sCoreVideoFramework = dlopen(COREVIDEO_FRAMEWORK_PATH,
+                            RTLD_LAZY | RTLD_LOCAL);
+
+  if (!sIOSurfaceFramework || !sOpenGLFramework || !sCoreGraphicsFramework ||
+      !sCoreVideoFramework) {
     if (sIOSurfaceFramework)
       dlclose(sIOSurfaceFramework);
     if (sOpenGLFramework)
       dlclose(sOpenGLFramework);
     if (sCoreGraphicsFramework)
       dlclose(sCoreGraphicsFramework);
+    if (sCoreVideoFramework)
+      dlclose(sCoreVideoFramework);
     sIOSurfaceFramework = nullptr;
     sOpenGLFramework = nullptr;
     sCoreGraphicsFramework = nullptr;
+    sCoreVideoFramework = nullptr;
     return;
   }
 
   kPropWidth = GetIOConst("kIOSurfaceWidth");
   kPropHeight = GetIOConst("kIOSurfaceHeight");
   kPropBytesPerElem = GetIOConst("kIOSurfaceBytesPerElement");
   kPropBytesPerRow = GetIOConst("kIOSurfaceBytesPerRow");
   kPropIsGlobal = GetIOConst("kIOSurfaceIsGlobal");
@@ -181,45 +220,73 @@ void MacIOSurfaceLib::LoadLibrary() {
   sGetID  = GET_IOSYM(sGetID,  "IOSurfaceGetID");
   sWidth = GET_IOSYM(sWidth, "IOSurfaceGetWidth");
   sHeight = GET_IOSYM(sHeight, "IOSurfaceGetHeight");
   sBytesPerRow = GET_IOSYM(sBytesPerRow, "IOSurfaceGetBytesPerRow");
   sGetPropertyMaximum = GET_IOSYM(sGetPropertyMaximum, "IOSurfaceGetPropertyMaximum");
   sLookup = GET_IOSYM(sLookup, "IOSurfaceLookup");
   sLock = GET_IOSYM(sLock, "IOSurfaceLock");
   sUnlock = GET_IOSYM(sUnlock, "IOSurfaceUnlock");
+  sIncrementUseCount =
+    GET_IOSYM(sIncrementUseCount, "IOSurfaceIncrementUseCount");
+  sDecrementUseCount =
+    GET_IOSYM(sDecrementUseCount, "IOSurfaceDecrementUseCount");
   sGetBaseAddress = GET_IOSYM(sGetBaseAddress, "IOSurfaceGetBaseAddress");
+  sGetBaseAddressOfPlane =
+    GET_IOSYM(sGetBaseAddressOfPlane, "IOSurfaceGetBaseAddressOfPlane");
+  sPlaneCount = GET_IOSYM(sPlaneCount, "IOSurfaceGetPlaneCount");
+
   sTexImage = GET_CGLSYM(sTexImage, "CGLTexImageIOSurface2D");
   sCGContextGetTypePtr = (unsigned int (*)(CGContext*))dlsym(RTLD_DEFAULT, "CGContextGetType");
 
+  sCVPixelBufferGetIOSurface =
+    GET_CVSYM(sCVPixelBufferGetIOSurface, "CVPixelBufferGetIOSurface");
+
   // Optional symbols
   sIOSurfaceContextCreate = GET_CGSYM(sIOSurfaceContextCreate, "CGIOSurfaceContextCreate");
   sIOSurfaceContextCreateImage = GET_CGSYM(sIOSurfaceContextCreateImage, "CGIOSurfaceContextCreateImage");
   sIOSurfaceContextGetSurface = GET_CGSYM(sIOSurfaceContextGetSurface, "CGIOSurfaceContextGetSurface");
 
   if (!sCreate || !sGetID || !sLookup || !sTexImage || !sGetBaseAddress ||
+      !sGetBaseAddressOfPlane || !sPlaneCount ||
       !kPropWidth || !kPropHeight || !kPropBytesPerElem || !kPropIsGlobal ||
-      !sLock || !sUnlock || !sWidth || !sHeight || !kPropBytesPerRow ||
-      !sBytesPerRow || !sGetPropertyMaximum) {
+      !sLock || !sUnlock || !sIncrementUseCount || !sDecrementUseCount ||
+      !sWidth || !sHeight || !kPropBytesPerRow ||
+      !sBytesPerRow || !sGetPropertyMaximum || !sCVPixelBufferGetIOSurface) {
     CloseLibrary();
   }
 }
 
 void MacIOSurfaceLib::CloseLibrary() {
   if (sIOSurfaceFramework) {
     dlclose(sIOSurfaceFramework);
   }
   if (sOpenGLFramework) {
     dlclose(sOpenGLFramework);
   }
+  if (sCoreVideoFramework) {
+    dlclose(sCoreVideoFramework);
+  }
   sIOSurfaceFramework = nullptr;
   sOpenGLFramework = nullptr;
+  sCoreVideoFramework = nullptr;
+}
+
+MacIOSurface::MacIOSurface(const void* aIOSurfacePtr,
+                           double aContentsScaleFactor, bool aHasAlpha)
+  : mIOSurfacePtr(aIOSurfacePtr)
+  , mContentsScaleFactor(aContentsScaleFactor)
+  , mHasAlpha(aHasAlpha)
+{
+  CFRetain(mIOSurfacePtr);
+  IncrementUseCount();
 }
 
 MacIOSurface::~MacIOSurface() {
+  DecrementUseCount();
   CFRelease(mIOSurfacePtr);
 }
 
 TemporaryRef<MacIOSurface> MacIOSurface::CreateIOSurface(int aWidth, int aHeight,
                                                          double aContentsScaleFactor,
                                                          bool aHasAlpha) {
   if (!MacIOSurfaceLib::isInit() || aContentsScaleFactor <= 0)
     return nullptr;
@@ -260,16 +327,19 @@ TemporaryRef<MacIOSurface> MacIOSurface:
     return nullptr;
 
   RefPtr<MacIOSurface> ioSurface = new MacIOSurface(surfaceRef, aContentsScaleFactor, aHasAlpha);
   if (!ioSurface) {
     ::CFRelease(surfaceRef);
     return nullptr;
   }
 
+  // Release the IOSurface because MacIOSurface retained it
+  CFRelease(surfaceRef);
+
   return ioSurface.forget();
 }
 
 TemporaryRef<MacIOSurface> MacIOSurface::LookupSurface(IOSurfaceID aIOSurfaceID,
                                                        double aContentsScaleFactor,
                                                        bool aHasAlpha) { 
   if (!MacIOSurfaceLib::isInit() || aContentsScaleFactor <= 0)
     return nullptr;
@@ -278,37 +348,51 @@ TemporaryRef<MacIOSurface> MacIOSurface:
   if (!surfaceRef)
     return nullptr;
 
   RefPtr<MacIOSurface> ioSurface = new MacIOSurface(surfaceRef, aContentsScaleFactor, aHasAlpha);
   if (!ioSurface) {
     ::CFRelease(surfaceRef);
     return nullptr;
   }
+
+  // Release the IOSurface because MacIOSurface retained it
+  CFRelease(surfaceRef);
+
   return ioSurface.forget();
 }
 
 IOSurfaceID MacIOSurface::GetIOSurfaceID() { 
   return MacIOSurfaceLib::IOSurfaceGetID(mIOSurfacePtr);
 }
 
 void* MacIOSurface::GetBaseAddress() { 
   return MacIOSurfaceLib::IOSurfaceGetBaseAddress(mIOSurfacePtr);
 }
 
+void* MacIOSurface::GetBaseAddressOfPlane(size_t aPlaneIndex)
+{
+  return MacIOSurfaceLib::IOSurfaceGetBaseAddressOfPlane(mIOSurfacePtr,
+                                                         aPlaneIndex);
+}
+
 size_t MacIOSurface::GetWidth() {
   size_t intScaleFactor = ceil(mContentsScaleFactor);
   return GetDevicePixelWidth() / intScaleFactor;
 }
 
 size_t MacIOSurface::GetHeight() {
   size_t intScaleFactor = ceil(mContentsScaleFactor);
   return GetDevicePixelHeight() / intScaleFactor;
 }
 
+size_t MacIOSurface::GetPlaneCount() {
+  return MacIOSurfaceLib::IOSurfaceGetPlaneCount(mIOSurfacePtr);
+}
+
 /*static*/ size_t MacIOSurface::GetMaxWidth() {
   return MacIOSurfaceLib::IOSurfaceGetPropertyMaximum(MacIOSurfaceLib::kPropWidth);
 }
 
 /*static*/ size_t MacIOSurface::GetMaxHeight() {
   return MacIOSurfaceLib::IOSurfaceGetPropertyMaximum(MacIOSurfaceLib::kPropHeight);
 }
 
@@ -319,16 +403,24 @@ size_t MacIOSurface::GetDevicePixelWidth
 size_t MacIOSurface::GetDevicePixelHeight() {
   return MacIOSurfaceLib::IOSurfaceGetHeight(mIOSurfacePtr);
 }
 
 size_t MacIOSurface::GetBytesPerRow() { 
   return MacIOSurfaceLib::IOSurfaceGetBytesPerRow(mIOSurfacePtr);
 }
 
+void MacIOSurface::IncrementUseCount() {
+  MacIOSurfaceLib::IOSurfaceIncrementUseCount(mIOSurfacePtr);
+}
+
+void MacIOSurface::DecrementUseCount() {
+  MacIOSurfaceLib::IOSurfaceDecrementUseCount(mIOSurfacePtr);
+}
+
 #define READ_ONLY 0x1
 void MacIOSurface::Lock() {
   MacIOSurfaceLib::IOSurfaceLock(mIOSurfacePtr, READ_ONLY, nullptr);
 }
 
 void MacIOSurface::Unlock() {
   MacIOSurfaceLib::IOSurfaceUnlock(mIOSurfacePtr, READ_ONLY, nullptr);
 }
@@ -408,19 +500,16 @@ TemporaryRef<MacIOSurface> MacIOSurface:
                                                                     bool aHasAlpha) {
   if (!MacIOSurfaceLib::isInit() || aContentsScaleFactor <= 0)
     return nullptr;
 
   IOSurfacePtr surfaceRef = MacIOSurfaceLib::IOSurfaceContextGetSurface(aContext);
   if (!surfaceRef)
     return nullptr;
 
-  // Retain the IOSurface because MacIOSurface will release it
-  CFRetain(surfaceRef);
-
   RefPtr<MacIOSurface> ioSurface = new MacIOSurface(surfaceRef, aContentsScaleFactor, aHasAlpha);
   if (!ioSurface) {
     ::CFRelease(surfaceRef);
     return nullptr;
   }
   return ioSurface.forget();
 }
 
--- a/gfx/2d/MacIOSurface.h
+++ b/gfx/2d/MacIOSurface.h
@@ -9,40 +9,41 @@
 #ifdef XP_MACOSX
 #include <QuartzCore/QuartzCore.h>
 #include <dlfcn.h>
 #include "mozilla/RefPtr.h"
 
 typedef CFTypeRef IOSurfacePtr;
 typedef IOSurfacePtr (*IOSurfaceCreateFunc) (CFDictionaryRef properties);
 typedef IOSurfacePtr (*IOSurfaceLookupFunc) (uint32_t io_surface_id);
-typedef IOSurfaceID (*IOSurfaceGetIDFunc) (CFTypeRef io_surface);
-typedef IOReturn (*IOSurfaceLockFunc) (CFTypeRef io_surface, 
-                                       uint32_t options, 
-                                       uint32_t *seed);
-typedef IOReturn (*IOSurfaceUnlockFunc) (CFTypeRef io_surface, 
-                                         uint32_t options, 
-                                         uint32_t *seed);
-typedef void* (*IOSurfaceGetBaseAddressFunc) (CFTypeRef io_surface);
-typedef size_t (*IOSurfaceGetWidthFunc) (IOSurfacePtr io_surface);
-typedef size_t (*IOSurfaceGetHeightFunc) (IOSurfacePtr io_surface);
-typedef size_t (*IOSurfaceGetBytesPerRowFunc) (IOSurfacePtr io_surface);
+typedef IOSurfaceID (*IOSurfaceGetIDFunc)(IOSurfacePtr io_surface);
+typedef void (*IOSurfaceVoidFunc)(IOSurfacePtr io_surface);
+typedef IOReturn (*IOSurfaceLockFunc)(IOSurfacePtr io_surface, uint32_t options,
+                                      uint32_t *seed);
+typedef IOReturn (*IOSurfaceUnlockFunc)(IOSurfacePtr io_surface,
+                                        uint32_t options, uint32_t *seed);
+typedef void* (*IOSurfaceGetBaseAddressFunc)(IOSurfacePtr io_surface);
+typedef void* (*IOSurfaceGetBaseAddressOfPlaneFunc)(IOSurfacePtr io_surface,
+                                                    size_t planeIndex);
+typedef size_t (*IOSurfaceSizeTFunc)(IOSurfacePtr io_surface);
 typedef size_t (*IOSurfaceGetPropertyMaximumFunc) (CFStringRef property);
 typedef CGLError (*CGLTexImageIOSurface2DFunc) (CGLContextObj ctxt,
                              GLenum target, GLenum internalFormat,
                              GLsizei width, GLsizei height,
                              GLenum format, GLenum type,
                              IOSurfacePtr ioSurface, GLuint plane);
 typedef CGContextRef (*IOSurfaceContextCreateFunc)(CFTypeRef io_surface,
                              unsigned width, unsigned height,
                              unsigned bitsPerComponent, unsigned bytes,
                              CGColorSpaceRef colorSpace, CGBitmapInfo bitmapInfo);
 typedef CGImageRef (*IOSurfaceContextCreateImageFunc)(CGContextRef ref);
 typedef IOSurfacePtr (*IOSurfaceContextGetSurfaceFunc)(CGContextRef ref);
 
+typedef IOSurfacePtr (*CVPixelBufferGetIOSurfaceFunc)(
+  CVPixelBufferRef pixelBuffer);
 
 #import <OpenGL/OpenGL.h>
 #include "2D.h"
 #include "mozilla/RefPtr.h"
 
 struct _CGLContextObject;
 
 typedef _CGLContextObject* CGLContextObj;
@@ -59,41 +60,50 @@ enum CGContextType {
 
 CGContextType GetContextType(CGContextRef ref);
 
 class MacIOSurface : public mozilla::RefCounted<MacIOSurface> {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(MacIOSurface)
   typedef mozilla::gfx::SourceSurface SourceSurface;
 
+  // The usage count of the IOSurface is increased by 1 during the lifetime
+  // of the MacIOSurface instance.
+  // MacIOSurface holds a reference to the corresponding IOSurface.
+
   static mozilla::TemporaryRef<MacIOSurface> CreateIOSurface(int aWidth, int aHeight,
                                                              double aContentsScaleFactor = 1.0,
                                                              bool aHasAlpha = true);
   static void ReleaseIOSurface(MacIOSurface *aIOSurface);
   static mozilla::TemporaryRef<MacIOSurface> LookupSurface(IOSurfaceID aSurfaceID,
                                                            double aContentsScaleFactor = 1.0,
                                                            bool aHasAlpha = true);
 
-  explicit MacIOSurface(const void *aIOSurfacePtr, double aContentsScaleFactor = 1.0, bool aHasAlpha = true)
-    : mIOSurfacePtr(aIOSurfacePtr), mContentsScaleFactor(aContentsScaleFactor), mHasAlpha(aHasAlpha) {}
+  explicit MacIOSurface(const void *aIOSurfacePtr,
+                        double aContentsScaleFactor = 1.0,
+                        bool aHasAlpha = true);
   virtual ~MacIOSurface();
   IOSurfaceID GetIOSurfaceID();
   void *GetBaseAddress();
+  void *GetBaseAddressOfPlane(size_t planeIndex);
+  size_t GetPlaneCount();
   // GetWidth() and GetHeight() return values in "display pixels".  A
   // "display pixel" is the smallest fully addressable part of a display.
   // But in HiDPI modes each "display pixel" corresponds to more than one
   // device pixel.  Use GetDevicePixel**() to get device pixels.
   size_t GetWidth();
   size_t GetHeight();
   double GetContentsScaleFactor() { return mContentsScaleFactor; }
   size_t GetDevicePixelWidth();
   size_t GetDevicePixelHeight();
   size_t GetBytesPerRow();
   void Lock();
   void Unlock();
+  void IncrementUseCount();
+  void DecrementUseCount();
   bool HasAlpha() { return mHasAlpha; }
   // We would like to forward declare NSOpenGLContext, but it is an @interface
   // and this file is also used from c++, so we use a void *.
   CGLError CGLTexImageIOSurface2D(CGLContextObj ctxt);
   mozilla::TemporaryRef<SourceSurface> GetAsSurface();
   CGContextRef CreateIOSurfaceContext();
 
   // FIXME This doesn't really belong here
@@ -112,62 +122,74 @@ private:
 };
 
 class MacIOSurfaceLib: public MacIOSurface {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(MacIOSurfaceLib)
   static void                        *sIOSurfaceFramework;
   static void                        *sOpenGLFramework;
   static void                        *sCoreGraphicsFramework;
+  static void                        *sCoreVideoFramework;
   static bool                         isLoaded;
   static IOSurfaceCreateFunc          sCreate;
   static IOSurfaceGetIDFunc           sGetID;
   static IOSurfaceLookupFunc          sLookup;
   static IOSurfaceGetBaseAddressFunc  sGetBaseAddress;
+  static IOSurfaceGetBaseAddressOfPlaneFunc sGetBaseAddressOfPlane;
+  static IOSurfaceSizeTFunc           sPlaneCount;
   static IOSurfaceLockFunc            sLock;
   static IOSurfaceUnlockFunc          sUnlock;
-  static IOSurfaceGetWidthFunc        sWidth;
-  static IOSurfaceGetHeightFunc       sHeight;
-  static IOSurfaceGetBytesPerRowFunc  sBytesPerRow;
+  static IOSurfaceVoidFunc            sIncrementUseCount;
+  static IOSurfaceVoidFunc            sDecrementUseCount;
+  static IOSurfaceSizeTFunc           sWidth;
+  static IOSurfaceSizeTFunc           sHeight;
+  static IOSurfaceSizeTFunc           sBytesPerRow;
   static IOSurfaceGetPropertyMaximumFunc  sGetPropertyMaximum;
   static CGLTexImageIOSurface2DFunc   sTexImage;
   static IOSurfaceContextCreateFunc   sIOSurfaceContextCreate;
   static IOSurfaceContextCreateImageFunc  sIOSurfaceContextCreateImage;
   static IOSurfaceContextGetSurfaceFunc   sIOSurfaceContextGetSurface;
+  static CVPixelBufferGetIOSurfaceFunc    sCVPixelBufferGetIOSurface;
   static CFStringRef                  kPropWidth;
   static CFStringRef                  kPropHeight;
   static CFStringRef                  kPropBytesPerElem;
   static CFStringRef                  kPropBytesPerRow;
   static CFStringRef                  kPropIsGlobal;
 
   static bool isInit();
   static CFStringRef GetIOConst(const char* symbole);
   static IOSurfacePtr IOSurfaceCreate(CFDictionaryRef properties);
   static IOSurfacePtr IOSurfaceLookup(IOSurfaceID aIOSurfaceID);
   static IOSurfaceID  IOSurfaceGetID(IOSurfacePtr aIOSurfacePtr);
   static void*        IOSurfaceGetBaseAddress(IOSurfacePtr aIOSurfacePtr);
+  static void*        IOSurfaceGetBaseAddressOfPlane(IOSurfacePtr aIOSurfacePtr,
+                                                     size_t aPlaneIndex);
+  static size_t       IOSurfaceGetPlaneCount(IOSurfacePtr aIOSurfacePtr);
   static size_t       IOSurfaceGetWidth(IOSurfacePtr aIOSurfacePtr);
   static size_t       IOSurfaceGetHeight(IOSurfacePtr aIOSurfacePtr);
   static size_t       IOSurfaceGetBytesPerRow(IOSurfacePtr aIOSurfacePtr);
   static size_t       IOSurfaceGetPropertyMaximum(CFStringRef property);
-  static IOReturn     IOSurfaceLock(IOSurfacePtr aIOSurfacePtr, 
+  static IOReturn     IOSurfaceLock(IOSurfacePtr aIOSurfacePtr,
                                     uint32_t options, uint32_t *seed);
-  static IOReturn     IOSurfaceUnlock(IOSurfacePtr aIOSurfacePtr, 
+  static IOReturn     IOSurfaceUnlock(IOSurfacePtr aIOSurfacePtr,
                                       uint32_t options, uint32_t *seed);
+  static void         IOSurfaceIncrementUseCount(IOSurfacePtr aIOSurfacePtr);
+  static void         IOSurfaceDecrementUseCount(IOSurfacePtr aIOSurfacePtr);
   static CGLError     CGLTexImageIOSurface2D(CGLContextObj ctxt,
                              GLenum target, GLenum internalFormat,
                              GLsizei width, GLsizei height,
                              GLenum format, GLenum type,
                              IOSurfacePtr ioSurface, GLuint plane);
   static CGContextRef IOSurfaceContextCreate(IOSurfacePtr aIOSurfacePtr,
                              unsigned aWidth, unsigned aHeight,
                              unsigned aBitsPerCompoent, unsigned aBytes,
                              CGColorSpaceRef aColorSpace, CGBitmapInfo bitmapInfo);
   static CGImageRef   IOSurfaceContextCreateImage(CGContextRef ref);
   static IOSurfacePtr IOSurfaceContextGetSurface(CGContextRef ref);
+  static IOSurfacePtr CVPixelBufferGetIOSurface(CVPixelBufferRef apixelBuffer);
   static unsigned int (*sCGContextGetTypePtr) (CGContextRef);
   static void LoadLibrary();
   static void CloseLibrary();
 
   // Static deconstructor
   static class LibraryUnloader {
   public:
     ~LibraryUnloader() {