зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1300864 - Disable paint skipping for scroll frames that contain out-of-flow content inside a CSS filter. r=mstange
MozReview-Commit-ID: 5TwC75wzOsm --HG-- extra : rebase_source : 2c38372e452cf6b78b4906b42e4b9e93a1762d26
This commit is contained in:
Родитель
49dff2257e
Коммит
f733efea1a
|
@ -2936,6 +2936,8 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||
inTransformSetter(aBuilder, inTransform);
|
||||
nsDisplayListBuilder::AutoSaveRestorePerspectiveIndex
|
||||
perspectiveIndex(aBuilder, this);
|
||||
nsDisplayListBuilder::AutoFilterASRSetter
|
||||
filterASRSetter(aBuilder, usingFilter);
|
||||
|
||||
CheckForApzAwareEventHandlers(aBuilder, this);
|
||||
|
||||
|
|
|
@ -1301,6 +1301,12 @@ ScrollFrameHelper::SetZoomableByAPZ(bool aZoomable)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScrollFrameHelper::SetHasOutOfFlowContentInsideFilter()
|
||||
{
|
||||
mHasOutOfFlowContentInsideFilter = true;
|
||||
}
|
||||
|
||||
bool
|
||||
ScrollFrameHelper::WantAsyncScroll() const
|
||||
{
|
||||
|
@ -2075,6 +2081,7 @@ ScrollFrameHelper::ScrollFrameHelper(nsContainerFrame* aOuter,
|
|||
, mTransformingByAPZ(false)
|
||||
, mScrollableByAPZ(false)
|
||||
, mZoomableByAPZ(false)
|
||||
, mHasOutOfFlowContentInsideFilter(false)
|
||||
, mSuppressScrollbarRepaints(false)
|
||||
, mVelocityQueue(aOuter->PresContext())
|
||||
{
|
||||
|
@ -2879,13 +2886,15 @@ ScrollFrameHelper::ScrollToImpl(nsPoint aPt, const nsRect& aRange, nsAtom* aOrig
|
|||
nsLayoutUtils::GetHighResolutionDisplayPort(content, &displayPort);
|
||||
displayPort.MoveBy(-mScrolledFrame->GetPosition());
|
||||
|
||||
PAINT_SKIP_LOG("New scrollpos %s usingDP %d dpEqual %d scrollableByApz %d plugins %d perspective %d bglocal %d\n",
|
||||
PAINT_SKIP_LOG("New scrollpos %s usingDP %d dpEqual %d scrollableByApz %d plugins"
|
||||
"%d perspective %d bglocal %d filter %d\n",
|
||||
Stringify(CSSPoint::FromAppUnits(GetScrollPosition())).c_str(),
|
||||
usingDisplayPort, displayPort.IsEqualEdges(oldDisplayPort),
|
||||
mScrollableByAPZ, HasPluginFrames(), HasPerspective(),
|
||||
HasBgAttachmentLocal());
|
||||
HasBgAttachmentLocal(), mHasOutOfFlowContentInsideFilter);
|
||||
if (usingDisplayPort && displayPort.IsEqualEdges(oldDisplayPort) &&
|
||||
!HasPerspective() && !HasBgAttachmentLocal()) {
|
||||
!HasPerspective() && !HasBgAttachmentLocal() &&
|
||||
!mHasOutOfFlowContentInsideFilter) {
|
||||
bool haveScrollLinkedEffects = content->GetComposedDoc()->HasScrollLinkedEffect();
|
||||
bool apzDisabled = haveScrollLinkedEffects && gfxPrefs::APZDisableForScrollLinkedEffects();
|
||||
if (!apzDisabled && !HasPluginFrames()) {
|
||||
|
|
|
@ -426,6 +426,7 @@ public:
|
|||
}
|
||||
void SetScrollableByAPZ(bool aScrollable);
|
||||
void SetZoomableByAPZ(bool aZoomable);
|
||||
void SetHasOutOfFlowContentInsideFilter();
|
||||
|
||||
bool UsesContainerScrolling() const;
|
||||
|
||||
|
@ -632,6 +633,10 @@ public:
|
|||
// True if the APZ is allowed to zoom this scrollframe.
|
||||
bool mZoomableByAPZ:1;
|
||||
|
||||
// True if the scroll frame contains out-of-flow content and is inside
|
||||
// a CSS filter.
|
||||
bool mHasOutOfFlowContentInsideFilter:1;
|
||||
|
||||
// True if we don't want the scrollbar to repaint itself right now.
|
||||
bool mSuppressScrollbarRepaints:1;
|
||||
|
||||
|
@ -1062,6 +1067,9 @@ public:
|
|||
void SetZoomableByAPZ(bool aZoomable) override {
|
||||
mHelper.SetZoomableByAPZ(aZoomable);
|
||||
}
|
||||
void SetHasOutOfFlowContentInsideFilter() override {
|
||||
mHelper.SetHasOutOfFlowContentInsideFilter();
|
||||
}
|
||||
|
||||
ScrollSnapInfo GetScrollSnapInfo() const override {
|
||||
return mHelper.GetScrollSnapInfo();
|
||||
|
@ -1497,6 +1505,9 @@ public:
|
|||
void SetZoomableByAPZ(bool aZoomable) override {
|
||||
mHelper.SetZoomableByAPZ(aZoomable);
|
||||
}
|
||||
void SetHasOutOfFlowContentInsideFilter() override {
|
||||
mHelper.SetHasOutOfFlowContentInsideFilter();
|
||||
}
|
||||
virtual bool DecideScrollableLayer(nsDisplayListBuilder* aBuilder,
|
||||
nsRect* aVisibleRect,
|
||||
nsRect* aDirtyRect,
|
||||
|
|
|
@ -448,6 +448,13 @@ public:
|
|||
*/
|
||||
virtual void SetZoomableByAPZ(bool aZoomable) = 0;
|
||||
|
||||
/**
|
||||
* Mark this scroll frame as having out-of-flow content inside a CSS filter.
|
||||
* Such content will move incorrectly during async-scrolling; to mitigate
|
||||
* this, paint skipping is disabled for such scroll frames.
|
||||
*/
|
||||
virtual void SetHasOutOfFlowContentInsideFilter() = 0;
|
||||
|
||||
/**
|
||||
* Whether or not this frame uses containerful scrolling.
|
||||
*/
|
||||
|
|
|
@ -919,6 +919,17 @@ nsDisplayListBuilder::AutoCurrentActiveScrolledRootSetter::SetCurrentActiveScrol
|
|||
mBuilder->mCurrentContainerASR = ActiveScrolledRoot::PickAncestor(
|
||||
mBuilder->mCurrentContainerASR, finiteBoundsASR);
|
||||
|
||||
// If we are entering out-of-flow content inside a CSS filter, mark
|
||||
// scroll frames wrt. which the content is fixed as containing such content.
|
||||
if (mBuilder->mFilterASR &&
|
||||
ActiveScrolledRoot::IsAncestor(aActiveScrolledRoot, mBuilder->mFilterASR)) {
|
||||
for (const ActiveScrolledRoot* asr = mBuilder->mFilterASR;
|
||||
asr && asr != aActiveScrolledRoot;
|
||||
asr = asr->mParent) {
|
||||
asr->mScrollableFrame->SetHasOutOfFlowContentInsideFilter();
|
||||
}
|
||||
}
|
||||
|
||||
mUsed = true;
|
||||
}
|
||||
|
||||
|
@ -970,6 +981,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
|
|||
mCurrentScrollbarFlags(nsDisplayOwnLayerFlags::eNone),
|
||||
mPerspectiveItemIndex(0),
|
||||
mSVGEffectsBuildingDepth(0),
|
||||
mFilterASR(nullptr),
|
||||
mContainsBlendMode(false),
|
||||
mIsBuildingScrollbar(false),
|
||||
mCurrentScrollbarWillHaveLayer(false),
|
||||
|
|
|
@ -1125,6 +1125,28 @@ public:
|
|||
bool mOldValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* A helper class to temporarily set the value of mFilterASR.
|
||||
*/
|
||||
class AutoFilterASRSetter;
|
||||
friend class AutoFilterASRSetter;
|
||||
class AutoFilterASRSetter {
|
||||
public:
|
||||
AutoFilterASRSetter(nsDisplayListBuilder* aBuilder, bool aUsingFilter)
|
||||
: mBuilder(aBuilder), mOldValue(aBuilder->mFilterASR)
|
||||
{
|
||||
if (!aBuilder->mFilterASR && aUsingFilter) {
|
||||
aBuilder->mFilterASR = aBuilder->CurrentActiveScrolledRoot();
|
||||
}
|
||||
}
|
||||
~AutoFilterASRSetter() {
|
||||
mBuilder->mFilterASR = mOldValue;
|
||||
}
|
||||
private:
|
||||
nsDisplayListBuilder* mBuilder;
|
||||
const ActiveScrolledRoot* mOldValue;
|
||||
};
|
||||
|
||||
class AutoSaveRestorePerspectiveIndex;
|
||||
friend class AutoSaveRestorePerspectiveIndex;
|
||||
class AutoSaveRestorePerspectiveIndex {
|
||||
|
@ -1771,6 +1793,9 @@ private:
|
|||
Preserves3DContext mPreserves3DCtx;
|
||||
uint32_t mPerspectiveItemIndex;
|
||||
int32_t mSVGEffectsBuildingDepth;
|
||||
// When we are inside a filter, the current ASR at the time we entered the
|
||||
// filter. Otherwise nullptr.
|
||||
const ActiveScrolledRoot* mFilterASR;
|
||||
bool mContainsBlendMode;
|
||||
bool mIsBuildingScrollbar;
|
||||
bool mCurrentScrollbarWillHaveLayer;
|
||||
|
|
Загрузка…
Ссылка в новой задаче