Bug 1127066 - Factor out code common to APZCCallbackHelper::UpdateRootFrame and UpdateSubFrame. r=kats
authorBotond Ballo <botond@mozilla.com>
Fri, 23 Jan 2015 18:54:19 -0500
changeset 242477 ea7de6b88d853f2c69d1bcc82e873ef3ed8635c7
parent 242476 4491d42a2c351dcf5567dac9c9edeb59b306dd26
child 242478 7acb85b25fbbda39f3b5ca24467cb27233d613b6
push id659
push userahalberstadt@mozilla.com
push dateThu, 12 Feb 2015 16:07:42 +0000
reviewerskats
bugs1127066
milestone38.0a1
Bug 1127066 - Factor out code common to APZCCallbackHelper::UpdateRootFrame and UpdateSubFrame. r=kats
gfx/layers/apz/util/APZCCallbackHelper.cpp
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -101,131 +101,125 @@ ScrollFrameTo(nsIScrollableFrame* aFrame
     aSuccessOut = true;
   }
   // Return the final scroll position after setting it so that anything that relies
   // on it can have an accurate value. Note that even if we set it above re-querying it
   // is a good idea because it may have gotten clamped or rounded.
   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.
+ */
+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);
+
+  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);
+}
+
+static void
+SetDisplayPortMargins(nsIDOMWindowUtils* aUtils,
+                      nsIContent* aContent,
+                      FrameMetrics& aMetrics)
+{
+  if (!aContent) {
+    return;
+  }
+  nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aContent);
+  if (!element) {
+    return;
+  }
+
+  ScreenMargin margins = aMetrics.GetDisplayPortMargins();
+  aUtils->SetDisplayPortMarginsForElement(margins.left,
+                                          margins.top,
+                                          margins.right,
+                                          margins.bottom,
+                                          element, 0);
+  CSSRect baseCSS = aMetrics.CalculateCompositedRectInCssPixels();
+  nsRect base(0, 0,
+              baseCSS.width * nsPresContext::AppUnitsPerCSSPixel(),
+              baseCSS.height * nsPresContext::AppUnitsPerCSSPixel());
+  nsLayoutUtils::SetDisplayPortBaseIfNotSet(aContent, base);
+}
+
 void
 APZCCallbackHelper::UpdateRootFrame(nsIDOMWindowUtils* aUtils,
                                     FrameMetrics& aMetrics)
 {
-    // Precondition checks
-    MOZ_ASSERT(aUtils);
-    MOZ_ASSERT(aMetrics.GetUseDisplayPortMargins());
-    if (aMetrics.GetScrollId() == FrameMetrics::NULL_SCROLL_ID) {
-        return;
-    }
-
-    // Set the scroll port size, which determines the scroll range. For example if
-    // a 500-pixel document is shown in a 100-pixel frame, the scroll port length would
-    // be 100, and gecko would limit the maximum scroll offset to 400 (so as to prevent
-    // overscroll). Note that if the content here was zoomed to 2x, the document would
-    // be 1000 pixels long but the frame would still be 100 pixels, and so the maximum
-    // scroll range would be 900. Therefore this calculation depends on the zoom applied
-    // to the content relative to the container.
-    CSSSize scrollPort = aMetrics.CalculateCompositedSizeInCssPixels();
-    aUtils->SetScrollPositionClampingScrollPortSize(scrollPort.width, scrollPort.height);
-
-    // Scroll the window to the desired spot
-    nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aMetrics.GetScrollId());
-    bool scrollUpdated = false;
-    CSSPoint actualScrollOffset = ScrollFrameTo(sf, aMetrics.GetScrollOffset(), scrollUpdated);
+  // Precondition checks
+  MOZ_ASSERT(aUtils);
+  MOZ_ASSERT(aMetrics.GetUseDisplayPortMargins());
+  if (aMetrics.GetScrollId() == FrameMetrics::NULL_SCROLL_ID) {
+    return;
+  }
 
-    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);
-
-    // The pres shell resolution is updated by the the async zoom since the
-    // last paint.
-    float presShellResolution = aMetrics.GetPresShellResolution()
-                              * aMetrics.GetAsyncZoom().scale;
-    aUtils->SetResolutionAndScaleTo(presShellResolution, presShellResolution);
+  // Set the scroll port size, which determines the scroll range. For example if
+  // a 500-pixel document is shown in a 100-pixel frame, the scroll port length would
+  // be 100, and gecko would limit the maximum scroll offset to 400 (so as to prevent
+  // overscroll). Note that if the content here was zoomed to 2x, the document would
+  // be 1000 pixels long but the frame would still be 100 pixels, and so the maximum
+  // scroll range would be 900. Therefore this calculation depends on the zoom applied
+  // to the content relative to the container.
+  // Note that this needs to happen before scrolling the frame (in UpdateFrameCommon),
+  // otherwise the scroll position may get clamped incorrectly.
+  CSSSize scrollPort = aMetrics.CalculateCompositedSizeInCssPixels();
+  aUtils->SetScrollPositionClampingScrollPortSize(scrollPort.width, scrollPort.height);
 
