Bug 1264297 - Don't do paint-skipping for elements with perspective, until we can properly populate the displayport. r?mstange
MozReview-Commit-ID: D3wKzWU72yi
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -2106,16 +2106,23 @@ ScrollFrameHelper::HasPluginFrames()
if (ctx.value) {
return true;
}
}
#endif
return false;
}
+bool
+ScrollFrameHelper::HasPerspective() const
+{
+ const nsStyleDisplay* disp = mOuter->StyleDisplay();
+ return disp->mChildPerspective.GetUnit() != eStyleUnit_None;
+}
+
void
ScrollFrameHelper::ScrollToCSSPixels(const CSSIntPoint& aScrollPosition,
nsIScrollableFrame::ScrollMode aMode)
{
nsPoint current = GetScrollPosition();
CSSIntPoint currentCSSPixels = GetScrollPositionCSSPixels();
nsPoint pt = CSSPoint::ToAppUnits(aScrollPosition);
nscoord halfPixel = nsPresContext::CSSPixelsToAppUnits(0.5f);
@@ -2733,26 +2740,31 @@ ScrollFrameHelper::ScrollToImpl(nsPoint
// unchanged.
// 2) If non-APZ triggered this scroll, but we can handle it by just asking
// APZ to update the scroll position. Again we make this conditional on
// the tile-aligned displayport being unchanged.
// We do the displayport check first since it's common to all scenarios,
// and then if the displayport is unchanged, we check if APZ triggered,
// or can handle, this scroll. If so, we set schedulePaint to false and
// skip the paint.
+ // Because of bug 1264297, we also don't do paint-skipping for elements with
+ // perspective, because the displayport may not have captured everything
+ // 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\n",
+ PAINT_SKIP_LOG("New scrollpos %s usingDP %d dpEqual %d scrollableByApz %d plugins %d perspective %d\n",
Stringify(CSSPoint::FromAppUnits(GetScrollPosition())).c_str(),
usingDisplayPort, displayPort.IsEqualEdges(oldDisplayPort),
- mScrollableByAPZ, HasPluginFrames());
- if (usingDisplayPort && displayPort.IsEqualEdges(oldDisplayPort)) {
+ mScrollableByAPZ, HasPluginFrames(), HasPerspective());
+ if (usingDisplayPort && displayPort.IsEqualEdges(oldDisplayPort) && !HasPerspective()) {
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
@@ -620,16 +620,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;
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
// an update of frame visibility.