Bug 1248323: P1. Add support for YUV422 IOSurface. r=nical
Those are really UYVY 16bpp surface.
MozReview-Commit-ID: DWkqrF6Norj
--- 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