Bug 1264297 - Don't do paint-skipping for elements with perspective, until we can properly populate the displayport. r?mstange draft
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 16 May 2016 12:07:01 -0400
changeset 367398 b823a9b4ff670c934ccf4d0c2d7a355fab284cac
parent 367249 d0be57e84807ce0853b2406de7ff6abb195ac898
child 521005 043e8733e9006633928ba22be8dc121f9a045e98
push id18234
push userkgupta@mozilla.com
push dateMon, 16 May 2016 16:07:17 +0000
reviewersmstange
bugs1264297
milestone49.0a1
Bug 1264297 - Don't do paint-skipping for elements with perspective, until we can properly populate the displayport. r?mstange MozReview-Commit-ID: D3wKzWU72yi
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
--- 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.