Backed out changeset 68b33692bed3 (bug 1147673)

This commit is contained in:
Carsten "Tomcat" Book 2015-12-16 11:52:37 +01:00
parent e146f8ac80
commit 48885cfee8
19 changed files with 296 additions and 727 deletions

View File

@ -1,42 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DisplayItemScrollClip.h"
namespace mozilla {
/* static */ bool
DisplayItemScrollClip::IsAncestor(const DisplayItemScrollClip* aAncestor,
const DisplayItemScrollClip* aDescendant)
{
if (!aAncestor) {
// null means root.
return true;
}
for (const DisplayItemScrollClip* sc = aDescendant; sc; sc = sc->mCrossStackingContextParent) {
if (sc == aAncestor) {
return true;
}
}
return false;
}
/* static */ nsCString
DisplayItemScrollClip::ToString(const DisplayItemScrollClip* aScrollClip)
{
nsAutoCString str;
for (const DisplayItemScrollClip* scrollClip = aScrollClip;
scrollClip; scrollClip = scrollClip->mParent) {
str.AppendPrintf("<%s>", scrollClip->mClip ? scrollClip->mClip->ToString().get() : "null");
if (scrollClip->mParent) {
str.Append(" ");
}
}
return str;
}
} // namespace mozilla

View File

@ -1,123 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef DISPLAYITEMSCROLLCLIP_H_
#define DISPLAYITEMSCROLLCLIP_H_
#include "mozilla/Assertions.h"
#include "nsString.h"
class nsIScrollableFrame;
namespace mozilla {
class DisplayItemClip;
/**
* A DisplayItemScrollClip represents a DisplayItemClip from a scrollable
* frame. This clip is stored on a display item separately from the item's
* regular DisplayItemClip for async scrolling purposes: The item's regular
* clip can be fused to the item's contents when drawing layer contents, but
* scroll clips need to be kept separate so that they can be applied at
* composition time, after any async scroll offsets have been applied.
* Scroll clips are created during display list construction when
* async-scrollable scroll frames are entered. At that point, the current
* regular clip is cleared on the display list clip state. They are also
* created for scroll frames that are inactivate and not async scrollable;
* in that case, mIsAsyncScrollable on the scroll clip will be false.
* When async-scrollable scroll frames are nested, the inner display items
* can walk the whole chain of scroll clips via the DisplayItemScrollClip's
* mParent pointer, or its mCrossStackingContextParent pointer if they need
* access to the complete chain.
* Storing scroll clips on display items allows easy access of all scroll
* frames that affect a certain display item, and it allows some display list
* operations to compute more accurate clips, for example when computing the
* bounds of a container item for a frame that contains an async-scrollable
* scroll frame.
*/
class DisplayItemScrollClip {
public:
DisplayItemScrollClip(const DisplayItemScrollClip* aParent,
const DisplayItemScrollClip* aCrossStackingContextParent,
nsIScrollableFrame* aScrollableFrame,
const DisplayItemClip* aClip,
bool aIsAsyncScrollable)
: mParent(aParent)
, mScrollableFrame(aScrollableFrame)
, mClip(aClip)
, mIsAsyncScrollable(aIsAsyncScrollable)
, mCrossStackingContextParent(aCrossStackingContextParent)
, mCrossStackingContextDepth(aCrossStackingContextParent ?
aCrossStackingContextParent->mCrossStackingContextDepth + 1 : 1)
{
MOZ_ASSERT(mScrollableFrame);
}
/**
* "Pick innermost" is analogous to the intersection operation on regular
* clips: In some cases, there are multiple candidate clips that can apply to
* an item, one of them being the ancestor of the other. This method picks
* the descendant.
* Both aClip1 and aClip2 are allowed to be null.
*/
static const DisplayItemScrollClip*
PickInnermost(const DisplayItemScrollClip* aClip1,
const DisplayItemScrollClip* aClip2)
{
MOZ_ASSERT(IsAncestor(aClip1, aClip2) || IsAncestor(aClip2, aClip1),
"one of the scroll clips must be an ancestor of the other");
return Depth(aClip1) > Depth(aClip2) ? aClip1 : aClip2;
}
/**
* Returns whether aAncestor is an ancestor scroll clip of aDescendant.
* A scroll clip that's null is considered the root scroll clip.
*/
static bool IsAncestor(const DisplayItemScrollClip* aAncestor,
const DisplayItemScrollClip* aDescendant);
/**
* Return a string which contains the list of stringified clips for this
* scroll clip and its ancestors. aScrollClip can be null.
*/
static nsCString ToString(const DisplayItemScrollClip* aScrollClip);
/**
* The previous (outer) scroll clip, or null.
*/
const DisplayItemScrollClip* mParent;
/**
* The scrollable frame that this scroll clip is for. Always non-null.
*/
nsIScrollableFrame* mScrollableFrame;
/**
* The clip represented by this scroll clip, relative to mScrollableFrame's
* reference frame. Can be null.
*/
const DisplayItemClip* mClip;
/**
* Whether this scroll clip is for an async-scrollable scroll frame.
* Can change during display list construction.
*/
bool mIsAsyncScrollable;
private:
static uint32_t Depth(const DisplayItemScrollClip* aSC)
{ return aSC ? aSC->mCrossStackingContextDepth : 0; }
/**
* The previous (outer) scroll clip, across stacking contexts, or null.
*/
const DisplayItemScrollClip* mCrossStackingContextParent;
const uint32_t mCrossStackingContextDepth;
};
} // namespace mozilla
#endif /* DISPLAYITEMSCROLLCLIP_H_ */

View File

@ -5,7 +5,6 @@
#include "DisplayListClipState.h"
#include "DisplayItemScrollClip.h"
#include "nsDisplayList.h"
namespace mozilla {
@ -108,99 +107,6 @@ DisplayListClipState::ClipContainingBlockDescendantsToContentBox(nsDisplayListBu
aClipOnStack);
}
const DisplayItemScrollClip*
DisplayListClipState::GetCurrentInnermostScrollClip()
{
return DisplayItemScrollClip::PickInnermost(
mScrollClipContentDescendants, mScrollClipContainingBlockDescendants);
}
void
DisplayListClipState::TurnClipIntoScrollClipForContentDescendants(
nsDisplayListBuilder* aBuilder, nsIScrollableFrame* aScrollableFrame)
{
const DisplayItemScrollClip* parent = GetCurrentInnermostScrollClip();
const DisplayItemScrollClip* crossStackingContextParent = parent;
if (!crossStackingContextParent) {
crossStackingContextParent = mCrossStackingContextParentScrollClip;
}
mScrollClipContentDescendants =
aBuilder->AllocateDisplayItemScrollClip(parent, crossStackingContextParent,
aScrollableFrame,
GetCurrentCombinedClip(aBuilder), true);
Clear();
}
void
DisplayListClipState::TurnClipIntoScrollClipForContainingBlockDescendants(
nsDisplayListBuilder* aBuilder, nsIScrollableFrame* aScrollableFrame)
{
const DisplayItemScrollClip* parent = GetCurrentInnermostScrollClip();
const DisplayItemScrollClip* crossStackingContextParent = parent;
if (!crossStackingContextParent) {
crossStackingContextParent = mCrossStackingContextParentScrollClip;
}
mScrollClipContainingBlockDescendants =
aBuilder->AllocateDisplayItemScrollClip(parent, crossStackingContextParent,
aScrollableFrame,
GetCurrentCombinedClip(aBuilder), true);
Clear();
}
const DisplayItemClip*
WithoutRoundedCorners(nsDisplayListBuilder* aBuilder, const DisplayItemClip* aClip)
{
if (!aClip) {
return nullptr;
}
DisplayItemClip rectClip(*aClip);
rectClip.RemoveRoundedCorners();
return aBuilder->AllocateDisplayItemClip(rectClip);
}
DisplayItemScrollClip*
DisplayListClipState::CreateInactiveScrollClip(
nsDisplayListBuilder* aBuilder, nsIScrollableFrame* aScrollableFrame)
{
// We ignore the rounded corners on the current clip because we don't want
// them to be double-applied (as scroll clip and as regular clip).
// Double-applying rectangle clips doesn't make a visual difference so it's
// fine.
const DisplayItemClip* rectClip =
WithoutRoundedCorners(aBuilder, GetCurrentCombinedClip(aBuilder));
const DisplayItemScrollClip* parent = GetCurrentInnermostScrollClip();
const DisplayItemScrollClip* crossStackingContextParent = parent;
if (!crossStackingContextParent) {
crossStackingContextParent = mCrossStackingContextParentScrollClip;
}
DisplayItemScrollClip* scrollClip =
aBuilder->AllocateDisplayItemScrollClip(parent, crossStackingContextParent,
aScrollableFrame,
rectClip, false);
return scrollClip;
}
DisplayItemScrollClip*
DisplayListClipState::InsertInactiveScrollClipForContentDescendants(
nsDisplayListBuilder* aBuilder, nsIScrollableFrame* aScrollableFrame)
{
DisplayItemScrollClip* scrollClip =
CreateInactiveScrollClip(aBuilder, aScrollableFrame);
mScrollClipContentDescendants = scrollClip;
return scrollClip;
}
DisplayItemScrollClip*
DisplayListClipState::InsertInactiveScrollClipForContainingBlockDescendants(
nsDisplayListBuilder* aBuilder, nsIScrollableFrame* aScrollableFrame)
{
DisplayItemScrollClip* scrollClip =
CreateInactiveScrollClip(aBuilder, aScrollableFrame);
mScrollClipContainingBlockDescendants = scrollClip;
return scrollClip;
}
DisplayListClipState::AutoSaveRestore::AutoSaveRestore(nsDisplayListBuilder* aBuilder)
: mState(aBuilder->ClipState())
, mSavedState(aBuilder->ClipState())

View File

