Bug 787445: B2G: Rip out async paint throttling code, use compression instead r=cjones
authorDoug Sherk <dsherk2@mozilla.com>
Sat, 29 Sep 2012 00:02:41 -0400
changeset 108708 9698936945c6159814a7246231856fb47cc20102
parent 108707 48d10ef28d529be510ad6771a5e4d8d6a50493d7
child 108709 33031c64f7d16d3b5fafa71ef6cbc857aeeb2482
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewerscjones
bugs787445
milestone18.0a1
Bug 787445: B2G: Rip out async paint throttling code, use compression instead r=cjones
dom/ipc/PBrowser.ipdl
gfx/layers/ipc/AsyncPanZoomController.cpp
gfx/layers/ipc/AsyncPanZoomController.h
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -283,19 +283,19 @@ child:
      * |Show()| and |Move()| take IntSizes rather than Rects because
      * content processes always render to a virtual <0, 0> top-left
      * point.
      */
     Show(nsIntSize size);
 
     LoadURL(nsCString uri);
 
-    UpdateDimensions(nsRect rect, nsIntSize size);
+    UpdateDimensions(nsRect rect, nsIntSize size) compress;
 
-    UpdateFrame(FrameMetrics frame);
+    UpdateFrame(FrameMetrics frame) compress;
 
     /**
      * Requests handling of a double tap. |point| is in CSS pixels, relative to
      * the scroll offset. This message is expected to round-trip back to
      * ZoomToRect() with a rect indicating where we should zoom to.
      */
     HandleDoubleTap(nsIntPoint point);
 
--- a/gfx/layers/ipc/AsyncPanZoomController.cpp
+++ b/gfx/layers/ipc/AsyncPanZoomController.cpp
@@ -87,17 +87,17 @@ AsyncPanZoomController::AsyncPanZoomCont
      mY(this),
      mAllowZoom(true),
      mMinZoom(MIN_ZOOM),
      mMaxZoom(MAX_ZOOM),
      mMonitor("AsyncPanZoomController"),
      mLastSampleTime(TimeStamp::Now()),
      mState(NOTHING),
      mDPI(72),
