Bug 1337589 - Improve Get*YuvColorMatrix. - r=mattwoodrow
MozReview-Commit-ID: 1FMnRNB7ksI
--- a/gfx/gl/GLBlitHelper.cpp
+++ b/gfx/gl/GLBlitHelper.cpp
@@ -760,17 +760,17 @@ GLBlitHelper::BlitPlanarYCbCrImage(layer
BindAndUploadYUVTexture(Channel_Cb, yuvData->mCbCrStride, yuvData->mCbCrSize.height, yuvData->mCbChannel, needsAllocation);
BindAndUploadYUVTexture(Channel_Cr, yuvData->mCbCrStride, yuvData->mCbCrSize.height, yuvData->mCrChannel, needsAllocation);
if (needsAllocation) {
mGL->fUniform2f(mYTexScaleLoc, (float)yuvData->mYSize.width/yuvData->mYStride, 1.0f);
mGL->fUniform2f(mCbCrTexScaleLoc, (float)yuvData->mCbCrSize.width/yuvData->mCbCrStride, 1.0f);
}
- float* yuvToRgb = gfxUtils::Get3x3YuvColorMatrix(yuvData->mYUVColorSpace);
+ const auto& yuvToRgb = gfxUtils::YuvToRgbMatrix3x3ColumnMajor(yuvData->mYUVColorSpace);
mGL->fUniformMatrix3fv(mYuvColorMatrixLoc, 1, 0, yuvToRgb);
mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
for (int i = 0; i < 3; i++) {
mGL->fActiveTexture(LOCAL_GL_TEXTURE0 + i);
mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, oldTex[i]);
}
return true;
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -884,17 +884,17 @@ CompositorD3D11::DrawQuad(const gfx::Rec
}
if (!source->GetSubSource(Y) || !source->GetSubSource(Cb) || !source->GetSubSource(Cr)) {
// This can happen if we failed to upload the textures, most likely
// because of unsupported dimensions (we don't tile YCbCr textures).
return;
}
- float* yuvToRgb = gfxUtils::Get4x3YuvColorMatrix(ycbcrEffect->mYUVColorSpace);
+ const float* yuvToRgb = gfxUtils::YuvToRgbMatrix4x3RowMajor(ycbcrEffect->mYUVColorSpace);
memcpy(&mPSConstants.yuvColorMatrix, yuvToRgb, sizeof(mPSConstants.yuvColorMatrix));
TextureSourceD3D11* sourceY = source->GetSubSource(Y)->AsSourceD3D11();
TextureSourceD3D11* sourceCb = source->GetSubSource(Cb)->AsSourceD3D11();
TextureSourceD3D11* sourceCr = source->GetSubSource(Cr)->AsSourceD3D11();
ID3D11ShaderResourceView* srViews[3] = { sourceY->GetShaderResourceView(),
sourceCb->GetShaderResourceView(),
--- a/gfx/layers/d3d9/CompositorD3D9.cpp
+++ b/gfx/layers/d3d9/CompositorD3D9.cpp
@@ -415,17 +415,17 @@ CompositorD3D9::DrawQuad(const gfx::Rect
if (!source->GetSubSource(Y) || !source->GetSubSource(Cb) || !source->GetSubSource(Cr)) {
// This can happen if we failed to upload the textures, most likely
// because of unsupported dimensions (we don't tile YCbCr textures).
return;
}
- float* yuvToRgb = gfxUtils::Get4x3YuvColorMatrix(ycbcrEffect->mYUVColorSpace);
+ const float* yuvToRgb = gfxUtils::YuvToRgbMatrix4x3RowMajor(ycbcrEffect->mYUVColorSpace);
d3d9Device->SetPixelShaderConstantF(CBmYuvColorMatrix, yuvToRgb, 3);
TextureSourceD3D9* sourceY = source->GetSubSource(Y)->AsSourceD3D9();
TextureSourceD3D9* sourceCb = source->GetSubSource(Cb)->AsSourceD3D9();
TextureSourceD3D9* sourceCr = source->GetSubSource(Cr)->AsSourceD3D9();
MOZ_ASSERT(sourceY->GetD3D9Texture());
@@ -569,17 +569,17 @@ CompositorD3D9::SetMask(const EffectChai
device()->SetTexture(aMaskTexture, source->GetD3D9Texture());
const gfx::Matrix4x4& maskTransform = maskEffect->mMaskTransform;
NS_ASSERTION(maskTransform.Is2D(), "How did we end up with a 3D transform here?!");
Rect bounds = Rect(Point(), Size(maskEffect->mSize));
bounds = maskTransform.As2D().TransformBounds(bounds);
- device()->SetVertexShaderConstantF(DeviceManagerD3D9::sMaskQuadRegister,
+ device()->SetVertexShaderConstantF(DeviceManagerD3D9::sMaskQuadRegister,
ShaderConstantRect(bounds.x,
bounds.y,
bounds.width,
bounds.height),
1);
}
/**
--- a/gfx/layers/opengl/OGLShaderProgram.cpp
+++ b/gfx/layers/opengl/OGLShaderProgram.cpp
@@ -961,14 +961,14 @@ ShaderProgramOGL::SetBlurRadius(float aR
gaussianKernel[i] /= sum;
}
SetArrayUniform(KnownUniform::BlurGaussianKernel, GAUSSIAN_KERNEL_HALF_WIDTH, gaussianKernel);
}
void
ShaderProgramOGL::SetYUVColorSpace(YUVColorSpace aYUVColorSpace)
{
- float* yuvToRgb = gfxUtils::Get3x3YuvColorMatrix(aYUVColorSpace);
+ const float* yuvToRgb = gfxUtils::YuvToRgbMatrix3x3ColumnMajor(aYUVColorSpace);
SetMatrix3fvUniform(KnownUniform::YuvColorMatrix, yuvToRgb);
}
} // namespace layers
} // namespace mozilla
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -1164,50 +1164,70 @@ From Rec709:
[B] [1.1643835616438356, 2.1124017857142854, 0.0] [Cr - 128]
For [0,1] instead of [0,255], and to 5 places:
[R] [1.16438, 0.00000, 1.79274] [ Y - 0.06275]
[G] = [1.16438, -0.21325, -0.53291] x [Cb - 0.50196]
[B] [1.16438, 2.11240, 0.00000] [Cr - 0.50196]
*/
-/* static */ float*
-gfxUtils::Get4x3YuvColorMatrix(YUVColorSpace aYUVColorSpace)
-{
- static const float yuv_to_rgb_rec601[12] = { 1.16438f, 0.0f, 1.59603f, 0.0f,
- 1.16438f, -0.39176f, -0.81297f, 0.0f,
- 1.16438f, 2.01723f, 0.0f, 0.0f,
- };
+static const float kRec601[9] = {
+ 1.16438f, 0.00000f, 1.59603f,
+ 1.16438f,-0.39176f,-0.81297f,
+ 1.16438f, 2.01723f, 0.00000f,
+};
+static const float kRec709[9] = {
+ 1.16438f, 0.00000f, 1.79274f,
+ 1.16438f,-0.21325f,-0.53291f,
+ 1.16438f, 2.11240f, 0.00000f,
+};
- static const float yuv_to_rgb_rec709[12] = { 1.16438f, 0.0f, 1.79274f, 0.0f,
- 1.16438f, -0.21325f, -0.53291f, 0.0f,
- 1.16438f, 2.11240f, 0.0f, 0.0f,
- };
+/* static */ const float*
+gfxUtils::YuvToRgbMatrix4x3RowMajor(YUVColorSpace aYUVColorSpace)
+{
+ #define X(x) { x[0], x[1], x[2], 0.0f, \
+ x[3], x[4], x[5], 0.0f, \
+ x[6], x[7], x[8], 0.0f }
+
+ static const float rec601[12] = X(kRec601);
+ static const float rec709[12] = X(kRec709);
- if (aYUVColorSpace == YUVColorSpace::BT709) {
- return const_cast<float*>(yuv_to_rgb_rec709);
- } else {
- return const_cast<float*>(yuv_to_rgb_rec601);
+ #undef X
+
+ switch (aYUVColorSpace) {
+ case YUVColorSpace::BT601:
+ return rec601;
+ case YUVColorSpace::BT709:
+ return rec709;
+ default: // YUVColorSpace::UNKNOWN
+ MOZ_ASSERT(false, "unknown aYUVColorSpace");
+ return rec601;
}
}
-/* static */ float*
-gfxUtils::Get3x3YuvColorMatrix(YUVColorSpace aYUVColorSpace)
+/* static */ const float*
+gfxUtils::YuvToRgbMatrix3x3ColumnMajor(YUVColorSpace aYUVColorSpace)
{
- static const float yuv_to_rgb_rec601[9] = {
- 1.16438f, 1.16438f, 1.16438f, 0.0f, -0.39176f, 2.01723f, 1.59603f, -0.81297f, 0.0f,
- };
- static const float yuv_to_rgb_rec709[9] = {
- 1.16438f, 1.16438f, 1.16438f, 0.0f, -0.21325f, 2.11240f, 1.79274f, -0.53291f, 0.0f,
- };
+ #define X(x) { x[0], x[3], x[6], \
+ x[1], x[4], x[7], \
+ x[2], x[5], x[8] }
+
+ static const float rec601[9] = X(kRec601);
+ static const float rec709[9] = X(kRec709);
+
+ #undef X
- if (aYUVColorSpace == YUVColorSpace::BT709) {
- return const_cast<float*>(yuv_to_rgb_rec709);
- } else {
- return const_cast<float*>(yuv_to_rgb_rec601);
+ switch (aYUVColorSpace) {
+ case YUVColorSpace::BT601:
+ return rec601;
+ case YUVColorSpace::BT709:
+ return rec709;
+ default: // YUVColorSpace::UNKNOWN
+ MOZ_ASSERT(false, "unknown aYUVColorSpace");
+ return rec601;
}
}
/* static */ void
gfxUtils::WriteAsPNG(SourceSurface* aSurface, const nsAString& aFile)
{
WriteAsPNG(aSurface, NS_ConvertUTF16toUTF8(aFile).get());
}
--- a/gfx/thebes/gfxUtils.h
+++ b/gfx/thebes/gfxUtils.h
@@ -37,17 +37,16 @@ class gfxUtils {
public:
typedef mozilla::gfx::DataSourceSurface DataSourceSurface;
typedef mozilla::gfx::DrawTarget DrawTarget;
typedef mozilla::gfx::IntPoint IntPoint;
typedef mozilla::gfx::Matrix Matrix;
typedef mozilla::gfx::SourceSurface SourceSurface;
typedef mozilla::gfx::SurfaceFormat SurfaceFormat;
typedef mozilla::image::ImageRegion ImageRegion;
- typedef mozilla::YUVColorSpace YUVColorSpace;
/*
* Premultiply or Unpremultiply aSourceSurface, writing the result
* to aDestSurface or back into aSourceSurface if aDestSurface is null.
*
* If aDestSurface is given, it must have identical format, dimensions, and
* stride as the source.
*
@@ -131,22 +130,18 @@ public:
*/
static gfxFloat ClampToScaleFactor(gfxFloat aVal);
/**
* Clears surface to aColor (which defaults to transparent black).
*/
static void ClearThebesSurface(gfxASurface* aSurface);
- /**
- * Get array of yuv to rgb conversion matrix.
- */
- static float* Get4x3YuvColorMatrix(YUVColorSpace aYUVColorSpace);
-
- static float* Get3x3YuvColorMatrix(YUVColorSpace aYUVColorSpace);
+ static const float* YuvToRgbMatrix4x3RowMajor(mozilla::YUVColorSpace aYUVColorSpace);
+ static const float* YuvToRgbMatrix3x3ColumnMajor(mozilla::YUVColorSpace aYUVColorSpace);
/**
* Creates a copy of aSurface, but having the SurfaceFormat aFormat.
*
* This function always creates a new surface. Do not call it if aSurface's
* format is the same as aFormat. Such a non-conversion would just be an
* unnecessary and wasteful copy (this function asserts to prevent that).
*