Bug 1213095 - Don't allow RequestContentRepaint to mutate the provided FrameMetrics. r=botond
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 18 Jan 2016 15:23:08 -0500
changeset 280405 1e5a5bfc9561b611aff4f8f6dd5816d26eb8d027
parent 280404 1c4fcd82c71d11e503c904fbf93f2e930d0b327a
child 280406 a829107699f097eac9819d5371421af7f4012f48
push id70434
push userkgupta@mozilla.com
push dateMon, 18 Jan 2016 20:24:53 +0000
treeherdermozilla-inbound@d7c04b4c6cff [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs1213095
milestone46.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 1213095 - Don't allow RequestContentRepaint to mutate the provided FrameMetrics. r=botond
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/apz/src/AsyncPanZoomController.h
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -2757,17 +2757,17 @@ void AsyncPanZoomController::FlushRepain
   RequestContentRepaint();
   UpdateSharedCompositorFrameMetrics();
 }
 
 void AsyncPanZoomController::FlushRepaintForNewInputBlock() {
   APZC_LOG("%p flushing repaint for new input block\n", this);
 
   ReentrantMonitorAutoEnter lock(mMonitor);
-  RequestContentRepaint(mFrameMetrics);
+  RequestContentRepaint();
   UpdateSharedCompositorFrameMetrics();
 }
 
 bool AsyncPanZoomController::SnapBackIfOverscrolled() {
   ReentrantMonitorAutoEnter lock(mMonitor);
   // It's possible that we're already in the middle of an overscroll
   // animation - if so, don't start a new one.
   if (IsOverscrolled() && mState != OVERSCROLL_ANIMATION) {
@@ -2800,36 +2800,38 @@ bool AsyncPanZoomController::IsPannable(
 }
 
 int32_t AsyncPanZoomController::GetLastTouchIdentifier() const {
   RefPtr<GestureEventListener> listener = GetGestureEventListener();
   return listener ? listener->GetLastTouchIdentifier() : -1;
 }
 
 void AsyncPanZoomController::RequestContentRepaint() {
-  RequestContentRepaint(mFrameMetrics);
+  ParentLayerPoint velocity = GetVelocityVector();
+  mFrameMetrics.SetDisplayPortMargins(CalculatePendingDisplayPort(mFrameMetrics, velocity));
+  mFrameMetrics.SetUseDisplayPortMargins(true);
+  mFrameMetrics.SetPaintRequestTime(TimeStamp::Now());
+  RequestContentRepaint(mFrameMetrics, velocity);
 }
 
 /*static*/ CSSRect
 GetDisplayPortRect(const FrameMetrics& aFrameMetrics)
 {
   // This computation is based on what happens in CalculatePendingDisplayPort. If that
   // changes then this might need to change too
   CSSRect baseRect(aFrameMetrics.GetScrollOffset(),
                    aFrameMetrics.CalculateBoundedCompositedSizeInCssPixels());
   baseRect.Inflate(aFrameMetrics.GetDisplayPortMargins() / aFrameMetrics.DisplayportPixelsPerCSSPixel());
   return baseRect;
 }
 
-void AsyncPanZoomController::RequestContentRepaint(FrameMetrics& aFrameMetrics)
+void
+AsyncPanZoomController::RequestContentRepaint(const FrameMetrics& aFrameMetrics,
+                                              const ParentLayerPoint& aVelocity)
 {
-  ParentLayerPoint velocity = GetVelocityVector();
-  aFrameMetrics.SetDisplayPortMargins(CalculatePendingDisplayPort(aFrameMetrics, velocity));
-  aFrameMetrics.SetUseDisplayPortMargins(true);
-
   // If we're trying to paint what we already think is painted, discard this
   // request since it's a pointless paint.
   ScreenMargin marginDelta = (mLastPaintRequestMetrics.GetDisplayPortMargins()
                            - aFrameMetrics.GetDisplayPortMargins());
   if (fabsf(marginDelta.left) < EPSILON &&
       fabsf(marginDelta.top) < EPSILON &&
       fabsf(marginDelta.right) < EPSILON &&
       fabsf(marginDelta.bottom) < EPSILON &&
@@ -2841,41 +2843,39 @@ void AsyncPanZoomController::RequestCont
       fabsf(aFrameMetrics.GetViewport().width -
             mLastPaintRequestMetrics.GetViewport().width) < EPSILON &&
       fabsf(aFrameMetrics.GetViewport().height -
             mLastPaintRequestMetrics.GetViewport().height) < EPSILON &&
       aFrameMetrics.GetScrollGeneration() == mLastPaintRequestMetrics.GetScrollGeneration()) {
     return;
   }
 
-  aFrameMetrics.SetPaintRequestTime(TimeStamp::Now());
   RefPtr<GeckoContentController> controller = GetGeckoContentController();
   if (!controller) {
     return;
   }
 
   APZC_LOG_FM(aFrameMetrics, "%p requesting content repaint", this);
   if (mCheckerboardEvent) {
     std::stringstream info;
-    info << " velocity " << velocity;
+    info << " velocity " << aVelocity;
     std::string str = info.str();
     mCheckerboardEvent->UpdateRendertraceProperty(
         CheckerboardEvent::RequestedDisplayPort, GetDisplayPortRect(aFrameMetrics),
         str);
   }
 
   if (NS_IsMainThread()) {
     controller->RequestContentRepaint(aFrameMetrics);
   } else {
     NS_DispatchToMainThread(NS_NewRunnableMethodWithArg<FrameMetrics>(
       controller, &GeckoContentController::RequestContentRepaint, aFrameMetrics));
   }
   mExpectedGeckoMetrics = aFrameMetrics;
   mLastPaintRequestMetrics = aFrameMetrics;
-  aFrameMetrics.SetPresShellId(mLastContentPaintMetrics.GetPresShellId());
 }
 
 bool AsyncPanZoomController::UpdateAnimation(const TimeStamp& aSampleTime,
                                              Vector<Task*>* aOutDeferredTasks)
 {
   APZThreadUtils::AssertOnCompositorThread();
 
   // This function may get called multiple with the same sample time, because
@@ -3448,29 +3448,31 @@ void AsyncPanZoomController::ZoomToRect(
     if (!zoomOut && (sizeAfterZoom.height > aRect.height)) {
       aRect.y -= (sizeAfterZoom.height - aRect.height) * 0.5f;
       if (aRect.y < 0.0f) {
         aRect.y = 0.0f;
       }
     }
 
     endZoomToMetrics.SetScrollOffset(aRect.TopLeft());
-    endZoomToMetrics.SetDisplayPortMargins(
-      CalculatePendingDisplayPort(endZoomToMetrics, ParentLayerPoint(0,0)));
-    endZoomToMetrics.SetUseDisplayPortMargins(true);
 
     StartAnimation(new ZoomAnimation(
         mFrameMetrics.GetScrollOffset(),
         mFrameMetrics.GetZoom(),
         endZoomToMetrics.GetScrollOffset(),
         endZoomToMetrics.GetZoom()));
 
     // Schedule a repaint now, so the new displayport will be painted before the
     // animation finishes.
-    RequestContentRepaint(endZoomToMetrics);
+    ParentLayerPoint velocity(0, 0);
+    endZoomToMetrics.SetDisplayPortMargins(
+      CalculatePendingDisplayPort(endZoomToMetrics, velocity));
+    endZoomToMetrics.SetUseDisplayPortMargins(true);
+    endZoomToMetrics.SetPaintRequestTime(TimeStamp::Now());
+    RequestContentRepaint(endZoomToMetrics, velocity);
   }
 }
 
 CancelableBlockState*
 AsyncPanZoomController::CurrentInputBlock() const
 {
   return GetInputQueue()->CurrentBlock();
 }
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -572,31 +572,26 @@ protected:
   /**
    * Does any panning required due to a new touch event.
    */
   void TrackTouch(const MultiTouchInput& aEvent);
 
   /**
    * Utility function to send updated FrameMetrics to Gecko so that it can paint
    * the displayport area. Calls into GeckoContentController to do the actual
-   * work. Note that only one paint request can be active at a time. If a paint
-   * request is made while a paint is currently happening, it gets queued up. If
-   * a new paint request arrives before a paint is completed, the old request
-   * gets discarded.
+   * work. This call will use the current metrics.
    */
   void RequestContentRepaint();
 
   /**
-   * Tell the paint throttler to request a content repaint with the given
-   * metrics.  (Helper function used by RequestContentRepaint.) If aThrottled
-   * is set to false, the repaint request is sent directly without going through
-   * the paint throttler. In particular, the GeckoContentController::RequestContentRepaint
-   * function will be invoked before this function returns.
+   * Send the provided metrics to Gecko to trigger a repaint. This function
+   * may filter duplicate calls with the same metrics.
    */
-  void RequestContentRepaint(FrameMetrics& aFrameMetrics);
+  void RequestContentRepaint(const FrameMetrics& aFrameMetrics,
+                             const ParentLayerPoint& aVelocity);
 
   /**
    * Gets the current frame metrics. This is *not* the Gecko copy stored in the
    * layers code.
    */
   const FrameMetrics& GetFrameMetrics() const;
 
   /**