Bug 1287185 - Disable paint skipping for scrollframes with background-attachment:local. r?mstange
MozReview-Commit-ID: GMgIyxUd20c
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -2114,16 +2114,23 @@ ScrollFrameHelper::HasPluginFrames()
bool
ScrollFrameHelper::HasPerspective() const
{
const nsStyleDisplay* disp = mOuter->StyleDisplay();
return disp->mChildPerspective.GetUnit() != eStyleUnit_None;
}
+bool
+ScrollFrameHelper::HasBgAttachmentLocal() const
+{
+ const nsStyleBackground* bg = mOuter->StyleBackground();
+ return bg->HasLocalBackground();
+}
+
void
ScrollFrameHelper::SetScrollsClipOnUnscrolledOutOfFlow()
{
mScrollsClipOnUnscrolledOutOfFlow = true;
}
void
ScrollFrameHelper::ScrollToCSSPixels(const CSSIntPoint& aScrollPosition,
@@ -2757,21 +2764,24 @@ ScrollFrameHelper::ScrollToImpl(nsPoint
// that needs to be painted. So even if the final tile-aligned displayport
// is the same, we force a repaint for these elements. Bug 1254260 tracks
// fixing this properly.
nsRect displayPort;
bool usingDisplayPort =
nsLayoutUtils::GetHighResolutionDisplayPort(content, &displayPort);
displayPort.MoveBy(-mScrolledFrame->GetPosition());
- PAINT_SKIP_LOG("New scrollpos %s usingDP %d dpEqual %d scrollableByApz %d plugins %d perspective %d clip %d\n",
+ PAINT_SKIP_LOG("New scrollpos %s usingDP %d dpEqual %d scrollableByApz %d plugins %d perspective %d clip %d bglocal %d\n",
Stringify(CSSPoint::FromAppUnits(GetScrollPosition())).c_str(),
usingDisplayPort, displayPort.IsEqualEdges(oldDisplayPort),
- mScrollableByAPZ, HasPluginFrames(), HasPerspective(), mScrollsClipOnUnscrolledOutOfFlow);
- if (usingDisplayPort && displayPort.IsEqualEdges(oldDisplayPort) && !HasPerspective() && !mScrollsClipOnUnscrolledOutOfFlow) {
+ mScrollableByAPZ, HasPluginFrames(), HasPerspective(),
+ mScrollsClipOnUnscrolledOutOfFlow, HasBgAttachmentLocal());
+ if (usingDisplayPort && displayPort.IsEqualEdges(oldDisplayPort) &&
+ !HasPerspective() && !mScrollsClipOnUnscrolledOutOfFlow &&
+ !HasBgAttachmentLocal()) {
bool haveScrollLinkedEffects = content->GetComposedDoc()->HasScrollLinkedEffect();
bool apzDisabled = haveScrollLinkedEffects && gfxPrefs::APZDisableForScrollLinkedEffects();
if (!apzDisabled) {
if (LastScrollOrigin() == nsGkAtoms::apz) {
schedulePaint = false;
PAINT_SKIP_LOG("Skipping due to APZ scroll\n");
} else if (mScrollableByAPZ && !HasPluginFrames()) {
nsIWidget* widget = presContext->GetNearestWidget();
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -624,16 +624,17 @@ protected:
* Helper that notifies plugins about async smooth scroll operations managed
* by nsGfxScrollFrame.
*/
enum AsyncScrollEventType { BEGIN_DOM, BEGIN_APZ, END_DOM, END_APZ };
void NotifyPluginFrames(AsyncScrollEventType aEvent);
AsyncScrollEventType mAsyncScrollEvent;
bool HasPluginFrames();
bool HasPerspective() const;
+ bool HasBgAttachmentLocal() const;
uint8_t GetScrolledFrameDir() const;
static void EnsureFrameVisPrefsCached();
static bool sFrameVisPrefsCached;
// The number of scrollports wide/high to expand when tracking frame visibility.
static uint32_t sHorzExpandScrollPort;
static uint32_t sVertExpandScrollPort;
// The fraction of the scrollport we allow to scroll by before we schedule
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -790,16 +790,20 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
bool IsTransparent() const;
// We have to take slower codepaths for fixed background attachment,
// but we don't want to do that when there's no image.
// Not inline because it uses an nsCOMPtr<imgIRequest>
// FIXME: Should be in nsStyleStructInlines.h.
bool HasFixedBackground(nsIFrame* aFrame) const;
+ // Checks to see if this has a non-empty image with "local" attachment.
+ // This is defined in nsStyleStructInlines.h.
+ inline bool HasLocalBackground() const;
+
const nsStyleImageLayers::Layer& BottomLayer() const { return mImage.BottomLayer(); }
nsStyleImageLayers mImage;
nscolor mBackgroundColor; // [reset]
};
// See https://bugzilla.mozilla.org/show_bug.cgi?id=271586#c43 for why
// this is hard to replace with 'currentColor'.
--- a/layout/style/nsStyleStructInlines.h
+++ b/layout/style/nsStyleStructInlines.h
@@ -188,9 +188,22 @@ nsStyleUserInterface::GetEffectivePointe
nsIFrame* f = aFrame->GetContent()->GetPrimaryFrame();
if (f) {
return f->StyleUserInterface()->mPointerEvents;
}
}
return mPointerEvents;
}
+bool
+nsStyleBackground::HasLocalBackground() const
+{
+ NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, mImage) {
+ const nsStyleImageLayers::Layer& layer = mImage.mLayers[i];
+ if (!layer.mImage.IsEmpty() &&
+ layer.mAttachment == NS_STYLE_IMAGELAYER_ATTACHMENT_LOCAL) {
+ return true;
+ }
+ }
+ return false;
+}
+
#endif /* !defined(nsStyleStructInlines_h_) */