mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-26 04:09:50 +00:00
Bug 880031 - Make animated transforms force all above content to be in a separate ThebesLayer. r=roc
This commit is contained in:
parent
c1aa7dd3e7
commit
4984e7db61
@ -329,7 +329,8 @@ protected:
|
||||
mNeedComponentAlpha(false),
|
||||
mForceTransparentSurface(false),
|
||||
mImage(nullptr),
|
||||
mCommonClipCount(-1) {}
|
||||
mCommonClipCount(-1),
|
||||
mAllDrawingAbove(false) {}
|
||||
/**
|
||||
* Record that an item has been added to the ThebesLayer, so we
|
||||
* need to update our regions.
|
||||
@ -357,20 +358,67 @@ protected:
|
||||
*/
|
||||
already_AddRefed<ImageContainer> CanOptimizeImageLayer(nsDisplayListBuilder* aBuilder);
|
||||
|
||||
void AddDrawAboveRegion(const nsIntRegion& aAbove)
|
||||
{
|
||||
if (!mAllDrawingAbove) {
|
||||
mDrawAboveRegion.Or(mDrawAboveRegion, aAbove);
|
||||
mDrawAboveRegion.SimplifyOutward(4);
|
||||
}
|
||||
}
|
||||
|
||||
void AddVisibleAboveRegion(const nsIntRegion& aAbove)
|
||||
{
|
||||
if (!mAllDrawingAbove) {
|
||||
mVisibleAboveRegion.Or(mVisibleAboveRegion, aAbove);
|
||||
mVisibleAboveRegion.SimplifyOutward(4);
|
||||
}
|
||||
}
|
||||
|
||||
void CopyAboveRegion(ThebesLayerData* aOther)
|
||||
{
|
||||
if (aOther->mAllDrawingAbove || mAllDrawingAbove) {
|
||||
SetAllDrawingAbove();
|
||||
} else {
|
||||
mVisibleAboveRegion.Or(mVisibleAboveRegion, aOther->mVisibleAboveRegion);
|
||||
mVisibleAboveRegion.Or(mVisibleAboveRegion, aOther->mVisibleRegion);
|
||||
mVisibleAboveRegion.SimplifyOutward(4);
|
||||
mDrawAboveRegion.Or(mDrawAboveRegion, aOther->mDrawAboveRegion);
|
||||
mDrawAboveRegion.Or(mDrawAboveRegion, aOther->mDrawRegion);
|
||||
mDrawAboveRegion.SimplifyOutward(4);
|
||||
}
|
||||
}
|
||||
|
||||
void SetAllDrawingAbove()
|
||||
{
|
||||
mAllDrawingAbove = true;
|
||||
mDrawAboveRegion.SetEmpty();
|
||||
mVisibleAboveRegion.SetEmpty();
|
||||
}
|
||||
|
||||
bool IsBelow(const nsIntRect& aRect)
|
||||
{
|
||||
return mAllDrawingAbove || mDrawAboveRegion.Intersects(aRect);
|
||||
}
|
||||
|
||||
bool IntersectsVisibleAboveRegion(const nsIntRegion& aVisibleRegion)
|
||||
{
|
||||
if (mAllDrawingAbove) {
|
||||
return true;
|
||||
}
|
||||
nsIntRegion visibleAboveIntersection;
|
||||
visibleAboveIntersection.And(mVisibleAboveRegion, aVisibleRegion);
|
||||
if (visibleAboveIntersection.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The region of visible content in the layer, relative to the
|
||||
* container layer (which is at the snapped top-left of the display
|
||||
* list reference frame).
|
||||
*/
|
||||
nsIntRegion mVisibleRegion;
|
||||
/**
|
||||
* The region of visible content above the layer and below the
|
||||
* next ThebesLayerData currently in the stack, if any. Note that not
|
||||
* all ThebesLayers for the container are in the ThebesLayerData stack.
|
||||
* Same coordinate system as mVisibleRegion.
|
||||
* This is a conservative approximation: it contains the true region.
|
||||
*/
|
||||
nsIntRegion mVisibleAboveRegion;
|
||||
/**
|
||||
* The region containing the bounds of all display items in the layer,
|
||||
* regardless of visbility.
|
||||
@ -378,15 +426,6 @@ protected:
|
||||
* This is a conservative approximation: it contains the true region.
|
||||
*/
|
||||
nsIntRegion mDrawRegion;
|
||||
/**
|
||||
* The region containing the bounds of all display items (regardless
|
||||
* of visibility) in the layer and below the next ThebesLayerData
|
||||
* currently in the stack, if any.
|
||||
* Note that not all ThebesLayers for the container are in the
|
||||
* ThebesLayerData stack.
|
||||
* Same coordinate system as mVisibleRegion.
|
||||
*/
|
||||
nsIntRegion mDrawAboveRegion;
|
||||
/**
|
||||
* The region of visible content in the layer that is opaque.
|
||||
* Same coordinate system as mVisibleRegion.
|
||||
@ -449,6 +488,30 @@ protected:
|
||||
* in mItemClip).
|
||||
*/
|
||||
void UpdateCommonClipCount(const DisplayItemClip& aCurrentClip);
|
||||
|
||||
private:
|
||||
/**
|
||||
* The region of visible content above the layer and below the
|
||||
* next ThebesLayerData currently in the stack, if any. Note that not
|
||||
* all ThebesLayers for the container are in the ThebesLayerData stack.
|
||||
* Same coordinate system as mVisibleRegion.
|
||||
* This is a conservative approximation: it contains the true region.
|
||||
*/
|
||||
nsIntRegion mVisibleAboveRegion;
|
||||
/**
|
||||
* The region containing the bounds of all display items (regardless
|
||||
* of visibility) in the layer and below the next ThebesLayerData
|
||||
* currently in the stack, if any.
|
||||
* Note that not all ThebesLayers for the container are in the
|
||||
* ThebesLayerData stack.
|
||||
* Same coordinate system as mVisibleRegion.
|
||||
*/
|
||||
nsIntRegion mDrawAboveRegion;
|
||||
/**
|
||||
* True if mDrawAboveRegion and mVisibleAboveRegion should be treated
|
||||
* as infinite, and all display items should be considered 'above' this layer.
|
||||
*/
|
||||
bool mAllDrawingAbove;
|
||||
};
|
||||
friend class ThebesLayerData;
|
||||
|
||||
@ -1452,9 +1515,7 @@ ContainerState::FindOpaqueBackgroundColorFor(int32_t aThebesLayerIndex)
|
||||
ThebesLayerData* target = mThebesLayerDataStack[aThebesLayerIndex];
|
||||
for (int32_t i = aThebesLayerIndex - 1; i >= 0; --i) {
|
||||
ThebesLayerData* candidate = mThebesLayerDataStack[i];
|
||||
nsIntRegion visibleAboveIntersection;
|
||||
visibleAboveIntersection.And(candidate->mVisibleAboveRegion, target->mVisibleRegion);
|
||||
if (!visibleAboveIntersection.IsEmpty()) {
|
||||
if (candidate->IntersectsVisibleAboveRegion(target->mVisibleRegion)) {
|
||||
// Some non-Thebes content between target and candidate; this is
|
||||
// hopeless
|
||||
break;
|
||||
@ -1663,16 +1724,7 @@ ContainerState::PopThebesLayerData()
|
||||
// mVisibleAboveRegion of the second-to-last item will need to include
|
||||
// the regions of the last item.
|
||||
ThebesLayerData* nextData = mThebesLayerDataStack[lastIndex - 1];
|
||||
nextData->mVisibleAboveRegion.Or(nextData->mVisibleAboveRegion,
|
||||
data->mVisibleAboveRegion);
|
||||
nextData->mVisibleAboveRegion.Or(nextData->mVisibleAboveRegion,
|
||||
data->mVisibleRegion);
|
||||
nextData->mVisibleAboveRegion.SimplifyOutward(4);
|
||||
nextData->mDrawAboveRegion.Or(nextData->mDrawAboveRegion,
|
||||
data->mDrawAboveRegion);
|
||||
nextData->mDrawAboveRegion.Or(nextData->mDrawAboveRegion,
|
||||
data->mDrawRegion);
|
||||
nextData->mDrawAboveRegion.SimplifyOutward(4);
|
||||
nextData->CopyAboveRegion(data);
|
||||
}
|
||||
|
||||
mThebesLayerDataStack.RemoveElementAt(lastIndex);
|
||||
@ -1850,7 +1902,7 @@ ContainerState::FindThebesLayerFor(nsDisplayItem* aItem,
|
||||
int32_t topmostLayerWithScrolledRoot = -1;
|
||||
for (i = mThebesLayerDataStack.Length() - 1; i >= 0; --i) {
|
||||
ThebesLayerData* data = mThebesLayerDataStack[i];
|
||||
if (data->mDrawAboveRegion.Intersects(aVisibleRect)) {
|
||||
if (data->IsBelow(aVisibleRect)) {
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
@ -2160,14 +2212,24 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
|
||||
}
|
||||
ThebesLayerData* data = GetTopThebesLayerData();
|
||||
if (data) {
|
||||
data->mVisibleAboveRegion.Or(data->mVisibleAboveRegion, itemVisibleRect);
|
||||
data->mVisibleAboveRegion.SimplifyOutward(4);
|
||||
// Add the entire bounds rect to the mDrawAboveRegion.
|
||||
// The visible region may be excluding opaque content above the
|
||||
// item, and we need to ensure that that content is not placed
|
||||
// in a ThebesLayer below the item!
|
||||
data->mDrawAboveRegion.Or(data->mDrawAboveRegion, itemDrawRect);
|
||||
data->mDrawAboveRegion.SimplifyOutward(4);
|
||||
// Prerendered transform items can be updated without layer building
|
||||
// (async animations or an empty transaction), so we treat all other
|
||||
// content as being above this so that the transformed layer can correctly
|
||||
// move behind other content.
|
||||
if (item->GetType() == nsDisplayItem::TYPE_TRANSFORM &&
|
||||
nsDisplayTransform::ShouldPrerenderTransformedContent(mBuilder,
|
||||
item->Frame(),
|
||||
false)) {
|
||||
data->SetAllDrawingAbove();
|
||||
} else {
|
||||
data->AddVisibleAboveRegion(itemVisibleRect);
|
||||
|
||||
// Add the entire bounds rect to the mDrawAboveRegion.
|
||||
// The visible region may be excluding opaque content above the
|
||||
// item, and we need to ensure that that content is not placed
|
||||
// in a ThebesLayer below the item!
|
||||
data->AddDrawAboveRegion(itemDrawRect);
|
||||
}
|
||||
}
|
||||
itemVisibleRect.MoveBy(mParameters.mOffset);
|
||||
if (setVisibleRegion) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user