From 8bacb52ca3cd52d3bf65b48fc2bf49a0180cb3dc Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Mon, 20 Feb 2023 10:12:47 -0600 Subject: [PATCH 1/9] Issue #2117 - Part 1 - Update Mac DMG platform names to intel64 for Intel and arm64 for Apple Silicon. --- toolkit/mozapps/installer/package-name.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toolkit/mozapps/installer/package-name.mk b/toolkit/mozapps/installer/package-name.mk index 548a93b47f..2c9b784883 100644 --- a/toolkit/mozapps/installer/package-name.mk +++ b/toolkit/mozapps/installer/package-name.mk @@ -43,9 +43,9 @@ ifdef UNIVERSAL_BINARY MOZ_PKG_PLATFORM := mac else ifeq ($(TARGET_CPU),x86_64) -MOZ_PKG_PLATFORM := mac64 +MOZ_PKG_PLATFORM := intel64 else -MOZ_PKG_PLATFORM := mac +MOZ_PKG_PLATFORM := arm64 endif endif endif From cbc529bb0ec2d3d9869d07be817ca2b210ad2185 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Mon, 20 Feb 2023 10:15:11 -0600 Subject: [PATCH 2/9] Issue #2117 - Part 2 - Revert "Follow up to d0eee8f01 - Run precomplete cmd during package staging" This reverts commit c622e988fed60f2e868cd0419f5cf517323b5c2a. --- toolkit/mozapps/installer/packager-uxp.mk | 1 + toolkit/mozapps/installer/packager.mk | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/toolkit/mozapps/installer/packager-uxp.mk b/toolkit/mozapps/installer/packager-uxp.mk index 8d7cb4e62d..856ca434c3 100644 --- a/toolkit/mozapps/installer/packager-uxp.mk +++ b/toolkit/mozapps/installer/packager-uxp.mk @@ -15,6 +15,7 @@ ifeq (,$(filter SunOS Linux WINNT,$(OS_ARCH))) else $(MAKE) stage-package make-buildinfo-file @echo 'Compressing...' + cd $(DIST)/$(MOZ_PKG_DIR); $(CREATE_PRECOMPLETE_CMD) ifeq (WINNT,$(OS_ARCH)) cd $(DIST); $(CYGWIN_WRAPPER) 7z a -t7z -m0=lzma2 -mx=9 -aoa -bb3 $(PKG_BASENAME).7z $(MOZ_PKG_DIR) else diff --git a/toolkit/mozapps/installer/packager.mk b/toolkit/mozapps/installer/packager.mk index 6cae156580..41a07cbfd5 100644 --- a/toolkit/mozapps/installer/packager.mk +++ b/toolkit/mozapps/installer/packager.mk @@ -55,7 +55,6 @@ stage-package: $(MOZ_PKG_MANIFEST) $(MOZ_PKG_MANIFEST_DEPS) $(MOZ_PKG_MANIFEST) '$(DIST)' '$(DIST)'/$(STAGEPATH)$(MOZ_PKG_DIR)$(if $(MOZ_PKG_MANIFEST),,$(_BINPATH)) \ $(if $(filter omni,$(MOZ_PACKAGER_FORMAT)),$(if $(NON_OMNIJAR_FILES),--non-resource $(NON_OMNIJAR_FILES))) $(PYTHON) $(MOZILLA_DIR)/toolkit/mozapps/installer/find-dupes.py $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR) - @(cd $(DIST)/$(MOZ_PKG_DIR) && $(CREATE_PRECOMPLETE_CMD)) ifdef MOZ_PACKAGE_JSSHELL # Package JavaScript Shell @echo 'Packaging JavaScript Shell...' From 691afc8c8b291c805126ca097986e7ec0bbb5191 Mon Sep 17 00:00:00 2001 From: FranklinDM Date: Sat, 25 Feb 2023 02:02:59 +0800 Subject: [PATCH 3/9] Issue #1382 - Part 1: Remove assertion that GetPreEffectsVisualOverflowRect is called only by frames whose parent is an anonymous block This is always hit if an SVG effect is applied on other frame types. Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1340257 --- layout/svg/nsSVGIntegrationUtils.cpp | 50 ++++++++-------------------- 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/layout/svg/nsSVGIntegrationUtils.cpp b/layout/svg/nsSVGIntegrationUtils.cpp index 4ce2941d49..b8440cc455 100644 --- a/layout/svg/nsSVGIntegrationUtils.cpp +++ b/layout/svg/nsSVGIntegrationUtils.cpp @@ -79,42 +79,20 @@ private: if (r) { return *r; } - // Despite the fact that we're invoked for frames with SVG effects applied, - // we can actually get here. All continuations and IB split siblings of a - // frame with SVG effects applied will have the PreEffectsBBoxProperty - // property set on them. Therefore, the frames that are passed to us will - // always have that property set...well, with one exception. If the frames - // for an element with SVG effects applied have been subject to an "IB - // split", then the block frame(s) that caused the split will have been - // wrapped in anonymous, inline-block, nsBlockFrames of pseudo-type - // nsCSSAnonBoxes::mozAnonymousBlock. These "IB split sibling" anonymous - // blocks will have the PreEffectsBBoxProperty property set on them, but - // they will never be passed to us. Instead, we'll be passed the block - // children that they wrap, which don't have the PreEffectsBBoxProperty - // property set on them. This is actually okay. What we care about is - // collecting the _pre_ effects visual overflow rects of the frames to - // which the SVG effects have been applied. Since the IB split results in - // any overflow rect adjustments for transforms, effects, etc. taking - // place on the anonymous block wrappers, the wrapped children are left - // with their overflow rects unaffected. In other words, calling - // GetVisualOverflowRect() on the children will return their pre-effects - // visual overflow rects, just as we need. - // - // A couple of tests that demonstrate the IB split and cause us to get here - // are: - // - // * reftests/svg/svg-integration/clipPath-html-06.xhtml - // * reftests/svg/svg-integration/clipPath-html-06-extref.xhtml - // - // If we ever got passed a frame with the PreTransformOverflowAreasProperty - // property set, that would be bad, since then our GetVisualOverflowRect() - // call would give us the post-effects, and post-transform, overflow rect. - // - NS_ASSERTION(aFrame->GetParent()->StyleContext()->GetPseudo() == - nsCSSAnonBoxes::mozAnonymousBlock, - "How did we getting here, then?"); - NS_ASSERTION(!aFrame->GetProperty(aFrame->PreTransformOverflowAreasProperty()), - "GetVisualOverflowRect() won't return the pre-effects rect!"); +#ifdef DEBUG + // Having PreTransformOverflowAreasProperty cached means + // GetVisualOverflowRect() will return post-effect rect, which is not what + // we want. This function intentional reports pre-effect rect. But it does + // not matter if there is no SVG effect on this frame, since no effect + // means post-effect rect matches pre-effect rect. + if (nsSVGIntegrationUtils::UsingEffectsForFrame(aFrame)) { + nsOverflowAreas* preTransformOverflows = + aFrame->GetProperty(aFrame->PreTransformOverflowAreasProperty()); + + NS_ASSERTION(!preTransformOverflows, + "GetVisualOverflowRect() won't return the pre-effects rect!"); + } +#endif return aFrame->GetVisualOverflowRect(); } From ebe27baa23b38bc8038874b738aad4d1b70373da Mon Sep 17 00:00:00 2001 From: FranklinDM Date: Sat, 25 Feb 2023 02:03:34 +0800 Subject: [PATCH 4/9] Issue #1382 - Part 2: Add crash test Based on https://bugzilla.mozilla.org/show_bug.cgi?id=842114 --- layout/base/crashtests/842114.html | 6 ++++++ layout/base/crashtests/crashtests.list | 1 + 2 files changed, 7 insertions(+) create mode 100644 layout/base/crashtests/842114.html diff --git a/layout/base/crashtests/842114.html b/layout/base/crashtests/842114.html new file mode 100644 index 0000000000..18af6aca95 --- /dev/null +++ b/layout/base/crashtests/842114.html @@ -0,0 +1,6 @@ + + + +
+ + diff --git a/layout/base/crashtests/crashtests.list b/layout/base/crashtests/crashtests.list index 1c8e2713ac..c0b0085493 100644 --- a/layout/base/crashtests/crashtests.list +++ b/layout/base/crashtests/crashtests.list @@ -438,6 +438,7 @@ load 833604-1.html load 835056.html load 836990-1.html load 840480.html +load 842114.html load 847242.html pref(layers.progressive-paint,false) pref(layers.low-precision-buffer,false) load 852293.html pref(layers.force-active,true) load 859526-1.html From edc45f68493ffc1a79b7f244a44f4e295f156910 Mon Sep 17 00:00:00 2001 From: FranklinDM Date: Sun, 26 Feb 2023 01:24:12 +0800 Subject: [PATCH 5/9] Issue #1593 - Follow-up: Fix :host selector matching Previously, we would match `:host` if: (a) we don't have any arguments and our parent is the shadow root, or; (b) if any of the arguments match, then reject if we don't have a containing shadow Revised, we would match `:host` if: (Preconditions) The element must have a shadow root, the selector must not have any feature selectors, and it is not blocked from matching `:host` (e.g. .matches outside of the shadow root context) (a) The selector does not have any arguments, or; (b) It matches any of its arguments in the functional part of the pseudo-class With this, we now pass these tests that were previously failing: http://wpt.live/css/css-scoping/css-scoping-shadow-host-rule.html http://wpt.live/css/css-scoping/host-descendant-002.html http://wpt.live/css/css-scoping/host-multiple-001.html Improved (1 less red box): http://wpt.live/css/css-scoping/css-scoping-shadow-host-namespace.html --- layout/style/nsCSSRuleProcessor.cpp | 53 ++++++++++++++--------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index 73209a951a..ebc3dad63e 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -1378,7 +1378,10 @@ enum class SelectorMatchesFlags : uint8_t { // The selector is part of an argument to a functional pseudo-class or // pseudo-element. - IS_PSEUDO_CLASS_ARGUMENT = 1 << 2 + IS_PSEUDO_CLASS_ARGUMENT = 1 << 2, + + // The selector should be blocked from matching the :host pseudo-class. + IS_HOST_INACCESSIBLE = 1 << 3 }; MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(SelectorMatchesFlags) @@ -1395,7 +1398,8 @@ static inline bool ActiveHoverQuirkMatches(nsCSSSelector* aSelector, // flags are unknown). aSelectorFlags & (SelectorMatchesFlags::UNKNOWN | SelectorMatchesFlags::HAS_PSEUDO_ELEMENT | - SelectorMatchesFlags::IS_PSEUDO_CLASS_ARGUMENT)) { + SelectorMatchesFlags::IS_PSEUDO_CLASS_ARGUMENT | + SelectorMatchesFlags::IS_HOST_INACCESSIBLE)) { return false; } @@ -1954,17 +1958,17 @@ static bool SelectorMatches(Element* aElement, // we must be matching only against host pseudo selectors, and the // selector's context must be the shadow root (the selector must be // featureless, the left-most selector, and be in a shadow root - // style). The :host selector may also be be functional, with a - // compound selector. If this is the case, then also ensure that the - // host element matches against the compound - // selector. - - // We match automatically if GetParent() and GetShadowRoot() have - // the same result iff our selector list is empty. Without special - // casing this ahead of all other selector matching, it fails. - // Have not determined the cause. - if (!pseudoClass->u.mSelectorList && - aElement->GetParent() == aElement->GetShadowRoot()) { + // style). + if (!aElement->GetShadowRoot() || + aSelector->HasFeatureSelectors() || + aSelectorFlags & SelectorMatchesFlags::IS_HOST_INACCESSIBLE) { + return false; + } + + // The :host selector may also be be functional, with a compound + // selector. If this is the case, then also ensure that the host + // element matches against the compound selector. + if (!pseudoClass->u.mSelectorList) { break; } @@ -1973,25 +1977,15 @@ static bool SelectorMatches(Element* aElement, // selector check under SelectorMatches. NodeMatchContext nodeContext(EventStates(), aNodeMatchContext.mIsRelevantLink); - if (SelectorListMatches(aElement, - pseudoClass, - nodeContext, - aTreeMatchContext)) { - break; - } - - // Finally, with the exception of the two above cases, make sure we - // don't match if GetContainingShadow() returns null. For whatever - // reason, we can't test for this case first. - - if (aElement->GetContainingShadow() == nullptr) { + if (!SelectorListMatches(aElement, + pseudoClass, + nodeContext, + aTreeMatchContext)) { return false; } - } break; - case CSSPseudoClassType::hostContext: { // In order to match host-context, the element must be a @@ -4162,11 +4156,14 @@ nsCSSRuleProcessor::RestrictedSelectorListMatches(Element* aElement, "SelectorMatchesTree call"); NodeMatchContext nodeContext(EventStates(), false); + SelectorMatchesFlags flags = aElement->IsInShadowTree() ? + SelectorMatchesFlags::NONE : + SelectorMatchesFlags::IS_HOST_INACCESSIBLE; return SelectorListMatches(aElement, aSelectorList, nodeContext, aTreeMatchContext, - SelectorMatchesFlags::NONE); + flags); } void From d9b7057ffdc803b458069b81dea724685f430096 Mon Sep 17 00:00:00 2001 From: FranklinDM Date: Sun, 26 Feb 2023 15:52:07 +0800 Subject: [PATCH 6/9] Issue #1344 - (Parser: Java) Don't reset containsHyphen value after finding one --- .../htmlparser/src/nu/validator/htmlparser/impl/Tokenizer.java | 1 - 1 file changed, 1 deletion(-) diff --git a/parser/html/java/htmlparser/src/nu/validator/htmlparser/impl/Tokenizer.java b/parser/html/java/htmlparser/src/nu/validator/htmlparser/impl/Tokenizer.java index c6f6797fff..a674189450 100644 --- a/parser/html/java/htmlparser/src/nu/validator/htmlparser/impl/Tokenizer.java +++ b/parser/html/java/htmlparser/src/nu/validator/htmlparser/impl/Tokenizer.java @@ -1784,7 +1784,6 @@ public class Tokenizer implements Locator { * name. */ appendStrBuf(c); - containsHyphen = false; /* * Stay in the tag name state. */ From 55100bb28ea97f70d7ff1b862599e7709721e3be Mon Sep 17 00:00:00 2001 From: FranklinDM Date: Sun, 26 Feb 2023 16:00:51 +0800 Subject: [PATCH 7/9] Issue #1344 - (Parser: C++) Don't reset containsHyphen value after finding one --- parser/html/nsHtml5Tokenizer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/parser/html/nsHtml5Tokenizer.cpp b/parser/html/nsHtml5Tokenizer.cpp index 4c6a32f731..c3b92fdc8d 100644 --- a/parser/html/nsHtml5Tokenizer.cpp +++ b/parser/html/nsHtml5Tokenizer.cpp @@ -598,7 +598,6 @@ nsHtml5Tokenizer::stateLoop(int32_t state, char16_t c, int32_t pos, char16_t* bu containsHyphen = true; } appendStrBuf(c); - containsHyphen = false; continue; } } From beef4376020be765b96c8001b73b0eb7ed75efad Mon Sep 17 00:00:00 2001 From: u3shit Date: Fri, 24 Feb 2023 19:11:36 +0100 Subject: [PATCH 8/9] 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. From 3e62b1fc9f641ee30b5b5b20374e8410d5ad2d6b Mon Sep 17 00:00:00 2001 From: u3shit Date: Fri, 24 Feb 2023 19:52:57 +0100 Subject: [PATCH 9/9] Issue #2118 - Part 2: Add support for Identity YUVColorSpace https://hg.mozilla.org/mozilla-central/rev/be342c90755d11551623362f2058c0326f63bbb3 --- dom/media/platforms/agnostic/AOMDecoder.cpp | 15 ++++++ dom/media/platforms/agnostic/VPXDecoder.cpp | 16 ++++++ .../platforms/ffmpeg/FFmpegVideoDecoder.cpp | 10 +++- gfx/layers/ImageTypes.h | 1 + gfx/thebes/gfxUtils.cpp | 10 ++++ gfx/ycbcr/yuv_convert.cpp | 52 ++++++++++++++++--- 6 files changed, 97 insertions(+), 7 deletions(-) diff --git a/dom/media/platforms/agnostic/AOMDecoder.cpp b/dom/media/platforms/agnostic/AOMDecoder.cpp index b5d21375e7..693b98c949 100644 --- a/dom/media/platforms/agnostic/AOMDecoder.cpp +++ b/dom/media/platforms/agnostic/AOMDecoder.cpp @@ -232,6 +232,21 @@ AOMDecoder::DoDecode(MediaRawData* aSample) RESULT_DETAIL("AOM Unknown image format")); } + switch (img->mc) { + case AOM_CICP_MC_BT_601: + b.mYUVColorSpace = YUVColorSpace::BT601; + break; + case AOM_CICP_MC_BT_709: + b.mYUVColorSpace = YUVColorSpace::BT709; + break; + case AOM_CICP_MC_IDENTITY: + b.mYUVColorSpace = YUVColorSpace::IDENTITY; + break; + default: + LOG("Unhandled colorspace %d", img->mc); + break; + } + RefPtr v = VideoData::CreateAndCopyData(mInfo, mImageContainer, diff --git a/dom/media/platforms/agnostic/VPXDecoder.cpp b/dom/media/platforms/agnostic/VPXDecoder.cpp index f06f6e08b1..ebc85c9e51 100644 --- a/dom/media/platforms/agnostic/VPXDecoder.cpp +++ b/dom/media/platforms/agnostic/VPXDecoder.cpp @@ -158,6 +158,22 @@ VPXDecoder::DoDecode(MediaRawData* aSample) RESULT_DETAIL("VPX Unknown image format")); } + b.mYUVColorSpace = [&]() { + switch (img->cs) { + case VPX_CS_BT_601: + case VPX_CS_SMPTE_170: + case VPX_CS_SMPTE_240: + return YUVColorSpace::BT601; + case VPX_CS_BT_709: + return YUVColorSpace::BT709; + case VPX_CS_SRGB: + return YUVColorSpace::IDENTITY; + default: + LOG("Unhandled colorspace %d", img->cs); + return YUVColorSpace::BT601; + } + }(); + RefPtr v = VideoData::CreateAndCopyData(mInfo, mImageContainer, diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp index f9e8a2d268..12317ca6e4 100644 --- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp +++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp @@ -24,6 +24,7 @@ #define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P #define AV_PIX_FMT_YUVJ420P PIX_FMT_YUVJ420P #define AV_PIX_FMT_YUV444P PIX_FMT_YUV444P +#define AV_PIX_FMT_GBRP PIX_FMT_GBRP #define AV_PIX_FMT_NONE PIX_FMT_NONE #endif @@ -54,6 +55,9 @@ ChoosePixelFormat(AVCodecContext* aCodecContext, const AVPixelFormat* aFormats) case AV_PIX_FMT_YUVJ420P: FFMPEG_LOG("Requesting pixel format YUVJ420P."); return AV_PIX_FMT_YUVJ420P; + case AV_PIX_FMT_GBRP: + FFMPEG_LOG("Requesting pixel format GBRP."); + return AV_PIX_FMT_GBRP; default: break; } @@ -353,7 +357,8 @@ FFmpegVideoDecoder::CreateImage(int64_t aOffset, int64_t aPts, b.mPlanes[0].mWidth = mFrame->width; b.mPlanes[0].mHeight = mFrame->height; - if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P) { + if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P || + mCodecContext->pix_fmt == AV_PIX_FMT_GBRP) { b.mPlanes[1].mWidth = b.mPlanes[2].mWidth = mFrame->width; b.mPlanes[1].mHeight = b.mPlanes[2].mHeight = mFrame->height; } else { @@ -369,6 +374,9 @@ FFmpegVideoDecoder::CreateImage(int64_t aOffset, int64_t aPts, case AVCOL_SPC_BT470BG: b.mYUVColorSpace = YUVColorSpace::BT601; break; + case AVCOL_SPC_RGB: + b.mYUVColorSpace = YUVColorSpace::IDENTITY; + break; default: break; } diff --git a/gfx/layers/ImageTypes.h b/gfx/layers/ImageTypes.h index 7a3b81f6e1..de154912b4 100644 --- a/gfx/layers/ImageTypes.h +++ b/gfx/layers/ImageTypes.h @@ -118,6 +118,7 @@ enum class StereoMode { enum class YUVColorSpace { BT601, BT709, + IDENTITY, // This represents the unknown format. UNKNOWN, }; diff --git a/gfx/thebes/gfxUtils.cpp b/gfx/thebes/gfxUtils.cpp index 499ae720e3..cad692a4d3 100644 --- a/gfx/thebes/gfxUtils.cpp +++ b/gfx/thebes/gfxUtils.cpp @@ -1091,6 +1091,10 @@ 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}; +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) @@ -1100,6 +1104,7 @@ gfxUtils::Get4x3YuvColorMatrix(YUVColorSpace aYUVColorSpace) 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 @@ -1108,6 +1113,8 @@ gfxUtils::Get4x3YuvColorMatrix(YUVColorSpace aYUVColorSpace) return rec601; case YUVColorSpace::BT709: return rec709; + case YUVColorSpace::IDENTITY: + return identity; default: MOZ_CRASH("Bad YUVColorSpace"); } @@ -1121,6 +1128,7 @@ gfxUtils::Get3x3YuvColorMatrix(YUVColorSpace aYUVColorSpace) static const float rec601[9] = X(kBT601NarrowYCbCrToRGB_RowMajor); static const float rec709[9] = X(kBT709NarrowYCbCrToRGB_RowMajor); + static const float identity[9] = X(kIdentityNarrowYCbCrToRGB_RowMajor); #undef X @@ -1129,6 +1137,8 @@ gfxUtils::Get3x3YuvColorMatrix(YUVColorSpace aYUVColorSpace) return rec601; case YUVColorSpace::BT709: return rec709; + case YUVColorSpace::IDENTITY: + return identity; default: MOZ_CRASH("Bad YUVColorSpace"); } diff --git a/gfx/ycbcr/yuv_convert.cpp b/gfx/ycbcr/yuv_convert.cpp index 78fd4ee89a..fae2c7df69 100644 --- a/gfx/ycbcr/yuv_convert.cpp +++ b/gfx/ycbcr/yuv_convert.cpp @@ -24,6 +24,7 @@ // Header for low level row functions. #include "yuv_row.h" #include "mozilla/SSE.h" +#include "mozilla/IntegerRange.h" namespace mozilla { @@ -63,6 +64,23 @@ libyuv::FourCC FourCCFromYUVType(YUVType aYUVType) } } +void GBRPlanarToARGB(const uint8_t* src_y, int y_pitch, + const uint8_t* src_u, int u_pitch, + const uint8_t* src_v, int v_pitch, + uint8_t* rgb_buf, int rgb_pitch, + int pic_width, int pic_height) { + // libyuv has no native conversion function for this + // fixme: replace with something less awful + for (const auto row : MakeRange(pic_height)) { + for (const auto col : MakeRange(pic_width)) { + rgb_buf[rgb_pitch * row + col * 4 + 0] = src_u[u_pitch * row + col]; + rgb_buf[rgb_pitch * row + col * 4 + 1] = src_y[y_pitch * row + col]; + rgb_buf[rgb_pitch * row + col * 4 + 2] = src_v[v_pitch * row + col]; + rgb_buf[rgb_pitch * row + col * 4 + 3] = 255; + } + } +} + // Convert a frame of YUV to 32 bit ARGB. void ConvertYCbCrToRGB32(const uint8* y_buf, const uint8* u_buf, @@ -106,12 +124,19 @@ void ConvertYCbCrToRGB32(const uint8* y_buf, const uint8* src_y = y_buf + y_pitch * pic_y + pic_x; const uint8* src_u = u_buf + uv_pitch * pic_y + pic_x; const uint8* src_v = v_buf + uv_pitch * pic_y + pic_x; - DebugOnly err = libyuv::I444ToARGB(src_y, y_pitch, - src_u, uv_pitch, - src_v, uv_pitch, - rgb_buf, rgb_pitch, - pic_width, pic_height); - MOZ_ASSERT(!err); + if (yuv_color_space == YUVColorSpace::IDENTITY) { + // Special case for RGB image + GBRPlanarToARGB(src_y, y_pitch, src_u, uv_pitch, src_v, uv_pitch, + rgb_buf, rgb_pitch, pic_width, pic_height); + return; + } else { + DebugOnly err = libyuv::I444ToARGB(src_y, y_pitch, + src_u, uv_pitch, + src_v, uv_pitch, + rgb_buf, rgb_pitch, + pic_width, pic_height); + MOZ_ASSERT(!err); + } } else if (yuv_type == YV16) { const uint8* src_y = y_buf + y_pitch * pic_y + pic_x; const uint8* src_u = u_buf + uv_pitch * pic_y + pic_x / 2; @@ -301,6 +326,21 @@ void ScaleYCbCrToRGB32(const uint8* y_buf, return; } + if (yuv_type == YV24 && yuv_color_space == YUVColorSpace::IDENTITY) { + auto buffer = MakeUnique(source_width * source_height * 4); + auto buffer_pitch = source_width * 4; + GBRPlanarToARGB(y_buf, y_pitch, u_buf, uv_pitch, v_buf, uv_pitch, + buffer.get(), buffer_pitch, source_width, source_height); + DebugOnly err = + libyuv::ARGBScale(buffer.get(), buffer_pitch, + source_width, source_height, + rgb_buf, rgb_pitch, + width, height, + libyuv::kFilterBilinear); + MOZ_ASSERT(!err); + return; + } + DebugOnly err = libyuv::YUVToARGBScale(y_buf, y_pitch, u_buf, uv_pitch,