Backed out 7 changesets (bug 1440177) for crashtest (on 1359658-1.html) and reftest failures

Backed out changeset f359ad5c4fc3 (bug 1440177)
Backed out changeset d63c5a6c13ae (bug 1440177)
Backed out changeset d22462ac7ee1 (bug 1440177)
Backed out changeset b7e46c4c7dc1 (bug 1440177)
Backed out changeset f92987184172 (bug 1440177)
Backed out changeset e6808a7dda3e (bug 1440177)
Backed out changeset ce353b632a31 (bug 1440177)
This commit is contained in:
Narcis Beleuzu 2018-03-01 06:21:43 +02:00
parent a2e576c75c
commit 6be3b8b032
5 changed files with 299 additions and 242 deletions

View File

@ -410,7 +410,7 @@ DisplayItemClip::AppendRoundedRects(nsTArray<RoundedRect>* aArray, uint32_t aCou
}
bool
DisplayItemClip::ComputeRegionInClips(const DisplayItemClip* aOldClip,
DisplayItemClip::ComputeRegionInClips(DisplayItemClip* aOldClip,
const nsPoint& aShift,
nsRegion* aCombined) const
{

View File

@ -121,7 +121,7 @@ public:
* The result is stored in aCombined. If the result would be infinite
* (because one or both of the clips does no clipping), returns false.
*/
bool ComputeRegionInClips(const DisplayItemClip* aOldClip,
bool ComputeRegionInClips(DisplayItemClip* aOldClip,
const nsPoint& aShift,
nsRegion* aCombined) const;

View File

@ -117,6 +117,23 @@ static inline MaskLayerImageCache* GetMaskLayerImageCache()
return gMaskLayerImageCache;
}
FrameLayerBuilder::FrameLayerBuilder()
: mRetainingManager(nullptr)
, mContainingPaintedLayer(nullptr)
, mInactiveLayerClip(nullptr)
, mInvalidateAllLayers(false)
, mInLayerTreeCompressionMode(false)
, mIsInactiveLayerManager(false)
{
MOZ_COUNT_CTOR(FrameLayerBuilder);
}
FrameLayerBuilder::~FrameLayerBuilder()
{
GetMaskLayerImageCache()->Sweep();
MOZ_COUNT_DTOR(FrameLayerBuilder);
}
DisplayItemData::DisplayItemData(LayerManagerData* aParent, uint32_t aKey,
Layer* aLayer, nsIFrame* aFrame)
@ -196,16 +213,6 @@ DisplayItemData::EndUpdate(nsAutoPtr<nsDisplayItemGeometry> aGeometry)
void
DisplayItemData::BeginUpdate(Layer* aLayer, LayerState aState,
nsDisplayItem* aItem /* = nullptr */)
{
BeginUpdate(aLayer, aState, aItem,
aItem ? aItem->IsReused() : false,
aItem ? aItem->HasMergedFrames() : false);
}
void
DisplayItemData::BeginUpdate(Layer* aLayer, LayerState aState,
nsDisplayItem* aItem, bool aIsReused,
bool aIsMerged)
{
MOZ_RELEASE_ASSERT(mLayer);
MOZ_RELEASE_ASSERT(aLayer);
@ -217,18 +224,13 @@ DisplayItemData::BeginUpdate(Layer* aLayer, LayerState aState,
if (aLayer->AsPaintedLayer()) {
mItem = aItem;
mReusedItem = aIsReused;
mReusedItem = aItem->IsReused();
}
if (!aItem) {
return;
}
if (!aIsMerged && mFrameList.Length() == 1) {
MOZ_ASSERT(mFrameList[0] == aItem->Frame());
return;
}
// We avoid adding or removing element unnecessarily
// since we have to modify userdata each time
AutoTArray<nsIFrame*, 4> copy(mFrameList);
@ -852,6 +854,11 @@ public:
void FinishAllChildren() { FinishAllChildren(true); }
protected:
/**
* Finish the topmost item in mPaintedLayerDataStack and pop it from the
* stack.
*/
void PopPaintedLayerData();
/**
* Finish all items in mPaintedLayerDataStack and clear the stack.
*/
@ -873,7 +880,7 @@ protected:
/**
* Our contents: a PaintedLayerData stack and our child nodes.
*/
AutoTArray<PaintedLayerData, 3> mPaintedLayerDataStack;
nsTArray<PaintedLayerData> mPaintedLayerDataStack;
/**
* UniquePtr is used here in the sense of "unique ownership", i.e. there is
@ -941,7 +948,6 @@ public:
nscolor& aBackgroundColor)
: mContainerState(aContainerState)
, mContainerUniformBackgroundColor(aBackgroundColor)
, mForInactiveLayer(false)
{}
~PaintedLayerDataTree()
@ -950,8 +956,6 @@ public:
MOZ_ASSERT(mNodes.Count() == 0);
}
void InitializeForInactiveLayer(AnimatedGeometryRoot* aAnimatedGeometryRoot);
/**
* Notify our contents that some non-PaintedLayer content has been added.
* *aRect needs to be a rectangle that doesn't move with respect to
@ -1039,7 +1043,7 @@ protected:
AnimatedGeometryRoot** aOutAncestorChild);
ContainerState& mContainerState;
Maybe<PaintedLayerDataNode> mRoot;
UniquePtr<PaintedLayerDataNode> mRoot;
/**
* The uniform opaque color from behind this container layer, or
@ -1054,8 +1058,6 @@ protected:
* geometry root.
*/
nsDataHashtable<nsPtrHashKey<AnimatedGeometryRoot>, PaintedLayerDataNode*> mNodes;
bool mForInactiveLayer;
};
/**
@ -1387,10 +1389,9 @@ protected:
* aRoundedRectClipCount is used when building mask layers for PaintedLayers,
* SetupMaskLayer will build a mask layer for only the first
* aRoundedRectClipCount rounded rects in aClip
* Returns the number of rounded rects included in the mask layer.
*/
uint32_t SetupMaskLayer(Layer *aLayer, const DisplayItemClip& aClip,
uint32_t aRoundedRectClipCount = UINT32_MAX);
void SetupMaskLayer(Layer *aLayer, const DisplayItemClip& aClip,
uint32_t aRoundedRectClipCount = UINT32_MAX);
/**
* If |aClip| has rounded corners, create a mask layer for them, and
@ -1499,15 +1500,12 @@ class PaintedDisplayItemLayerUserData : public LayerUserData
public:
PaintedDisplayItemLayerUserData() :
mMaskClipCount(0),
mLastCommonClipCount(0),
mForcedBackgroundColor(NS_RGBA(0,0,0,0)),
mXScale(1.f), mYScale(1.f),
mAppUnitsPerDevPixel(0),
mTranslation(0, 0),
mAnimatedGeometryRootPosition(0, 0),
mLastItemCount(0),
mContainerLayerFrame(nullptr),
mHasExplicitLastPaintOffset(false) {}
mLastItemCount(0) {}
/**
* Record the number of clips in the PaintedLayer's mask layer.
@ -1516,12 +1514,6 @@ public:
*/
uint32_t mMaskClipCount;
/**
* Records the number of clips in the PaintedLayer's mask layer during
* the previous paint. Used for invalidation.
*/
uint32_t mLastCommonClipCount;
/**
* A color that should be painted over the bounds of the layer's visible
* region before any other content is painted.
@ -1579,45 +1571,12 @@ public:
// The number of items assigned to this layer on the previous paint.
size_t mLastItemCount;
// The translation set on this PaintedLayer before we started updating the
// layer tree.
nsIntPoint mLastPaintOffset;
// Temporary state only valid during the FrameLayerBuilder's lifetime.
// FLB's mPaintedLayerItems is responsible for cleaning these up when
// we finish painting to avoid dangling pointers.
nsTArray<AssignedDisplayItem> mItems;
nsIFrame* mContainerLayerFrame;
bool mHasExplicitLastPaintOffset;
/**
* This is set when the painted layer has no component alpha.
*/
bool mDisabledAlpha;
};
FrameLayerBuilder::FrameLayerBuilder()
: mRetainingManager(nullptr)
, mContainingPaintedLayer(nullptr)
, mInactiveLayerClip(nullptr)
, mInvalidateAllLayers(false)
, mInLayerTreeCompressionMode(false)
, mIsInactiveLayerManager(false)
{
MOZ_COUNT_CTOR(FrameLayerBuilder);
}
FrameLayerBuilder::~FrameLayerBuilder()
{
GetMaskLayerImageCache()->Sweep();
for (PaintedDisplayItemLayerUserData* userData : mPaintedLayerItems) {
userData->mItems.Clear();
userData->mContainerLayerFrame = nullptr;
}
MOZ_COUNT_DTOR(FrameLayerBuilder);
}
/*
* User data for layers which will be used as masks.
*/
@ -2476,9 +2435,7 @@ ContainerState::PreparePaintedLayerForUse(PaintedLayer* aLayer,
aData->mAppUnitsPerDevPixel = mAppUnitsPerDevPixel;
aLayer->SetAllowResidualTranslation(mParameters.AllowResidualTranslation());
aData->mLastPaintOffset = GetTranslationForPaintedLayer(aLayer);
aData->mHasExplicitLastPaintOffset = true;
aData->mLastCommonClipCount = aData->mMaskClipCount;
mLayerBuilder->SavePreviousDataForLayer(aLayer, aData->mMaskClipCount);
// Set up transform so that 0,0 in the PaintedLayer corresponds to the
// (pixel-snapped) top-left of the aAnimatedGeometryRoot.
@ -2910,23 +2867,23 @@ PaintedLayerDataNode::SetAllDrawingAbove()
}
void
PaintedLayerDataNode::PopAllPaintedLayerData()
PaintedLayerDataNode::PopPaintedLayerData()
{
for (int32_t index = mPaintedLayerDataStack.Length() - 1; index >= 0; index--) {
PaintedLayerData& data = mPaintedLayerDataStack[index];
mTree.ContState().FinishPaintedLayerData(data, [this, &data, index]() {
return this->FindOpaqueBackgroundColor(data.mVisibleRegion, index);
});
}
mPaintedLayerDataStack.Clear();
MOZ_ASSERT(!mPaintedLayerDataStack.IsEmpty());
size_t lastIndex = mPaintedLayerDataStack.Length() - 1;
PaintedLayerData& data = mPaintedLayerDataStack[lastIndex];
mTree.ContState().FinishPaintedLayerData(data, [this, &data, lastIndex]() {
return this->FindOpaqueBackgroundColor(data.mVisibleRegion, lastIndex);
});
mPaintedLayerDataStack.RemoveElementAt(lastIndex);
}
void
PaintedLayerDataTree::InitializeForInactiveLayer(AnimatedGeometryRoot* aAnimatedGeometryRoot)
PaintedLayerDataNode::PopAllPaintedLayerData()
{
mForInactiveLayer = true;
mRoot.emplace(*this, nullptr, aAnimatedGeometryRoot);
while (!mPaintedLayerDataStack.IsEmpty()) {
PopPaintedLayerData();
}
}
nsDisplayListBuilder*
@ -2942,7 +2899,7 @@ PaintedLayerDataTree::Finish()
mRoot->Finish(false);
}
MOZ_ASSERT(mNodes.Count() == 0);
mRoot.reset();
mRoot = nullptr;
}
void
@ -2956,13 +2913,8 @@ PaintedLayerDataTree::AddingOwnLayer(AnimatedGeometryRoot* aAnimatedGeometryRoot
const nsIntRect* aRect,
nscolor* aOutUniformBackgroundColor)
{
PaintedLayerDataNode* node = nullptr;
if (mForInactiveLayer) {
node = mRoot.ptr();
} else {
FinishPotentiallyIntersectingNodes(aAnimatedGeometryRoot, aRect);
node = EnsureNodeFor(aAnimatedGeometryRoot);
}
FinishPotentiallyIntersectingNodes(aAnimatedGeometryRoot, aRect);
PaintedLayerDataNode* node = EnsureNodeFor(aAnimatedGeometryRoot);
if (aRect) {
if (aOutUniformBackgroundColor) {
*aOutUniformBackgroundColor = node->FindOpaqueBackgroundColor(*aRect);
@ -2986,13 +2938,8 @@ PaintedLayerDataTree::FindPaintedLayerFor(AnimatedGeometryRoot* aAnimatedGeometr
NewPaintedLayerCallbackType aNewPaintedLayerCallback)
{
const nsIntRect* bounds = &aVisibleRect;
PaintedLayerDataNode* node = nullptr;
if (mForInactiveLayer) {
node = mRoot.ptr();
} else {
FinishPotentiallyIntersectingNodes(aAnimatedGeometryRoot, bounds);
node = EnsureNodeFor(aAnimatedGeometryRoot);
}
FinishPotentiallyIntersectingNodes(aAnimatedGeometryRoot, bounds);
PaintedLayerDataNode* node = EnsureNodeFor(aAnimatedGeometryRoot);
PaintedLayerData* data =
node->FindPaintedLayerFor(aVisibleRect, aBackfaceHidden, aASR, aClipChain,
@ -3061,8 +3008,8 @@ PaintedLayerDataTree::EnsureNodeFor(AnimatedGeometryRoot* aAnimatedGeometryRoot)
if (!parentAnimatedGeometryRoot) {
MOZ_ASSERT(!mRoot);
MOZ_ASSERT(*aAnimatedGeometryRoot == Builder()->RootReferenceFrame());
mRoot.emplace(*this, nullptr, aAnimatedGeometryRoot);
node = mRoot.ptr();
mRoot = MakeUnique<PaintedLayerDataNode>(*this, nullptr, aAnimatedGeometryRoot);
node = mRoot.get();
} else {
PaintedLayerDataNode* parentNode = EnsureNodeFor(parentAnimatedGeometryRoot);
MOZ_ASSERT(parentNode);
@ -3077,9 +3024,6 @@ bool
PaintedLayerDataTree::IsClippedWithRespectToParentAnimatedGeometryRoot(AnimatedGeometryRoot* aAnimatedGeometryRoot,
nsIntRect* aOutClip)
{
if (mForInactiveLayer) {
return false;
}
nsIScrollableFrame* scrollableFrame = nsLayoutUtils::GetScrollableFrameFor(*aAnimatedGeometryRoot);
if (!scrollableFrame) {
return false;
@ -3223,14 +3167,18 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB
MOZ_ASSERT(item.mItem->GetType() != DisplayItemType::TYPE_LAYER_EVENT_REGIONS);
MOZ_ASSERT(item.mItem->GetType() != DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO);
InvalidateForLayerChange(item.mItem, data->mLayer, item.mDisplayItemData);
mLayerBuilder->AddPaintedDisplayItem(data, item, *this,
data->mAnimatedGeometryRootOffset);
item.mDisplayItemData = nullptr;
DisplayItemData* oldData =
mLayerBuilder->GetOldLayerForFrame(item.mItem->Frame(),
item.mItem->GetPerFrameKey(),
item.mItem->HasMergedFrames() ? nullptr : item.mItem->GetDisplayItemData());
InvalidateForLayerChange(item.mItem, data->mLayer, oldData);
mLayerBuilder->AddPaintedDisplayItem(data, item.mItem, item.mClip,
*this, item.mLayerState,
data->mAnimatedGeometryRootOffset,
oldData, item);
}
PaintedDisplayItemLayerUserData* userData = GetPaintedDisplayItemLayerUserData(data->mLayer);
NS_ASSERTION(userData, "where did our user data go?");
userData->mLastItemCount = data->mAssignedDisplayItems.Length();
NewLayerEntry* newLayerEntry = &mNewChildLayers[data->mNewChildLayersIndex];
@ -3306,7 +3254,9 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB
}
#endif
mLayerBuilder->AddPaintedLayerItemsEntry(userData);
FrameLayerBuilder::PaintedLayerItemsEntry* entry = mLayerBuilder->
AddPaintedLayerItemsEntry(static_cast<PaintedLayer*>(layer.get()));
MOZ_ASSERT(entry);
nsIntRegion transparentRegion;
transparentRegion.Sub(data->mVisibleRegion, data->mOpaqueRegion);
@ -3324,6 +3274,9 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB
}
// Store the background color
PaintedDisplayItemLayerUserData* userData =
GetPaintedDisplayItemLayerUserData(data->mLayer);
NS_ASSERTION(userData, "where did our user data go?");
if (userData->mForcedBackgroundColor != backgroundColor) {
// Invalidate the entire target PaintedLayer since we're changing
// the background color
@ -3343,18 +3296,11 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB
// use a mask layer for rounded rect clipping.
// data->mCommonClipCount may be -1 if we haven't put any actual
// drawable items in this layer (i.e. it's only catching events).
uint32_t commonClipCount;
int32_t commonClipCount;
commonClipCount = std::max(0, data->mCommonClipCount);
// if the number of clips we are going to mask has decreased, then aLayer might have
// cached graphics which assume the existence of a soon-to-be non-existent mask layer
// in that case, invalidate the whole layer.
if (commonClipCount < userData->mMaskClipCount) {
PaintedLayer* painted = layer->AsPaintedLayer();
painted->InvalidateWholeLayer();
}
userData->mMaskClipCount = SetupMaskLayer(layer, data->mItemClip, commonClipCount);
SetupMaskLayer(layer, data->mItemClip, commonClipCount);
// copy commonClipCount to the entry
entry->mCommonClipCount = commonClipCount;
} else {
// mask layer for image and color layers
SetupMaskLayer(layer, data->mItemClip);
@ -3377,8 +3323,8 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB
}
layer->SetContentFlags(flags);
userData->mItems = Move(data->mAssignedDisplayItems);
userData->mContainerLayerFrame = GetContainerFrame();
entry->mItems = Move(data->mAssignedDisplayItems);
entry->mContainerLayerFrame = GetContainerFrame();
PaintedLayerData* containingPaintedLayerData =
mLayerBuilder->GetContainingPaintedLayerData();
@ -3526,11 +3472,7 @@ PaintedLayerData::Accumulate(ContainerState* aState,
bool clipMatches = mItemClip == aClip;
mItemClip = aClip;
DisplayItemData* oldData =
aState->mLayerBuilder->GetOldLayerForFrame(aItem->Frame(),
aItem->GetPerFrameKey(),
aItem->HasMergedFrames() ? nullptr : aItem->GetDisplayItemData());
mAssignedDisplayItems.AppendElement(AssignedDisplayItem(aItem, aClip, aLayerState, oldData));
mAssignedDisplayItems.AppendElement(AssignedDisplayItem(aItem, aClip, aLayerState));
if (aItem->MustPaintOnContentSide()) {
mShouldPaintOnContentSide = true;
@ -4141,10 +4083,6 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
bool hadCompositorHitTestInfo = false;
#endif
if (!mManager->IsWidgetLayerManager()) {
mPaintedLayerDataTree.InitializeForInactiveLayer(mContainerAnimatedGeometryRoot);
}
AnimatedGeometryRoot* lastAnimatedGeometryRoot = nullptr;
nsPoint lastTopLeft;
FlattenedDisplayItemIterator iter(mBuilder, aList);
@ -4638,11 +4576,9 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
* No need to allocate geometry for items that aren't
* part of a PaintedLayer.
*/
if (ownLayer->Manager() == mLayerBuilder->GetRetainingLayerManager()) {
oldData =
mLayerBuilder->GetOldLayerForFrame(item->Frame(), item->GetPerFrameKey());
mLayerBuilder->StoreDataForFrame(item, ownLayer, layerState, oldData);
}
oldData =
mLayerBuilder->GetOldLayerForFrame(item->Frame(), item->GetPerFrameKey());
mLayerBuilder->AddLayerDisplayItem(ownLayer, item, layerState, nullptr, oldData);
} else {
const bool backfaceHidden = item->In3DContextAndBackfaceIsHidden();
const nsIFrame* referenceFrame = item->ReferenceFrame();
@ -4798,9 +4734,10 @@ FrameLayerBuilder::ComputeGeometryChangeForItem(DisplayItemData* aData)
if (!combined.IsEmpty() || aData->mLayerState == LAYER_INACTIVE) {
geometry = item->AllocateGeometry(mDisplayListBuilder);
}
aData->mClip.AddOffsetAndComputeDifference(layerData->mMaskClipCount,
PaintedLayerItemsEntry* entry = mPaintedLayerItems.GetEntry(paintedLayer);
aData->mClip.AddOffsetAndComputeDifference(entry->mCommonClipCount,
shift, aData->mGeometry->ComputeInvalidationRegion(),
clip, layerData->mLastCommonClipCount,
clip, entry->mLastCommonClipCount,
geometry ? geometry->ComputeInvalidationRegion() :
aData->mGeometry->ComputeInvalidationRegion(),
&combined);
@ -4833,9 +4770,13 @@ FrameLayerBuilder::ComputeGeometryChangeForItem(DisplayItemData* aData)
void
FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
AssignedDisplayItem& aItem,
ContainerState& aContainerState,
const nsPoint& aTopLeft)
nsDisplayItem* aItem,
const DisplayItemClip& aClip,
ContainerState& aContainerState,
LayerState aLayerState,
const nsPoint& aTopLeft,
DisplayItemData* aData,
AssignedDisplayItem& aAssignedDisplayItem)
{
PaintedLayer* layer = aLayerData->mLayer;
PaintedDisplayItemLayerUserData* paintedData =
@ -4844,42 +4785,37 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
RefPtr<BasicLayerManager> tempManager;
nsIntRect intClip;
bool hasClip = false;
if (aItem.mLayerState != LAYER_NONE) {
if (aItem.mDisplayItemData) {
tempManager = aItem.mDisplayItemData->mInactiveManager;
// We need to grab these before updating the DisplayItemData because it will overwrite them.
nsRegion clip;
if (aItem.mClip.ComputeRegionInClips(&aItem.mDisplayItemData->GetClip(),
aTopLeft - paintedData->mLastAnimatedGeometryRootOrigin,
&clip)) {
intClip = clip.GetBounds().ScaleToOutsidePixels(paintedData->mXScale,
paintedData->mYScale,
paintedData->mAppUnitsPerDevPixel);
}
if (aLayerState != LAYER_NONE) {
DisplayItemData *data = GetDisplayItemDataForManager(aItem, layer->Manager());
if (data) {
tempManager = data->mInactiveManager;
}
if (!tempManager) {
tempManager = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
}
// We need to grab these before calling AddLayerDisplayItem because it will overwrite them.
nsRegion clip;
DisplayItemClip* oldClip = nullptr;
GetOldLayerFor(aItem, nullptr, &oldClip);
hasClip = aClip.ComputeRegionInClips(oldClip,
aTopLeft - paintedData->mLastAnimatedGeometryRootOrigin,
&clip);
if (hasClip) {
intClip = clip.GetBounds().ScaleToOutsidePixels(paintedData->mXScale,
paintedData->mYScale,
paintedData->mAppUnitsPerDevPixel);
}
}
if (layer->Manager() == mRetainingManager) {
DisplayItemData *data = aItem.mDisplayItemData;
if (data) {
if (!data->mUsed) {
data->BeginUpdate(layer, aItem.mLayerState, aItem.mItem, aItem.mReused, aItem.mMerged);
}
} else {
data = StoreDataForFrame(aItem.mItem, layer, aItem.mLayerState, nullptr);
}
data->mInactiveManager = tempManager;
}
AddLayerDisplayItem(layer, aItem, aLayerState, tempManager, aData);
if (tempManager) {
FLB_LOG_PAINTED_LAYER_DECISION(aLayerData, "Creating nested FLB for item %p\n", aItem.mItem);
FLB_LOG_PAINTED_LAYER_DECISION(aLayerData, "Creating nested FLB for item %p\n", aItem);
FrameLayerBuilder* layerBuilder = new FrameLayerBuilder();
layerBuilder->Init(mDisplayListBuilder, tempManager, aLayerData, true,
&aItem.mClip);
&aClip);
tempManager->BeginTransaction();
if (mRetainingManager) {
@ -4888,24 +4824,24 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
UniquePtr<LayerProperties> props(LayerProperties::CloneFrom(tempManager->GetRoot()));
RefPtr<Layer> tmpLayer =
aItem.mItem->BuildLayer(mDisplayListBuilder, tempManager, ContainerLayerParameters());
aItem->BuildLayer(mDisplayListBuilder, tempManager, ContainerLayerParameters());
// We have no easy way of detecting if this transaction will ever actually get finished.
// For now, I've just silenced the warning with nested transactions in BasicLayers.cpp
if (!tmpLayer) {
tempManager->EndTransaction(nullptr, nullptr);
tempManager->SetUserData(&gLayerManagerLayerBuilder, nullptr);
aItem.mItem = nullptr;
aAssignedDisplayItem.mItem = nullptr;
return;
}
bool snap;
nsRect visibleRect =
aItem.mItem->GetVisibleRect().Intersect(aItem.mItem->GetBounds(mDisplayListBuilder, &snap));
aItem->GetVisibleRect().Intersect(aItem->GetBounds(mDisplayListBuilder, &snap));
nsIntRegion rgn = visibleRect.ToOutsidePixels(paintedData->mAppUnitsPerDevPixel);
// Convert the visible rect to a region and give the item
// a chance to try restrict it further.
nsRegion tightBounds = aItem.mItem->GetTightBounds(mDisplayListBuilder, &snap);
nsRegion tightBounds = aItem->GetTightBounds(mDisplayListBuilder, &snap);
if (!tightBounds.IsEmpty()) {
rgn.AndWith(tightBounds.ToOutsidePixels(paintedData->mAppUnitsPerDevPixel));
}
@ -4921,8 +4857,8 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
(tempManager->GetUserData(&gLayerManagerUserData));
lmd->mParent = parentLmd;
#endif
DisplayItemData* data = layerBuilder->GetDisplayItemDataForManager(aItem.mItem, tempManager);
layerBuilder->StoreDataForFrame(aItem.mItem, tmpLayer, LAYER_ACTIVE, data);
DisplayItemData* data = layerBuilder->GetDisplayItemDataForManager(aItem, tempManager);
layerBuilder->StoreDataForFrame(aItem, tmpLayer, LAYER_ACTIVE, data);
}
tempManager->SetRoot(tmpLayer);
@ -4931,7 +4867,7 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
#ifdef MOZ_DUMP_PAINTING
if (gfxUtils::DumpDisplayList() || gfxEnv::DumpPaint()) {
fprintf_stderr(gfxUtils::sDumpPaintFile, "Basic layer tree for painting contents of display item %s(%p):\n", aItem.mItem->Name(), aItem.mItem->Frame());
fprintf_stderr(gfxUtils::sDumpPaintFile, "Basic layer tree for painting contents of display item %s(%p):\n", aItem->Name(), aItem->Frame());
std::stringstream stream;
tempManager->Dump(stream, "", gfxEnv::DumpPaintToFile());
fprint_stderr(gfxUtils::sDumpPaintFile, stream); // not a typo, fprint_stderr declared in LayersLogging.h
@ -4944,18 +4880,18 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
tmpLayer->ComputeEffectiveTransforms(Matrix4x4());
nsIntRegion invalid;
if (!props->ComputeDifferences(tmpLayer, invalid, nullptr)) {
nsRect visible = aItem.mItem->Frame()->GetVisualOverflowRect();
nsRect visible = aItem->Frame()->GetVisualOverflowRect();
invalid = visible.ToOutsidePixels(paintedData->mAppUnitsPerDevPixel);
}
if (aItem.mLayerState == LAYER_SVG_EFFECTS) {
invalid = nsSVGIntegrationUtils::AdjustInvalidAreaForSVGEffects(aItem.mItem->Frame(),
aItem.mItem->ToReferenceFrame(),
if (aLayerState == LAYER_SVG_EFFECTS) {
invalid = nsSVGIntegrationUtils::AdjustInvalidAreaForSVGEffects(aItem->Frame(),
aItem->ToReferenceFrame(),
invalid);
}
if (!invalid.IsEmpty()) {
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
printf_stderr("Inactive LayerManager(%p) for display item %s(%p) has an invalid region - invalidating layer %p\n", tempManager.get(), aItem.mItem->Name(), aItem.mItem->Frame(), layer);
printf_stderr("Inactive LayerManager(%p) for display item %s(%p) has an invalid region - invalidating layer %p\n", tempManager.get(), aItem->Name(), aItem->Frame(), layer);
}
#endif
invalid.ScaleRoundOut(paintedData->mXScale, paintedData->mYScale);
@ -4968,7 +4904,7 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
GetTranslationForPaintedLayer(layer));
}
}
aItem.mInactiveLayerManager = tempManager;
aAssignedDisplayItem.mInactiveLayerManager = tempManager;
}
DisplayItemData*
@ -5021,18 +4957,6 @@ FrameLayerBuilder::StoreDataForFrame(nsIFrame* aFrame,
lmd->mDisplayItems.PutEntry(data);
}
AssignedDisplayItem::AssignedDisplayItem(nsDisplayItem* aItem,
const DisplayItemClip& aClip,
LayerState aLayerState,
DisplayItemData* aData)
: mItem(aItem)
, mClip(aClip)
, mLayerState(aLayerState)
, mDisplayItemData(aData)
, mReused(aItem->IsReused())
, mMerged(aItem->HasMergedFrames())
{}
AssignedDisplayItem::~AssignedDisplayItem()
{
if (mInactiveLayerManager) {
@ -5040,17 +4964,62 @@ AssignedDisplayItem::~AssignedDisplayItem()
}
}
FrameLayerBuilder::PaintedLayerItemsEntry::PaintedLayerItemsEntry(const PaintedLayer *aKey)
: nsPtrHashKey<PaintedLayer>(aKey)
, mContainerLayerFrame(nullptr)
, mLastCommonClipCount(0)
, mHasExplicitLastPaintOffset(false)
, mCommonClipCount(0)
{
}
FrameLayerBuilder::PaintedLayerItemsEntry::PaintedLayerItemsEntry(const PaintedLayerItemsEntry& aOther)
: nsPtrHashKey<PaintedLayer>(aOther.mKey)
, mItems(aOther.mItems)
{
NS_ERROR("Should never be called, since we ALLOW_MEMMOVE");
}
FrameLayerBuilder::PaintedLayerItemsEntry::~PaintedLayerItemsEntry()
{
}
void
FrameLayerBuilder::AddLayerDisplayItem(Layer* aLayer,
nsDisplayItem* aItem,
LayerState aLayerState,
BasicLayerManager* aManager,
DisplayItemData* aData)
{
if (aLayer->Manager() != mRetainingManager)
return;
DisplayItemData *data = StoreDataForFrame(aItem, aLayer, aLayerState, aData);
data->mInactiveManager = aManager;
}
nsIntPoint
FrameLayerBuilder::GetLastPaintOffset(PaintedLayer* aLayer)
{
PaintedDisplayItemLayerUserData* layerData = GetPaintedDisplayItemLayerUserData(aLayer);
MOZ_ASSERT(layerData);
if (layerData->mHasExplicitLastPaintOffset) {
return layerData->mLastPaintOffset;
PaintedLayerItemsEntry* entry = mPaintedLayerItems.PutEntry(aLayer);
if (entry) {
if (entry->mHasExplicitLastPaintOffset)
return entry->mLastPaintOffset;
}
return GetTranslationForPaintedLayer(aLayer);
}
void
FrameLayerBuilder::SavePreviousDataForLayer(PaintedLayer* aLayer, uint32_t aClipCount)
{
PaintedLayerItemsEntry* entry = mPaintedLayerItems.PutEntry(aLayer);
if (entry) {
entry->mLastPaintOffset = GetTranslationForPaintedLayer(aLayer);
entry->mHasExplicitLastPaintOffset = true;
entry->mLastCommonClipCount = aClipCount;
}
}
bool
FrameLayerBuilder::CheckInLayerTreeCompressionMode()
{
@ -5518,6 +5487,7 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
const Matrix4x4* aTransform,
const ContainerLayerParameters& aIncomingScale,
ContainerLayer* aLayer,
LayerState aState,
ContainerLayerParameters& aOutgoingScale)
{
nsIntPoint offset;
@ -5536,7 +5506,7 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
}
Matrix transform2d;
if (aContainerFrame &&
aLayerBuilder->GetContainingPaintedLayerData() &&
(aState == LAYER_INACTIVE || aState == LAYER_SVG_EFFECTS) &&
(!aTransform || (aTransform->Is2D(&transform2d) &&
!transform2d.HasNonTranslation()))) {
// When we have an inactive ContainerLayer, translate the container by the offset to the
@ -5717,7 +5687,13 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
return nullptr;
}
if (aContainerItem && aContainerItem->GetType() == DisplayItemType::TYPE_SCROLL_INFO_LAYER) {
LayerState layerState = aContainerItem ? aContainerItem->GetLayerState(aBuilder, aManager, aParameters) : LAYER_ACTIVE;
if (layerState == LAYER_INACTIVE &&
nsDisplayItem::ForceActiveLayers()) {
layerState = LAYER_ACTIVE;
}
if (aContainerItem && layerState == LAYER_ACTIVE_EMPTY) {
// Empty layers only have metadata and should never have display items. We
// early exit because later, invalidation will walk up the frame tree to
// determine which painted layer gets invalidated. Since an empty layer
@ -5745,7 +5721,7 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
aContainerItem,
bounds.Intersect(childrenVisible),
aTransform, aParameters,
containerLayer, scaleParameters)) {
containerLayer, layerState, scaleParameters)) {
return nullptr;
}
@ -6166,13 +6142,17 @@ FrameLayerBuilder::DrawPaintedLayer(PaintedLayer* aLayer,
FrameLayerBuilder *layerBuilder = aLayer->Manager()->GetLayerBuilder();
NS_ASSERTION(layerBuilder, "Unexpectedly null layer builder!");
PaintedLayerItemsEntry* entry = layerBuilder->mPaintedLayerItems.GetEntry(aLayer);
NS_ASSERTION(entry, "We shouldn't be drawing into a layer with no items!");
if (!entry->mContainerLayerFrame) {
return;
}
PaintedDisplayItemLayerUserData* userData =
static_cast<PaintedDisplayItemLayerUserData*>
(aLayer->GetUserData(&gPaintedDisplayItemLayerUserData));
NS_ASSERTION(userData, "where did our user data go?");
if (!userData->mContainerLayerFrame) {
return;
}
bool shouldDrawRectsSeparately =
ShouldDrawRectsSeparately(&aDrawTarget, aClip);
@ -6190,7 +6170,7 @@ FrameLayerBuilder::DrawPaintedLayer(PaintedLayer* aLayer,
// PaintedLayer
gfxContextMatrixAutoSaveRestore saveMatrix(aContext);
nsIntPoint offset = GetTranslationForPaintedLayer(aLayer);
nsPresContext* presContext = userData->mContainerLayerFrame->PresContext();
nsPresContext* presContext = entry->mContainerLayerFrame->PresContext();
if (!userData->mVisibilityComputedRegion.Contains(aDirtyRegion) &&
!layerBuilder->GetContainingPaintedLayerData()) {
@ -6200,7 +6180,7 @@ FrameLayerBuilder::DrawPaintedLayer(PaintedLayer* aLayer,
// PaintedLayers. If aDirtyRegion has not changed since the previous call
// then we can skip this.
int32_t appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
RecomputeVisibilityForItems(userData->mItems, builder, aDirtyRegion,
RecomputeVisibilityForItems(entry->mItems, builder, aDirtyRegion,
offset, appUnitsPerDevPixel,
userData->mXScale, userData->mYScale);
userData->mVisibilityComputedRegion = aDirtyRegion;
@ -6224,10 +6204,10 @@ FrameLayerBuilder::DrawPaintedLayer(PaintedLayer* aLayer,
aContext->CurrentMatrixDouble().PreTranslate(aLayer->GetResidualTranslation() - gfxPoint(offset.x, offset.y)).
PreScale(userData->mXScale, userData->mYScale));
layerBuilder->PaintItems(userData->mItems, iterRect, aContext,
layerBuilder->PaintItems(entry->mItems, iterRect, aContext,
builder, presContext,
offset, userData->mXScale, userData->mYScale,
userData->mMaskClipCount);
entry->mCommonClipCount);
if (gfxPrefs::GfxLoggingPaintedPixelCountEnabled()) {
aLayer->Manager()->AddPaintedPixelCount(iterRect.Area());
}
@ -6240,10 +6220,10 @@ FrameLayerBuilder::DrawPaintedLayer(PaintedLayer* aLayer,
aContext->CurrentMatrixDouble().PreTranslate(aLayer->GetResidualTranslation() - gfxPoint(offset.x, offset.y)).
PreScale(userData->mXScale,userData->mYScale));
layerBuilder->PaintItems(userData->mItems, aRegionToDraw.GetBounds(), aContext,
layerBuilder->PaintItems(entry->mItems, aRegionToDraw.GetBounds(), aContext,
builder, presContext,
offset, userData->mXScale, userData->mYScale,
userData->mMaskClipCount);
entry->mCommonClipCount);
if (gfxPrefs::GfxLoggingPaintedPixelCountEnabled()) {
aLayer->Manager()->AddPaintedPixelCount(
aRegionToDraw.GetBounds().Area());
@ -6320,26 +6300,47 @@ CalculateBounds(const nsTArray<DisplayItemClip::RoundedRect>& aRects, int32_t aA
return gfx::Rect(bounds.ToNearestPixels(aAppUnitsPerDevPixel));
}
uint32_t
static void
SetClipCount(PaintedDisplayItemLayerUserData* apaintedData,
uint32_t aClipCount)
{
if (apaintedData) {
apaintedData->mMaskClipCount = aClipCount;
}
}
void
ContainerState::SetupMaskLayer(Layer *aLayer,
const DisplayItemClip& aClip,
uint32_t aRoundedRectClipCount)
{
// if the number of clips we are going to mask has decreased, then aLayer might have
// cached graphics which assume the existence of a soon-to-be non-existent mask layer
// in that case, invalidate the whole layer.
PaintedDisplayItemLayerUserData* paintedData = GetPaintedDisplayItemLayerUserData(aLayer);
if (paintedData &&
aRoundedRectClipCount < paintedData->mMaskClipCount) {
PaintedLayer* painted = aLayer->AsPaintedLayer();
painted->InvalidateWholeLayer();
}
// don't build an unnecessary mask
if (aClip.GetRoundedRectCount() == 0 ||
aRoundedRectClipCount == 0) {
return 0;
SetClipCount(paintedData, 0);
return;
}
RefPtr<Layer> maskLayer =
CreateMaskLayer(aLayer, aClip, Nothing(), aRoundedRectClipCount);
if (!maskLayer) {
return 0;
SetClipCount(paintedData, 0);
return;
}
aLayer->SetMaskLayer(maskLayer);
return aRoundedRectClipCount;
SetClipCount(paintedData, aRoundedRectClipCount);
}
MaskLayerUserData*

View File

@ -43,7 +43,6 @@ class FrameLayerBuilder;
class LayerManagerData;
class PaintedLayerData;
class ContainerState;
class PaintedDisplayItemLayerUserData;
/**
* Retained data storage:
@ -69,7 +68,6 @@ public:
uint32_t GetDisplayItemKey() { return mDisplayItemKey; }
layers::Layer* GetLayer() const { return mLayer; }
nsDisplayItemGeometry* GetGeometry() const { return mGeometry.get(); }
const DisplayItemClip& GetClip() const { return mClip; }
void Invalidate() { mIsInvalid = true; }
void ClearAnimationCompositorState();
@ -156,8 +154,6 @@ private:
*/
void BeginUpdate(layers::Layer* aLayer, LayerState aState,
nsDisplayItem* aItem = nullptr);
void BeginUpdate(layers::Layer* aLayer, LayerState aState,
nsDisplayItem* aItem, bool aIsReused, bool aIsMerged);
/**
* Completes the update of this, and removes any references to data that won't live
@ -214,14 +210,17 @@ struct AssignedDisplayItem
{
AssignedDisplayItem(nsDisplayItem* aItem,
const DisplayItemClip& aClip,
LayerState aLayerState,
DisplayItemData* aData);
LayerState aLayerState)
: mItem(aItem)
, mClip(aClip)
, mLayerState(aLayerState)
{}
~AssignedDisplayItem();
nsDisplayItem* mItem;
DisplayItemClip mClip;
LayerState mLayerState;
DisplayItemData* mDisplayItemData;
/**
* If the display item is being rendered as an inactive
@ -229,9 +228,6 @@ struct AssignedDisplayItem
* used for the inactive transaction.
*/
RefPtr<layers::LayerManager> mInactiveLayerManager;
bool mReused;
bool mMerged;
};
@ -503,6 +499,21 @@ public:
* to be called by file-scope helper functions in FrameLayerBuilder.cpp.
*/
/**
* Record aItem as a display item that is rendered by aLayer.
*
* @param aLayer Layer that the display item will be rendered into
* @param aItem Display item to be drawn.
* @param aLayerState What LayerState the item is using.
* @param aManager If the layer is in the LAYER_INACTIVE state,
* then this is the temporary layer manager to draw with.
*/
void AddLayerDisplayItem(Layer* aLayer,
nsDisplayItem* aItem,
LayerState aLayerState,
BasicLayerManager* aManager,
DisplayItemData* aData);
/**
* Record aItem as a display item that is rendered by the PaintedLayer
* aLayer, with aClipRect, where aContainerLayerFrame is the frame
@ -511,9 +522,13 @@ public:
* @param aTopLeft offset from active scrolled root to reference frame
*/
void AddPaintedDisplayItem(PaintedLayerData* aLayer,
AssignedDisplayItem& aAssignedDisplayItem,
ContainerState& aContainerState,
const nsPoint& aTopLeft);
nsDisplayItem* aItem,
const DisplayItemClip& aClip,
ContainerState& aContainerState,
LayerState aLayerState,
const nsPoint& aTopLeft,
DisplayItemData* aData,
AssignedDisplayItem& aAssignedDisplayItem);
/**
* Calls GetOldLayerForFrame on the underlying frame of the display item,
@ -574,6 +589,12 @@ public:
typedef void (*DisplayItemDataCallback)(nsIFrame *aFrame, DisplayItemData* aItem);
/**
* Save transform that was in aLayer when we last painted, and the position
* of the active scrolled root frame. It must be an integer
* translation.
*/
void SavePreviousDataForLayer(PaintedLayer* aLayer, uint32_t aClipCount);
/**
* Get the translation transform that was in aLayer when we last painted. It's either
* the transform saved by SaveLastPaintTransform, or else the transform
@ -610,6 +631,10 @@ public:
*/
DisplayItemData* GetOldLayerForFrame(nsIFrame* aFrame, uint32_t aDisplayItemKey, DisplayItemData* aOldData = nullptr);
protected:
friend class LayerManagerData;
/**
* Stores DisplayItemData associated with aFrame, stores the data in
* mNewDisplayItemData.
@ -621,9 +646,6 @@ public:
Layer* aLayer,
LayerState aState);
protected:
friend class LayerManagerData;
// Flash the area within the context clip if paint flashing is enabled.
static void FlashPaint(gfxContext *aContext);
@ -682,13 +704,36 @@ protected:
* the paint process. This is the hashentry for that hashtable.
*/
public:
class PaintedLayerItemsEntry : public nsPtrHashKey<PaintedLayer> {
public:
explicit PaintedLayerItemsEntry(const PaintedLayer *key);
PaintedLayerItemsEntry(const PaintedLayerItemsEntry&);
~PaintedLayerItemsEntry();
nsTArray<AssignedDisplayItem> mItems;
nsIFrame* mContainerLayerFrame;
// The translation set on this PaintedLayer before we started updating the
// layer tree.
nsIntPoint mLastPaintOffset;
uint32_t mLastCommonClipCount;
bool mHasExplicitLastPaintOffset;
/**
* The first mCommonClipCount rounded rectangle clips are identical for
* all items in the layer. Computed in PaintedLayerData.
*/
uint32_t mCommonClipCount;
enum { ALLOW_MEMMOVE = true };
};
/**
* Add the PaintedDisplayItemLayerUserData object as being used in this
* transaction so that we clean it up afterwards.
* Get the PaintedLayerItemsEntry object associated with aLayer in this
* FrameLayerBuilder
*/
void AddPaintedLayerItemsEntry(PaintedDisplayItemLayerUserData* aData)
PaintedLayerItemsEntry* AddPaintedLayerItemsEntry(PaintedLayer* aLayer)
{
mPaintedLayerItems.AppendElement(aData);
return mPaintedLayerItems.PutEntry(aLayer);
}
PaintedLayerData* GetContainingPaintedLayerData()
@ -731,12 +776,10 @@ protected:
*/
nsDisplayListBuilder* mDisplayListBuilder;
/**
* An array of PaintedLayer user data objects containing the
* list of display items (plus clipping data) to be rendered in the
* layer. We clean these up at the end of the transaction to
* remove references to display items.
* A map from PaintedLayers to the list of display items (plus
* clipping data) to be rendered in the layer.
*/
AutoTArray<PaintedDisplayItemLayerUserData*, 5> mPaintedLayerItems;
nsTHashtable<PaintedLayerItemsEntry> mPaintedLayerItems;
/**
* When building layers for an inactive layer, this is where the

View File

@ -3295,7 +3295,7 @@ nsDisplayItem::IntersectClip(nsDisplayListBuilder* aBuilder,
const DisplayItemClipChain* aOther,
bool aStore)
{
if (!aOther || mClipChain == aOther) {
if (!aOther) {
return;
}
@ -6712,8 +6712,21 @@ nsDisplayOpacity::ShouldFlattenAway(nsDisplayListBuilder* aBuilder)
}
}
// When intersecting the children's clip, only intersect with the clip for
// our ASR and not with the whole clip chain, because the rest of the clip
// chain is usually already set on the children. In fact, opacity items
// usually never have their own clip because during display item creation
// time we propagated the clip to our contents, so maybe we should just
// remove the clip parameter from ApplyOpacity completely.
const DisplayItemClipChain* clip = nullptr;
if (mClip) {
clip = aBuilder->AllocateDisplayItemClipChain(*mClip, mActiveScrolledRoot,
nullptr);
}
for (uint32_t i = 0; i < childCount; i++) {
children[i].item->ApplyOpacity(aBuilder, mOpacity, mClipChain);
children[i].item->ApplyOpacity(aBuilder, mOpacity, clip);
}
return true;