diff options
author | u3shit <u3shit@gmail.com> | 2023-02-25 00:29:56 +0100 |
---|---|---|
committer | Moonchild <moonchild@palemoon.org> | 2023-02-26 19:42:14 +0100 |
commit | c64fe52b2878f45de08b3525c40068b4234279d1 (patch) | |
tree | e007ed1248f3c7d417c12ed0a6c87dcccd49a2fc /gfx | |
parent | 338cbff242bba9270451f6cd172241dfe09dead8 (diff) | |
download | uxp-c64fe52b2878f45de08b3525c40068b4234279d1.tar.gz |
Issue #2101 - Part 7: Add color range support on GPUs
Diffstat (limited to 'gfx')
-rw-r--r-- | gfx/gl/GLBlitHelper.cpp | 14 | ||||
-rw-r--r-- | gfx/layers/Effects.h | 9 | ||||
-rw-r--r-- | gfx/layers/composite/GPUVideoTextureHost.cpp | 9 | ||||
-rw-r--r-- | gfx/layers/composite/GPUVideoTextureHost.h | 1 | ||||
-rw-r--r-- | gfx/layers/composite/TextureHost.cpp | 10 | ||||
-rw-r--r-- | gfx/layers/composite/TextureHost.h | 2 | ||||
-rw-r--r-- | gfx/layers/d3d11/CompositorD3D11.cpp | 3 | ||||
-rw-r--r-- | gfx/layers/d3d11/CompositorD3D11.h | 2 | ||||
-rw-r--r-- | gfx/layers/d3d11/CompositorD3D11.hlsl | 17 | ||||
-rw-r--r-- | gfx/layers/d3d11/TextureD3D11.h | 1 | ||||
-rw-r--r-- | gfx/layers/opengl/CompositorOGL.cpp | 2 | ||||
-rw-r--r-- | gfx/layers/opengl/OGLShaderProgram.cpp | 16 | ||||
-rw-r--r-- | gfx/layers/opengl/OGLShaderProgram.h | 2 | ||||
-rw-r--r-- | gfx/thebes/gfxUtils.cpp | 64 | ||||
-rw-r--r-- | gfx/thebes/gfxUtils.h | 7 |
15 files changed, 96 insertions, 63 deletions
diff --git a/gfx/gl/GLBlitHelper.cpp b/gfx/gl/GLBlitHelper.cpp index 32b1b1cf64..78accf82e0 100644 --- a/gfx/gl/GLBlitHelper.cpp +++ b/gfx/gl/GLBlitHelper.cpp @@ -171,18 +171,14 @@ GLBlitHelper::InitTexQuadProgram(BlitType target) uniform sampler2D uCrTexture; \n\ uniform vec2 uYTexScale; \n\ uniform vec2 uCbCrTexScale; \n\ - uniform mat3 uYuvColorMatrix; \n\ + uniform mat4 uYuvColorMatrix; \n\ void main() \n\ { \n\ float y = texture2D(uYTexture, vTexCoord * uYTexScale).r; \n\ float cb = texture2D(uCbTexture, vTexCoord * uCbCrTexScale).r; \n\ float cr = texture2D(uCrTexture, vTexCoord * uCbCrTexScale).r; \n\ - y = y - 0.06275; \n\ - cb = cb - 0.50196; \n\ - cr = cr - 0.50196; \n\ - vec3 yuv = vec3(y, cb, cr); \n\ - gl_FragColor.rgb = uYuvColorMatrix * yuv; \n\ - gl_FragColor.a = 1.0; \n\ + vec4 yuv = vec4(y, cb, cr, 1.0); \n\ + gl_FragColor = uYuvColorMatrix * yuv; \n\ } \n\ "; @@ -667,8 +663,8 @@ GLBlitHelper::BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage) mGL->fUniform2f(mCbCrTexScaleLoc, (float)yuvData->mCbCrSize.width/yuvData->mCbCrStride, 1.0f); } - const float* yuvToRgb = gfxUtils::Get3x3YuvColorMatrix(yuvData->mYUVColorSpace); - mGL->fUniformMatrix3fv(mYuvColorMatrixLoc, 1, 0, yuvToRgb); + const float* yuvToRgb = gfxUtils::YuvToRgbMatrix4x4ColumnMajor(yuvData->mYUVColorSpace, yuvData->mColorRange); + mGL->fUniformMatrix4fv(mYuvColorMatrixLoc, 1, 0, yuvToRgb); mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4); for (int i = 0; i < 3; i++) { diff --git a/gfx/layers/Effects.h b/gfx/layers/Effects.h index a0859a539e..53dab35ea5 100644 --- a/gfx/layers/Effects.h +++ b/gfx/layers/Effects.h @@ -158,14 +158,17 @@ struct EffectRGB : public TexturedEffect struct EffectYCbCr : public TexturedEffect { - EffectYCbCr(TextureSource *aSource, YUVColorSpace aYUVColorSpace, gfx::SamplingFilter aSamplingFilter) + EffectYCbCr(TextureSource *aSource, YUVColorSpace aYUVColorSpace, ColorRange aColorRange, + gfx::SamplingFilter aSamplingFilter) : TexturedEffect(EffectTypes::YCBCR, aSource, false, aSamplingFilter) , mYUVColorSpace(aYUVColorSpace) + , mColorRange(aColorRange) {} virtual const char* Name() { return "EffectYCbCr"; } YUVColorSpace mYUVColorSpace; + ColorRange mColorRange; }; struct EffectNV12 : public TexturedEffect @@ -271,7 +274,9 @@ CreateTexturedEffect(TextureHost* aHost, RefPtr<TexturedEffect> result; if (aHost->GetReadFormat() == gfx::SurfaceFormat::YUV) { MOZ_ASSERT(aHost->GetYUVColorSpace() != YUVColorSpace::UNKNOWN); - result = new EffectYCbCr(aSource, aHost->GetYUVColorSpace(), aSamplingFilter); + MOZ_ASSERT(aHost->GetColorRange() != ColorRange::UNKNOWN); + result = new EffectYCbCr(aSource, aHost->GetYUVColorSpace(), aHost->GetColorRange(), + aSamplingFilter); } else { result = CreateTexturedEffect(aHost->GetReadFormat(), aSource, diff --git a/gfx/layers/composite/GPUVideoTextureHost.cpp b/gfx/layers/composite/GPUVideoTextureHost.cpp index 1e539d8ac9..a187c63104 100644 --- a/gfx/layers/composite/GPUVideoTextureHost.cpp +++ b/gfx/layers/composite/GPUVideoTextureHost.cpp @@ -68,6 +68,15 @@ GPUVideoTextureHost::GetYUVColorSpace() const return YUVColorSpace::UNKNOWN; } +ColorRange +GPUVideoTextureHost::GetColorRange() const +{ + if (mWrappedTextureHost) { + return mWrappedTextureHost->GetColorRange(); + } + return ColorRange::UNKNOWN; +} + gfx::IntSize GPUVideoTextureHost::GetSize() const { diff --git a/gfx/layers/composite/GPUVideoTextureHost.h b/gfx/layers/composite/GPUVideoTextureHost.h index fd6bdc3fb2..1e0fb3323c 100644 --- a/gfx/layers/composite/GPUVideoTextureHost.h +++ b/gfx/layers/composite/GPUVideoTextureHost.h @@ -36,6 +36,7 @@ public: } virtual YUVColorSpace GetYUVColorSpace() const override; + virtual ColorRange GetColorRange() const override; virtual gfx::IntSize GetSize() const override; diff --git a/gfx/layers/composite/TextureHost.cpp b/gfx/layers/composite/TextureHost.cpp index 768bf0c3d2..5277e42836 100644 --- a/gfx/layers/composite/TextureHost.cpp +++ b/gfx/layers/composite/TextureHost.cpp @@ -816,6 +816,16 @@ BufferTextureHost::GetYUVColorSpace() const return YUVColorSpace::UNKNOWN; } +ColorRange +BufferTextureHost::GetColorRange() const +{ + if (mFormat == gfx::SurfaceFormat::YUV) { + const YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor(); + return desc.colorRange(); + } + return ColorRange::UNKNOWN; +} + bool BufferTextureHost::MaybeUpload(nsIntRegion *aRegion) { diff --git a/gfx/layers/composite/TextureHost.h b/gfx/layers/composite/TextureHost.h index 7784112254..2babeda5fc 100644 --- a/gfx/layers/composite/TextureHost.h +++ b/gfx/layers/composite/TextureHost.h @@ -418,6 +418,7 @@ public: virtual gfx::SurfaceFormat GetReadFormat() const { return GetFormat(); } virtual YUVColorSpace GetYUVColorSpace() const { return YUVColorSpace::UNKNOWN; } + virtual ColorRange GetColorRange() const { return ColorRange::UNKNOWN; } /** * Called during the transaction. The TextureSource may or may not be composited. @@ -670,6 +671,7 @@ public: virtual gfx::SurfaceFormat GetFormat() const override; virtual YUVColorSpace GetYUVColorSpace() const override; + virtual ColorRange GetColorRange() const override; virtual gfx::IntSize GetSize() const override { return mSize; } diff --git a/gfx/layers/d3d11/CompositorD3D11.cpp b/gfx/layers/d3d11/CompositorD3D11.cpp index a68996de60..b33fc1b00b 100644 --- a/gfx/layers/d3d11/CompositorD3D11.cpp +++ b/gfx/layers/d3d11/CompositorD3D11.cpp @@ -885,7 +885,8 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect, return; } - const float* yuvToRgb = gfxUtils::Get4x3YuvColorMatrix(ycbcrEffect->mYUVColorSpace); + const float* yuvToRgb = gfxUtils::YuvToRgbMatrix4x4XRowMajor( + ycbcrEffect->mYUVColorSpace, ycbcrEffect->mColorRange); memcpy(&mPSConstants.yuvColorMatrix, yuvToRgb, sizeof(mPSConstants.yuvColorMatrix)); TextureSourceD3D11* sourceY = source->GetSubSource(Y)->AsSourceD3D11(); diff --git a/gfx/layers/d3d11/CompositorD3D11.h b/gfx/layers/d3d11/CompositorD3D11.h index 7a1a5cc7d0..ca775cd60b 100644 --- a/gfx/layers/d3d11/CompositorD3D11.h +++ b/gfx/layers/d3d11/CompositorD3D11.h @@ -35,7 +35,7 @@ struct PixelShaderConstants float layerColor[4]; float layerOpacity[4]; int blendConfig[4]; - float yuvColorMatrix[3][4]; + float yuvColorMatrix[4][4]; }; struct DeviceAttachmentsD3D11; diff --git a/gfx/layers/d3d11/CompositorD3D11.hlsl b/gfx/layers/d3d11/CompositorD3D11.hlsl index 21175704b7..cc5aebb112 100644 --- a/gfx/layers/d3d11/CompositorD3D11.hlsl +++ b/gfx/layers/d3d11/CompositorD3D11.hlsl @@ -25,7 +25,7 @@ float fLayerOpacity : register(ps, c1); // w = is premultiplied uint4 iBlendConfig : register(ps, c2); -row_major float3x3 mYuvColorMatrix : register(ps, c3); +row_major float4x4 mYuvColorMatrix : register(ps, c3); sampler sSampler : register(ps, s0); @@ -205,17 +205,14 @@ For [0,1] instead of [0,255], and to 5 places: */ float4 CalculateYCbCrColor(const float2 aTexCoords) { - float3 yuv; - float4 color; + float4 yuv; - yuv.x = tY.Sample(sSampler, aTexCoords).r - 0.06275; - yuv.y = tCb.Sample(sSampler, aTexCoords).r - 0.50196; - yuv.z = tCr.Sample(sSampler, aTexCoords).r - 0.50196; + yuv.x = tY.Sample(sSampler, aTexCoords).r; + yuv.y = tCb.Sample(sSampler, aTexCoords).r; + yuv.z = tCr.Sample(sSampler, aTexCoords).r; + yuv.w = 1.0; - color.rgb = mul(mYuvColorMatrix, yuv); - color.a = 1.0f; - - return color; + return mul(mYuvColorMatrix, yuv); } float4 YCbCrShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target diff --git a/gfx/layers/d3d11/TextureD3D11.h b/gfx/layers/d3d11/TextureD3D11.h index 831342aa2e..7e24410f3d 100644 --- a/gfx/layers/d3d11/TextureD3D11.h +++ b/gfx/layers/d3d11/TextureD3D11.h @@ -361,6 +361,7 @@ public: // Bug 1305906 fixes YUVColorSpace handling virtual YUVColorSpace GetYUVColorSpace() const override { return YUVColorSpace::BT601; } + virtual ColorRange GetColorRange() const override { return ColorRange::LIMITED; } virtual bool Lock() override; diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index 6e5a011004..e51839d190 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -1303,7 +1303,7 @@ CompositorOGL::DrawGeometry(const Geometry& aGeometry, program->SetYCbCrTextureUnits(Y, Cb, Cr); program->SetTextureTransform(Matrix4x4()); - program->SetYUVColorSpace(effectYCbCr->mYUVColorSpace); + program->SetYUVColorSpace(effectYCbCr->mYUVColorSpace, effectYCbCr->mColorRange); if (maskType != MaskType::MaskNone) { BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE3, maskQuadTransform); diff --git a/gfx/layers/opengl/OGLShaderProgram.cpp b/gfx/layers/opengl/OGLShaderProgram.cpp index dfd9fe0de6..f07132a400 100644 --- a/gfx/layers/opengl/OGLShaderProgram.cpp +++ b/gfx/layers/opengl/OGLShaderProgram.cpp @@ -377,7 +377,7 @@ ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig) fs << "uniform sampler2D uYTexture;" << endl; fs << "uniform sampler2D uCbTexture;" << endl; fs << "uniform sampler2D uCrTexture;" << endl; - fs << "uniform mat3 uYuvColorMatrix;" << endl; + fs << "uniform mat4 uYuvColorMatrix;" << endl; } else if (aConfig.mFeatures & ENABLE_TEXTURE_NV12) { fs << "uniform " << sampler2D << " uYTexture;" << endl; fs << "uniform " << sampler2D << " uCbTexture;" << endl; @@ -436,12 +436,8 @@ ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig) } } - fs << " y = y - 0.06275;" << endl; - fs << " cb = cb - 0.50196;" << endl; - fs << " cr = cr - 0.50196;" << endl; - fs << " vec3 yuv = vec3(y, cb, cr);" << endl; - fs << " color.rgb = uYuvColorMatrix * yuv;" << endl; - fs << " color.a = 1.0;" << endl; + fs << " vec4 yuv = vec4(y, cb, cr, 1.0);" << endl; + fs << " color = uYuvColorMatrix * yuv;" << endl; } else if (aConfig.mFeatures & ENABLE_TEXTURE_COMPONENT_ALPHA) { if (aConfig.mFeatures & ENABLE_TEXTURE_RECT) { fs << " COLOR_PRECISION vec3 onBlack = " << texture2D << "(uBlackTexture, coord * uTexCoordMultiplier).rgb;" << endl; @@ -964,10 +960,10 @@ ShaderProgramOGL::SetBlurRadius(float aRX, float aRY) } void -ShaderProgramOGL::SetYUVColorSpace(YUVColorSpace aYUVColorSpace) +ShaderProgramOGL::SetYUVColorSpace(YUVColorSpace aYUVColorSpace, ColorRange aColorRange) { - const float* yuvToRgb = gfxUtils::Get3x3YuvColorMatrix(aYUVColorSpace); - SetMatrix3fvUniform(KnownUniform::YuvColorMatrix, yuvToRgb); + const float* yuvToRgb = gfxUtils::YuvToRgbMatrix4x4ColumnMajor(aYUVColorSpace, aColorRange); + SetMatrixUniform(KnownUniform::YuvColorMatrix, yuvToRgb); } } // namespace layers diff --git a/gfx/layers/opengl/OGLShaderProgram.h b/gfx/layers/opengl/OGLShaderProgram.h index ff4fb825f5..7a7c7dfe46 100644 --- a/gfx/layers/opengl/OGLShaderProgram.h +++ b/gfx/layers/opengl/OGLShaderProgram.h @@ -479,7 +479,7 @@ public: SetUniform(KnownUniform::CbCrTexCoordMultiplier, 2, f); } - void SetYUVColorSpace(YUVColorSpace aYUVColorSpace); + void SetYUVColorSpace(YUVColorSpace aYUVColorSpace, ColorRange aColorRange); // Set whether we want the component alpha shader to return the color // vector (pass 1, false) or the alpha vector (pass2, true). With support diff --git a/gfx/thebes/gfxUtils.cpp b/gfx/thebes/gfxUtils.cpp index dfd1d6d0d0..1ec73fbde0 100644 --- a/gfx/thebes/gfxUtils.cpp +++ b/gfx/thebes/gfxUtils.cpp @@ -1084,59 +1084,71 @@ gfxUtils::EncodeSourceSurface(SourceSurface* aSurface, // 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}; + 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 kBT601FullYCbCrToRGB_RowMajor[16] = { + 1.00000f, 0.00000f, 1.40752f, -0.70652f, + 1.00000f, -0.34549f, -0.71695f, 0.53330f, + 1.00000f, 1.77898f, -0.00000f, -0.89298f, + 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}; + 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}; +const float kBT709FullYCbCrToRGB_RowMajor[16] = { + 1.00000f, 0.00000f, 1.58100f, -0.79360f, + 1.00000f, -0.18806f, -0.46997f, 0.33030f, + 1.00000f, 1.86291f, 0.00000f, -0.93511f, + 0.00000f, 0.00000f, 0.00000f, 1.00000f}; + const float kIdentityNarrowYCbCrToRGB_RowMajor[16] = { 0.00000f, 0.00000f, 1.00000f, 0.00000f, 1.00000f, 0.00000f, 0.00000f, 0.00000f, 0.00000f, 1.00000f, 0.00000f, 0.00000f, 0.00000f, 0.00000f, 0.00000f, 1.00000f}; /* static */ const float* -gfxUtils::Get4x3YuvColorMatrix(YUVColorSpace aYUVColorSpace) +gfxUtils::YuvToRgbMatrix4x4XRowMajor(YUVColorSpace aYUVColorSpace, ColorRange aColorRange) { -#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 rec601[12] = X(kBT601NarrowYCbCrToRGB_RowMajor); - static const float rec709[12] = X(kBT709NarrowYCbCrToRGB_RowMajor); - static const float identity[12] = X(kIdentityNarrowYCbCrToRGB_RowMajor); - -#undef X - switch (aYUVColorSpace) { case YUVColorSpace::BT601: - return rec601; + return aColorRange == ColorRange::LIMITED ? kBT601NarrowYCbCrToRGB_RowMajor + : kBT601FullYCbCrToRGB_RowMajor; case YUVColorSpace::BT709: - return rec709; + return aColorRange == ColorRange::LIMITED ? kBT709NarrowYCbCrToRGB_RowMajor + : kBT709FullYCbCrToRGB_RowMajor; case YUVColorSpace::IDENTITY: - return identity; + return kIdentityNarrowYCbCrToRGB_RowMajor; default: MOZ_CRASH("Bad YUVColorSpace"); } } /* static */ const float* -gfxUtils::Get3x3YuvColorMatrix(YUVColorSpace aYUVColorSpace) +gfxUtils::YuvToRgbMatrix4x4ColumnMajor(YUVColorSpace aYUVColorSpace, ColorRange aColorRange) { #define X(x) \ - { x[0], x[4], x[8], x[1], x[5], x[9], x[2], x[6], x[10] } + { x[0], x[4], x[8], 0.0f, \ + x[1], x[5], x[9], 0.0f, \ + x[2], x[6], x[10], 0.0f, \ + x[3], x[7], x[11], 1.0f } - static const float rec601[9] = X(kBT601NarrowYCbCrToRGB_RowMajor); - static const float rec709[9] = X(kBT709NarrowYCbCrToRGB_RowMajor); - static const float identity[9] = X(kIdentityNarrowYCbCrToRGB_RowMajor); + static const float rec601Narrow[16] = X(kBT601NarrowYCbCrToRGB_RowMajor); + static const float rec601Full[16] = X(kBT601FullYCbCrToRGB_RowMajor); + static const float rec709Narrow[16] = X(kBT709NarrowYCbCrToRGB_RowMajor); + static const float rec709Full[16] = X(kBT709FullYCbCrToRGB_RowMajor); + static const float identity[16] = X(kIdentityNarrowYCbCrToRGB_RowMajor); #undef X switch (aYUVColorSpace) { case YUVColorSpace::BT601: - return rec601; + return aColorRange == ColorRange::LIMITED ? rec601Narrow : rec601Full; case YUVColorSpace::BT709: - return rec709; + return aColorRange == ColorRange::LIMITED ? rec709Narrow : rec709Full; case YUVColorSpace::IDENTITY: return identity; default: diff --git a/gfx/thebes/gfxUtils.h b/gfx/thebes/gfxUtils.h index a86d9a8898..80094a762f 100644 --- a/gfx/thebes/gfxUtils.h +++ b/gfx/thebes/gfxUtils.h @@ -43,6 +43,7 @@ public: typedef mozilla::gfx::SurfaceFormat SurfaceFormat; typedef mozilla::image::ImageRegion ImageRegion; typedef mozilla::YUVColorSpace YUVColorSpace; + typedef mozilla::ColorRange ColorRange; /* * Premultiply or Unpremultiply aSourceSurface, writing the result @@ -139,9 +140,11 @@ public: /** * Get array of yuv to rgb conversion matrix. */ - static const float* Get4x3YuvColorMatrix(YUVColorSpace aYUVColorSpace); + static const float* YuvToRgbMatrix4x4XRowMajor(YUVColorSpace aYUVColorSpace, + ColorRange aColorRange); - static const float* Get3x3YuvColorMatrix(YUVColorSpace aYUVColorSpace); + static const float* YuvToRgbMatrix4x4ColumnMajor(YUVColorSpace aYUVColorSpace, + ColorRange aColorRange); /** * Creates a copy of aSurface, but having the SurfaceFormat aFormat. |