Bug 1331693 - Do not attempt async scrollbar dragging for scroll info layers. r=tnikkel draft
authorBotond Ballo <botond@mozilla.com>
Wed, 18 Jan 2017 18:45:43 -0500
changeset 464526 293d68db3cea84810679a59dcfa234103643d8bb
parent 463391 2233e03ef6fcee477e6436f932d7464dff161054
child 542920 7005713b3c755667d2a2c9fdeb2e1109d17d6995
push id42353
push userbballo@mozilla.com
push dateFri, 20 Jan 2017 23:39:04 +0000
reviewerstnikkel
bugs1331693
milestone53.0a1
Bug 1331693 - Do not attempt async scrollbar dragging for scroll info layers. r=tnikkel MozReview-Commit-ID: 8QjqexfaKkY
layout/painting/nsDisplayList.h
layout/xul/nsSliderFrame.cpp
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -1086,16 +1086,21 @@ public:
    * answer. This effectively implements a first-come, first-served
    * allocation of the will-change budget.
    */
   bool IsInWillChangeBudget(nsIFrame* aFrame, const nsSize& aSize);
 
   void EnterSVGEffectsContents(nsDisplayList* aHoistedItemsStorage);
   void ExitSVGEffectsContents();
 
+  /**
+   * Note: if changing the conditions under which scroll info layers
+   * are created, make a corresponding change to
+   * ScrollFrameWillBuildScrollInfoLayer() in nsSliderFrame.cpp.
+   */
   bool ShouldBuildScrollInfoItemsForHoisting() const
   { return mSVGEffectsBuildingDepth > 0; }
 
   void AppendNewScrollInfoItemForHoisting(nsDisplayScrollInfoLayer* aScrollInfoItem);
 
   /**
    * A helper class to install/restore nsDisplayListBuilder::mPreserves3DCtx.
    *
--- a/layout/xul/nsSliderFrame.cpp
+++ b/layout/xul/nsSliderFrame.cpp
@@ -33,16 +33,17 @@
 #include "nsRepeatService.h"
 #include "nsBoxLayoutState.h"
 #include "nsSprocketLayout.h"
 #include "nsIServiceManager.h"
 #include "nsContentUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsDisplayList.h"
 #include "nsRefreshDriver.h"            // for nsAPostRefreshObserver
+#include "nsSVGIntegrationUtils.h"
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "mozilla/layers/AsyncDragMetrics.h"
 #include "mozilla/layers/InputAPZContext.h"
@@ -963,16 +964,36 @@ public:
 
 private:
   RefPtr<nsIPresShell> mPresShell;
   RefPtr<nsIWidget> mWidget;
   AsyncDragMetrics mDragMetrics;
 };
 
 bool
+UsesSVGEffects(nsIFrame* aFrame)
+{
+  return aFrame->StyleEffects()->HasFilters()
+      || nsSVGIntegrationUtils::UsingMaskOrClipPathForFrame(aFrame);
+}
+
+bool
+ScrollFrameWillBuildScrollInfoLayer(nsIFrame* aScrollFrame)
+{
+  nsIFrame* current = aScrollFrame;
+  while (current) {
+    if (UsesSVGEffects(current)) {
+      return true;
+    }
+    current = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(current);
+  }
+  return false;
+}
+
+bool
 nsSliderFrame::StartAPZDrag(WidgetGUIEvent* aEvent)
 {
   if (!aEvent->mFlags.mHandledByAPZ) {
     return false;
   }
 
   if (!gfxPlatform::GetPlatform()->SupportsApzDragInput()) {
     return false;
@@ -988,16 +1009,22 @@ nsSliderFrame::StartAPZDrag(WidgetGUIEve
     return false;
   }
 
   nsIScrollableFrame* scrollFrameAsScrollable = do_QueryFrame(scrollFrame);
   if (!scrollFrameAsScrollable) {
     return false;
   }
 
+  // APZ dragging requires the scrollbar to be layerized, which doesn't
+  // happen for scroll info layers.
+  if (ScrollFrameWillBuildScrollInfoLayer(scrollFrame)) {
+    return false;
+  }
+
   mozilla::layers::FrameMetrics::ViewID scrollTargetId;
   bool hasID = nsLayoutUtils::FindIDFor(scrollableContent, &scrollTargetId);
   bool hasAPZView = hasID && (scrollTargetId != layers::FrameMetrics::NULL_SCROLL_ID);
 
   if (!hasAPZView) {
     return false;
   }