Bug 1247964 - Allow InputBlockState::SetScrolledApzc to accept new APZC when it is an ancestor of the current APZC r=kats
authorBotond Ballo <botond@mozilla.com>
Mon, 14 Mar 2016 16:36:54 -0700
changeset 289035 28ec277c75ac72f0a27a4440d0ce6dbba551d380
parent 289034 4dd55f40eb7abc1d5f799ae4d0585029f46bbc23
child 289036 149e047e916c4b4e882287a80386313408d1c2f0
push id30096
push usercbook@mozilla.com
push dateThu, 17 Mar 2016 10:00:34 +0000
treeherdermozilla-central@fefe2bc3e54f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1247964
milestone48.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1247964 - Allow InputBlockState::SetScrolledApzc to accept new APZC when it is an ancestor of the current APZC r=kats
gfx/layers/apz/src/InputBlockState.cpp
gfx/layers/apz/src/InputBlockState.h
--- a/gfx/layers/apz/src/InputBlockState.cpp
+++ b/gfx/layers/apz/src/InputBlockState.cpp
@@ -82,21 +82,43 @@ InputBlockState::GetBlockId() const
 }
 
 bool
 InputBlockState::IsTargetConfirmed() const
 {
   return mTargetConfirmed;
 }
 
+bool
+InputBlockState::IsAncestorOf(AsyncPanZoomController* aA, AsyncPanZoomController* aB)
+{
+  if (aA == aB) {
+    return true;
+  }
+
+  bool seenA = false;
+  for (size_t i = 0; i < mOverscrollHandoffChain->Length(); ++i) {
+    AsyncPanZoomController* apzc = mOverscrollHandoffChain->GetApzcAtIndex(i);
+    if (apzc == aB) {
+      return seenA;
+    }
+    if (apzc == aA) {
+      seenA = true;
+    }
+  }
+  return false;
+}
+
+
 void
 InputBlockState::SetScrolledApzc(AsyncPanZoomController* aApzc)
 {
-  // An input block should only have one scrolled APZC.
-  MOZ_ASSERT(!mScrolledApzc || mScrolledApzc == aApzc);
+  // With immediate handoff disabled, the scrolled APZC cannot move down the handoff chain
+  // but it can move up the handoff chain if we change scrolling directions.
+  MOZ_ASSERT(!mScrolledApzc || IsAncestorOf(aApzc, mScrolledApzc));
 
   mScrolledApzc = aApzc;
 }
 
 AsyncPanZoomController*
 InputBlockState::GetScrolledApzc() const
 {
   return mScrolledApzc;
--- a/gfx/layers/apz/src/InputBlockState.h
+++ b/gfx/layers/apz/src/InputBlockState.h
@@ -52,16 +52,21 @@ public:
 
   void SetScrolledApzc(AsyncPanZoomController* aApzc);
   AsyncPanZoomController* GetScrolledApzc() const;
 
 protected:
   virtual void UpdateTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc);
 
 private:
+  // Checks whether |aA| is an ancestor of |aB| (or the same as |aB|) in
+  // |mOverscrollHandoffChain|.
+  bool IsAncestorOf(AsyncPanZoomController* aA, AsyncPanZoomController* aB);
+
+private:
   RefPtr<AsyncPanZoomController> mTargetApzc;
   bool mTargetConfirmed;
   const uint64_t mBlockId;
 
   // The APZC that was actually scrolled by events in this input block.
   // This is used in configurations where a single input block is only
   // allowed to scroll a single APZC (configurations where gfxPrefs::
   // APZAllowImmediateHandoff() is false).