mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1098654 - Improve layerization of display items when dealing with async scrollable layers. r=tnikkel
The function IsSubjectToAsyncTransforms() was not correctly reporting when a layer was actually subject to async transforms. As a result, sometimes display items from above such a layer would end up in a layer below. This could manifest as page elements being improperly covered by async scrolling elements.
This commit is contained in:
parent
505701294d
commit
43054fe29c
@ -254,6 +254,7 @@ class PaintedLayerData {
|
|||||||
public:
|
public:
|
||||||
PaintedLayerData() :
|
PaintedLayerData() :
|
||||||
mAnimatedGeometryRoot(nullptr),
|
mAnimatedGeometryRoot(nullptr),
|
||||||
|
mIsAsyncScrollable(false),
|
||||||
mFixedPosFrameForLayerData(nullptr),
|
mFixedPosFrameForLayerData(nullptr),
|
||||||
mReferenceFrame(nullptr),
|
mReferenceFrame(nullptr),
|
||||||
mLayer(nullptr),
|
mLayer(nullptr),
|
||||||
@ -342,7 +343,16 @@ public:
|
|||||||
|
|
||||||
void CopyAboveRegion(PaintedLayerData* aOther)
|
void CopyAboveRegion(PaintedLayerData* aOther)
|
||||||
{
|
{
|
||||||
if (aOther->mAllDrawingAbove || mAllDrawingAbove) {
|
// If aOther has a draw region and is subject to async transforms then the
|
||||||
|
// layer can potentially be moved arbitrarily on the compositor. So we
|
||||||
|
// should avoid moving display items from on top of the layer to below the
|
||||||
|
// layer, which we do by calling SetAllDrawingAbove. Note that if the draw
|
||||||
|
// region is empty (such as when aOther has only event-regions items) then
|
||||||
|
// we don't need to do this.
|
||||||
|
bool aOtherCanDrawAnywhere = aOther->IsSubjectToAsyncTransforms()
|
||||||
|
&& !aOther->mDrawRegion.IsEmpty();
|
||||||
|
|
||||||
|
if (aOther->mAllDrawingAbove || mAllDrawingAbove || aOtherCanDrawAnywhere) {
|
||||||
SetAllDrawingAbove();
|
SetAllDrawingAbove();
|
||||||
} else {
|
} else {
|
||||||
mVisibleAboveRegion.Or(mVisibleAboveRegion, aOther->mVisibleAboveRegion);
|
mVisibleAboveRegion.Or(mVisibleAboveRegion, aOther->mVisibleAboveRegion);
|
||||||
@ -386,7 +396,8 @@ public:
|
|||||||
|
|
||||||
bool IsSubjectToAsyncTransforms()
|
bool IsSubjectToAsyncTransforms()
|
||||||
{
|
{
|
||||||
return mFixedPosFrameForLayerData != nullptr;
|
return mFixedPosFrameForLayerData != nullptr
|
||||||
|
|| mIsAsyncScrollable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -425,6 +436,12 @@ public:
|
|||||||
* active scrolled root.
|
* active scrolled root.
|
||||||
*/
|
*/
|
||||||
const nsIFrame* mAnimatedGeometryRoot;
|
const nsIFrame* mAnimatedGeometryRoot;
|
||||||
|
/**
|
||||||
|
* Whether or not this layer is async scrollable. If it is, that means display
|
||||||
|
* items above this layer should not end up in a layer below this one, as they
|
||||||
|
* might be obscured when they shouldn't be.
|
||||||
|
*/
|
||||||
|
bool mIsAsyncScrollable;
|
||||||
/**
|
/**
|
||||||
* If non-null, the frame from which we'll extract "fixed positioning"
|
* If non-null, the frame from which we'll extract "fixed positioning"
|
||||||
* metadata for this layer. This can be a position:fixed frame or a viewport
|
* metadata for this layer. This can be a position:fixed frame or a viewport
|
||||||
@ -815,6 +832,13 @@ protected:
|
|||||||
* flag, and pop it off the stack.
|
* flag, and pop it off the stack.
|
||||||
*/
|
*/
|
||||||
void PopPaintedLayerData();
|
void PopPaintedLayerData();
|
||||||
|
/**
|
||||||
|
* Check if any of the animated geometry roots from aAnimatedGeometryRoot up
|
||||||
|
* to and including mContainerAnimatedGeometryRoot are async scrollable. If
|
||||||
|
* so, return true. This is used to flag a particular PaintedLayer as being
|
||||||
|
* subject to async transforms.
|
||||||
|
*/
|
||||||
|
bool HasAsyncScrollableGeometryInContainer(const nsIFrame* aAnimatedGeometryRoot);
|
||||||
/**
|
/**
|
||||||
* Find the PaintedLayer to which we should assign the next display item.
|
* Find the PaintedLayer to which we should assign the next display item.
|
||||||
* We scan the PaintedLayerData stack to find the topmost PaintedLayer
|
* We scan the PaintedLayerData stack to find the topmost PaintedLayer
|
||||||
@ -2482,6 +2506,28 @@ PaintedLayerData::Accumulate(ContainerState* aState,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ContainerState::HasAsyncScrollableGeometryInContainer(const nsIFrame* aAnimatedGeometryRoot)
|
||||||
|
{
|
||||||
|
const nsIFrame* f = aAnimatedGeometryRoot;
|
||||||
|
while (f) {
|
||||||
|
if (nsLayoutUtils::GetScrollableFrameFor(f) &&
|
||||||
|
nsLayoutUtils::GetDisplayPort(f->GetContent(), nullptr)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (f == mContainerAnimatedGeometryRoot) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nsIFrame* fParent = nsLayoutUtils::GetCrossDocParentFrame(f);
|
||||||
|
if (!fParent) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
f = nsLayoutUtils::GetAnimatedGeometryRootForFrame(
|
||||||
|
this->mBuilder, fParent, mContainerAnimatedGeometryRoot);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
PaintedLayerData*
|
PaintedLayerData*
|
||||||
ContainerState::FindPaintedLayerFor(nsDisplayItem* aItem,
|
ContainerState::FindPaintedLayerFor(nsDisplayItem* aItem,
|
||||||
const nsIntRect& aVisibleRect,
|
const nsIntRect& aVisibleRect,
|
||||||
@ -2549,6 +2595,8 @@ ContainerState::FindPaintedLayerFor(nsDisplayItem* aItem,
|
|||||||
paintedLayerData->mAnimatedGeometryRoot = aAnimatedGeometryRoot;
|
paintedLayerData->mAnimatedGeometryRoot = aAnimatedGeometryRoot;
|
||||||
paintedLayerData->mFixedPosFrameForLayerData =
|
paintedLayerData->mFixedPosFrameForLayerData =
|
||||||
FindFixedPosFrameForLayerData(aAnimatedGeometryRoot, aShouldFixToViewport);
|
FindFixedPosFrameForLayerData(aAnimatedGeometryRoot, aShouldFixToViewport);
|
||||||
|
paintedLayerData->mIsAsyncScrollable =
|
||||||
|
HasAsyncScrollableGeometryInContainer(aAnimatedGeometryRoot);
|
||||||
paintedLayerData->mReferenceFrame = aItem->ReferenceFrame();
|
paintedLayerData->mReferenceFrame = aItem->ReferenceFrame();
|
||||||
paintedLayerData->mSingleItemFixedToViewport = aShouldFixToViewport;
|
paintedLayerData->mSingleItemFixedToViewport = aShouldFixToViewport;
|
||||||
|
|
||||||
|
@ -1802,7 +1802,7 @@ fuzzy-if(B2G,1,7) == 942672-1.html 942672-1-ref.html
|
|||||||
== 950436-1.html 950436-1-ref.html
|
== 950436-1.html 950436-1-ref.html
|
||||||
== 957770-1.svg 957770-1-ref.svg
|
== 957770-1.svg 957770-1-ref.svg
|
||||||
== 960277-1.html 960277-1-ref.html
|
== 960277-1.html 960277-1-ref.html
|
||||||
pref(layout.css.overflow-clip-box.enabled,true) fuzzy(50,31) == 966992-1.html 966992-1-ref.html
|
pref(layout.css.overflow-clip-box.enabled,true) fuzzy(50,145) == 966992-1.html 966992-1-ref.html
|
||||||
skip-if(Android) == 966510-1.html 966510-1-ref.html # scrollable elements other than the root probably won't work well on android until bug 776030 is fixed
|
skip-if(Android) == 966510-1.html 966510-1-ref.html # scrollable elements other than the root probably won't work well on android until bug 776030 is fixed
|
||||||
skip-if(Android) == 966510-2.html 966510-2-ref.html # same as above
|
skip-if(Android) == 966510-2.html 966510-2-ref.html # same as above
|
||||||
== 978911-1.svg 978911-1-ref.svg
|
== 978911-1.svg 978911-1-ref.svg
|
||||||
|
Loading…
Reference in New Issue
Block a user