diff options
Diffstat (limited to 'layout/painting')
-rw-r--r-- | layout/painting/ActiveLayerTracker.cpp | 50 | ||||
-rw-r--r-- | layout/painting/RetainedDisplayListBuilder.cpp | 11 | ||||
-rw-r--r-- | layout/painting/nsDisplayItemTypesList.h | 4 | ||||
-rw-r--r-- | layout/painting/nsDisplayList.cpp | 31 | ||||
-rw-r--r-- | layout/painting/nsDisplayList.h | 16 |
5 files changed, 83 insertions, 29 deletions
diff --git a/layout/painting/ActiveLayerTracker.cpp b/layout/painting/ActiveLayerTracker.cpp index 053445e486..b30ecdf5c2 100644 --- a/layout/painting/ActiveLayerTracker.cpp +++ b/layout/painting/ActiveLayerTracker.cpp @@ -218,23 +218,47 @@ void ActiveLayerTracker::TransferActivityToFrame(nsIContent* aContent, static void IncrementScaleRestyleCountIfNeeded(nsIFrame* aFrame, LayerActivity* aActivity) { + // This function is basically a simplified copy of + // nsDisplayTransform::GetResultingTransformMatrixInternal. + + Matrix svgTransform, parentsChildrenOnlyTransform; + const bool hasSVGTransforms = + aFrame->HasAnyStateBits(NS_FRAME_MAY_BE_TRANSFORMED) && + aFrame->IsSVGTransformed(&svgTransform, &parentsChildrenOnlyTransform); + const nsStyleDisplay* display = aFrame->StyleDisplay(); - if (!display->HasTransformProperty() && !display->HasIndividualTransform() && - display->mOffsetPath.IsNone()) { - // The transform was removed. - aActivity->mPreviousTransformScale = Nothing(); - IncrementMutationCount( - &aActivity->mRestyleCounts[LayerActivity::ACTIVITY_SCALE]); + if (!aFrame->HasAnyStateBits(NS_FRAME_MAY_BE_TRANSFORMED) || + (!display->HasTransformProperty() && !display->HasIndividualTransform() && + display->mOffsetPath.IsNone() && !hasSVGTransforms)) { + if (aActivity->mPreviousTransformScale.isSome()) { + // The transform was removed. + aActivity->mPreviousTransformScale = Nothing(); + IncrementMutationCount( + &aActivity->mRestyleCounts[LayerActivity::ACTIVITY_SCALE]); + } + return; } - // Compute the new scale due to the CSS transform property. - // Note: Motion path doesn't contribute to scale factor. (It only has 2d - // translate and 2d rotate, so we use Nothing() for it.) - nsStyleTransformMatrix::TransformReferenceBox refBox(aFrame); - Matrix4x4 transform = nsStyleTransformMatrix::ReadTransforms( - display->mTranslate, display->mRotate, display->mScale, nullptr, - display->mTransform, refBox, AppUnitsPerCSSPixel()); + Matrix4x4 transform; + if (aFrame->IsCSSTransformed()) { + // Compute the new scale due to the CSS transform property. + // Note: Motion path doesn't contribute to scale factor. (It only has 2d + // translate and 2d rotate, so we use Nothing() for it.) + nsStyleTransformMatrix::TransformReferenceBox refBox(aFrame); + transform = nsStyleTransformMatrix::ReadTransforms( + display->mTranslate, display->mRotate, display->mScale, nullptr, + display->mTransform, refBox, AppUnitsPerCSSPixel()); + } else if (hasSVGTransforms) { + transform = Matrix4x4::From2D(svgTransform); + } + + const bool parentHasChildrenOnlyTransform = + hasSVGTransforms && !parentsChildrenOnlyTransform.IsIdentity(); + if (parentHasChildrenOnlyTransform) { + transform *= Matrix4x4::From2D(parentsChildrenOnlyTransform); + } + Matrix transform2D; if (!transform.Is2D(&transform2D)) { // We don't attempt to handle 3D transforms; just assume the scale changed. diff --git a/layout/painting/RetainedDisplayListBuilder.cpp b/layout/painting/RetainedDisplayListBuilder.cpp index bb3a896b9a..ca8f37a252 100644 --- a/layout/painting/RetainedDisplayListBuilder.cpp +++ b/layout/painting/RetainedDisplayListBuilder.cpp @@ -523,6 +523,17 @@ class MergeState { // current ASR, which gets reset during RestoreState(), so we always need // to run it again. aOutItem->UpdateBounds(mBuilder->Builder()); + + if (aOutItem->GetType() == DisplayItemType::TYPE_TRANSFORM) { + MOZ_ASSERT(!aNewItem || + aNewItem->GetType() == DisplayItemType::TYPE_TRANSFORM); + MOZ_ASSERT(aOldItem->GetType() == DisplayItemType::TYPE_TRANSFORM); + static_cast<nsDisplayTransform*>(aOutItem)->SetContainsASRs( + static_cast<nsDisplayTransform*>(aOldItem)->GetContainsASRs() || + (aNewItem + ? static_cast<nsDisplayTransform*>(aNewItem)->GetContainsASRs() + : false)); + } } bool ShouldUseNewItem(nsDisplayItem* aNewItem) { diff --git a/layout/painting/nsDisplayItemTypesList.h b/layout/painting/nsDisplayItemTypesList.h index b3d4f14c4d..ecc107a20b 100644 --- a/layout/painting/nsDisplayItemTypesList.h +++ b/layout/painting/nsDisplayItemTypesList.h @@ -18,9 +18,6 @@ DECLARE_DISPLAY_ITEM_TYPE(BLEND_MODE, DECLARE_DISPLAY_ITEM_TYPE(BORDER, 0) DECLARE_DISPLAY_ITEM_TYPE(BOX_SHADOW_INNER, TYPE_RENDERS_NO_IMAGES) DECLARE_DISPLAY_ITEM_TYPE(BOX_SHADOW_OUTER, TYPE_RENDERS_NO_IMAGES) -DECLARE_DISPLAY_ITEM_TYPE(BUTTON_BORDER_BACKGROUND, TYPE_IS_CONTENTFUL) -DECLARE_DISPLAY_ITEM_TYPE(BUTTON_BOX_SHADOW_OUTER, - TYPE_RENDERS_NO_IMAGES | TYPE_IS_CONTENTFUL) DECLARE_DISPLAY_ITEM_TYPE(BUTTON_FOREGROUND, TYPE_IS_CONTENTFUL) DECLARE_DISPLAY_ITEM_TYPE(CANVAS, TYPE_RENDERS_NO_IMAGES) DECLARE_DISPLAY_ITEM_TYPE(CANVAS_BACKGROUND_COLOR, TYPE_RENDERS_NO_IMAGES) @@ -34,7 +31,6 @@ DECLARE_DISPLAY_ITEM_TYPE(CHECKED_CHECKBOX, DECLARE_DISPLAY_ITEM_TYPE(CHECKED_RADIOBUTTON, TYPE_RENDERS_NO_IMAGES | TYPE_IS_CONTENTFUL) DECLARE_DISPLAY_ITEM_TYPE(COLUMN_RULE, TYPE_RENDERS_NO_IMAGES) -DECLARE_DISPLAY_ITEM_TYPE(COMBOBOX_FOCUS, TYPE_RENDERS_NO_IMAGES) DECLARE_DISPLAY_ITEM_TYPE(COMPOSITOR_HITTEST_INFO, TYPE_RENDERS_NO_IMAGES) DECLARE_DISPLAY_ITEM_TYPE(CONTAINER, TYPE_RENDERS_NO_IMAGES | TYPE_IS_CONTAINER) DECLARE_DISPLAY_ITEM_TYPE(DESTINATION, TYPE_RENDERS_NO_IMAGES) diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index 46f8b05f82..78388d2185 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -868,6 +868,11 @@ void nsDisplayListBuilder::SetIsRelativeToLayoutViewport() { UpdateShouldBuildAsyncZoomContainer(); } +void nsDisplayListBuilder::ForceLayerForScrollParent() { + mForceLayerForScrollParent = true; + mNumActiveScrollframesEncountered++; +} + void nsDisplayListBuilder::UpdateShouldBuildAsyncZoomContainer() { const Document* document = mReferenceFrame->PresContext()->Document(); mBuildAsyncZoomContainer = !mIsRelativeToLayoutViewport && @@ -5974,7 +5979,8 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, mPrerenderDecision(PrerenderDecision::No), mIsTransformSeparator(true), mHasTransformGetter(false), - mHasAssociatedPerspective(false) { + mHasAssociatedPerspective(false), + mContainsASRs(false) { MOZ_COUNT_CTOR(nsDisplayTransform); MOZ_ASSERT(aFrame, "Must have a frame!"); Init(aBuilder, aList); @@ -5990,7 +5996,8 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, mPrerenderDecision(aPrerenderDecision), mIsTransformSeparator(false), mHasTransformGetter(false), - mHasAssociatedPerspective(false) { + mHasAssociatedPerspective(false), + mContainsASRs(false) { MOZ_COUNT_CTOR(nsDisplayTransform); MOZ_ASSERT(aFrame, "Must have a frame!"); SetReferenceFrameToAncestor(aBuilder); @@ -6007,7 +6014,8 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, mPrerenderDecision(PrerenderDecision::No), mIsTransformSeparator(false), mHasTransformGetter(true), - mHasAssociatedPerspective(false) { + mHasAssociatedPerspective(false), + mContainsASRs(false) { MOZ_COUNT_CTOR(nsDisplayTransform); MOZ_ASSERT(aFrame, "Must have a frame!"); MOZ_ASSERT(aFrame->GetTransformGetter()); @@ -6194,6 +6202,9 @@ Matrix4x4 nsDisplayTransform::GetResultingTransformMatrixInternal( NS_ASSERTION(frame || !(aFlags & INCLUDE_PERSPECTIVE), "Must have a frame to compute perspective!"); + // IncrementScaleRestyleCountIfNeeded in ActiveLayerTracker.cpp is a + // simplified copy of this function. + // Get the underlying transform matrix: /* Get the matrix, then change its basis to factor in the origin. */ @@ -6637,12 +6648,12 @@ bool nsDisplayTransform::CreateWebRenderCommands( key}; nsDisplayTransform* deferredTransformItem = nullptr; - if (!mFrame->ChildrenHavePerspective()) { + if (ShouldDeferTransform()) { // If it has perspective, we create a new scroll data via the - // UpdateScrollData call because that scenario is more complex. Otherwise - // we can just stash the transform on the StackingContextHelper and - // apply it to any scroll data that are created inside this - // nsDisplayTransform. + // UpdateScrollData call because that scenario is more complex. Otherwise, + // if we don't contain any ASRs then just stash the transform on the + // StackingContextHelper and apply it to any scroll data that are created + // inside this nsDisplayTransform. deferredTransformItem = this; } @@ -6693,14 +6704,14 @@ bool nsDisplayTransform::CreateWebRenderCommands( bool nsDisplayTransform::UpdateScrollData( WebRenderScrollData* aData, WebRenderLayerScrollData* aLayerData) { - if (!mFrame->ChildrenHavePerspective()) { + if (ShouldDeferTransform()) { // This case is handled in CreateWebRenderCommands by stashing the transform // on the stacking context. return false; } if (aLayerData) { aLayerData->SetTransform(GetTransform().GetMatrix()); - aLayerData->SetTransformIsPerspective(true); + aLayerData->SetTransformIsPerspective(mFrame->ChildrenHavePerspective()); } return true; } diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h index cf4eb1dd16..5064677cc7 100644 --- a/layout/painting/nsDisplayList.h +++ b/layout/painting/nsDisplayList.h @@ -457,7 +457,10 @@ class nsDisplayListBuilder { * a displayport, and for scroll handoff to work properly the ancestor * scrollframes should also get their own scrollable layers. */ - void ForceLayerForScrollParent() { mForceLayerForScrollParent = true; } + void ForceLayerForScrollParent(); + uint32_t GetNumActiveScrollframesEncountered() const { + return mNumActiveScrollframesEncountered; + } /** * Set the flag that indicates there is a non-minimal display port in the * current subtree. This is used to determine display port expiry. @@ -1848,6 +1851,8 @@ class nsDisplayListBuilder { nsDisplayListBuilderMode mMode; static uint32_t sPaintSequenceNumber; + uint32_t mNumActiveScrollframesEncountered = 0; + bool mContainsBlendMode; bool mIsBuildingScrollbar; bool mCurrentScrollbarWillHaveLayer; @@ -3570,7 +3575,7 @@ class RetainedDisplayList : public nsDisplayList { for (OldItemInfo& i : mOldItems) { if (i.mItem && i.mOwnsItem) { i.mItem->Destroy(aBuilder); - MOZ_ASSERT(!GetBottom(), + MOZ_ASSERT(!GetBottom() || aBuilder->PartialBuildFailed(), "mOldItems should not be owning items if we also have items " "in the normal list"); } @@ -6414,6 +6419,12 @@ class nsDisplayTransform : public nsPaintedDisplayItem { bool CreatesStackingContextHelper() override { return true; } + void SetContainsASRs(bool aContainsASRs) { mContainsASRs = aContainsASRs; } + bool GetContainsASRs() const { return mContainsASRs; } + bool ShouldDeferTransform() const { + return !mFrame->ChildrenHavePerspective() && !mContainsASRs; + } + private: void ComputeBounds(nsDisplayListBuilder* aBuilder); nsRect TransformUntransformedBounds(nsDisplayListBuilder* aBuilder, @@ -6459,6 +6470,7 @@ class nsDisplayTransform : public nsPaintedDisplayItem { // True if this item is created together with `nsDisplayPerspective` // from the same CSS stacking context. bool mHasAssociatedPerspective : 1; + bool mContainsASRs : 1; }; /* A display item that applies a perspective transformation to a single |