From beef4376020be765b96c8001b73b0eb7ed75efad Mon Sep 17 00:00:00 2001 From: u3shit Date: Fri, 24 Feb 2023 19:11:36 +0100 Subject: [PATCH] Issue #2118 - Part 1: Update gfxUtils YuvColorMatrix functions to match upstream mozilla code more closely. https://hg.mozilla.org/mozilla-central/file/4fba5295dc19f9d2f5d065ba502a44d8f2dc9e85/gfx/thebes/gfxUtils.cpp#l1246 --- gfx/gl/GLBlitHelper.cpp | 2 +- gfx/layers/d3d11/CompositorD3D11.cpp | 2 +- gfx/layers/d3d9/CompositorD3D9.cpp | 2 +- gfx/layers/opengl/OGLShaderProgram.cpp | 2 +- gfx/thebes/gfxUtils.cpp | 82 ++++++++++++-------------- gfx/thebes/gfxUtils.h | 4 +- 6 files changed, 44 insertions(+), 50 deletions(-) diff --git a/gfx/gl/GLBlitHelper.cpp b/gfx/gl/GLBlitHelper.cpp index da7f5b462d..32b1b1cf64 100644 --- a/gfx/gl/GLBlitHelper.cpp +++ b/gfx/gl/GLBlitHelper.cpp @@ -667,7 +667,7 @@ GLBlitHelper::BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage) mGL->fUniform2f(mCbCrTexScaleLoc, (float)yuvData->mCbCrSize.width/yuvData->mCbCrStride, 1.0f); } - float* yuvToRgb = gfxUtils::Get3x3YuvColorMatrix(yuvData->mYUVColorSpace); + const float* yuvToRgb = gfxUtils::Get3x3YuvColorMatrix(yuvData->mYUVColorSpace); mGL->fUniformMatrix3fv(mYuvColorMatrixLoc, 1, 0, yuvToRgb); mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4); diff --git a/gfx/layers/d3d11/CompositorD3D11.cpp b/gfx/layers/d3d11/CompositorD3D11.cpp index 505e5881d4..8a08449adf 100644 --- a/gfx/layers/d3d11/CompositorD3D11.cpp +++ b/gfx/layers/d3d11/CompositorD3D11.cpp @@ -886,7 +886,7 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect, return; } - float* yuvToRgb = gfxUtils::Get4x3YuvColorMatrix(ycbcrEffect->mYUVColorSpace); + const float* yuvToRgb = gfxUtils::Get4x3YuvColorMatrix(ycbcrEffect->mYUVColorSpace); memcpy(&mPSConstants.yuvColorMatrix, yuvToRgb, sizeof(mPSConstants.yuvColorMatrix)); TextureSourceD3D11* sourceY = source->GetSubSource(Y)->AsSourceD3D11(); diff --git a/gfx/layers/d3d9/CompositorD3D9.cpp b/gfx/layers/d3d9/CompositorD3D9.cpp index 6f01e7d152..0d3a188488 100644 --- a/gfx/layers/d3d9/CompositorD3D9.cpp +++ b/gfx/layers/d3d9/CompositorD3D9.cpp @@ -413,7 +413,7 @@ CompositorD3D9::DrawQuad(const gfx::Rect &aRect, } - float* yuvToRgb = gfxUtils::Get4x3YuvColorMatrix(ycbcrEffect->mYUVColorSpace); + const float* yuvToRgb = gfxUtils::Get4x3YuvColorMatrix(ycbcrEffect->mYUVColorSpace); d3d9Device->SetPixelShaderConstantF(CBmYuvColorMatrix, yuvToRgb, 3); TextureSourceD3D9* sourceY = source->GetSubSource(Y)->AsSourceD3D9(); diff --git a/gfx/layers/opengl/OGLShaderProgram.cpp b/gfx/layers/opengl/OGLShaderProgram.cpp index c06dc52ddd..dfd9fe0de6 100644 --- a/gfx/layers/opengl/OGLShaderProgram.cpp +++ b/gfx/layers/opengl/OGLShaderProgram.cpp @@ -966,7 +966,7 @@ ShaderProgramOGL::SetBlurRadius(float aRX, float aRY) void ShaderProgramOGL::SetYUVColorSpace(YUVColorSpace aYUVColorSpace) { - float* yuvToRgb = gfxUtils::Get3x3YuvColorMatrix(aYUVColorSpace); + const float* yuvToRgb = gfxUtils::Get3x3YuvColorMatrix(aYUVColorSpace); SetMatrix3fvUniform(KnownUniform::YuvColorMatrix, yuvToRgb); } diff --git a/gfx/thebes/gfxUtils.cpp b/gfx/thebes/gfxUtils.cpp index adc48b972f..499ae720e3 100644 --- a/gfx/thebes/gfxUtils.cpp +++ b/gfx/thebes/gfxUtils.cpp @@ -1082,61 +1082,55 @@ gfxUtils::EncodeSourceSurface(SourceSurface* aSurface, aBinaryOrData, aFile, nullptr); } -/* From Rec601: -[R] [1.1643835616438356, 0.0, 1.5960267857142858] [ Y - 16] -[G] = [1.1643835616438358, -0.3917622900949137, -0.8129676472377708] x [Cb - 128] -[B] [1.1643835616438356, 2.017232142857143, 8.862867620416422e-17] [Cr - 128] +// https://jdashg.github.io/misc/colors/from-coeffs.html +const float kBT601NarrowYCbCrToRGB_RowMajor[16] = { + 1.16438f, 0.00000f, 1.59603f, -0.87420f, 1.16438f, -0.39176f, + -0.81297f, 0.53167f, 1.16438f, 2.01723f, 0.00000f, -1.08563f, + 0.00000f, 0.00000f, 0.00000f, 1.00000f}; +const float kBT709NarrowYCbCrToRGB_RowMajor[16] = { + 1.16438f, 0.00000f, 1.79274f, -0.97295f, 1.16438f, -0.21325f, + -0.53291f, 0.30148f, 1.16438f, 2.11240f, 0.00000f, -1.13340f, + 0.00000f, 0.00000f, 0.00000f, 1.00000f}; -For [0,1] instead of [0,255], and to 5 places: -[R] [1.16438, 0.00000, 1.59603] [ Y - 0.06275] -[G] = [1.16438, -0.39176, -0.81297] x [Cb - 0.50196] -[B] [1.16438, 2.01723, 0.00000] [Cr - 0.50196] - -From Rec709: -[R] [1.1643835616438356, 4.2781193979771426e-17, 1.7927410714285714] [ Y - 16] -[G] = [1.1643835616438358, -0.21324861427372963, -0.532909328559444] x [Cb - 128] -[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* +/* static */ const 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, - }; +#define X(x) \ + { x[0], x[1], x[2], 0.0f, x[4], x[5], x[6], 0.0f, x[8], x[9], x[10], 0.0f } - 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 rec601[12] = X(kBT601NarrowYCbCrToRGB_RowMajor); + static const float rec709[12] = X(kBT709NarrowYCbCrToRGB_RowMajor); - if (aYUVColorSpace == YUVColorSpace::BT709) { - return const_cast(yuv_to_rgb_rec709); - } else { - return const_cast(yuv_to_rgb_rec601); +#undef X + + switch (aYUVColorSpace) { + case YUVColorSpace::BT601: + return rec601; + case YUVColorSpace::BT709: + return rec709; + default: + MOZ_CRASH("Bad YUVColorSpace"); } } -/* static */ float* +/* static */ const float* gfxUtils::Get3x3YuvColorMatrix(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[4], x[8], x[1], x[5], x[9], x[2], x[6], x[10] } - if (aYUVColorSpace == YUVColorSpace::BT709) { - return const_cast(yuv_to_rgb_rec709); - } else { - return const_cast(yuv_to_rgb_rec601); + static const float rec601[9] = X(kBT601NarrowYCbCrToRGB_RowMajor); + static const float rec709[9] = X(kBT709NarrowYCbCrToRGB_RowMajor); + +#undef X + + switch (aYUVColorSpace) { + case YUVColorSpace::BT601: + return rec601; + case YUVColorSpace::BT709: + return rec709; + default: + MOZ_CRASH("Bad YUVColorSpace"); } } diff --git a/gfx/thebes/gfxUtils.h b/gfx/thebes/gfxUtils.h index 7a4679fb97..a86d9a8898 100644 --- a/gfx/thebes/gfxUtils.h +++ b/gfx/thebes/gfxUtils.h @@ -139,9 +139,9 @@ public: /** * Get array of yuv to rgb conversion matrix. */ - static float* Get4x3YuvColorMatrix(YUVColorSpace aYUVColorSpace); + static const float* Get4x3YuvColorMatrix(YUVColorSpace aYUVColorSpace); - static float* Get3x3YuvColorMatrix(YUVColorSpace aYUVColorSpace); + static const float* Get3x3YuvColorMatrix(YUVColorSpace aYUVColorSpace); /** * Creates a copy of aSurface, but having the SurfaceFormat aFormat.