Bug 1127066 - Fold APZCCallbackHelper::UpdateCallbackTransform() into ScrollFrame(). r=kats
authorBotond Ballo <botond@mozilla.com>
Wed, 28 Jan 2015 17:40:29 -0500
changeset 242478 7acb85b25fbbda39f3b5ca24467cb27233d613b6
parent 242477 ea7de6b88d853f2c69d1bcc82e873ef3ed8635c7
child 242479 5669834a94543c7d12fc21939276a2e4fdab2d82
push id659
push userahalberstadt@mozilla.com
push dateThu, 12 Feb 2015 16:07:42 +0000
reviewerskats
bugs1127066
milestone38.0a1
Bug 1127066 - Fold APZCCallbackHelper::UpdateCallbackTransform() into ScrollFrame(). r=kats
dom/ipc/TabChild.cpp
gfx/layers/apz/util/APZCCallbackHelper.cpp
gfx/layers/apz/util/APZCCallbackHelper.h
widget/android/APZCCallbackHandler.cpp
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -534,28 +534,26 @@ bool
 TabChildBase::UpdateFrameHandler(const FrameMetrics& aFrameMetrics)
 {
   MOZ_ASSERT(aFrameMetrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID);
 
   if (aFrameMetrics.GetIsRoot()) {
     nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils());
     if (APZCCallbackHelper::HasValidPresShellId(utils, aFrameMetrics)) {
       mLastRootMetrics = ProcessUpdateFrame(aFrameMetrics);
-      APZCCallbackHelper::UpdateCallbackTransform(aFrameMetrics, mLastRootMetrics);
       return true;
     }
   } else {
     // aFrameMetrics.mIsRoot is false, so we are trying to update a subframe.
     // This requires special handling.
     nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(
                                       aFrameMetrics.GetScrollId());
     if (content) {
       FrameMetrics newSubFrameMetrics(aFrameMetrics);
       APZCCallbackHelper::UpdateSubFrame(content, newSubFrameMetrics);
-      APZCCallbackHelper::UpdateCallbackTransform(aFrameMetrics, newSubFrameMetrics);
       return true;
     }
   }
   return true;
 }
 
 FrameMetrics
 TabChildBase::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -106,43 +106,55 @@ ScrollFrameTo(nsIScrollableFrame* aFrame
   return geckoScrollPosition;
 }
 
 /**
  * Scroll the scroll frame associated with |aContent| to the scroll position
  * requested in |aMetrics|.
  * The scroll offset in |aMetrics| is updated to reflect the actual scroll
  * position.
- * The displayport stored in |aMetrics| is updated to reflect any difference
- * between the requested and actual scroll positions.
+ * The displayport stored in |aMetrics| and the callback-transform stored on
+ * the content are updated to reflect any difference between the requested
+ * and actual scroll positions.
  */
 static void
 ScrollFrame(nsIContent* aContent,
             FrameMetrics& aMetrics)
 {
   // Scroll the window to the desired spot
   nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aMetrics.GetScrollId());
   bool scrollUpdated = false;
-  CSSPoint actualScrollOffset = ScrollFrameTo(sf, aMetrics.GetScrollOffset(), scrollUpdated);
+  CSSPoint apzScrollOffset = aMetrics.GetScrollOffset();
+  CSSPoint actualScrollOffset = ScrollFrameTo(sf, apzScrollOffset, scrollUpdated);
 
   if (scrollUpdated) {
     // Correct the display port due to the difference between mScrollOffset and the
     // actual scroll offset.
     AdjustDisplayPortForScrollDelta(aMetrics, actualScrollOffset);
   } else {
     // For whatever reason we couldn't update the scroll offset on the scroll frame,
     // which means the data APZ used for its displayport calculation is stale. Fall
     // back to a sane default behaviour. Note that we don't tile-align the recentered
     // displayport because tile-alignment depends on the scroll position, and the
     // scroll position here is out of our control. See bug 966507 comment 21 for a
     // more detailed explanation.
     RecenterDisplayPort(aMetrics);
   }
 
   aMetrics.SetScrollOffset(actualScrollOffset);
