Bug 1337589 - Improve Get*YuvColorMatrix. - r=mattwoodrow
authorJeff Gilbert <jgilbert@mozilla.com>
Tue, 07 Feb 2017 17:28:22 -0800
changeset 387963 0649459cb1278e4b33852e904304b995b4c43e70
parent 387962 99769e92f4a97630fa9847512d841da98fc02a13
child 387964 f1160dc58eb87eeee22c686a193830b6731abe74
push id7198
push userjlorenzo@mozilla.com
push dateTue, 18 Apr 2017 12:07:49 +0000
treeherdermozilla-beta@d57aa49c3948 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1337589
milestone54.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 1337589 - Improve Get*YuvColorMatrix. - r=mattwoodrow MozReview-Commit-ID: 1FMnRNB7ksI
gfx/gl/GLBlitHelper.cpp
gfx/layers/d3d11/CompositorD3D11.cpp
gfx/layers/d3d9/CompositorD3D9.cpp
gfx/layers/opengl/OGLShaderProgram.cpp
gfx/thebes/gfxUtils.cpp
gfx/thebes/gfxUtils.h
--- 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).
      *