From 654125d823ceb94ff76407180f17a4ecccdf1468 Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Wed, 18 May 2016 15:12:44 +1200 Subject: [PATCH] Bug 1141468 - Clean up prerendering code in nsDisplayTransform to be easier to follow. r=mstange --HG-- extra : rebase_source : ae9ded54e633e2ebffaeb8fef0b47a2d041dab1f --- layout/base/FrameLayerBuilder.cpp | 2 +- layout/base/FrameLayerBuilder.h | 4 +-- layout/base/nsDisplayList.cpp | 49 ++++++++++--------------------- layout/base/nsDisplayList.h | 12 +++----- layout/generic/nsFrame.cpp | 6 +++- 5 files changed, 26 insertions(+), 47 deletions(-) diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index f9e978989af6..c7afd6805cad 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -3903,7 +3903,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList) } nsIntRect itemDrawRect = ScaleToOutsidePixels(itemContent, snap); bool prerenderedTransform = itemType == nsDisplayItem::TYPE_TRANSFORM && - static_cast(item)->ShouldPrerender(); + static_cast(item)->MayBeAnimated(mBuilder); ParentLayerIntRect clipRect; const DisplayItemClip& itemClip = item->GetClip(); if (itemClip.HasClip()) { diff --git a/layout/base/FrameLayerBuilder.h b/layout/base/FrameLayerBuilder.h index 3b74676fb9b8..b6f8ee25042d 100644 --- a/layout/base/FrameLayerBuilder.h +++ b/layout/base/FrameLayerBuilder.h @@ -217,8 +217,6 @@ public: void DidEndTransaction(); enum { - CONTAINER_NOT_CLIPPED_BY_ANCESTORS = 0x01, - /** * Set this when pulling an opaque background color from behind the * container layer into the container doesn't change the visual results, @@ -226,7 +224,7 @@ public: * For example, this is compatible with opacity or clipping/masking, but * not with non-OVER blend modes or filters. */ - CONTAINER_ALLOW_PULL_BACKGROUND_COLOR = 0x02 + CONTAINER_ALLOW_PULL_BACKGROUND_COLOR = 0x01 }; /** * Build a container layer for a display item that contains a child diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 359360f778c2..84c2cdf97e5e 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -5269,6 +5269,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, , mNoExtendContext(false) , mIsTransformSeparator(false) , mTransformPreserves3DInited(false) + , mIsFullyVisible(false) { MOZ_COUNT_CTOR(nsDisplayTransform); MOZ_ASSERT(aFrame, "Must have a frame!"); @@ -5318,16 +5319,13 @@ nsDisplayTransform::Init(nsDisplayListBuilder* aBuilder) mHasBounds = false; mStoredList.SetClip(aBuilder, DisplayItemClip::NoClip()); mStoredList.SetVisibleRect(mChildrenVisibleRect); - // If this is true, then BuildDisplayListForStacking context should have already - // set the correct visible region and made sure we built all the necessary - // descendant display items. - mPrerender = ShouldPrerenderTransformedContent(aBuilder, mFrame); } nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame, nsDisplayList *aList, const nsRect& aChildrenVisibleRect, - uint32_t aIndex) + uint32_t aIndex, + bool aIsFullyVisible) : nsDisplayItem(aBuilder, aFrame) , mStoredList(aBuilder, aFrame, aList) , mTransformGetter(nullptr) @@ -5338,6 +5336,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, , mNoExtendContext(false) , mIsTransformSeparator(false) , mTransformPreserves3DInited(false) + , mIsFullyVisible(aIsFullyVisible) { MOZ_COUNT_CTOR(nsDisplayTransform); MOZ_ASSERT(aFrame, "Must have a frame!"); @@ -5360,6 +5359,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, , mNoExtendContext(false) , mIsTransformSeparator(false) , mTransformPreserves3DInited(false) + , mIsFullyVisible(false) { MOZ_COUNT_CTOR(nsDisplayTransform); MOZ_ASSERT(aFrame, "Must have a frame!"); @@ -5383,6 +5383,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, , mNoExtendContext(false) , mIsTransformSeparator(true) , mTransformPreserves3DInited(false) + , mIsFullyVisible(false) { MOZ_COUNT_CTOR(nsDisplayTransform); MOZ_ASSERT(aFrame, "Must have a frame!"); @@ -5783,15 +5784,10 @@ nsDisplayOpacity::CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) return false; } -bool -nsDisplayTransform::ShouldPrerender() { - return mPrerender; -} - bool nsDisplayTransform::CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) { - return mPrerender; + return mIsFullyVisible; } /* static */ bool @@ -5935,7 +5931,7 @@ nsDisplayTransform::ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuild // The visible rect of a Preserves-3D frame is just an intermediate // result. It should always build a layer to make sure it is // rendering correctly. - return ShouldPrerender() || mFrame->Combines3DTransformWithAncestors(); + return MayBeAnimated(aBuilder) || mFrame->Combines3DTransformWithAncestors(); } already_AddRefed nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBuilder, @@ -5948,9 +5944,7 @@ already_AddRefed nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu */ const Matrix4x4& newTransformMatrix = GetTransformForRendering(); - uint32_t flags = ShouldPrerender() ? - FrameLayerBuilder::CONTAINER_NOT_CLIPPED_BY_ANCESTORS : 0; - flags |= FrameLayerBuilder::CONTAINER_ALLOW_PULL_BACKGROUND_COLOR; + uint32_t flags = FrameLayerBuilder::CONTAINER_ALLOW_PULL_BACKGROUND_COLOR; RefPtr container = aManager->GetLayerBuilder()-> BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mStoredList.GetChildren(), aContainerParameters, &newTransformMatrix, flags); @@ -5970,7 +5964,7 @@ already_AddRefed nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(container, aBuilder, this, mFrame, eCSSProperty_transform); - if (ShouldPrerender()) { + if (mIsFullyVisible) { if (MayBeAnimated(aBuilder)) { // Only allow async updates to the transform if we're an animated layer, since that's what // triggers us to set the correct AGR in the constructor and makes sure FrameLayerBuilder @@ -6038,8 +6032,7 @@ bool nsDisplayTransform::ComputeVisibility(nsDisplayListBuilder *aBuilder, * think that it's painting in its original rectangular coordinate space. * If we can't untransform, take the entire overflow rect */ nsRect untransformedVisibleRect; - if (ShouldPrerender() || - !UntransformVisibleRect(aBuilder, &untransformedVisibleRect)) + if (!UntransformVisibleRect(aBuilder, &untransformedVisibleRect)) { untransformedVisibleRect = mFrame->GetVisualOverflowRectRelativeToSelf(); } @@ -6184,9 +6177,7 @@ nsDisplayTransform::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) return nsRect(); } - nsRect untransformedBounds = ShouldPrerender() ? - mFrame->GetVisualOverflowRectRelativeToSelf() : - mStoredList.GetBounds(aBuilder, aSnap); + nsRect untransformedBounds = mStoredList.GetBounds(aBuilder, aSnap); // GetTransform always operates in dev pixels. float factor = mFrame->PresContext()->AppUnitsPerDevPixel(); mBounds = nsLayoutUtils::MatrixTransformRect(untransformedBounds, @@ -6223,9 +6214,7 @@ nsDisplayTransform::ComputeBounds(nsDisplayListBuilder* aBuilder) * nsDisplayListBuilder. */ bool snap; - nsRect untransformedBounds = ShouldPrerender() ? - mFrame->GetVisualOverflowRectRelativeToSelf() : - mStoredList.GetBounds(aBuilder, &snap); + nsRect untransformedBounds = mStoredList.GetBounds(aBuilder, &snap); // GetTransform always operates in dev pixels. float factor = mFrame->PresContext()->AppUnitsPerDevPixel(); nsRect rect = @@ -6257,14 +6246,7 @@ nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder, { *aSnap = false; nsRect untransformedVisible; - // If we're going to prerender all our content, pretend like we - // don't have opqaue content so that everything under us is rendered - // as well. That will increase graphics memory usage if our frame - // covers the entire window, but it allows our transform to be - // updated extremely cheaply, without invalidating any other - // content. - if (ShouldPrerender() || - !UntransformVisibleRect(aBuilder, &untransformedVisible)) { + if (!UntransformVisibleRect(aBuilder, &untransformedVisible)) { return nsRegion(); } @@ -6592,8 +6574,7 @@ nsDisplayVR::BuildLayer(nsDisplayListBuilder* aBuilder, const ContainerLayerParameters& aContainerParameters) { ContainerLayerParameters newContainerParameters = aContainerParameters; - uint32_t flags = FrameLayerBuilder::CONTAINER_NOT_CLIPPED_BY_ANCESTORS | - FrameLayerBuilder::CONTAINER_ALLOW_PULL_BACKGROUND_COLOR; + uint32_t flags = FrameLayerBuilder::CONTAINER_ALLOW_PULL_BACKGROUND_COLOR; RefPtr container = aManager->GetLayerBuilder()-> BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList, newContainerParameters, nullptr, flags); diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 1cd627d3cdec..a28be9de4b6b 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -3898,7 +3898,7 @@ public: */ nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame, nsDisplayList *aList, const nsRect& aChildrenVisibleRect, - uint32_t aIndex = 0); + uint32_t aIndex = 0, bool aIsFullyVisible = false); nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame, nsDisplayItem *aItem, const nsRect& aChildrenVisibleRect, uint32_t aIndex = 0); @@ -4116,12 +4116,6 @@ public: bool MayBeAnimated(nsDisplayListBuilder* aBuilder); - /** - * Check if this element will be prerendered. This must be done after the - * display list has been fully built. - */ - bool ShouldPrerender(); - virtual void WriteDebugInfo(std::stringstream& aStream) override; // Force the layer created for this item not to extend 3D context. @@ -4206,7 +4200,6 @@ private: nsRect mBounds; // True for mBounds is valid. bool mHasBounds; - bool mPrerender; // Be forced not to extend 3D context. Since we don't create a // transform item, a container layer, for every frames in a // preserves3d context, the transform items of a child preserves3d @@ -4219,6 +4212,9 @@ private: bool mIsTransformSeparator; // True if mTransformPreserves3D have been initialized. bool mTransformPreserves3DInited; + // True if the entire untransformed area has been treated as + // visible during display list construction. + bool mIsFullyVisible; }; /* A display item that applies a perspective transformation to a single diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 9ac49bf5ceee..ad0bf434cd76 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -2513,8 +2513,12 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, if (!aBuilder->IsForGenerateGlyphMask() && !aBuilder->IsForPaintingSelectionBG()) { + bool isFullyVisible = + dirtyRectOutsideSVGEffects.Contains(GetVisualOverflowRectRelativeToSelf()); nsDisplayTransform *transformItem = - new (aBuilder) nsDisplayTransform(aBuilder, this, &resultList, dirtyRect); + new (aBuilder) nsDisplayTransform(aBuilder, this, + &resultList, dirtyRect, 0, + isFullyVisible); resultList.AppendNewToTop(transformItem); }