+
+  // APZ transforms inputs assuming we applied the exact scroll offset it
+  // requested (|apzScrollOffset|). Since we may not have, record the difference
+  // between what APZ asked for and what we actually applied, and apply it to
+  // input events to compensate.
+  if (aContent) {
+    CSSPoint scrollDelta = apzScrollOffset - actualScrollOffset;
+    aContent->SetProperty(nsGkAtoms::apzCallbackTransform, new CSSPoint(scrollDelta),
+                          nsINode::DeleteProperty<CSSPoint>);
+  }
 }
 
 static void
 SetDisplayPortMargins(nsIDOMWindowUtils* aUtils,
                       nsIContent* aContent,
                       FrameMetrics& aMetrics)
 {
   if (!aContent) {
@@ -295,28 +307,16 @@ APZCCallbackHelper::AcknowledgeScrollUpd
     nsCOMPtr<nsIRunnable> r1 = new AcknowledgeScrollUpdateEvent(aScrollId, aScrollGeneration);
     if (!NS_IsMainThread()) {
         NS_DispatchToMainThread(r1);
     } else {
         r1->Run();
     }
 }
 
-void
-APZCCallbackHelper::UpdateCallbackTransform(const FrameMetrics& aApzcMetrics, const FrameMetrics& aActualMetrics)
-{
-    nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aApzcMetrics.GetScrollId());
-    if (!content) {
-        return;
-    }
-    CSSPoint scrollDelta = aApzcMetrics.GetScrollOffset() - aActualMetrics.GetScrollOffset();
-    content->SetProperty(nsGkAtoms::apzCallbackTransform, new CSSPoint(scrollDelta),
-                         nsINode::DeleteProperty<CSSPoint>);
-}
-
 CSSPoint
 APZCCallbackHelper::ApplyCallbackTransform(const CSSPoint& aInput,
                                            const ScrollableLayerGuid& aGuid,
                                            float aPresShellResolution)
 {
     // First, scale inversely by the pres shell resolution to cancel the
     // scale-to-resolution transform that the compositor adds to the layer with
     // the pres shell resolution. The points sent to Gecko by APZ don't have
--- a/gfx/layers/apz/util/APZCCallbackHelper.h
+++ b/gfx/layers/apz/util/APZCCallbackHelper.h
@@ -70,29 +70,16 @@ public:
                                              uint32_t* aPresShellIdOut,
                                              FrameMetrics::ViewID* aViewIdOut);
 
     /* Tell layout that we received the scroll offset update for the given view ID, so
        that it accepts future scroll offset updates from APZ. */
     static void AcknowledgeScrollUpdate(const FrameMetrics::ViewID& aScrollId,
                                         const uint32_t& aScrollGeneration);
 
-    /* Save an "input transform" property on the content element corresponding to
-       the scrollable content. This is needed because in some cases when the APZ code
-       sends a paint request via the GeckoContentController interface, we don't always
-       apply the scroll offset that was requested. Since the APZ code doesn't know
-       that we didn't apply it, it will transform inputs assuming that we had applied
-       it, and so we need to apply a fixup to the input to account for the fact that
-       we didn't.
-       The |aApzcMetrics| argument are the metrics that the APZ sent us, and the
-       |aActualMetrics| argument are the metrics representing the gecko state after we
-       applied some or all of the APZ metrics. */
-    static void UpdateCallbackTransform(const FrameMetrics& aApzcMetrics,
-                                        const FrameMetrics& aActualMetrics);
-
     /* Apply an "input transform" to the given |aInput| and return the transformed value.
        The input transform applied is the one for the content element corresponding to
        |aGuid|; this is populated in a previous call to UpdateCallbackTransform. See that
        method's documentations for details.
        This method additionally adjusts |aInput| by inversely scaling by the provided
        pres shell resolution, to cancel out a compositor-side transform (added in
        bug 1076241) that APZ doesn't unapply. */
     static CSSPoint ApplyCallbackTransform(const CSSPoint& aInput,
--- a/widget/android/APZCCallbackHandler.cpp
+++ b/widget/android/APZCCallbackHandler.cpp
@@ -85,26 +85,24 @@ APZCCallbackHandler::RequestContentRepai
     MOZ_ASSERT(NS_IsMainThread());
     MOZ_ASSERT(aFrameMetrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID);
 
     if (aFrameMetrics.GetIsRoot()) {
         nsIDOMWindowUtils* utils = GetDOMWindowUtils();
         if (utils && APZCCallbackHelper::HasValidPresShellId(utils, aFrameMetrics)) {
             FrameMetrics metrics = aFrameMetrics;
             APZCCallbackHelper::UpdateRootFrame(utils, metrics);
-            APZCCallbackHelper::UpdateCallbackTransform(aFrameMetrics, metrics);
         }
     } else {
         // aFrameMetrics.mIsRoot is false, so we are trying to update a subframe.
         // This requires special handling.
         nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aFrameMetrics.GetScrollId());
         if (content) {
             FrameMetrics newSubFrameMetrics(aFrameMetrics);
             APZCCallbackHelper::UpdateSubFrame(content, newSubFrameMetrics);
-            APZCCallbackHelper::UpdateCallbackTransform(aFrameMetrics, newSubFrameMetrics);
         }
     }
 }
 
 void
 APZCCallbackHandler::AcknowledgeScrollUpdate(const FrameMetrics::ViewID& aScrollId,
                                              const uint32_t& aScrollGeneration)
 {