Bug 1061525 - Part 1: Add support for planar MacIOSurfaces. r=BenWa
☠☠ backed out by 5ddf7484b5ea ☠ ☠
authorMatt Woodrow <mwoodrow@mozilla.com>
Mon, 03 Aug 2015 17:57:19 -0400
changeset 287647 5dfbd6e73c7afe11aea5e842100373c9fdf8fc1e
parent 287646 c2b62aef6a4421753e42b9856a55579c62b98921
child 287648 fae6602192a7e4881246f84b7f7a6f9a69088aeb
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBenWa
bugs1061525
milestone42.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 1061525 - Part 1: Add support for planar MacIOSurfaces. r=BenWa
gfx/2d/MacIOSurface.cpp
gfx/2d/MacIOSurface.h
gfx/2d/Types.h
gfx/layers/LayersLogging.cpp
--- a/gfx/2d/MacIOSurface.cpp
+++ b/gfx/2d/MacIOSurface.cpp
@@ -41,31 +41,32 @@ void*                         MacIOSurfa
 void*                         MacIOSurfaceLib::sOpenGLFramework;
 void*                         MacIOSurfaceLib::sCoreGraphicsFramework;
 void*                         MacIOSurfaceLib::sCoreVideoFramework;
 IOSurfaceCreateFunc           MacIOSurfaceLib::sCreate;
 IOSurfaceGetIDFunc            MacIOSurfaceLib::sGetID;
 IOSurfaceLookupFunc           MacIOSurfaceLib::sLookup;
 IOSurfaceGetBaseAddressFunc   MacIOSurfaceLib::sGetBaseAddress;
 IOSurfaceGetBaseAddressOfPlaneFunc  MacIOSurfaceLib::sGetBaseAddressOfPlane;
-IOSurfaceSizeTFunc            MacIOSurfaceLib::sWidth;
-IOSurfaceSizeTFunc            MacIOSurfaceLib::sHeight;
+IOSurfaceSizePlaneTFunc       MacIOSurfaceLib::sWidth;
+IOSurfaceSizePlaneTFunc       MacIOSurfaceLib::sHeight;
 IOSurfaceSizeTFunc            MacIOSurfaceLib::sPlaneCount;