-     mContentPainterStatus(CONTENT_IDLE),
+     mWaitingForContentToPaint(false),
      mDisableNextTouchBatch(false),
      mHandlingTouchQueue(false)
 {
   if (aGestures == USE_GESTURE_DETECTOR) {
     mGestureEventListener = new GestureEventListener(this);
   }
 
   SetDPI(mDPI);
@@ -814,23 +814,22 @@ void AsyncPanZoomController::RequestCont
   if (fabsf(oldDisplayPort.x - newDisplayPort.x) < EPSILON &&
       fabsf(oldDisplayPort.y - newDisplayPort.y) < EPSILON &&
       fabsf(oldDisplayPort.width - newDisplayPort.width) < EPSILON &&
       fabsf(oldDisplayPort.height - newDisplayPort.height) < EPSILON &&
       mFrameMetrics.mResolution.width == mLastPaintRequestMetrics.mResolution.width) {
     return;
   }
 
-  if (mContentPainterStatus == CONTENT_IDLE) {
-    mContentPainterStatus = CONTENT_PAINTING;
-    mLastPaintRequestMetrics = mFrameMetrics;
-    mGeckoContentController->RequestContentRepaint(mFrameMetrics);
-  } else {
-    mContentPainterStatus = CONTENT_PAINTING_AND_PAINT_PENDING;
-  }
+  // This message is compressed, so fire whether or not we already have a paint
+  // queued up. We need to know whether or not a paint was requested anyways,
+  // ofr the purposes of content calling window.scrollTo().
+  mGeckoContentController->RequestContentRepaint(mFrameMetrics);
+  mLastPaintRequestMetrics = mFrameMetrics;
+  mWaitingForContentToPaint = true;
 }
 
 bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSampleTime,
                                                             ContainerLayer* aLayer,
                                                             gfx3DMatrix* aNewTransform) {
   // The eventual return value of this function. The compositor needs to know
   // whether or not to advance by a frame as soon as it can. For example, if a
   // fling is happening, it has to keep compositing so that the animation is
@@ -927,24 +926,17 @@ bool AsyncPanZoomController::SampleConte
   return requestAnimationFrame;
 }
 
 void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFrame, bool aIsFirstPaint) {
   MonitorAutoLock monitor(mMonitor);
 
   mLastContentPaintMetrics = aViewportFrame;
 
-  if (mContentPainterStatus != CONTENT_IDLE) {
-    if (mContentPainterStatus == CONTENT_PAINTING_AND_PAINT_PENDING) {
-      mContentPainterStatus = CONTENT_IDLE;
-      RequestContentRepaint();
-    } else {
-      mContentPainterStatus = CONTENT_IDLE;
-    }
-  } else {
+  if (!mWaitingForContentToPaint) {
     // No paint was requested, but we got one anyways. One possible cause of this
     // is that content could have fired a scrollTo(). In this case, we should take
     // the new scroll offset. Document/viewport changes are handled elsewhere.
     // Also note that, since NotifyLayersUpdated() is called whenever there's a
     // layers update, we didn't necessarily get a new scroll offset, but we're
     // updating our local copy of it anyways just in case.
     switch (mState) {
     case NOTHING:
@@ -954,19 +946,19 @@ void AsyncPanZoomController::NotifyLayer
       mFrameMetrics.mScrollOffset = aViewportFrame.mScrollOffset;
       break;
     // Don't clobber if we're in other states.
     default:
       break;
     }
   }
 
+  mWaitingForContentToPaint = false;
+
   if (aIsFirstPaint || mFrameMetrics.IsDefault()) {
-    mContentPainterStatus = CONTENT_IDLE;
-
     mX.CancelTouch();
     mY.CancelTouch();
 
     // The composition bounds are not stored within the layers code, so we have
     // to reset them back to what they were every time we overwrite them.
     nsIntRect compositionBounds = mFrameMetrics.mCompositionBounds;
     mFrameMetrics = aViewportFrame;
     mFrameMetrics.mCompositionBounds = compositionBounds;
--- a/gfx/layers/ipc/AsyncPanZoomController.h
+++ b/gfx/layers/ipc/AsyncPanZoomController.h
@@ -419,35 +419,16 @@ private:
     PANNING,        /* panning without axis lock */
     PINCHING,       /* nth touch-start, where n > 1. this mode allows pan and zoom */
     ANIMATING_ZOOM, /* animated zoom to a new rect */
     WAITING_LISTENERS, /* a state halfway between NOTHING and TOUCHING - the user has
                     put a finger down, but we don't yet know if a touch listener has
                     prevented the default actions yet. we still need to abort animations. */
   };
 
-  enum ContentPainterStatus {
-    // A paint may be happening, but it is not due to any action taken by this
-    // thread. For example, content could be invalidating itself, but
-    // AsyncPanZoomController has nothing to do with that.
-    CONTENT_IDLE,
-    // Set every time we dispatch a request for a repaint. When a
-    // ShadowLayersUpdate arrives and the metrics of this frame have changed, we
-    // toggle this off and assume that the paint has completed.
-    CONTENT_PAINTING,
-    // Set when we have a new displayport in the pipeline that we want to paint.
-    // When a ShadowLayersUpdate comes in, we dispatch a new repaint using
-    // mFrameMetrics.mDisplayPort (the most recent request) if this is toggled.
-    // This is distinct from CONTENT_PAINTING in that it signals that a repaint
-    // is happening, whereas this signals that we want to repaint as soon as the
-    // previous paint finishes. When the request is eventually made, it will use
-    // the most up-to-date metrics.
-   CONTENT_PAINTING_AND_PAINT_PENDING
-  };
-
   /**
    * Helper to set the current state. Holds the monitor before actually setting
    * it. If the monitor is already held by the current thread, it is safe to
    * instead use: |mState = NEWSTATE;|
    */
   void SetState(PanZoomState aState);
 
   nsRefPtr<CompositorParent> mCompositorParent;
@@ -516,17 +497,17 @@ private:
   PanZoomState mState;
 
   int mDPI;
 
   // Stores the current paint status of the frame that we're managing. Repaints
   // may be triggered by other things (like content doing things), in which case
   // this status will not be updated. It is only changed when this class
   // requests a repaint.
-  ContentPainterStatus mContentPainterStatus;
+  bool mWaitingForContentToPaint;
 
   // Flag used to determine whether or not we should disable handling of the
   // next batch of touch events. This is used for sync scrolling of subframes.
   bool mDisableNextTouchBatch;
 
   // Flag used to determine whether or not we should try to enter the
   // WAITING_LISTENERS state. This is used in the case that we are processing a
   // queued up event block. If set, this means that we are handling this queue