author | Miko Mynttinen <mikokm@gmail.com> |
Fri, 04 Jan 2019 18:30:32 +0000 | |
changeset 452571 | b82f7f67b8aede2cafede289e89f42f1268eed86 |
parent 452570 | 21ae926713a06f914151f01612eda3412f529172 |
child 452572 | 6df75e023fc2a37009b8e3759d94b6e7bed5b570 |
push id | 35315 |
push user | shindli@mozilla.com |
push date | Sat, 05 Jan 2019 03:59:26 +0000 |
treeherder | mozilla-central@6dd228164d42 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mattwoodrow |
bugs | 1512244 |
milestone | 66.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
|
layout/generic/nsFrame.cpp | file | annotate | diff | comparison | revisions | |
layout/generic/nsIFrame.h | file | annotate | diff | comparison | revisions |
--- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -1485,20 +1485,22 @@ bool nsIFrame::HasAnimationOfTransform() bool nsIFrame::ChildrenHavePerspective( const nsStyleDisplay* aStyleDisplay) const { MOZ_ASSERT(aStyleDisplay == StyleDisplay()); return aStyleDisplay->HasPerspective(this); } bool nsIFrame::HasOpacityInternal(float aThreshold, + const nsStyleDisplay* aStyleDisplay, + const nsStyleEffects* aStyleEffects, EffectSet* aEffectSet) const { MOZ_ASSERT(0.0 <= aThreshold && aThreshold <= 1.0, "Invalid argument"); - if (StyleEffects()->mOpacity < aThreshold || - (StyleDisplay()->mWillChangeBitField & NS_STYLE_WILL_CHANGE_OPACITY)) { + if (aStyleEffects->mOpacity < aThreshold || + (aStyleDisplay->mWillChangeBitField & NS_STYLE_WILL_CHANGE_OPACITY)) { return true; } if (!mMayHaveOpacityAnimation) { return false; } EffectSet* effects = aEffectSet ? aEffectSet : EffectSet::GetEffectSet(this); @@ -1513,37 +1515,38 @@ bool nsIFrame::HasOpacityInternal(float } bool nsIFrame::IsSVGTransformed(gfx::Matrix* aOwnTransforms, gfx::Matrix* aFromParentTransforms) const { return false; } bool nsIFrame::Extend3DContext(const nsStyleDisplay* aStyleDisplay, + const nsStyleEffects* aStyleEffects, mozilla::EffectSet* aEffectSet) const { if (!(mState & NS_FRAME_MAY_BE_TRANSFORMED)) { return false; } const nsStyleDisplay* disp = StyleDisplayWithOptionalParam(aStyleDisplay); if (disp->mTransformStyle != NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D || !IsFrameOfType(nsIFrame::eSupportsCSSTransforms)) { return false; } // If we're all scroll frame, then all descendants will be clipped, so we // can't preserve 3d. if (IsScrollFrame()) { return false; } - if (HasOpacity(aEffectSet)) { + const nsStyleEffects* effects = StyleEffectsWithOptionalParam(aStyleEffects); + if (HasOpacity(disp, effects, aEffectSet)) { return false; } - const nsStyleEffects* effects = StyleEffects(); return !nsFrame::ShouldApplyOverflowClipping(this, disp) && !GetClipPropClipRect(disp, effects, GetSize()) && !nsSVGIntegrationUtils::UsingEffectsForFrame(this); } bool nsIFrame::Combines3DTransformWithAncestors( const nsStyleDisplay* aStyleDisplay) const { MOZ_ASSERT(aStyleDisplay == StyleDisplay()); @@ -2718,19 +2721,31 @@ void nsIFrame::BuildDisplayListForStacki } // For preserves3d, use the dirty rect already installed on the // builder, since aDirtyRect maybe distorted for transforms along // the chain. nsRect visibleRect = aBuilder->GetVisibleRect(); nsRect dirtyRect = aBuilder->GetDirtyRect(); + // We build an opacity item if it's not going to be drawn by SVG content. + // We could in principle skip creating an nsDisplayOpacity item if + // nsDisplayOpacity::NeedsActiveLayer returns false and usingSVGEffects is + // true (the nsDisplayFilter/nsDisplayMasksAndClipPaths could handle the + // opacity). Since SVG has perf issues where we sometimes spend a lot of + // time creating display list items that might be helpful. We'd need to + // restore our mechanism to do that (changed in bug 1482403), and we'd + // need to invalidate the frame if the value that would be return from + // NeedsActiveLayer was to change, which we don't currently do. + const bool useOpacity = HasVisualOpacity(disp, effects, effectSet) && + !nsSVGUtils::CanOptimizeOpacity(this); + const bool isTransformed = IsTransformed(disp); const bool hasPerspective = isTransformed && HasPerspective(disp); - const bool extend3DContext = Extend3DContext(disp, effectSet); + const bool extend3DContext = Extend3DContext(disp, effects, effectSet); const bool combines3DTransformWithAncestors = (extend3DContext || isTransformed) && Combines3DTransformWithAncestors(disp); Maybe<nsDisplayListBuilder::AutoPreserves3DContext> autoPreserves3DContext; if (extend3DContext && !combines3DTransformWithAncestors) { // Start a new preserves3d context to keep informations on // nsDisplayListBuilder. @@ -2826,28 +2841,16 @@ void nsIFrame::BuildDisplayListForStacki if (usingSVGEffects) { dirtyRect = nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(this, dirtyRect); visibleRect = nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea( this, visibleRect); aBuilder->EnterSVGEffectsContents(&hoistedScrollInfoItemsStorage); } - // We build an opacity item if it's not going to be drawn by SVG content. - // We could in principle skip creating an nsDisplayOpacity item if - // nsDisplayOpacity::NeedsActiveLayer returns false and usingSVGEffects is - // true (the nsDisplayFilter/nsDisplayMasksAndClipPaths could handle the - // opacity). Since SVG has perf issues where we sometimes spend a lot of - // time creating display list items that might be helpful. We'd need to - // restore our mechanism to do that (changed in bug 1482403), and we'd - // need to invalidate the frame if the value that would be return from - // NeedsActiveLayer was to change, which we don't currently do. - bool useOpacity = - HasVisualOpacity(effectSet) && !nsSVGUtils::CanOptimizeOpacity(this); - bool useBlendMode = effects->mMixBlendMode != NS_STYLE_BLEND_NORMAL; bool useStickyPosition = disp->mPosition == NS_STYLE_POSITION_STICKY && IsScrollFrameActive( aBuilder, nsLayoutUtils::GetNearestScrollableFrame( GetParent(), nsLayoutUtils::SCROLLABLE_SAME_DOC | nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN)); @@ -3545,25 +3548,24 @@ void nsIFrame::BuildDisplayListForChild( child->PresShell()->EnsureFrameInApproximatelyVisibleList(child); awayFromCommonPath = true; } child->SetBuiltDisplayList(true); // Child is composited if it's transformed, partially transparent, or has // SVG effects or a blend mode.. - EffectSet* effectSet = EffectSet::GetEffectSet(child); const nsStyleDisplay* disp = child->StyleDisplay(); const nsStyleEffects* effects = child->StyleEffects(); const nsStylePosition* pos = child->StylePosition(); const bool isPositioned = disp->IsAbsPosContainingBlock(child); const bool isStackingContext = - child->IsStackingContext(effectSet, disp, pos, effects, isPositioned) || + child->IsStackingContext(disp, pos, effects, isPositioned) || (aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT); if (pseudoStackingContext || isStackingContext || isPositioned || (!isSVG && disp->IsFloating(child)) || (isSVG && (effects->mClipFlags & NS_STYLE_CLIP_RECT) && IsSVGContentWithCSSClip(child))) { pseudoStackingContext = true; awayFromCommonPath = true; @@ -8988,17 +8990,17 @@ bool nsIFrame::FinishAndStoreOverflow(ns o = nsDisplayTransform::TransformRect(o, this); } /* If we're the root of the 3d context, then we want to include the * overflow areas of all the participants. This won't have happened yet as * the code above set their overflow area to empty. Manually collect these * overflow areas now. */ - if (Extend3DContext(disp, effectSet)) { + if (Extend3DContext(disp, effects, effectSet)) { ComputePreserve3DChildrenOverflow(aOverflowAreas); } } } else { DeleteProperty(nsIFrame::PreTransformOverflowAreasProperty()); } /* Revert the size change in case some caller is depending on this. */ @@ -9079,17 +9081,17 @@ void nsIFrame::ComputePreserve3DChildren nsRect& o = childOverflow.Overflow(otype); o = nsDisplayTransform::TransformRect(o, child); } aOverflowAreas.UnionWith(childOverflow); // If this child also extends the 3d context, then recurse into it // looking for more participants. - if (child->Extend3DContext(childDisp)) { + if (child->Extend3DContext(childDisp, child->StyleEffects())) { child->ComputePreserve3DChildrenOverflow(aOverflowAreas); } } } } } uint32_t nsIFrame::GetDepthInFrameTree() const { @@ -10288,22 +10290,22 @@ void nsIFrame::CreateOwnLayerIfNeeded(ns aList->AppendToTop(MakeDisplayItem<nsDisplayOwnLayer>( aBuilder, this, aList, aBuilder->CurrentActiveScrolledRoot())); if (aCreatedContainerItem) { *aCreatedContainerItem = true; } } } -bool nsIFrame::IsStackingContext(EffectSet* aEffectSet, - const nsStyleDisplay* aStyleDisplay, +bool nsIFrame::IsStackingContext(const nsStyleDisplay* aStyleDisplay, const nsStylePosition* aStylePosition, const nsStyleEffects* aStyleEffects, bool aIsPositioned) { - return HasOpacity(aEffectSet) || IsTransformed(aStyleDisplay) || + return HasOpacity(aStyleDisplay, aStyleEffects, nullptr) || + IsTransformed(aStyleDisplay) || (IsFrameOfType(eSupportsContainLayoutAndPaint) && (aStyleDisplay->IsContainPaint() || aStyleDisplay->IsContainLayout())) || // strictly speaking, 'perspective' doesn't require visual atomicity, // but the spec says it acts like the rest of these ChildrenHavePerspective(aStyleDisplay) || aStyleEffects->mMixBlendMode != NS_STYLE_BLEND_NORMAL || nsSVGIntegrationUtils::UsingEffectsForFrame(this) || @@ -10313,18 +10315,17 @@ bool nsIFrame::IsStackingContext(EffectS (aStyleDisplay->mWillChangeBitField & NS_STYLE_WILL_CHANGE_STACKING_CONTEXT) || aStyleDisplay->mIsolation != NS_STYLE_ISOLATION_AUTO; } bool nsIFrame::IsStackingContext() { const nsStyleDisplay* disp = StyleDisplay(); const bool isPositioned = disp->IsAbsPosContainingBlock(this); - return IsStackingContext(EffectSet::GetEffectSet(this), disp, StylePosition(), - StyleEffects(), isPositioned); + return IsStackingContext(disp, StylePosition(), StyleEffects(), isPositioned); } static bool IsFrameScrolledOutOfView(const nsIFrame* aTarget, const nsRect& aTargetRect, const nsIFrame* aParent) { nsIScrollableFrame* scrollableFrame = nsLayoutUtils::GetNearestScrollableFrame( const_cast<nsIFrame*>(aParent),
--- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -1718,35 +1718,47 @@ class nsIFrame : public nsQueryFrame { * */ bool HasAnimationOfTransform() const; /** * Returns true if the frame is translucent or the frame has opacity * animations for the purposes of creating a stacking context. * + * @param aStyleDisplay: This function needs style display struct. + * + * @param aStyleEffects: This function needs style effects struct. + * * @param aEffectSet: This function may need to look up EffectSet property. * If a caller already have one, pass it in can save property look up - * time; otherwise, just left it as nullptr. - */ - bool HasOpacity(mozilla::EffectSet* aEffectSet = nullptr) const { - return HasOpacityInternal(1.0f, aEffectSet); + * time; otherwise, just leave it as nullptr. + */ + bool HasOpacity(const nsStyleDisplay* aStyleDisplay, + const nsStyleEffects* aStyleEffects, + mozilla::EffectSet* aEffectSet = nullptr) const { + return HasOpacityInternal(1.0f, aStyleDisplay, aStyleEffects, aEffectSet); } /** * Returns true if the frame is translucent for display purposes. * + * @param aStyleDisplay: This function needs style display struct. + * + * @param aStyleEffects: This function needs style effects struct. + * * @param aEffectSet: This function may need to look up EffectSet property. * If a caller already have one, pass it in can save property look up - * time; otherwise, just left it as nullptr. - */ - bool HasVisualOpacity(mozilla::EffectSet* aEffectSet = nullptr) const { + * time; otherwise, just leave it as nullptr. + */ + bool HasVisualOpacity(const nsStyleDisplay* aStyleDisplay, + const nsStyleEffects* aStyleEffects, + mozilla::EffectSet* aEffectSet = nullptr) const { // Treat an opacity value of 0.99 and above as opaque. This is an // optimization aimed at Web content which use opacity:0.99 as a hint for // creating a stacking context only. - return HasOpacityInternal(0.99f, aEffectSet); + return HasOpacityInternal(0.99f, aStyleDisplay, aStyleEffects, aEffectSet); } /** * Return true if this frame might be using a transform getter. */ virtual bool HasTransformGetter() const { return false; } /** @@ -1764,24 +1776,28 @@ class nsIFrame : public nsQueryFrame { /** * Returns whether this frame will attempt to extend the 3d transforms of its * children. This requires transform-style: preserve-3d, as well as no * clipping or svg effects. * * @param aStyleDisplay: If the caller has this->StyleDisplay(), providing * it here will improve performance. * + * @param aStyleEffects: If the caller has this->StyleEffects(), providing + * it here will improve performance. + * * @param aEffectSet: This function may need to look up EffectSet property. * If a caller already have one, pass it in can save property look up - * time; otherwise, just left it as nullptr. + * time; otherwise, just leave it as nullptr. */ bool Extend3DContext(const nsStyleDisplay* aStyleDisplay, + const nsStyleEffects* aStyleEffects, mozilla::EffectSet* aEffectSet = nullptr) const; bool Extend3DContext(mozilla::EffectSet* aEffectSet = nullptr) const { - return Extend3DContext(StyleDisplay(), aEffectSet); + return Extend3DContext(StyleDisplay(), StyleEffects(), aEffectSet); } /** * Returns whether this frame has a parent that Extend3DContext() and has * its own transform (or hidden backface) to be combined with the parent's * transform. * * @param aStyleDisplay: If the caller has this->StyleDisplay(), providing @@ -1799,17 +1815,17 @@ class nsIFrame : public nsQueryFrame { * backface can safely be ignored if it could not be visible anyway. * */ bool In3DContextAndBackfaceIsHidden() const; bool IsPreserve3DLeaf(const nsStyleDisplay* aStyleDisplay, mozilla::EffectSet* aEffectSet = nullptr) const { return Combines3DTransformWithAncestors(aStyleDisplay) && - !Extend3DContext(aStyleDisplay, aEffectSet); + !Extend3DContext(aStyleDisplay, StyleEffects(), aEffectSet); } bool IsPreserve3DLeaf(mozilla::EffectSet* aEffectSet = nullptr) const { return IsPreserve3DLeaf(StyleDisplay(), aEffectSet); } bool HasPerspective(const nsStyleDisplay* aStyleDisplay) const; bool HasPerspective() const { return HasPerspective(StyleDisplay()); } @@ -3422,18 +3438,17 @@ class nsIFrame : public nsQueryFrame { bool IsVisibleOrCollapsedForPainting(); /** * Determines if this frame is a stacking context. * * @param aIsPositioned The precomputed result of IsAbsPosContainingBlock * on the StyleDisplay(). */ - bool IsStackingContext(mozilla::EffectSet* aEffectSet, - const nsStyleDisplay* aStyleDisplay, + bool IsStackingContext(const nsStyleDisplay* aStyleDisplay, const nsStylePosition* aStylePosition, const nsStyleEffects* aStyleEffects, bool aIsPositioned); bool IsStackingContext(); virtual bool HonorPrintBackgroundSettings() { return true; } /** @@ -4420,17 +4435,18 @@ class nsIFrame : public nsQueryFrame { // Helper-functions for SortFrameList(): template <bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)> static nsIFrame* SortedMerge(nsIFrame* aLeft, nsIFrame* aRight); template <bool IsLessThanOrEqual(nsIFrame*, nsIFrame*)> static nsIFrame* MergeSort(nsIFrame* aSource); - bool HasOpacityInternal(float aThreshold, + bool HasOpacityInternal(float aThreshold, const nsStyleDisplay* aStyleDisplay, + const nsStyleEffects* aStyleEffects, mozilla::EffectSet* aEffectSet = nullptr) const; // Maps mClass to LayoutFrameType. static const mozilla::LayoutFrameType sLayoutFrameTypes[ #define FRAME_ID(...) 1 + #define ABSTRACT_FRAME_ID(...) #include "nsFrameIdList.h" #undef FRAME_ID