-    // Finally, we set the displayport.
-    nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aMetrics.GetScrollId());
-    if (!content) {
-        return;
-    }
-    nsCOMPtr<nsIDOMElement> element = do_QueryInterface(content);
-    if (!element) {
-        return;
-    }
+  nsIContent* content = nsLayoutUtils::FindContentFor(aMetrics.GetScrollId());
+  ScrollFrame(content, aMetrics);
 
-    ScreenMargin margins = aMetrics.GetDisplayPortMargins();
-    aUtils->SetDisplayPortMarginsForElement(margins.left,
-                                            margins.top,
-                                            margins.right,
-                                            margins.bottom,
-                                            element, 0);
-    CSSRect baseCSS = aMetrics.CalculateCompositedRectInCssPixels();
-    nsRect base(0, 0,
-                baseCSS.width * nsPresContext::AppUnitsPerCSSPixel(),
-                baseCSS.height * nsPresContext::AppUnitsPerCSSPixel());
-    nsLayoutUtils::SetDisplayPortBaseIfNotSet(content, base);
+  // The pres shell resolution is updated by the the async zoom since the
+  // last paint.
+  float presShellResolution = aMetrics.GetPresShellResolution()
+                            * aMetrics.GetAsyncZoom().scale;
+  aUtils->SetResolutionAndScaleTo(presShellResolution, presShellResolution);
+
+  SetDisplayPortMargins(aUtils, content, aMetrics);
 }
 
 void
 APZCCallbackHelper::UpdateSubFrame(nsIContent* aContent,
                                    FrameMetrics& aMetrics)
 {
-    // Precondition checks
-    MOZ_ASSERT(aContent);
-    MOZ_ASSERT(aMetrics.GetUseDisplayPortMargins());
-    if (aMetrics.GetScrollId() == FrameMetrics::NULL_SCROLL_ID) {
-        return;
-    }
-
-    nsCOMPtr<nsIDOMWindowUtils> utils = GetDOMWindowUtils(aContent);
-    if (!utils) {
-        return;
-    }
-
-    // We currently do not support zooming arbitrary subframes. They can only
-    // be scrolled, so here we only have to set the scroll position and displayport.
-
-    nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aMetrics.GetScrollId());
-    bool scrollUpdated = false;
-    CSSPoint actualScrollOffset = ScrollFrameTo(sf, aMetrics.GetScrollOffset(), scrollUpdated);
+  // Precondition checks
+  MOZ_ASSERT(aContent);
+  MOZ_ASSERT(aMetrics.GetUseDisplayPortMargins());
 
-    nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aContent);
-    if (element) {
-        if (scrollUpdated) {
-            AdjustDisplayPortForScrollDelta(aMetrics, actualScrollOffset);
-        } else {
-            RecenterDisplayPort(aMetrics);
-        }
-        ScreenMargin margins = aMetrics.GetDisplayPortMargins();
-        utils->SetDisplayPortMarginsForElement(margins.left,
-                                               margins.top,
-                                               margins.right,
-                                               margins.bottom,
-                                               element, 0);
-        CSSRect baseCSS = aMetrics.CalculateCompositedRectInCssPixels();
-        nsRect base(0, 0,
-                    baseCSS.width * nsPresContext::AppUnitsPerCSSPixel(),
-                    baseCSS.height * nsPresContext::AppUnitsPerCSSPixel());
-        nsLayoutUtils::SetDisplayPortBaseIfNotSet(aContent, base);
-    }
-
-    aMetrics.SetScrollOffset(actualScrollOffset);
+  // We don't currently support zooming for subframes, so nothing extra
+  // needs to be done beyond the tasks common to this and UpdateRootFrame.
+  ScrollFrame(aContent, aMetrics);
+  if (nsCOMPtr<nsIDOMWindowUtils> utils = GetDOMWindowUtils(aContent)) {
+    SetDisplayPortMargins(utils, aContent, aMetrics);
+  }
 }
 
 already_AddRefed<nsIDOMWindowUtils>
 APZCCallbackHelper::GetDOMWindowUtils(const nsIDocument* aDoc)
 {
     nsCOMPtr<nsIDOMWindowUtils> utils;
     nsCOMPtr<nsIDOMWindow> window = aDoc->GetDefaultView();
     if (window) {