@ -11,13 +11,10 @@
#include "mozilla/DebugOnly.h"
class nsIFrame;
class nsIScrollableFrame;
class nsDisplayListBuilder;
namespace mozilla {
class DisplayItemScrollClip;
/**
* All clip coordinates are in appunits relative to the reference frame
* for the display item we're building.
@ -28,9 +25,6 @@ public:
: mClipContentDescendants(nullptr)
, mClipContainingBlockDescendants(nullptr)
, mCurrentCombinedClip(nullptr)
, mScrollClipContentDescendants(nullptr)
, mScrollClipContainingBlockDescendants(nullptr)
, mCrossStackingContextParentScrollClip(nullptr)
{}
/**
@ -48,8 +42,6 @@ public:
return mClipContentDescendants;
}
const DisplayItemScrollClip* GetCurrentInnermostScrollClip();
class AutoSaveRestore;
friend class AutoSaveRestore;
@ -70,62 +62,13 @@ private:
mCurrentCombinedClip = nullptr;
}
void SetScrollClipForContainingBlockDescendants(const DisplayItemScrollClip* aScrollClip)
{
mScrollClipContainingBlockDescendants = aScrollClip;
}
void Clear()
{
mClipContentDescendants = nullptr;
mClipContainingBlockDescendants = nullptr;
mCurrentCombinedClip = nullptr;
// We do not clear scroll clips.
}
void ClearForStackingContextContents()
{
mClipContentDescendants = nullptr;
mClipContainingBlockDescendants = nullptr;
mCurrentCombinedClip = nullptr;
mCrossStackingContextParentScrollClip = GetCurrentInnermostScrollClip();
mScrollClipContentDescendants = nullptr;
mScrollClipContainingBlockDescendants = nullptr;
}
void ClearIncludingScrollClip()
{
mClipContentDescendants = nullptr;
mClipContainingBlockDescendants = nullptr;
mCurrentCombinedClip = nullptr;
mCrossStackingContextParentScrollClip = nullptr;
mScrollClipContentDescendants = nullptr;
mScrollClipContainingBlockDescendants = nullptr;
}
/**
* Clear the current clip, and instead add it as a scroll clip to the current
* scroll clip chain.
*/
void TurnClipIntoScrollClipForContentDescendants(nsDisplayListBuilder* aBuilder,
nsIScrollableFrame* aScrollableFrame);
void TurnClipIntoScrollClipForContainingBlockDescendants(nsDisplayListBuilder* aBuilder,
nsIScrollableFrame* aScrollableFrame);
/**
* Insert a scroll clip without clearing the current clip.
* The returned DisplayItemScrollClip will have mIsAsyncScrollable == false,
* and it can be activated once the scroll frame knows that it needs to be
* async scrollable.
*/
DisplayItemScrollClip* InsertInactiveScrollClipForContentDescendants(nsDisplayListBuilder* aBuilder,
nsIScrollableFrame* aScrollableFrame);
DisplayItemScrollClip* InsertInactiveScrollClipForContainingBlockDescendants(nsDisplayListBuilder* aBuilder,
nsIScrollableFrame* aScrollableFrame);
DisplayItemScrollClip* CreateInactiveScrollClip(nsDisplayListBuilder* aBuilder,
nsIScrollableFrame* aScrollableFrame);
/**
* Intersects the given clip rect (with optional aRadii) with the current
* mClipContainingBlockDescendants and sets mClipContainingBlockDescendants to
@ -177,13 +120,6 @@ private:
* are null.
*/
const DisplayItemClip* mCurrentCombinedClip;
/**
* The same for scroll clips.
*/
const DisplayItemScrollClip* mScrollClipContentDescendants;
const DisplayItemScrollClip* mScrollClipContainingBlockDescendants;
const DisplayItemScrollClip* mCrossStackingContextParentScrollClip;
};
/**
@ -213,51 +149,6 @@ public:
mClipUsed = false;
}
void ClearForStackingContextContents()
{
NS_ASSERTION(!mRestored, "Already restored!");
mState.ClearForStackingContextContents();
mClipUsed = false;
}
void ClearIncludingScrollClip()
{
NS_ASSERTION(!mRestored, "Already restored!");
mState.ClearIncludingScrollClip();
mClipUsed = false;
}
void TurnClipIntoScrollClipForContentDescendants(nsDisplayListBuilder* aBuilder, nsIScrollableFrame* aScrollableFrame)
{
NS_ASSERTION(!mRestored, "Already restored!");
mState.TurnClipIntoScrollClipForContentDescendants(aBuilder, aScrollableFrame);
mClipUsed = true;
}
void TurnClipIntoScrollClipForContainingBlockDescendants(nsDisplayListBuilder* aBuilder, nsIScrollableFrame* aScrollableFrame)
{
NS_ASSERTION(!mRestored, "Already restored!");
mState.TurnClipIntoScrollClipForContainingBlockDescendants(aBuilder, aScrollableFrame);
mClipUsed = true;
}
DisplayItemScrollClip* InsertInactiveScrollClipForContentDescendants(nsDisplayListBuilder* aBuilder, nsIScrollableFrame* aScrollableFrame)
{
NS_ASSERTION(!mRestored, "Already restored!");
DisplayItemScrollClip* scrollClip = mState.InsertInactiveScrollClipForContentDescendants(aBuilder, aScrollableFrame);
mClipUsed = true;
return scrollClip;
}
DisplayItemScrollClip* InsertInactiveScrollClipForContainingBlockDescendants(nsDisplayListBuilder* aBuilder, nsIScrollableFrame* aScrollableFrame)
{
NS_ASSERTION(!mRestored, "Already restored!");
DisplayItemScrollClip* scrollClip = mState.InsertInactiveScrollClipForContainingBlockDescendants(aBuilder, aScrollableFrame);
mClipUsed = true;
return scrollClip;
}
/**
* Intersects the given clip rect (with optional aRadii) with the current
* mClipContainingBlockDescendants and sets mClipContainingBlockDescendants to
@ -349,11 +240,6 @@ public:
mState.SetClipForContainingBlockDescendants(aClip);
}
void SetScrollClipForContainingBlockDescendants(const DisplayItemScrollClip* aScrollClip)
{
mState.SetScrollClipForContainingBlockDescendants(aScrollClip);
}
/**
* Intersects the given clip rect (with optional aRadii) with the current
* mClipContainingBlockDescendants and sets mClipContainingBlockDescendants to

View File

@ -13,7 +13,6 @@
#include "mozilla/gfx/Matrix.h"
#include "ActiveLayerTracker.h"
#include "BasicLayers.h"
#include "DisplayItemScrollClip.h"
#include "ImageContainer.h"
#include "ImageLayers.h"
#include "LayerTreeInvalidation.h"
@ -409,7 +408,6 @@ class PaintedLayerData {
public:
PaintedLayerData() :
mAnimatedGeometryRoot(nullptr),
mScrollClip(nullptr),
mFixedPosFrameForLayerData(nullptr),
mReferenceFrame(nullptr),
mLayer(nullptr),
@ -542,9 +540,9 @@ public:
*/
AnimatedGeometryRoot* mAnimatedGeometryRoot;
/**
* The scroll clip for this layer.
* See NewLayerEntry::mAnimatedGeometryRootForScrollMetadata.
*/
const DisplayItemScrollClip* mScrollClip;
AnimatedGeometryRoot* mAnimatedGeometryRootForScrollMetadata;
/**
* The offset between mAnimatedGeometryRoot and the reference frame.
*/
@ -670,7 +668,7 @@ public:
struct NewLayerEntry {
NewLayerEntry()
: mAnimatedGeometryRoot(nullptr)
, mScrollClip(nullptr)
, mAnimatedGeometryRootForScrollMetadata(nullptr)
, mFixedPosFrameForLayerData(nullptr)
, mLayerContentsVisibleRect(0, 0, -1, -1)
, mHideAllLayersBelow(false)
@ -684,7 +682,12 @@ struct NewLayerEntry {
// been optimized to some other form (yet).
RefPtr<Layer> mLayer;
AnimatedGeometryRoot* mAnimatedGeometryRoot;
const DisplayItemScrollClip* mScrollClip;
// For fixed background layers, mAnimatedGeometryRoot is the animated geometry
// root of the viewport frame it's fixed to, but we need to annotate it with
// scroll metadata starting from the animated geometry root of the element
// it's the background of, so that during async scrolling we can correctly
// transform the fixed layer's clip.
AnimatedGeometryRoot* mAnimatedGeometryRootForScrollMetadata;
const nsIFrame* mFixedPosFrameForLayerData;
// If non-null, this FrameMetrics is set to the be the first FrameMetrics
// on the layer.
@ -771,7 +774,6 @@ public:
template<typename NewPaintedLayerCallbackType>
PaintedLayerData* FindPaintedLayerFor(const nsIntRect& aVisibleRect,
bool aBackfaceHidden,
const DisplayItemScrollClip* aScrollClip,
NewPaintedLayerCallbackType aNewPaintedLayerCallback);
/**
@ -945,7 +947,6 @@ public:
*/
template<typename NewPaintedLayerCallbackType>
PaintedLayerData* FindPaintedLayerFor(AnimatedGeometryRoot* aAnimatedGeometryRoot,
const DisplayItemScrollClip* aScrollClip,
const nsIntRect& aVisibleRect,
bool aForceOwnLayer,
bool aBackfaceidden,
@ -1044,14 +1045,12 @@ public:
ContainerLayer* aContainerLayer,
const ContainerLayerParameters& aParameters,
bool aFlattenToSingleLayer,
nscolor aBackgroundColor,
const DisplayItemScrollClip* aContainerScrollClip) :
nscolor aBackgroundColor) :
mBuilder(aBuilder), mManager(aManager),
mLayerBuilder(aLayerBuilder),
mContainerFrame(aContainerFrame),
mContainerLayer(aContainerLayer),
mContainerBounds(aContainerBounds),
mContainerScrollClip(aContainerScrollClip),
mParameters(aParameters),
mPaintedLayerDataTree(*this, aBackgroundColor),
mFlattenToSingleLayer(aFlattenToSingleLayer)
@ -1334,7 +1333,10 @@ protected:
* @param aItem The item that is going to be added.
* @param aVisibleRect The visible rect of the item.
* @param aAnimatedGeometryRoot The item's animated geometry root.
* @param aScrollClip The scroll clip for this PaintedLayer.
* @param aAnimatedGeometryRootForScrollMetadata
* The animated geometry root to be used as
* the starting point in SetupScrollMetadata().
* See NewLayerEntry::mAnimatedGeometryRootForScrollMetadata.
* @param aTopLeft The offset between aAnimatedGeometryRoot and
* the reference frame.
* @param aShouldFixToViewport If true, aAnimatedGeometryRoot is the
@ -1345,7 +1347,7 @@ protected:
PaintedLayerData NewPaintedLayerData(nsDisplayItem* aItem,
const nsIntRect& aVisibleRect,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
const DisplayItemScrollClip* aScrollClip,
AnimatedGeometryRoot* aAnimatedGeometryRootForScrollMetadata,
const nsPoint& aTopLeft,
bool aShouldFixToViewport);
@ -1382,7 +1384,6 @@ protected:
const nsIFrame* mContainerFixedPosFrame;
ContainerLayer* mContainerLayer;
nsRect mContainerBounds;
const DisplayItemScrollClip* mContainerScrollClip;
DebugOnly<nsRect> mAccumulatedChildBounds;
ContainerLayerParameters mParameters;
/**
@ -2669,7 +2670,6 @@ template<typename NewPaintedLayerCallbackType>
PaintedLayerData*
PaintedLayerDataNode::FindPaintedLayerFor(const nsIntRect& aVisibleRect,
bool aBackfaceHidden,
const DisplayItemScrollClip* aScrollClip,
NewPaintedLayerCallbackType aNewPaintedLayerCallback)
{
if (!mPaintedLayerDataStack.IsEmpty()) {
@ -2684,8 +2684,7 @@ PaintedLayerDataNode::FindPaintedLayerFor(const nsIntRect& aVisibleRect,
break;
}
MOZ_ASSERT(!data.mExclusiveToOneItem);
if (data.mBackfaceHidden == aBackfaceHidden &&
data.mScrollClip == aScrollClip) {
if (data.mBackfaceHidden == aBackfaceHidden) {
lowestUsableLayer = &data;
}
nsIntRegion visibleRegion = data.mVisibleRegion;
@ -2832,7 +2831,6 @@ PaintedLayerDataTree::AddingOwnLayer(AnimatedGeometryRoot* aAnimatedGeometryRoot
template<typename NewPaintedLayerCallbackType>
PaintedLayerData*
PaintedLayerDataTree::FindPaintedLayerFor(AnimatedGeometryRoot* aAnimatedGeometryRoot,
const DisplayItemScrollClip* aScrollClip,
const nsIntRect& aVisibleRect,
bool aForceOwnLayer,
bool aBackfaceHidden,
@ -2845,7 +2843,7 @@ PaintedLayerDataTree::FindPaintedLayerFor(AnimatedGeometryRoot* aAnimatedGeometr
node->SetAllDrawingAbove();
}
PaintedLayerData* data =
node->FindPaintedLayerFor(aVisibleRect, aBackfaceHidden, aScrollClip,
node->FindPaintedLayerFor(aVisibleRect, aBackfaceHidden,
aNewPaintedLayerCallback);
data->mExclusiveToOneItem = aForceOwnLayer;
return data;
@ -3176,7 +3174,7 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB
NS_ASSERTION(!newLayerEntry->mLayer, "Slot already occupied?");
newLayerEntry->mLayer = layer;
newLayerEntry->mAnimatedGeometryRoot = data->mAnimatedGeometryRoot;
newLayerEntry->mScrollClip = data->mScrollClip;
newLayerEntry->mAnimatedGeometryRootForScrollMetadata = data->mAnimatedGeometryRootForScrollMetadata;
newLayerEntry->mFixedPosFrameForLayerData = data->mFixedPosFrameForLayerData;
newLayerEntry->mIsCaret = data->mIsCaret;
@ -3572,13 +3570,13 @@ PaintedLayerData
ContainerState::NewPaintedLayerData(nsDisplayItem* aItem,
const nsIntRect& aVisibleRect,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
const DisplayItemScrollClip* aScrollClip,
AnimatedGeometryRoot* aAnimatedGeometryRootForScrollMetadata,
const nsPoint& aTopLeft,
bool aShouldFixToViewport)
{
PaintedLayerData data;
data.mAnimatedGeometryRoot = aAnimatedGeometryRoot;
data.mScrollClip = aScrollClip;
data.mAnimatedGeometryRootForScrollMetadata = aAnimatedGeometryRootForScrollMetadata;
data.mAnimatedGeometryRootOffset = aTopLeft;
data.mFixedPosFrameForLayerData =
FindFixedPosFrameForLayerData(aAnimatedGeometryRoot, aShouldFixToViewport);
@ -3590,7 +3588,7 @@ ContainerState::NewPaintedLayerData(nsDisplayItem* aItem,
data.mNewChildLayersIndex = mNewChildLayers.Length();
NewLayerEntry* newLayerEntry = mNewChildLayers.AppendElement();
newLayerEntry->mAnimatedGeometryRoot = aAnimatedGeometryRoot;
newLayerEntry->mScrollClip = aScrollClip;
newLayerEntry->mAnimatedGeometryRootForScrollMetadata = aAnimatedGeometryRootForScrollMetadata;
newLayerEntry->mFixedPosFrameForLayerData = data.mFixedPosFrameForLayerData;
newLayerEntry->mIsCaret = data.mIsCaret;
// newLayerEntry->mOpaqueRegion is filled in later from
@ -3753,25 +3751,41 @@ ContainerState::ComputeOpaqueRect(nsDisplayItem* aItem,
return opaquePixels;
}
static const DisplayItemScrollClip*
InnermostScrollClipApplicableToAGR(const DisplayItemScrollClip* aItemScrollClip,
AnimatedGeometryRoot* aAnimatedGeometryRoot)
static bool
IsCaretWithCustomClip(nsDisplayItem* aItem, nsDisplayItem::Type aItemType)
{
// "Applicable" scroll clips are those that are for nsIScrollableFrames
// that are ancestors of aAnimatedGeometryRoot or ancestors of aContainerScrollClip.
// They can be applied to all items sharing this animated geometry root, so
// instead of applying to the items individually, they can be applied to the
// whole layer.
for (const DisplayItemScrollClip* scrollClip = aItemScrollClip;
scrollClip;
scrollClip = scrollClip->mParent) {
nsIFrame* scrolledFrame = scrollClip->mScrollableFrame->GetScrolledFrame();
if (nsLayoutUtils::IsAncestorFrameCrossDoc(scrolledFrame, *aAnimatedGeometryRoot)) {
// scrollClip and all its ancestors are applicable.
return scrollClip;
return aItemType == nsDisplayItem::TYPE_CARET &&
static_cast<nsDisplayCaret*>(aItem)->NeedsCustomScrollClip();
}
static DisplayItemClip
GetScrollClipIntersection(nsDisplayListBuilder* aBuilder, AnimatedGeometryRoot* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aStopAtAnimatedGeometryRoot, bool aIsCaret)
{
DisplayItemClip resultClip;
for (AnimatedGeometryRoot* agr = aAnimatedGeometryRoot;
agr != aStopAtAnimatedGeometryRoot;
agr = agr->mParentAGR) {
if (!agr) {
// This means aStopAtAnimatedGeometryRoot was not an ancestor
// of aAnimatedGeometryRoot. This is a weird case but it
// can happen, e.g. when a scrolled frame contains a frame with opacity
// which contains a frame that is not scrolled by the scrolled frame.
// For now, we just don't apply any specific scroll clip to this layer.
return DisplayItemClip();
}
nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(*agr);
if (!scrollFrame) {
continue;
}
Maybe<DisplayItemClip> clip = scrollFrame->ComputeScrollClip(aIsCaret);
if (clip) {
resultClip.IntersectWith(*clip);
}
}
return nullptr;
return resultClip;
}
/*
@ -3857,15 +3871,16 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
bool forceInactive;
AnimatedGeometryRoot* animatedGeometryRoot;
AnimatedGeometryRoot* animatedGeometryRootForClip = nullptr;
AnimatedGeometryRoot* animatedGeometryRootForScrollMetadata = nullptr;
AnimatedGeometryRoot* realAnimatedGeometryRootOfItem = item->GetAnimatedGeometryRoot();
if (mFlattenToSingleLayer) {
forceInactive = true;
animatedGeometryRoot = lastAnimatedGeometryRoot;
} else {
forceInactive = false;
if (mManager->IsWidgetLayerManager()) {
animatedGeometryRoot = item->GetAnimatedGeometryRoot();
animatedGeometryRootForClip = item->AnimatedGeometryRootForScrollMetadata();
animatedGeometryRoot = realAnimatedGeometryRootOfItem;
animatedGeometryRootForScrollMetadata = item->AnimatedGeometryRootForScrollMetadata();
} else {
// For inactive layer subtrees, splitting content into PaintedLayers
// based on animated geometry roots is pointless. It's more efficient
@ -3875,42 +3890,17 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
}
topLeft = (*animatedGeometryRoot)->GetOffsetToCrossDoc(mContainerReferenceFrame);
}
if (!animatedGeometryRootForClip) {
animatedGeometryRootForClip = animatedGeometryRoot;
if (!animatedGeometryRootForScrollMetadata) {
animatedGeometryRootForScrollMetadata = animatedGeometryRoot;
}
const DisplayItemScrollClip* itemScrollClip = item->ScrollClip();
if (itemType == nsDisplayItem::TYPE_OPACITY && layerState == LAYER_INACTIVE) {
// This is an unfortunate hack. For opacity items, we usually want to
// apply clips and scroll transforms to their descendants. However, if
// an opacity is inactive and gets painted into a PaintedLayer, we can't
// apply async scrolling offsets to the inactive layer manager contents;
// instead, we need to move the opacity item itself, by moving the
// PaintedLayer that it gets painted into.
itemScrollClip = InnermostScrollClipApplicableToAGR(
static_cast<nsDisplayOpacity*>(item)->ScrollClipForSameAGRChildren(),
animatedGeometryRootForClip);
item->SetScrollClip(itemScrollClip);
item->UpdateBounds(mBuilder);
}
// Now we need to separate the item's scroll clip chain into those scroll
// clips that can be applied to the whole layer (i.e. to all items
// sharing the item's animated geometry root), and those that need to be
// applied to the item itself.
const DisplayItemScrollClip* agrScrollClip =
InnermostScrollClipApplicableToAGR(itemScrollClip, animatedGeometryRootForClip);
MOZ_ASSERT(DisplayItemScrollClip::IsAncestor(agrScrollClip, itemScrollClip));
if (agrScrollClip != itemScrollClip) {
if (animatedGeometryRoot != realAnimatedGeometryRootOfItem) {
// Pick up any scroll clips that should apply to the item and apply them.
DisplayItemClip clip = item->GetClip();
for (const DisplayItemScrollClip* scrollClip = itemScrollClip;
scrollClip && scrollClip != agrScrollClip && scrollClip != mContainerScrollClip;
scrollClip = scrollClip->mParent) {
if (scrollClip->mClip) {
clip.IntersectWith(*scrollClip->mClip);
}
}
DisplayItemClip clip =
GetScrollClipIntersection(mBuilder, realAnimatedGeometryRootOfItem,
animatedGeometryRoot,
IsCaretWithCustomClip(item, itemType));
clip.IntersectWith(item->GetClip());
item->SetClip(mBuilder, clip);
}
@ -3957,13 +3947,6 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
}
}
bounds = fixedToViewportClip.ApplyNonRoundedIntersection(bounds);
for (const DisplayItemScrollClip* scrollClip = itemScrollClip;
scrollClip && scrollClip != mContainerScrollClip;
scrollClip = scrollClip->mParent) {
if (scrollClip->mClip) {
bounds = scrollClip->mClip->ApplyNonRoundedIntersection(bounds);
}
}
((nsRect&)mAccumulatedChildBounds).UnionRect(mAccumulatedChildBounds, bounds);
#endif
@ -4065,7 +4048,6 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
}
mParameters.mBackgroundColor = uniformColor;
mParameters.mScrollClip = DisplayItemScrollClip::PickInnermost(agrScrollClip, mContainerScrollClip);
// Just use its layer.
// Set layerContentsVisibleRect.width/height to -1 to indicate we
@ -4135,7 +4117,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
NewLayerEntry* newLayerEntry = mNewChildLayers.AppendElement();
newLayerEntry->mLayer = ownLayer;
newLayerEntry->mAnimatedGeometryRoot = animatedGeometryRoot;
newLayerEntry->mScrollClip = agrScrollClip;
newLayerEntry->mAnimatedGeometryRootForScrollMetadata = animatedGeometryRootForScrollMetadata;
newLayerEntry->mFixedPosFrameForLayerData = fixedPosFrame;
if (itemType == nsDisplayItem::TYPE_PERSPECTIVE) {
newLayerEntry->mIsPerspectiveItem = true;
@ -4207,14 +4189,15 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
layerState,
topLeft, nullptr);
} else {
bool forceOwnLayer = shouldFixToViewport;
bool forceOwnLayer = shouldFixToViewport || IsCaretWithCustomClip(item, itemType);
PaintedLayerData* paintedLayerData =
mPaintedLayerDataTree.FindPaintedLayerFor(animatedGeometryRoot, agrScrollClip,
itemVisibleRect, forceOwnLayer,
mPaintedLayerDataTree.FindPaintedLayerFor(animatedGeometryRoot, itemVisibleRect,
forceOwnLayer,
item->Frame()->BackfaceIsHidden(),
[&]() {
return NewPaintedLayerData(item, itemVisibleRect, animatedGeometryRoot,
agrScrollClip, topLeft, shouldFixToViewport);
animatedGeometryRootForScrollMetadata,
topLeft, shouldFixToViewport);
});
if (itemType == nsDisplayItem::TYPE_LAYER_EVENT_REGIONS) {
@ -4748,29 +4731,43 @@ ContainerState::SetupScrollingMetadata(NewLayerEntry* aEntry)
// should not have a mask layer.
MOZ_ASSERT(!aEntry->mBaseFrameMetrics->GetMaskLayerIndex());
}
uint32_t baseLength = metricsArray.Length();
// Any extra mask layers we need to attach to FrameMetrics.
nsTArray<RefPtr<Layer>> maskLayers;
for (const DisplayItemScrollClip* scrollClip = aEntry->mScrollClip;
scrollClip && scrollClip != mContainerScrollClip;
scrollClip = scrollClip->mParent) {
if (!scrollClip->mIsAsyncScrollable) {
// This scroll clip was created for a scroll frame that didn't know
// whether it needs to be async scrollable for scroll handoff. It was
// not activated, so we don't need to create a frame metrics for it.
nsIFrame* fParent;
for (AnimatedGeometryRoot* agr = aEntry->mAnimatedGeometryRootForScrollMetadata;
agr != mContainerAnimatedGeometryRoot;
agr = agr->mParentAGR) {
fParent = nsLayoutUtils::GetCrossDocParentFrame(*agr);
if (!fParent) {
// This means mContainerAnimatedGeometryRoot was not an ancestor
// of aEntry->mAnimatedGeometryRoot. This is a weird case but it
// can happen, e.g. when a scrolled frame contains a frame with opacity
// which contains a frame that is not scrolled by the scrolled frame.
// For now, we just don't apply any specific async scrolling to this layer.
// It will async-scroll with mContainerAnimatedGeometryRoot, which
// is substandard but not fatal.
metricsArray.SetLength(baseLength);
aEntry->mLayer->SetFrameMetrics(metricsArray);
return;
}
nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(*agr);
if (!scrollFrame) {
continue;
}
nsIScrollableFrame* scrollFrame = scrollClip->mScrollableFrame;
const DisplayItemClip* clip = scrollClip->mClip;
Maybe<FrameMetrics> metrics =
scrollFrame->ComputeFrameMetrics(aEntry->mLayer, mContainerReferenceFrame, mParameters, clip);
if (!metrics) {
Maybe<FrameMetricsAndClip> info =
scrollFrame->ComputeFrameMetrics(aEntry->mLayer, mContainerReferenceFrame, mParameters, aEntry->mIsCaret);
if (!info) {
continue;
}
FrameMetrics& metrics = info->metrics;
Maybe<DisplayItemClip> clip = info->clip;
if (clip &&
clip->HasClip() &&
clip->GetRoundedRectCount() > 0)
@ -4783,12 +4780,12 @@ ContainerState::SetupScrollingMetadata(NewLayerEntry* aEntry)
RefPtr<Layer> maskLayer =
CreateMaskLayer(aEntry->mLayer, *clip, aEntry->mVisibleRegion, nextIndex, clip->GetRoundedRectCount());
if (maskLayer) {
metrics->SetMaskLayerIndex(nextIndex);
metrics.SetMaskLayerIndex(nextIndex);
maskLayers.AppendElement(maskLayer);
}
}
metricsArray.AppendElement(*metrics);
metricsArray.AppendElement(metrics);
}
// Watch out for FrameMetrics copies in profiles
@ -4942,10 +4939,8 @@ ContainerState::Finish(uint32_t* aTextContentFlags, LayerManagerData* aData,
{
mPaintedLayerDataTree.Finish();
if (!mParameters.mForEventsOnly) {
NS_ASSERTION(mContainerBounds.IsEqualInterior(mAccumulatedChildBounds),
"Bounds computation mismatch");
}
NS_ASSERTION(mContainerBounds.Contains(mAccumulatedChildBounds),
"Bounds computation mismatch");
if (mLayerBuilder->IsBuildingRetainedLayers()) {
nsIntRegion containerOpaqueRegion;
@ -5283,10 +5278,8 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
return containerLayer.forget();
}
const DisplayItemScrollClip* containerScrollClip = aParameters.mScrollClip;
ContainerLayerParameters scaleParameters;
nsRect bounds = aChildren->GetClippedBoundsUpTo(aBuilder, containerScrollClip);
nsRect bounds = aChildren->GetBounds(aBuilder);
nsRect childrenVisible =
aContainerItem ? aContainerItem->GetVisibleRectForChildren() :
aContainerFrame->GetVisualOverflowRectRelativeToSelf();
@ -5334,7 +5327,7 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
ContainerState state(aBuilder, aManager, aManager->GetLayerBuilder(),
aContainerFrame, aContainerItem, bounds,
containerLayer, scaleParameters, flattenToSingleLayer,
backgroundColor, containerScrollClip);
backgroundColor);
state.ProcessDisplayItems(aChildren);

View File

@ -24,7 +24,6 @@ class gfxContext;
class nsDisplayItemGeometry;
namespace mozilla {
class DisplayItemScrollClip;
namespace layers {
class ContainerLayer;
class LayerManager;
@ -55,7 +54,6 @@ struct ContainerLayerParameters {
, mYScale(1)
, mLayerContentsVisibleRect(nullptr)
, mBackgroundColor(NS_RGBA(0,0,0,0))
, mScrollClip(nullptr)
, mInTransformedSubtree(false)
, mInActiveTransformedSubtree(false)
, mDisableSubpixelAntialiasingInDescendants(false)
@ -67,7 +65,6 @@ struct ContainerLayerParameters {
, mYScale(aYScale)
, mLayerContentsVisibleRect(nullptr)
, mBackgroundColor(NS_RGBA(0,0,0,0))
, mScrollClip(nullptr)
, mInTransformedSubtree(false)
, mInActiveTransformedSubtree(false)
, mDisableSubpixelAntialiasingInDescendants(false)
@ -82,7 +79,6 @@ struct ContainerLayerParameters {
, mLayerContentsVisibleRect(nullptr)
, mOffset(aOffset)
, mBackgroundColor(aParent.mBackgroundColor)
, mScrollClip(aParent.mScrollClip)
, mInTransformedSubtree(aParent.mInTransformedSubtree)
, mInActiveTransformedSubtree(aParent.mInActiveTransformedSubtree)
, mDisableSubpixelAntialiasingInDescendants(aParent.mDisableSubpixelAntialiasingInDescendants)
@ -112,7 +108,6 @@ struct ContainerLayerParameters {
}
nscolor mBackgroundColor;
const DisplayItemScrollClip* mScrollClip;
bool mInTransformedSubtree;
bool mInActiveTransformedSubtree;
bool mDisableSubpixelAntialiasingInDescendants;

View File

@ -44,7 +44,6 @@
#include "nsSMILAnimationController.h"
#include "nsCSSRuleProcessor.h"
#include "ChildIterator.h"
#include "Layers.h"
#ifdef ACCESSIBILITY
#include "nsAccessibilityService.h"
@ -53,7 +52,6 @@
namespace mozilla {
using namespace layers;
using namespace dom;
#define LOG_RESTYLE_CONTINUE(reason_, ...) \
LOG_RESTYLE("continuing restyle since " reason_, ##__VA_ARGS__)

View File

@ -59,7 +59,6 @@ EXPORTS += [
'ActiveLayerTracker.h',
'CaretAssociationHint.h',
'DisplayItemClip.h',
'DisplayItemScrollClip.h',
'DisplayListClipState.h',
'FrameLayerBuilder.h',
'FramePropertyTable.h',
@ -114,7 +113,6 @@ UNIFIED_SOURCES += [
'AccessibleCaretManager.cpp',
'ActiveLayerTracker.cpp',
'DisplayItemClip.cpp',
'DisplayItemScrollClip.cpp',
'DisplayListClipState.cpp',
'FrameLayerBuilder.cpp',
'FramePropertyTable.cpp',

View File

@ -75,7 +75,6 @@
#include "mozilla/RuleNodeCacheConditions.h"
#include "nsCSSProps.h"
#include "nsPluginFrame.h"
#include "DisplayItemScrollClip.h"
// GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
// GetTickCount().
@ -747,6 +746,36 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
const nsRect& aDirtyRect)
{
nsRect dirtyRectRelativeToDirtyFrame = aDirtyRect;
DisplayItemClip clip;
const DisplayItemClip* clipPtr = nullptr;
if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(aFrame) &&
IsPaintingToWindow()) {
NS_ASSERTION(aDirtyFrame == aFrame->GetParent(), "Dirty frame should be viewport frame");
// position: fixed items are reflowed into and only drawn inside the
// viewport, or the scroll position clamping scrollport size, if one is
// set.
nsIPresShell* ps = aFrame->PresContext()->PresShell();
dirtyRectRelativeToDirtyFrame.MoveTo(0, 0);
if (ps->IsScrollPositionClampingScrollPortSizeSet()) {
dirtyRectRelativeToDirtyFrame.SizeTo(ps->GetScrollPositionClampingScrollPortSize());
} else {
dirtyRectRelativeToDirtyFrame.SizeTo(aDirtyFrame->GetSize());
}
// Always clip fixed items to the root scroll frame's scrollport, because
// we skip setting the clip in ScrollFrameHelper if we have a displayport.
nsIFrame* rootScroll = aFrame->PresContext()->PresShell()->GetRootScrollFrame();
if (rootScroll) {
nsIScrollableFrame* scrollable = do_QueryFrame(rootScroll);
nsRect clipRect = scrollable->GetScrollPortRect() + ToReferenceFrame(rootScroll);
nscoord radii[8];
bool haveRadii = rootScroll->GetPaddingBoxBorderRadii(radii);
clip.SetTo(clipRect, haveRadii ? radii : nullptr);
clipPtr = &clip;
}
}
nsRect dirty = dirtyRectRelativeToDirtyFrame - aFrame->GetOffsetTo(aDirtyFrame);
nsRect overflowRect = aFrame->GetVisualOverflowRect();
@ -764,9 +793,16 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
if (!dirty.IntersectRect(dirty, overflowRect))
return;
// Combine clips if necessary
const DisplayItemClip* oldClip = mClipState.GetClipForContainingBlockDescendants();
const DisplayItemScrollClip* sc = mClipState.GetCurrentInnermostScrollClip();
OutOfFlowDisplayData* data = new OutOfFlowDisplayData(oldClip, sc, dirty);
if (clipPtr && oldClip) {
clip.IntersectWith(*oldClip);
} else if (oldClip) {
clipPtr = oldClip;
}
OutOfFlowDisplayData* data = clipPtr ? new OutOfFlowDisplayData(*clipPtr, dirty)
: new OutOfFlowDisplayData(dirty);
aFrame->Properties().Set(nsDisplayListBuilder::OutOfFlowDisplayDataProperty(), data);
MarkFrameForDisplay(aFrame, aDirtyFrame);
@ -794,11 +830,8 @@ nsDisplayListBuilder::~nsDisplayListBuilder() {
nsCSSRendering::EndFrameTreesLocked();
for (DisplayItemClip* c : mDisplayItemClipsToDestroy) {
c->DisplayItemClip::~DisplayItemClip();
}
for (DisplayItemScrollClip* c : mScrollClipsToDestroy) {
c->DisplayItemScrollClip::~DisplayItemScrollClip();
for (uint32_t i = 0; i < mDisplayItemClipsToDestroy.Length(); ++i) {
mDisplayItemClipsToDestroy[i]->DisplayItemClip::~DisplayItemClip();
}
PL_FinishArenaPool(&mPool);
@ -1000,20 +1033,6 @@ nsDisplayListBuilder::AllocateDisplayItemClip(const DisplayItemClip& aOriginal)
return c;
}
DisplayItemScrollClip*
nsDisplayListBuilder::AllocateDisplayItemScrollClip(const DisplayItemScrollClip* aParent,
const DisplayItemScrollClip* aCrossStackingContextParent,
nsIScrollableFrame* aScrollableFrame,
const DisplayItemClip* aClip,
bool aIsAsyncScrollable)
{
void* p = Allocate(sizeof(DisplayItemScrollClip));
DisplayItemScrollClip* c =
new (p) DisplayItemScrollClip(aParent, aCrossStackingContextParent, aScrollableFrame, aClip, aIsAsyncScrollable);
mScrollClipsToDestroy.AppendElement(c);
return c;
}
const nsIFrame*
nsDisplayListBuilder::FindReferenceFrameFor(const nsIFrame *aFrame,
nsPoint* aOffset)
@ -1381,16 +1400,6 @@ nsDisplayList::GetBounds(nsDisplayListBuilder* aBuilder) const {
return bounds;
}
nsRect
nsDisplayList::GetClippedBoundsUpTo(nsDisplayListBuilder* aBuilder,
const DisplayItemScrollClip* aIncludeScrollClipsUpTo) const {
nsRect bounds;
for (nsDisplayItem* i = GetBottom(); i != nullptr; i = i->GetAbove()) {
bounds.UnionRect(bounds, i->GetClippedBoundsUpTo(aBuilder, aIncludeScrollClipsUpTo));
}
return bounds;
}
nsRect
nsDisplayList::GetVisibleRect() const {
nsRect result;
@ -2072,7 +2081,6 @@ void nsDisplayList::Sort(nsDisplayListBuilder* aBuilder,
nsDisplayItem::nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
: mFrame(aFrame)
, mClip(aBuilder->ClipState().GetCurrentCombinedClip(aBuilder))
, mScrollClip(aBuilder->ClipState().GetCurrentInnermostScrollClip())
, mAnimatedGeometryRoot(nullptr)
#ifdef MOZ_DUMP_PAINTING
, mPainted(false)
@ -2172,21 +2180,6 @@ nsDisplayItem::GetClippedBounds(nsDisplayListBuilder* aBuilder)
return GetClip().ApplyNonRoundedIntersection(r);
}
nsRect
nsDisplayItem::GetClippedBoundsUpTo(nsDisplayListBuilder* aBuilder,
const DisplayItemScrollClip* aIncludeScrollClipsUpTo)
{
nsRect r = GetClippedBounds(aBuilder);
for (const DisplayItemScrollClip* sc = mScrollClip;
sc && sc != aIncludeScrollClipsUpTo;
sc = sc->mParent) {
if (sc->mClip) {
r = sc->mClip->ApplyNonRoundedIntersection(r);
}
}
return r;
}
nsRect
nsDisplaySolidColor::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
{
@ -3441,6 +3434,7 @@ nsDisplayCaret::nsDisplayCaret(nsDisplayListBuilder* aBuilder,
: nsDisplayItem(aBuilder, aCaretFrame)
, mCaret(aBuilder->GetCaret())
, mBounds(aBuilder->GetCaretRect() + ToReferenceFrame())
, mNeedsCustomScrollClip(false)
{
MOZ_COUNT_CTOR(nsDisplayCaret);
}
@ -4018,10 +4012,8 @@ nsresult nsDisplayWrapper::WrapListsInPlace(nsDisplayListBuilder* aBuilder,
nsDisplayOpacity::nsDisplayOpacity(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList,
const DisplayItemScrollClip* aScrollClipForSameAGRChildren,
bool aForEventsOnly)
: nsDisplayWrapList(aBuilder, aFrame, aList)
, mScrollClipForSameAGRChildren(aScrollClipForSameAGRChildren)
, mOpacity(aFrame->StyleDisplay()->mOpacity)
, mForEventsOnly(aForEventsOnly)
{
@ -4206,8 +4198,6 @@ bool nsDisplayOpacity::TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* a
return false;
if (aItem->GetClip() != GetClip())
return false;
if (aItem->ScrollClip() != ScrollClip())
return false;
MergeFromTrackingMergedFrames(static_cast<nsDisplayOpacity*>(aItem));
return true;
}
@ -4293,8 +4283,6 @@ bool nsDisplayMixBlendMode::TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayIt
return false;
if (aItem->GetClip() != GetClip())
return false;
if (aItem->ScrollClip() != ScrollClip())
return false;
MergeFromTrackingMergedFrames(static_cast<nsDisplayMixBlendMode*>(aItem));
return true;
}
@ -4365,8 +4353,6 @@ bool nsDisplayBlendContainer::TryMerge(nsDisplayListBuilder* aBuilder, nsDisplay
return false;
if (aItem->GetClip() != GetClip())
return false;
if (aItem->ScrollClip() != ScrollClip())
return false;
MergeFromTrackingMergedFrames(static_cast<nsDisplayBlendContainer*>(aItem));
return true;
}
@ -4692,8 +4678,6 @@ bool nsDisplayStickyPosition::TryMerge(nsDisplayListBuilder* aBuilder, nsDisplay
return false;
if (aItem->GetClip() != GetClip())
return false;
if (aItem->ScrollClip() != ScrollClip())
return false;
MergeFromTrackingMergedFrames(other);
return true;
}
@ -5971,9 +5955,6 @@ nsDisplayTransform::TryMerge(nsDisplayListBuilder *aBuilder,
if (aItem->GetClip() != GetClip())
return false;
if (aItem->ScrollClip() != ScrollClip())
return false;
/* Now, move everything over to this frame and signal that
* we merged things!
*/
@ -6327,8 +6308,6 @@ bool nsDisplaySVGEffects::TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem
return false;
if (aItem->GetClip() != GetClip())
return false;
if (aItem->ScrollClip() != ScrollClip())
return false;
nsDisplaySVGEffects* other = static_cast<nsDisplaySVGEffects*>(aItem);
MergeFromTrackingMergedFrames(other);
mEffectsBounds.UnionRect(mEffectsBounds,

View File

@ -40,14 +40,12 @@ class nsRenderingContext;
class nsDisplayList;
class nsDisplayTableItem;
class nsISelection;
class nsIScrollableFrame;
class nsDisplayLayerEventRegions;
class nsDisplayScrollInfoLayer;
class nsCaret;
namespace mozilla {
class FrameLayerBuilder;
class DisplayItemScrollClip;
namespace layers {
class Layer;
class ImageLayer;
@ -206,7 +204,6 @@ public:
typedef mozilla::FrameLayerBuilder FrameLayerBuilder;
typedef mozilla::DisplayItemClip DisplayItemClip;
typedef mozilla::DisplayListClipState DisplayListClipState;
typedef mozilla::DisplayItemScrollClip DisplayItemScrollClip;
typedef nsIWidget::ThemeGeometry ThemeGeometry;
typedef mozilla::layers::Layer Layer;
typedef mozilla::layers::FrameMetrics FrameMetrics;
@ -628,21 +625,11 @@ public:
void* Allocate(size_t aSize);
/**
* Allocate a new DisplayItemClip in the arena. Will be cleaned up
* Allocate a new DisplayListClip in the arena. Will be cleaned up
* automatically when the arena goes away.
*/
const DisplayItemClip* AllocateDisplayItemClip(const DisplayItemClip& aOriginal);
/**
* Allocate a new DisplayItemScrollClip in the arena. Will be cleaned up
* automatically when the arena goes away.
*/
DisplayItemScrollClip* AllocateDisplayItemScrollClip(const DisplayItemScrollClip* aParent,
const DisplayItemScrollClip* aCrossStackingContextParent,
nsIScrollableFrame* aScrollableFrame,
const DisplayItemClip* aClip,
bool aIsAsyncScrollable);
/**
* Transfer off main thread animations to the layer. May be called
* with aBuilder and aItem both null, but only if the caller has
@ -946,15 +933,15 @@ public:
void SetCurrentTableItem(nsDisplayTableItem* aTableItem) { mCurrentTableItem = aTableItem; }
struct OutOfFlowDisplayData {
OutOfFlowDisplayData(const DisplayItemClip* aContainingBlockClip,
const DisplayItemScrollClip* aContainingBlockScrollClip,
OutOfFlowDisplayData(const DisplayItemClip& aContainingBlockClip,
const nsRect &aDirtyRect)
: mContainingBlockClip(aContainingBlockClip ? *aContainingBlockClip : DisplayItemClip())
, mContainingBlockScrollClip(aContainingBlockScrollClip)
: mContainingBlockClip(aContainingBlockClip)
, mDirtyRect(aDirtyRect)
{}
explicit OutOfFlowDisplayData(const nsRect &aDirtyRect)
: mDirtyRect(aDirtyRect)
{}
DisplayItemClip mContainingBlockClip;
const DisplayItemScrollClip* mContainingBlockScrollClip;
nsRect mDirtyRect;
};
@ -1236,7 +1223,6 @@ private:
// info items until the end of display list building.
nsDisplayList* mPendingScrollInfoItems;
nsDisplayList* mCommittedScrollInfoItems;
nsTArray<DisplayItemScrollClip*> mScrollClipsToDestroy;
nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy;
Mode mMode;
ViewID mCurrentScrollParentId;
@ -1312,7 +1298,6 @@ class nsDisplayItem : public nsDisplayItemLink {
public:
typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
typedef mozilla::DisplayItemClip DisplayItemClip;
typedef mozilla::DisplayItemScrollClip DisplayItemScrollClip;
typedef mozilla::layers::FrameMetrics FrameMetrics;
typedef mozilla::layers::FrameMetrics::ViewID ViewID;
typedef mozilla::layers::Layer Layer;
@ -1329,7 +1314,6 @@ public:
explicit nsDisplayItem(nsIFrame* aFrame)
: mFrame(aFrame)
, mClip(nullptr)
, mScrollClip(nullptr)
, mReferenceFrame(nullptr)
, mAnimatedGeometryRoot(nullptr)
#ifdef MOZ_DUMP_PAINTING
@ -1429,17 +1413,6 @@ public:
* account.
*/
nsRect GetClippedBounds(nsDisplayListBuilder* aBuilder);
/**
* Returns the result of GetClippedBounds, intersected with the item's
* scroll clips. The item walks up its chain of scroll clips, *not* crossing
* stacking contexts, applying each scroll clip until aIncludeScrollClipsUpTo
* is reached. aIncludeScrollClipsUpTo is *not* applied.
* The intersection is approximate since rounded corners are not taking into
* account.
*/
nsRect GetClippedBoundsUpTo(nsDisplayListBuilder* aBuilder,
const DisplayItemScrollClip* aIncludeScrollClipsUpTo);
nsRect GetBorderRect() {
return nsRect(ToReferenceFrame(), Frame()->GetSize());
}
@ -1861,9 +1834,6 @@ public:
}
}
void SetScrollClip(const DisplayItemScrollClip* aScrollClip) { mScrollClip = aScrollClip; }
const DisplayItemScrollClip* ScrollClip() const { return mScrollClip; }
bool BackfaceIsHidden() {
return mFrame->StyleDisplay()->BackfaceIsHidden();
}
@ -1875,7 +1845,6 @@ protected:
nsIFrame* mFrame;
const DisplayItemClip* mClip;
const DisplayItemScrollClip* mScrollClip;
// Result of FindReferenceFrameFor(mFrame), if mFrame is non-null
const nsIFrame* mReferenceFrame;
struct AnimatedGeometryRoot* mAnimatedGeometryRoot;
@ -1911,7 +1880,6 @@ protected:
*/
class nsDisplayList {
public:
typedef mozilla::DisplayItemScrollClip DisplayItemScrollClip;
typedef mozilla::layers::Layer Layer;
typedef mozilla::layers::LayerManager LayerManager;
typedef mozilla::layers::PaintedLayer PaintedLayer;
@ -2162,8 +2130,6 @@ public:
* The result is not cached.
*/
nsRect GetBounds(nsDisplayListBuilder* aBuilder) const;
nsRect GetClippedBoundsUpTo(nsDisplayListBuilder* aBuilder,
const DisplayItemScrollClip* aIncludeScrollClipsUpTo) const;
/**
* Find the topmost display item that returns a non-null frame, and return
* the frame.
@ -2511,9 +2477,13 @@ public:
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) override;
NS_DISPLAY_DECL_NAME("Caret", TYPE_CARET)
bool NeedsCustomScrollClip() { return mNeedsCustomScrollClip; }
void SetNeedsCustomScrollClip() { mNeedsCustomScrollClip = true; }
protected:
RefPtr<nsCaret> mCaret;
nsRect mBounds;
bool mNeedsCustomScrollClip;
};
/**
@ -3187,7 +3157,7 @@ public:
*/
virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) override
{
mBounds = mList.GetClippedBoundsUpTo(aBuilder, mScrollClip);
mBounds = mList.GetBounds(aBuilder);
// The display list may contain content that's visible outside the visible
// rect (i.e. the current dirty rect) passed in when the item was created.
// This happens when the dirty rect has been restricted to the visual
@ -3330,9 +3300,7 @@ protected:
class nsDisplayOpacity : public nsDisplayWrapList {
public:
nsDisplayOpacity(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList,
const DisplayItemScrollClip* aScrollClipForSameAGRChildren,
bool aForEventsOnly);
nsDisplayList* aList, bool aForEventsOnly);
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayOpacity();
#endif
@ -3365,11 +3333,7 @@ public:
bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) override;
const DisplayItemScrollClip* ScrollClipForSameAGRChildren() const
{ return mScrollClipForSameAGRChildren; }
private:
const DisplayItemScrollClip* mScrollClipForSameAGRChildren;
float mOpacity;
bool mForEventsOnly;
};

View File

@ -13,7 +13,6 @@
#include "nsDisplayList.h"
#include "FrameLayerBuilder.h"
#include "nsPrintfCString.h"
#include "DisplayItemScrollClip.h"
#include <stdio.h>
@ -178,7 +177,7 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
aStream << nsPrintfCString("<a href=\"javascript:ViewImage('%s')\">", string.BeginReading());
}
#endif
aStream << nsPrintfCString("%s p=0x%p f=0x%p(%s) %sbounds(%d,%d,%d,%d) layerBounds(%d,%d,%d,%d) visible(%d,%d,%d,%d) componentAlpha(%d,%d,%d,%d) clip(%s) scrollClip(%s)%s ref=0x%p agr=0x%p",
aStream << nsPrintfCString("%s p=0x%p f=0x%p(%s) %sbounds(%d,%d,%d,%d) layerBounds(%d,%d,%d,%d) visible(%d,%d,%d,%d) componentAlpha(%d,%d,%d,%d) clip(%s) %s ref=0x%p agr=0x%p",
aItem->Name(), aItem, (void*)f, NS_ConvertUTF16toUTF8(contentData).get(),
(aItem->ZIndex() ? nsPrintfCString("z=%d ", aItem->ZIndex()).get() : ""),
rect.x, rect.y, rect.width, rect.height,
@ -186,7 +185,6 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
vis.x, vis.y, vis.width, vis.height,
component.x, component.y, component.width, component.height,
clip.ToString().get(),
DisplayItemScrollClip::ToString(aItem->ScrollClip()).get(),
aItem->IsUniform(aBuilder, &color) ? " uniform" : "",
aItem->ReferenceFrame(), *aItem->GetAnimatedGeometryRoot());

View File

@ -2058,11 +2058,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
// item itself will be clipped.
// For transforms we also need to clear ancestor clipping because it's
// relative to the wrong display item reference frame anyway.
// We clear both regular and scroll clips here. Our content needs to be
// able to walk up the complete cross stacking context scroll clip chain,
// so we call a special method on the clip state that keeps the ancestor
// scroll clip around.
clipState.ClearForStackingContextContents();
clipState.Clear();
}
nsDisplayListCollection set;
@ -2179,19 +2175,10 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
// Don't clip nsDisplayOpacity items. We clip their descendants instead.
// The clip we would set on an element with opacity would clip
// all descendant content, but some should not be clipped.
// We clear both regular clips and scroll clips. If this item's animated
// geometry root has async scrolling, then the async scroll transform will
// be applied on the opacity's descendants (because that's where the
// scroll clip will be). However, this won't work if the opacity item is
// inactive, which is why we record the pre-clear scroll clip here.
const DisplayItemScrollClip* scrollClipForSameAGRChildren =
aBuilder->ClipState().GetCurrentInnermostScrollClip();
DisplayListClipState::AutoSaveRestore opacityClipState(aBuilder);
opacityClipState.ClearIncludingScrollClip();
opacityClipState.Clear();
resultList.AppendNewToTop(
new (aBuilder) nsDisplayOpacity(aBuilder, this, &resultList,
scrollClipForSameAGRChildren,
opacityItemForEventsOnly));
new (aBuilder) nsDisplayOpacity(aBuilder, this, &resultList, opacityItemForEventsOnly));
}
/* If we're going to apply a transformation and don't have preserve-3d set, wrap
@ -2508,8 +2495,6 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
if (savedOutOfFlowData) {
clipState.SetClipForContainingBlockDescendants(
&savedOutOfFlowData->mContainingBlockClip);
clipState.SetScrollClipForContainingBlockDescendants(
savedOutOfFlowData->mContainingBlockScrollClip);
}
// Setup clipping for the parent's overflow:-moz-hidden-unscrollable,

View File

@ -9,7 +9,6 @@
#include "base/compiler_specific.h"
#include "DisplayItemClip.h"
#include "DisplayItemScrollClip.h"
#include "nsCOMPtr.h"
#include "nsPresContext.h"
#include "nsView.h"
@ -2816,42 +2815,32 @@ static void
ClipItemsExceptCaret(nsDisplayList* aList,
nsDisplayListBuilder* aBuilder,
nsIFrame* aClipFrame,
const DisplayItemClip* aNonCaretClip,
const DisplayItemScrollClip* aNonCaretScrollClip)
const DisplayItemClip& aNonCaretClip,
bool aUsingDisplayPort)
{
for (nsDisplayItem* i = aList->GetBottom(); i; i = i->GetAbove()) {
if (!ShouldBeClippedByFrame(aClipFrame, i->Frame())) {
continue;
}
if (i->GetType() != nsDisplayItem::TYPE_CARET) {
bool isCaret = i->GetType() == nsDisplayItem::TYPE_CARET;
if (aUsingDisplayPort && isCaret) {
static_cast<nsDisplayCaret*>(i)->SetNeedsCustomScrollClip();
}
if (!aUsingDisplayPort && !isCaret) {
bool unused;
nsRect bounds = i->GetBounds(aBuilder, &unused);
if (aNonCaretClip && aNonCaretClip->IsRectAffectedByClip(bounds)) {
if (aNonCaretClip.IsRectAffectedByClip(bounds)) {
DisplayItemClip newClip;
newClip.IntersectWith(i->GetClip());
newClip.IntersectWith(*aNonCaretClip);
newClip.IntersectWith(aNonCaretClip);
i->SetClip(aBuilder, newClip);
}
if (aNonCaretScrollClip) {
const DisplayItemScrollClip* currentScrollClip = i->ScrollClip();
MOZ_ASSERT(DisplayItemScrollClip::IsAncestor(aNonCaretScrollClip->mParent,
currentScrollClip));
// Overwrite the existing scroll clip with aNonCaretScrollClip, unless
// the current scroll clip is deeper than aNonCaretScrollClip (which
// means that the display item is nested inside another scroll frame).
if (!currentScrollClip ||
currentScrollClip->mParent == aNonCaretScrollClip->mParent) {
i->SetScrollClip(aNonCaretScrollClip);
}
}
}
nsDisplayList* children = i->GetSameCoordinateSystemChildren();
if (children) {
ClipItemsExceptCaret(children, aBuilder, aClipFrame, aNonCaretClip,
aNonCaretScrollClip);
aUsingDisplayPort);
}
}
}
@ -2860,15 +2849,17 @@ static void
ClipListsExceptCaret(nsDisplayListCollection* aLists,
nsDisplayListBuilder* aBuilder,
nsIFrame* aClipFrame,
const DisplayItemClip* aNonCaretClip,
const DisplayItemScrollClip* aNonCaretScrollClip)
const nsRect& aNonCaretClip,
bool aUsingDisplayPort)
{
ClipItemsExceptCaret(aLists->BorderBackground(), aBuilder, aClipFrame, aNonCaretClip, aNonCaretScrollClip);
ClipItemsExceptCaret(aLists->BlockBorderBackgrounds(), aBuilder, aClipFrame, aNonCaretClip, aNonCaretScrollClip);
ClipItemsExceptCaret(aLists->Floats(), aBuilder, aClipFrame, aNonCaretClip, aNonCaretScrollClip);
ClipItemsExceptCaret(aLists->PositionedDescendants(), aBuilder, aClipFrame, aNonCaretClip, aNonCaretScrollClip);
ClipItemsExceptCaret(aLists->Outlines(), aBuilder, aClipFrame, aNonCaretClip, aNonCaretScrollClip);
ClipItemsExceptCaret(aLists->Content(), aBuilder, aClipFrame, aNonCaretClip, aNonCaretScrollClip);
DisplayItemClip clip;
clip.SetTo(aNonCaretClip);
ClipItemsExceptCaret(aLists->BorderBackground(), aBuilder, aClipFrame, clip, aUsingDisplayPort);
ClipItemsExceptCaret(aLists->BlockBorderBackgrounds(), aBuilder, aClipFrame, clip, aUsingDisplayPort);
ClipItemsExceptCaret(aLists->Floats(), aBuilder, aClipFrame, clip, aUsingDisplayPort);
ClipItemsExceptCaret(aLists->PositionedDescendants(), aBuilder, aClipFrame, clip, aUsingDisplayPort);
ClipItemsExceptCaret(aLists->Outlines(), aBuilder, aClipFrame, clip, aUsingDisplayPort);
ClipItemsExceptCaret(aLists->Content(), aBuilder, aClipFrame, clip, aUsingDisplayPort);
}
void
@ -2896,6 +2887,10 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
}
// Clear the scroll port clip that was set during the last paint.
mAncestorClip = Nothing();
mAncestorClipForCaret = Nothing();
// We put non-overlay scrollbars in their own layers when this is the root
// scroll frame and we are a toplevel content document. In this situation,
// the scrollbar(s) would normally be assigned their own layer anyway, since
@ -3032,9 +3027,6 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
}
nsIScrollableFrame* sf = do_QueryFrame(mOuter);
MOZ_ASSERT(sf);
nsDisplayListCollection scrolledContent;
{
// Note that setting the current scroll parent id here means that positioned children
@ -3048,6 +3040,12 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
? nsLayoutUtils::FindOrCreateIDFor(mScrolledFrame->GetContent())
: aBuilder->GetCurrentScrollParentId());
// We need to apply at least one clip, potentially more, and each needs to be applied
// through a separate DisplayListClipState::AutoSaveRestore object.
// clipStatePtr will always point to the innermost used one.
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
DisplayListClipState::AutoSaveRestore* clipStatePtr = &clipState;
nsRect clipRect = mScrollPort + aBuilder->ToReferenceFrame(mOuter);
// Our override of GetBorderRadii ensures we never have a radius at
// the corners where we have a scrollbar.
@ -3062,68 +3060,61 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
}
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
if (mClipAllDescendants) {
clipState.ClipContentDescendants(clipRect, haveRadii ? radii : nullptr);
} else {
clipState.ClipContainingBlockDescendants(clipRect, haveRadii ? radii : nullptr);
}
DisplayItemScrollClip* inactiveScrollClip = nullptr;
{
DisplayListClipState::AutoSaveRestore contentBoxClipState(aBuilder);
if (contentBoxClipForCaret) {
if (mClipAllDescendants) {
contentBoxClipState.ClipContentDescendants(*contentBoxClipForCaret);
} else {
contentBoxClipState.ClipContainingBlockDescendants(*contentBoxClipForCaret);
}
}
DisplayListClipState::AutoSaveRestore clipStateForScrollClip(aBuilder);
if (usingDisplayPort) {
if (mClipAllDescendants) {
clipStateForScrollClip.TurnClipIntoScrollClipForContentDescendants(aBuilder, sf);
} else {
clipStateForScrollClip.TurnClipIntoScrollClipForContainingBlockDescendants(aBuilder, sf);
}
} else {
// Create a scroll clip anyway because we might need to activate for scroll handoff.
if (mClipAllDescendants) {
inactiveScrollClip = clipStateForScrollClip.InsertInactiveScrollClipForContentDescendants(aBuilder, sf);
} else {
inactiveScrollClip = clipStateForScrollClip.InsertInactiveScrollClipForContainingBlockDescendants(aBuilder, sf);
}
MOZ_ASSERT(!inactiveScrollClip->mIsAsyncScrollable);
}
aBuilder->StoreDirtyRectForScrolledContents(mOuter, dirtyRect);
mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, scrolledContent);
}
if (contentBoxClipForNonCaretContent) {
DisplayListClipState::AutoSaveRestore contentBoxClipState(aBuilder);
Maybe<DisplayListClipState::AutoSaveRestore> clipStateCaret;
if (contentBoxClipForCaret) {
clipStateCaret.emplace(aBuilder);
clipStatePtr = &*clipStateCaret;
if (mClipAllDescendants) {
contentBoxClipState.ClipContentDescendants(*contentBoxClipForNonCaretContent);
clipStateCaret->ClipContentDescendants(*contentBoxClipForCaret);
} else {
contentBoxClipState.ClipContainingBlockDescendants(*contentBoxClipForNonCaretContent);
clipStateCaret->ClipContainingBlockDescendants(*contentBoxClipForCaret);
}
}
DisplayListClipState::AutoSaveRestore clipStateForScrollClip(aBuilder);
if (usingDisplayPort) {
Maybe<DisplayListClipState::AutoSaveRestore> clipStateNonCaret;
if (usingDisplayPort) {
// Capture the clip state of the parent scroll frame. This will be saved
// on FrameMetrics for layers with this frame as their animated geoemetry
// root.
mAncestorClipForCaret = ToMaybe(aBuilder->ClipState().GetCurrentCombinedClip(aBuilder));
// Add the non-caret content box clip here so that it gets picked up by
// mAncestorClip.
if (contentBoxClipForNonCaretContent) {
clipStateNonCaret.emplace(aBuilder);
clipStatePtr = &*clipStateNonCaret;
if (mClipAllDescendants) {
clipStateForScrollClip.TurnClipIntoScrollClipForContentDescendants(aBuilder, sf);
clipStateNonCaret->ClipContentDescendants(*contentBoxClipForNonCaretContent);
} else {
clipStateForScrollClip.TurnClipIntoScrollClipForContainingBlockDescendants(aBuilder, sf);
clipStateNonCaret->ClipContainingBlockDescendants(*contentBoxClipForNonCaretContent);
}
}
const DisplayItemClip* clipNonCaret = aBuilder->ClipState().GetCurrentCombinedClip(aBuilder);
const DisplayItemScrollClip* scrollClipNonCaret = aBuilder->ClipState().GetCurrentInnermostScrollClip();
ClipListsExceptCaret(&scrolledContent, aBuilder, mScrolledFrame,
clipNonCaret, scrollClipNonCaret);
mAncestorClip = ToMaybe(aBuilder->ClipState().GetCurrentCombinedClip(aBuilder));
// If we are using a display port, then ignore any pre-existing clip
// passed down from our parents. The pre-existing clip would just defeat
// the purpose of a display port which is to paint regions that are not
// currently visible so that they can be brought into view asynchronously.
// Notes:
// - The pre-existing clip state will be restored when the
// AutoSaveRestore goes out of scope, so there is no permanent change
// to this clip state.
// - We still set a clip to the scroll port further below where we
// build the scroll wrapper. This doesn't prevent us from painting
// the entire displayport, but it lets the compositor know to
// clip to the scroll port after compositing.
clipStatePtr->Clear();
}
aBuilder->StoreDirtyRectForScrolledContents(mOuter, dirtyRect);
mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, scrolledContent);
if (idSetter.ShouldForceLayerForScrollParent() &&
!gfxPrefs::LayoutUseContainersForRootFrames())
{
@ -3133,9 +3124,6 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
//
// This is not compatible when using containes for root scrollframes.
MOZ_ASSERT(couldBuildLayer && mScrolledFrame->GetContent());
if (inactiveScrollClip) {
inactiveScrollClip->mIsAsyncScrollable = true;
}
if (!mWillBuildScrollableLayer) {
// Set a displayport so next paint we don't have to force layerization
// after the fact.
@ -3158,6 +3146,11 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
aBuilder->ForceLayerForScrollParent();
}
if (contentBoxClipForNonCaretContent) {
ClipListsExceptCaret(&scrolledContent, aBuilder, mScrolledFrame,
*contentBoxClipForNonCaretContent, usingDisplayPort);
}
if (couldBuildLayer) {
// Make sure that APZ will dispatch events back to content so we can create
// a displayport for this frame. We'll add the item later on.
@ -3257,23 +3250,36 @@ ScrollFrameHelper::DecideScrollableLayer(nsDisplayListBuilder* aBuilder,
}
Maybe<FrameMetrics>
Maybe<DisplayItemClip>
ScrollFrameHelper::ComputeScrollClip(bool aIsForCaret) const
{
const Maybe<DisplayItemClip>& ancestorClip = aIsForCaret ? mAncestorClipForCaret : mAncestorClip;
if (!mWillBuildScrollableLayer || mIsScrollableLayerInRootContainer) {
return Nothing();
}
return ancestorClip;
}
Maybe<FrameMetricsAndClip>
ScrollFrameHelper::ComputeFrameMetrics(Layer* aLayer,
nsIFrame* aContainerReferenceFrame,
const ContainerLayerParameters& aParameters,
const DisplayItemClip* aClip) const
bool aIsForCaret) const
{
if (!mWillBuildScrollableLayer || mIsScrollableLayerInRootContainer) {
return Nothing();
}
const Maybe<DisplayItemClip>& ancestorClip = aIsForCaret ? mAncestorClipForCaret : mAncestorClip;
nsPoint toReferenceFrame = mOuter->GetOffsetToCrossDoc(aContainerReferenceFrame);
Maybe<nsRect> parentLayerClip;
// For containerful frames, the clip is on the container layer.
if (aClip &&
if (ancestorClip &&
(!gfxPrefs::LayoutUseContainersForRootFrames() || mAddClipRectToLayer)) {
parentLayerClip = Some(aClip->GetClipRect());
parentLayerClip = Some(ancestorClip->GetClipRect());
}
bool isRootContent = mIsRoot && mOuter->PresContext()->IsRootContentDocument();
@ -3311,12 +3317,16 @@ ScrollFrameHelper::ComputeFrameMetrics(Layer* aLayer,
MOZ_ASSERT(mScrolledFrame->GetContent());
nsRect scrollport = mScrollPort + toReferenceFrame;
FrameMetricsAndClip result;
return Some(nsLayoutUtils::ComputeFrameMetrics(
nsRect scrollport = mScrollPort + toReferenceFrame;
result.metrics = nsLayoutUtils::ComputeFrameMetrics(
mScrolledFrame, mOuter, mOuter->GetContent(),
aContainerReferenceFrame, aLayer, mScrollParentID,
scrollport, parentLayerClip, isRootContent, aParameters));
scrollport, parentLayerClip, isRootContent, aParameters);
result.clip = ancestorClip;
return Some(result);
}
bool

View File

@ -383,10 +383,11 @@ public:
}
}
bool WantAsyncScroll() const;
Maybe<mozilla::layers::FrameMetrics> ComputeFrameMetrics(
Maybe<FrameMetricsAndClip> ComputeFrameMetrics(
Layer* aLayer, nsIFrame* aContainerReferenceFrame,
const ContainerLayerParameters& aParameters,
const mozilla::DisplayItemClip* aClip) const;
bool aIsForCaret) const;
mozilla::Maybe<mozilla::DisplayItemClip> ComputeScrollClip(bool aIsForCaret) const;
// nsIScrollbarMediator
void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection,
@ -463,6 +464,10 @@ public:
FrameMetrics::ViewID mScrollParentID;
// The scroll port clip.
Maybe<DisplayItemClip> mAncestorClip;
Maybe<DisplayItemClip> mAncestorClipForCaret;
bool mNeverHasVerticalScrollbar:1;
bool mNeverHasHorizontalScrollbar:1;
bool mHasVerticalScrollbar:1;
@ -827,12 +832,16 @@ public:
virtual bool WantAsyncScroll() const override {
return mHelper.WantAsyncScroll();
}
virtual mozilla::Maybe<mozilla::layers::FrameMetrics> ComputeFrameMetrics(
virtual mozilla::Maybe<mozilla::FrameMetricsAndClip> ComputeFrameMetrics(
Layer* aLayer, nsIFrame* aContainerReferenceFrame,
const ContainerLayerParameters& aParameters,
const mozilla::DisplayItemClip* aClip) const override
bool aIsForCaret) const override
{
return mHelper.ComputeFrameMetrics(aLayer, aContainerReferenceFrame, aParameters, aClip);
return mHelper.ComputeFrameMetrics(aLayer, aContainerReferenceFrame, aParameters, aIsForCaret);
}
virtual mozilla::Maybe<mozilla::DisplayItemClip> ComputeScrollClip(bool aIsForCaret) const override
{
return mHelper.ComputeScrollClip(aIsForCaret);
}
virtual bool IsIgnoringViewportClipping() const override {
return mHelper.IsIgnoringViewportClipping();
@ -1219,12 +1228,16 @@ public:
virtual bool WantAsyncScroll() const override {
return mHelper.WantAsyncScroll();
}
virtual mozilla::Maybe<mozilla::layers::FrameMetrics> ComputeFrameMetrics(
virtual mozilla::Maybe<mozilla::FrameMetricsAndClip> ComputeFrameMetrics(
Layer* aLayer, nsIFrame* aContainerReferenceFrame,
const ContainerLayerParameters& aParameters,
const mozilla::DisplayItemClip* aClip) const override
bool aIsForCaret) const override
{
return mHelper.ComputeFrameMetrics(aLayer, aContainerReferenceFrame, aParameters, aClip);
return mHelper.ComputeFrameMetrics(aLayer, aContainerReferenceFrame, aParameters, aIsForCaret);
}
virtual mozilla::Maybe<mozilla::DisplayItemClip> ComputeScrollClip(bool aIsForCaret) const override
{
return mHelper.ComputeScrollClip(aIsForCaret);
}
virtual bool IsIgnoringViewportClipping() const override {
return mHelper.IsIgnoringViewportClipping();

View File

@ -36,6 +36,13 @@ struct ContainerLayerParameters;
namespace layers {
class Layer;
} // namespace layers
struct FrameMetricsAndClip
{
layers::FrameMetrics metrics;
mozilla::Maybe<DisplayItemClip> clip;
};
} // namespace mozilla
/**
@ -400,11 +407,11 @@ public:
* aLayer's animated geometry root is this frame. If there needs to be a
* FrameMetrics contributed by this frame, append it to aOutput.
*/
virtual mozilla::Maybe<mozilla::layers::FrameMetrics> ComputeFrameMetrics(
virtual mozilla::Maybe<mozilla::FrameMetricsAndClip> ComputeFrameMetrics(
mozilla::layers::Layer* aLayer,
nsIFrame* aContainerReferenceFrame,
const ContainerLayerParameters& aParameters,
const mozilla::DisplayItemClip* aClip) const = 0;
bool aIsForCaret) const = 0;
/**
* If this scroll frame is ignoring viewporting clipping
@ -429,6 +436,8 @@ public:
*/
virtual bool UsesContainerScrolling() const = 0;
virtual mozilla::Maybe<mozilla::DisplayItemClip> ComputeScrollClip(bool aIsForCaret) const = 0;
/**
* Determine if we should build a scrollable layer for this scroll frame and
* return the result. It will also record this result on the scroll frame.

View File

@ -21,7 +21,7 @@ skip-if(!asyncPan) == position-fixed-cover-3.html position-fixed-cover-3-ref.htm
skip-if(!asyncPan) == position-fixed-transformed-1.html position-fixed-transformed-1-ref.html
skip-if(!asyncPan) == split-layers-1.html split-layers-1-ref.html
skip-if(!asyncPan) == split-layers-multi-scrolling-1.html split-layers-multi-scrolling-1-ref.html
skip-if(!asyncPan) == split-opacity-layers-1.html split-opacity-layers-1-ref.html
fails skip-if(!asyncPan) == split-opacity-layers-1.html split-opacity-layers-1-ref.html
skip-if(!asyncPan) == sticky-pos-scrollable-1.html sticky-pos-scrollable-1-ref.html
skip-if(!asyncPan) == fixed-pos-scrollable-1.html fixed-pos-scrollable-1-ref.html
skip-if(!asyncPan) == culling-1.html culling-1-ref.html

View File

@ -1672,7 +1672,7 @@ skip-if(B2G||Mulet) == 641770-1.html 641770-1-ref.html # Initial mulet triage: p
== 641856-1.html 641856-1-ref.html
== 645491-1.html 645491-1-ref.html
== 645768-1.html 645768-1-ref.html
fails-if(layersGPUAccelerated&&cocoaWidget) fails-if(Android&&AndroidVersion<15&&AndroidVersion!=10) fuzzy-if(!layersGPUAccelerated,41,260) == 650228-1.html 650228-1-ref.html # Quartz alpha blending doesn't match GL alpha blending
fails-if(layersGPUAccelerated&&cocoaWidget) fails-if(Android&&AndroidVersion<15&&AndroidVersion!=10) fuzzy-if(asyncPan&&!layersGPUAccelerated,41,260) == 650228-1.html 650228-1-ref.html # Quartz alpha blending doesn't match GL alpha blending
needs-focus == 652301-1a.html 652301-1-ref.html
needs-focus == 652301-1b.html 652301-1-ref.html
== 652775-1.html 652775-1-ref.html

View File

@ -16,6 +16,6 @@ skip-if(!asyncPan) != pull-background-displayport-1.html about:blank
skip-if(!asyncPan) != pull-background-displayport-2.html about:blank
skip-if(!asyncPan) != pull-background-displayport-3.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515
skip-if(!asyncPan) != pull-background-displayport-4.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515
skip-if(!asyncPan) != pull-background-displayport-5.html about:blank
fails skip-if(!asyncPan) != pull-background-displayport-5.html about:blank # bug 1147673
skip-if(!asyncPan) != pull-background-displayport-6.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515
fuzzy(2,30150) == opacity-blending.html opacity-blending-ref.html

View File

@ -58,5 +58,5 @@ skip-if(B2G||Mulet) == border-separate-opacity-table.html border-separate-opacit
== scrollable-rowgroup-separate-border.html scrollable-rowgroup-separate-notref.html # scrolling rowgroups were removed in bug 28800
== empty-cells-default-1.html empty-cells-default-1-ref.html
== empty-cells-default-2.html empty-cells-default-2-ref.html
fuzzy-if(OSX,1,113) fuzzy-if(winWidget,1,12) fuzzy-if(Android,1,39) fuzzy-if(winWidget&&!layersGPUAccelerated,82,116) == table-row-opacity-dynamic-1.html table-row-opacity-dynamic-1-ref.html
fuzzy-if(OSX,1,113) fuzzy-if(winWidget,1,12) fuzzy-if(Android,1,39) == table-row-opacity-dynamic-1.html table-row-opacity-dynamic-1-ref.html
== table-row-opacity-dynamic-2.html table-row-opacity-dynamic-2-ref.html