Bug 1248323: P1. Add support for YUV422 IOSurface. r=nical
authorJean-Yves Avenard <jyavenard@mozilla.com>
Tue, 23 Feb 2016 13:26:27 +1100
changeset 321870 bb4b4249dda8b5372bac11bb36a8b3bf4c44f6c5
parent 321869 f523d47054813ad85464c6dc898c24908f978b46
child 321871 a8677612e6581ee1c6fb97d3b23156d98ade51e7
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1248323
milestone47.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 1248323: P1. Add support for YUV422 IOSurface. r=nical Those are really UYVY 16bpp surface. MozReview-Commit-ID: DWkqrF6Norj
gfx/2d/MacIOSurface.cpp
gfx/2d/MacIOSurface.h
gfx/2d/Types.h
gfx/layers/LayersLogging.cpp
gfx/layers/composite/ImageHost.cpp
gfx/layers/composite/TextureHost.h
gfx/layers/opengl/CompositorOGL.cpp
gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
--- a/gfx/2d/MacIOSurface.cpp
+++ b/gfx/2d/MacIOSurface.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MacIOSurface.h"
 #include <OpenGL/gl.h>
 #include <QuartzCore/QuartzCore.h>
 #include <dlfcn.h>
 #include "mozilla/RefPtr.h"
 #include "mozilla/Assertions.h"
+#include "GLConsts.h"
 
 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 \
