Bug 1248323: P1. Add support for YUV422 IOSurface. r=nical draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Tue, 23 Feb 2016 13:26:27 +1100
changeset 334389 66c569e6e44c9dd041e85a0ccec84cc6dbb1edb1
parent 334388 6ecde9c54b08d831a7660fd44a0202c9badd2691
child 334390 0f63c1399f08a1d02c6baa7fc105a4f3196b5808
push id11531
push userbmo:jyavenard@mozilla.com
push dateThu, 25 Feb 2016 03:18:04 +0000
reviewersnical
bugs1248323
milestone47.0a1
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