summaryrefslogtreecommitdiffstats
path: root/layout/painting
diff options
context:
space:
mode:
Diffstat (limited to 'layout/painting')
-rw-r--r--layout/painting/ActiveLayerTracker.cpp50
-rw-r--r--layout/painting/RetainedDisplayListBuilder.cpp11
-rw-r--r--layout/painting/nsDisplayItemTypesList.h4
-rw-r--r--layout/painting/nsDisplayList.cpp31
-rw-r--r--layout/painting/nsDisplayList.h16
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