@@ -471,16 +472,31 @@ MacIOSurface::GetAsSurface() {
 }
 
 SurfaceFormat
 MacIOSurface::GetFormat()
 {
   OSType pixelFormat = GetPixelFormat();
   if (pixelFormat == '420v') {
     return SurfaceFormat::NV12;
+  } else if (pixelFormat == '2vuy') {
+    return SurfaceFormat::YUV422;
+  } else  {
+    return HasAlpha() ? SurfaceFormat::R8G8B8A8 : SurfaceFormat::R8G8B8X8;
+  }
+}
+
+SurfaceFormat
+MacIOSurface::GetReadFormat()
+{
+  OSType pixelFormat = GetPixelFormat();
+  if (pixelFormat == '420v') {
+    return SurfaceFormat::NV12;
+  } else if (pixelFormat == '2vuy') {
+    return SurfaceFormat::R8G8B8X8;
   } else  {
     return HasAlpha() ? SurfaceFormat::R8G8B8A8 : SurfaceFormat::R8G8B8X8;
   }
 }
 
 CGLError
 MacIOSurface::CGLTexImageIOSurface2D(CGLContextObj ctx, size_t plane)
 {
@@ -495,16 +511,22 @@ MacIOSurface::CGLTexImageIOSurface2D(CGL
     MOZ_ASSERT(plane < 2);
 
     if (plane == 0) {
       internalFormat = format = GL_LUMINANCE;
     } else {
       internalFormat = format = GL_LUMINANCE_ALPHA;
     }
     type = GL_UNSIGNED_BYTE;
+  } else if (pixelFormat == '2vuy') {
+    MOZ_ASSERT(plane == 0);
+
+    internalFormat = GL_RGB;
+    format = LOCAL_GL_YCBCR_422_APPLE;
+    type = GL_UNSIGNED_SHORT_8_8_APPLE;
   } 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,
--- a/gfx/2d/MacIOSurface.h
+++ b/gfx/2d/MacIOSurface.h
@@ -111,16 +111,18 @@ public:
   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();
+  mozilla::gfx::SurfaceFormat GetReadFormat();
+
   // 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, size_t plane = 0);
   already_AddRefed<SourceSurface> GetAsSurface();
   CGContextRef CreateIOSurfaceContext();
 
   // FIXME This doesn't really belong here
   static CGImageRef CreateImageFromIOSurfaceContext(CGContextRef aContext);
--- a/gfx/2d/Types.h
+++ b/gfx/2d/Types.h
@@ -49,16 +49,17 @@ enum class SurfaceFormat : int8_t {
   R5G6B5_UINT16,                    // 0bRRRRRGGGGGGBBBBB
 
   // This one is a single-byte, so endianness isn't an issue.
   A8,
 
   // These ones are their own special cases.
   YUV,
   NV12,
+  YUV422,
 
   // This represents the unknown format.
   UNKNOWN,
 
   // The following values are endian-independent synonyms. The _UINT32 suffix
   // indicates that the name reflects the layout when viewed as a uint32_t
   // value.
 #if MOZ_LITTLE_ENDIAN
@@ -75,16 +76,17 @@ enum class SurfaceFormat : int8_t {
 inline bool IsOpaque(SurfaceFormat aFormat)
 {
   switch (aFormat) {
   case SurfaceFormat::B8G8R8X8:
   case SurfaceFormat::R8G8B8X8:
   case SurfaceFormat::R5G6B5_UINT16:
   case SurfaceFormat::YUV:
   case SurfaceFormat::NV12:
+  case SurfaceFormat::YUV422:
     return true;
   default:
     return false;
   }
 }
 
 enum class FilterType : int8_t {
   BLEND = 0,
--- a/gfx/layers/LayersLogging.cpp
+++ b/gfx/layers/LayersLogging.cpp
@@ -295,16 +295,17 @@ AppendToString(std::stringstream& aStrea
   case SurfaceFormat::B8G8R8X8:  aStream << "SurfaceFormat::B8G8R8X8"; break;
   case SurfaceFormat::R8G8B8A8:  aStream << "SurfaceFormat::R8G8B8A8"; break;
   case SurfaceFormat::R8G8B8X8:  aStream << "SurfaceFormat::R8G8B8X8"; break;
   case SurfaceFormat::R5G6B5_UINT16:
                                  aStream << "SurfaceFormat::R5G6B5_UINT16"; break;
   case SurfaceFormat::A8:        aStream << "SurfaceFormat::A8"; break;
   case SurfaceFormat::YUV:       aStream << "SurfaceFormat::YUV"; break;
   case SurfaceFormat::NV12:      aStream << "SurfaceFormat::NV12"; break;
+  case SurfaceFormat::YUV422:    aStream << "SurfaceFormat::YUV422"; break;
   case SurfaceFormat::UNKNOWN:   aStream << "SurfaceFormat::UNKNOWN"; break;
   default:
     NS_ERROR("unknown surface format");
     aStream << "???";
   }
 
   aStream << sfx;
 }
--- a/gfx/layers/composite/ImageHost.cpp
+++ b/gfx/layers/composite/ImageHost.cpp
@@ -326,17 +326,17 @@ ImageHost::Composite(LayerComposite* aLa
       // BindTextureSource above should have returned false!
       MOZ_ASSERT(false);
       return;
     }
 
     bool isAlphaPremultiplied =
         !(img->mFrontBuffer->GetFlags() & TextureFlags::NON_PREMULTIPLIED);
     RefPtr<TexturedEffect> effect =
-        CreateTexturedEffect(img->mFrontBuffer->GetFormat(),
+        CreateTexturedEffect(img->mFrontBuffer->GetReadFormat(),
             img->mTextureSource.get(), aFilter, isAlphaPremultiplied,
             GetRenderState());
     if (!effect) {
       return;
     }
 
     if (!GetCompositor()->SupportsEffect(effect->mType)) {
       return;
@@ -561,17 +561,17 @@ ImageHost::GenEffect(const gfx::Filter& 
   if (!img->mFrontBuffer->BindTextureSource(img->mTextureSource)) {
     return nullptr;
   }
   bool isAlphaPremultiplied = true;
   if (img->mFrontBuffer->GetFlags() & TextureFlags::NON_PREMULTIPLIED) {
     isAlphaPremultiplied = false;
   }
 
-  return CreateTexturedEffect(img->mFrontBuffer->GetFormat(),
+  return CreateTexturedEffect(img->mFrontBuffer->GetReadFormat(),
                               img->mTextureSource,
                               aFilter,
                               isAlphaPremultiplied,
                               GetRenderState());
 }
 
 void
 ImageHost::SetImageContainer(ImageContainerParent* aImageContainer)
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -358,16 +358,21 @@ public:
   virtual void Unlock() {}
 
   /**
    * Note that the texture host format can be different from its corresponding
    * texture source's. For example a ShmemTextureHost can have the ycbcr
    * format and produce 3 "alpha" textures sources.
    */
   virtual gfx::SurfaceFormat GetFormat() const = 0;
+  /**
+   * Return the format used for reading the texture.
+   * Apple's YCBCR_422 is R8G8B8X8.
+   */
+  virtual gfx::SurfaceFormat GetReadFormat() const { return GetFormat(); }
 
   /**
    * Called during the transaction. The TextureSource may or may not be composited.
    *
    * Note that this is called outside of lock/unlock.
    */
   virtual void PrepareTextureSource(CompositableTextureSourceRef& aTexture) {}
 
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -862,17 +862,18 @@ CompositorOGL::GetShaderConfigFor(Effect
         static_cast<TexturedEffect*>(aEffect);
     TextureSourceOGL* source = texturedEffect->mTexture->AsSourceOGL();
     MOZ_ASSERT_IF(source->GetTextureTarget() == LOCAL_GL_TEXTURE_EXTERNAL,
                   source->GetFormat() == gfx::SurfaceFormat::R8G8B8A8 ||
                   source->GetFormat() == gfx::SurfaceFormat::R8G8B8X8);
     MOZ_ASSERT_IF(source->GetTextureTarget() == LOCAL_GL_TEXTURE_RECTANGLE_ARB,
                   source->GetFormat() == gfx::SurfaceFormat::R8G8B8A8 ||
                   source->GetFormat() == gfx::SurfaceFormat::R8G8B8X8 ||
-                  source->GetFormat() == gfx::SurfaceFormat::R5G6B5_UINT16);
+                  source->GetFormat() == gfx::SurfaceFormat::R5G6B5_UINT16 ||
+                  source->GetFormat() == gfx::SurfaceFormat::YUV422 );
     config = ShaderConfigFromTargetAndFormat(source->GetTextureTarget(),
                                              source->GetFormat());
     if (!texturedEffect->mPremultiplied) {
       config.SetNoPremultipliedAlpha();
     }
     break;
   }
   }
--- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
+++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
@@ -75,16 +75,21 @@ MacIOSurfaceTextureHostOGL::SetComposito
   }
 }
 
 gfx::SurfaceFormat
 MacIOSurfaceTextureHostOGL::GetFormat() const {
   return mSurface->GetFormat();
 }
 
+gfx::SurfaceFormat
+MacIOSurfaceTextureHostOGL::GetReadFormat() const {
+  return mSurface->GetReadFormat();
+}
+
 gfx::IntSize
 MacIOSurfaceTextureHostOGL::GetSize() const {
   if (!mSurface) {
     return gfx::IntSize();
   }
   return gfx::IntSize(mSurface->GetDevicePixelWidth(),
                       mSurface->GetDevicePixelHeight());
 }
--- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
+++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
@@ -71,16 +71,17 @@ public:
   // MacIOSurfaceTextureSourceOGL doesn't own any GL texture
   virtual void DeallocateDeviceData() override {}
 
   virtual void SetCompositor(Compositor* aCompositor) override;
 
   virtual bool Lock() override;
 
   virtual gfx::SurfaceFormat GetFormat() const override;
+  virtual gfx::SurfaceFormat GetReadFormat() const override;
 
   virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override
   {
     aTexture = mTextureSource;
     return !!aTexture;
   }
 
   virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override