-IOSurfaceSizeTFunc            MacIOSurfaceLib::sBytesPerRow;
+IOSurfaceSizePlaneTFunc       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;
+IOSurfacePixelFormatFunc      MacIOSurfaceLib::sPixelFormat;
 
 CFStringRef                   MacIOSurfaceLib::kPropWidth;
 CFStringRef                   MacIOSurfaceLib::kPropHeight;
 CFStringRef                   MacIOSurfaceLib::kPropBytesPerElem;
 CFStringRef                   MacIOSurfaceLib::kPropBytesPerRow;
 CFStringRef                   MacIOSurfaceLib::kPropIsGlobal;
 
 bool MacIOSurfaceLib::isInit() {
@@ -97,32 +98,36 @@ void* MacIOSurfaceLib::IOSurfaceGetBaseA
                                                       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::IOSurfaceGetWidth(IOSurfacePtr aIOSurfacePtr, size_t plane) {
+  return sWidth(aIOSurfacePtr, plane);
 }
 
-size_t MacIOSurfaceLib::IOSurfaceGetHeight(IOSurfacePtr aIOSurfacePtr) {
-  return sHeight(aIOSurfacePtr);
+size_t MacIOSurfaceLib::IOSurfaceGetHeight(IOSurfacePtr aIOSurfacePtr, size_t plane) {
+  return sHeight(aIOSurfacePtr, plane);
 }
 
-size_t MacIOSurfaceLib::IOSurfaceGetBytesPerRow(IOSurfacePtr aIOSurfacePtr) {
-  return sBytesPerRow(aIOSurfacePtr);
+size_t MacIOSurfaceLib::IOSurfaceGetBytesPerRow(IOSurfacePtr aIOSurfacePtr, size_t plane) {
+  return sBytesPerRow(aIOSurfacePtr, plane);
 }
 
 size_t MacIOSurfaceLib::IOSurfaceGetPropertyMaximum(CFStringRef property) {
   return sGetPropertyMaximum(property);
 }
 
+OSType MacIOSurfaceLib::IOSurfaceGetPixelFormat(IOSurfacePtr aIOSurfacePtr) {
+  return sPixelFormat(aIOSurfacePtr);
+}
+
 IOReturn MacIOSurfaceLib::IOSurfaceLock(IOSurfacePtr aIOSurfacePtr,
                                        uint32_t options, uint32_t* seed) {
   return sLock(aIOSurfacePtr, options, seed);
 }
 
 IOReturn MacIOSurfaceLib::IOSurfaceUnlock(IOSurfacePtr aIOSurfacePtr,
                                          uint32_t options, uint32_t *seed) {
   return sUnlock(aIOSurfacePtr, options, seed);
@@ -213,31 +218,32 @@ void MacIOSurfaceLib::LoadLibrary() {
 
   kPropWidth = GetIOConst("kIOSurfaceWidth");
   kPropHeight = GetIOConst("kIOSurfaceHeight");
   kPropBytesPerElem = GetIOConst("kIOSurfaceBytesPerElement");
   kPropBytesPerRow = GetIOConst("kIOSurfaceBytesPerRow");
   kPropIsGlobal = GetIOConst("kIOSurfaceIsGlobal");
   sCreate = GET_IOSYM(sCreate, "IOSurfaceCreate");
   sGetID  = GET_IOSYM(sGetID,  "IOSurfaceGetID");
-  sWidth = GET_IOSYM(sWidth, "IOSurfaceGetWidth");
-  sHeight = GET_IOSYM(sHeight, "IOSurfaceGetHeight");
-  sBytesPerRow = GET_IOSYM(sBytesPerRow, "IOSurfaceGetBytesPerRow");
+  sWidth = GET_IOSYM(sWidth, "IOSurfaceGetWidthOfPlane");
+  sHeight = GET_IOSYM(sHeight, "IOSurfaceGetHeightOfPlane");
+  sBytesPerRow = GET_IOSYM(sBytesPerRow, "IOSurfaceGetBytesPerRowOfPlane");
   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");
+  sPixelFormat = GET_IOSYM(sPixelFormat, "IOSurfaceGetPixelFormat");
 
   sTexImage = GET_CGLSYM(sTexImage, "CGLTexImageIOSurface2D");
   sCGContextGetTypePtr = (unsigned int (*)(CGContext*))dlsym(RTLD_DEFAULT, "CGContextGetType");
 
   sCVPixelBufferGetIOSurface =
     GET_CVSYM(sCVPixelBufferGetIOSurface, "CVPixelBufferGetIOSurface");
 
   // Optional symbols
@@ -369,24 +375,24 @@ void* MacIOSurface::GetBaseAddress() {
 }
 
 void* MacIOSurface::GetBaseAddressOfPlane(size_t aPlaneIndex)
 {
   return MacIOSurfaceLib::IOSurfaceGetBaseAddressOfPlane(mIOSurfacePtr,
                                                          aPlaneIndex);
 }
 
-size_t MacIOSurface::GetWidth() {
+size_t MacIOSurface::GetWidth(size_t plane) {
   size_t intScaleFactor = ceil(mContentsScaleFactor);
-  return GetDevicePixelWidth() / intScaleFactor;
+  return GetDevicePixelWidth(plane) / intScaleFactor;
 }
 
-size_t MacIOSurface::GetHeight() {
+size_t MacIOSurface::GetHeight(size_t plane) {
   size_t intScaleFactor = ceil(mContentsScaleFactor);
-  return GetDevicePixelHeight() / intScaleFactor;
+  return GetDevicePixelHeight(plane) / intScaleFactor;
 }
 
 size_t MacIOSurface::GetPlaneCount() {
   return MacIOSurfaceLib::IOSurfaceGetPlaneCount(mIOSurfacePtr);
 }
 
 /*static*/ size_t MacIOSurface::GetMaxWidth() {
   if (!MacIOSurfaceLib::isInit())
@@ -395,26 +401,30 @@ size_t MacIOSurface::GetPlaneCount() {
 }
 
 /*static*/ size_t MacIOSurface::GetMaxHeight() {
   if (!MacIOSurfaceLib::isInit())
     return -1;
   return MacIOSurfaceLib::IOSurfaceGetPropertyMaximum(MacIOSurfaceLib::kPropHeight);
 }
 
-size_t MacIOSurface::GetDevicePixelWidth() {
-  return MacIOSurfaceLib::IOSurfaceGetWidth(mIOSurfacePtr);
+size_t MacIOSurface::GetDevicePixelWidth(size_t plane) {
+  return MacIOSurfaceLib::IOSurfaceGetWidth(mIOSurfacePtr, plane);
 }
 
-size_t MacIOSurface::GetDevicePixelHeight() {
-  return MacIOSurfaceLib::IOSurfaceGetHeight(mIOSurfacePtr);
+size_t MacIOSurface::GetDevicePixelHeight(size_t plane) {
+  return MacIOSurfaceLib::IOSurfaceGetHeight(mIOSurfacePtr, plane);
 }
 
-size_t MacIOSurface::GetBytesPerRow() { 
-  return MacIOSurfaceLib::IOSurfaceGetBytesPerRow(mIOSurfacePtr);
+size_t MacIOSurface::GetBytesPerRow(size_t plane) {
+  return MacIOSurfaceLib::IOSurfaceGetBytesPerRow(mIOSurfacePtr, plane);
+}
+
+OSType MacIOSurface::GetPixelFormat() {
+  return MacIOSurfaceLib::IOSurfaceGetPixelFormat(mIOSurfacePtr);
 }
 
 void MacIOSurface::IncrementUseCount() {
   MacIOSurfaceLib::IOSurfaceIncrementUseCount(mIOSurfacePtr);
 }
 
 void MacIOSurface::DecrementUseCount() {
   MacIOSurfaceLib::IOSurfaceDecrementUseCount(mIOSurfacePtr);
@@ -455,27 +465,62 @@ MacIOSurface::GetAsSurface() {
                                       mozilla::gfx::SurfaceFormat::B8G8R8X8;
 
   RefPtr<SourceSurfaceRawData> surf = new SourceSurfaceRawData();
   surf->InitWrappingData(dataCpy, IntSize(ioWidth, ioHeight), bytesPerRow, format, true);
 
   return surf.forget();
 }
 
+SurfaceFormat
+MacIOSurface::GetFormat()
+{
+  OSType pixelFormat = GetPixelFormat();
+  if (pixelFormat == '420v') {
+    return SurfaceFormat::NV12;
+  } else  {
+    return HasAlpha() ? SurfaceFormat::R8G8B8A8 : SurfaceFormat::R8G8B8X8;
+  }
+}
+
 CGLError
-MacIOSurface::CGLTexImageIOSurface2D(CGLContextObj ctx)
+MacIOSurface::CGLTexImageIOSurface2D(CGLContextObj ctx, size_t plane)
 {
-  return MacIOSurfaceLib::CGLTexImageIOSurface2D(ctx,
+  MOZ_ASSERT(plane >= 0);
+  OSType pixelFormat = GetPixelFormat();
+
+  GLenum internalFormat;
+  GLenum format;
+  GLenum type;
+  if (pixelFormat == '420v') {
+    MOZ_ASSERT(GetPlaneCount() == 2);
+    MOZ_ASSERT(plane < 2);
+
+    if (plane == 0) {
+      internalFormat = format = GL_LUMINANCE;
+    } else {
+      internalFormat = format = GL_LUMINANCE_ALPHA;
+    }
+    type = GL_UNSIGNED_BYTE;
+  } else  {
+    MOZ_ASSERT(plane == 0);
+
+    internalFormat = HasAlpha() ? GL_RGBA : GL_RGB;
+    format = GL_BGRA;
+    type = GL_UNSIGNED_INT_8_8_8_8_REV;
+  }
+  CGLError temp =  MacIOSurfaceLib::CGLTexImageIOSurface2D(ctx,
                                                 GL_TEXTURE_RECTANGLE_ARB,
-                                                HasAlpha() ? GL_RGBA : GL_RGB,
-                                                GetDevicePixelWidth(),
-                                                GetDevicePixelHeight(),
-                                                GL_BGRA,
-                                                GL_UNSIGNED_INT_8_8_8_8_REV,
-                                                mIOSurfacePtr, 0);
+                                                internalFormat,
+                                                GetDevicePixelWidth(plane),
+                                                GetDevicePixelHeight(plane),
+                                                format,
+                                                type,
+                                                mIOSurfacePtr, plane);
+  return temp;
 }
 
 static
 CGColorSpaceRef CreateSystemColorSpace() {
   CGColorSpaceRef cspace = ::CGDisplayCopyColorSpace(::CGMainDisplayID());
   if (!cspace) {
     cspace = ::CGColorSpaceCreateDeviceRGB();
   }
--- a/gfx/2d/MacIOSurface.h
+++ b/gfx/2d/MacIOSurface.h
@@ -19,32 +19,35 @@ typedef void (*IOSurfaceVoidFunc)(IOSurf
 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 (*IOSurfaceSizePlaneTFunc)(IOSurfacePtr io_surface, size_t plane);
 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);
 
+typedef OSType (*IOSurfacePixelFormatFunc)(IOSurfacePtr io_surface);
+
 #import <OpenGL/OpenGL.h>
 #include "2D.h"
 #include "mozilla/RefPtr.h"
 
 struct _CGLContextObject;
 
 typedef _CGLContextObject* CGLContextObj;
 typedef struct CGContext* CGContextRef;
@@ -80,34 +83,36 @@ public:
   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();
+  OSType GetPixelFormat();
   // 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();
+  size_t GetWidth(size_t plane = 0);
+  size_t GetHeight(size_t plane = 0);
   double GetContentsScaleFactor() { return mContentsScaleFactor; }
-  size_t GetDevicePixelWidth();
-  size_t GetDevicePixelHeight();
-  size_t GetBytesPerRow();
+  size_t GetDevicePixelWidth(size_t plane = 0);
+  size_t GetDevicePixelHeight(size_t plane = 0);
+  size_t GetBytesPerRow(size_t plane = 0);
   void Lock();
   void Unlock();
   void IncrementUseCount();
   void DecrementUseCount();
   bool HasAlpha() { return mHasAlpha; }
+  mozilla::gfx::SurfaceFormat GetFormat();
   // 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);
+  CGLError CGLTexImageIOSurface2D(CGLContextObj ctxt, size_t plane = 0);
   already_AddRefed<SourceSurface> GetAsSurface();
   CGContextRef CreateIOSurfaceContext();
 
   // FIXME This doesn't really belong here
   static CGImageRef CreateImageFromIOSurfaceContext(CGContextRef aContext);
   static already_AddRefed<MacIOSurface> IOSurfaceContextGetSurface(CGContextRef aContext,
                                                                         double aContentsScaleFactor = 1.0,
                                                                         bool aHasAlpha = true);
@@ -134,43 +139,44 @@ public:
   static IOSurfaceLookupFunc          sLookup;
   static IOSurfaceGetBaseAddressFunc  sGetBaseAddress;
   static IOSurfaceGetBaseAddressOfPlaneFunc sGetBaseAddressOfPlane;
   static IOSurfaceSizeTFunc           sPlaneCount;
   static IOSurfaceLockFunc            sLock;
   static IOSurfaceUnlockFunc          sUnlock;
   static IOSurfaceVoidFunc            sIncrementUseCount;
   static IOSurfaceVoidFunc            sDecrementUseCount;
-  static IOSurfaceSizeTFunc           sWidth;
-  static IOSurfaceSizeTFunc           sHeight;
-  static IOSurfaceSizeTFunc           sBytesPerRow;
+  static IOSurfaceSizePlaneTFunc      sWidth;
+  static IOSurfaceSizePlaneTFunc      sHeight;
+  static IOSurfaceSizePlaneTFunc      sBytesPerRow;
   static IOSurfaceGetPropertyMaximumFunc  sGetPropertyMaximum;
   static CGLTexImageIOSurface2DFunc   sTexImage;
   static IOSurfaceContextCreateFunc   sIOSurfaceContextCreate;
   static IOSurfaceContextCreateImageFunc  sIOSurfaceContextCreateImage;
   static IOSurfaceContextGetSurfaceFunc   sIOSurfaceContextGetSurface;
   static CVPixelBufferGetIOSurfaceFunc    sCVPixelBufferGetIOSurface;
+  static IOSurfacePixelFormatFunc     sPixelFormat;
   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       IOSurfaceGetWidth(IOSurfacePtr aIOSurfacePtr, size_t plane);
+  static size_t       IOSurfaceGetHeight(IOSurfacePtr aIOSurfacePtr, size_t plane);
+  static size_t       IOSurfaceGetBytesPerRow(IOSurfacePtr aIOSurfacePtr, size_t plane);
   static size_t       IOSurfaceGetPropertyMaximum(CFStringRef property);
   static IOReturn     IOSurfaceLock(IOSurfacePtr aIOSurfacePtr,
                                     uint32_t options, uint32_t *seed);
   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,
@@ -180,16 +186,17 @@ public:
                              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 OSType       IOSurfaceGetPixelFormat(IOSurfacePtr aIOSurfacePtr);
   static unsigned int (*sCGContextGetTypePtr) (CGContextRef);
   static void LoadLibrary();
   static void CloseLibrary();
 
   // Static deconstructor
   static class LibraryUnloader {
   public:
     ~LibraryUnloader() {
--- a/gfx/2d/Types.h
+++ b/gfx/2d/Types.h
@@ -32,26 +32,28 @@ enum class SurfaceType : int8_t {
 enum class SurfaceFormat : int8_t {
   B8G8R8A8,
   B8G8R8X8,
   R8G8B8A8,
   R8G8B8X8,
   R5G6B5,
   A8,
   YUV,
+  NV12,
   UNKNOWN
 };
 
 inline bool IsOpaque(SurfaceFormat aFormat)
 {
   switch (aFormat) {
   case SurfaceFormat::B8G8R8X8:
   case SurfaceFormat::R8G8B8X8:
   case SurfaceFormat::R5G6B5:
   case SurfaceFormat::YUV:
+  case SurfaceFormat::NV12:
     return true;
   default:
     return false;
   }
 }
 
 enum class FilterType : int8_t {
   BLEND = 0,
--- a/gfx/layers/LayersLogging.cpp
+++ b/gfx/layers/LayersLogging.cpp
@@ -332,16 +332,17 @@ AppendToString(std::stringstream& aStrea
   switch (format) {
   case SurfaceFormat::B8G8R8A8:  aStream << "SurfaceFormat::B8G8R8A8"; break;
   case SurfaceFormat::B8G8R8X8:  aStream << "SurfaceFormat::B8G8R8X8"; break;
   case SurfaceFormat::R8G8B8A8:  aStream << "SurfaceFormat::R8G8B8A8"; break;
   case SurfaceFormat::R8G8B8X8:  aStream << "SurfaceFormat::R8G8B8X8"; break;
   case SurfaceFormat::R5G6B5:    aStream << "SurfaceFormat::R5G6B5"; break;
   case SurfaceFormat::A8:        aStream << "SurfaceFormat::A8"; break;
   case SurfaceFormat::YUV:       aStream << "SurfaceFormat::YUV"; break;
+  case SurfaceFormat::NV12:      aStream << "SurfaceFormat::NV12"; break;
   case SurfaceFormat::UNKNOWN:   aStream << "SurfaceFormat::UNKNOWN"; break;
   default:
     NS_ERROR("unknown surface format");
     aStream << "???";
   }
 
   aStream << sfx;
 }