Bug 1226826 - Record if painted displayport updates were due to repaints from the relevant layer tree or not. r?botond draft
authorKartikaya Gupta <kgupta@mozilla.com>
Wed, 13 Jan 2016 13:53:58 -0500
changeset 321503 87d91ccc2d5fe1ecc2902e654bafbba302f0b4d0
parent 321502 f561c59930af4b62c902a421d0ed5c36a08ce05c
child 512911 75c8adaed82c0eef5c603720c5dc78eb08ca6359
push id9390
push userkgupta@mozilla.com
push dateWed, 13 Jan 2016 18:54:16 +0000
reviewersbotond
bugs1226826
milestone46.0a1
Bug 1226826 - Record if painted displayport updates were due to repaints from the relevant layer tree or not. r?botond
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/apz/src/AsyncPanZoomController.h
gfx/layers/apz/test/gtest/TestAsyncPanZoomController.cpp
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -450,18 +450,18 @@ APZCTreeManager::PrepareNodeForLayer(con
       // to be destroyed, because it's going to remain active.
       aState.mNodesToDestroy.RemoveElement(node);
       node->SetPrevSibling(nullptr);
       node->SetLastChild(nullptr);
     }
 
     APZCTM_LOG("Using APZC %p for layer %p with identifiers %" PRId64 " %" PRId64 "\n", apzc, aLayer.GetLayer(), aLayersId, aMetrics.GetScrollId());
 
-    apzc->NotifyLayersUpdated(aMetrics,
-        aState.mIsFirstPaint && (aLayersId == aState.mOriginatingLayersId));
+    apzc->NotifyLayersUpdated(aMetrics, aState.mIsFirstPaint,
+        aLayersId == aState.mOriginatingLayersId);
 
     // Since this is the first time we are encountering an APZC with this guid,
     // the node holding it must be the primary holder. It may be newly-created
     // or not, depending on whether it went through the newApzc branch above.
     MOZ_ASSERT(node->IsPrimaryHolder() && node->GetApzc() && node->GetApzc()->Matches(guid));
 
     ParentLayerIntRegion clipRegion = ComputeClipRegion(state->mController, aLayer);
     node->SetHitTestData(
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -3126,34 +3126,50 @@ bool AsyncPanZoomController::IsCurrently
   if (painted.Contains(visible)) {
     return false;
   }
   APZC_LOG_FM(mFrameMetrics, "%p is currently checkerboarding (painted %s visble %s)",
     this, Stringify(painted).c_str(), Stringify(visible).c_str());
   return true;
 }
 
-void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetrics, bool aIsFirstPaint) {
+void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetrics,
+                                                 bool aIsFirstPaint,
+                                                 bool aThisLayerTreeUpdated)
+{
   APZThreadUtils::AssertOnCompositorThread();
 
   ReentrantMonitorAutoEnter lock(mMonitor);
   bool isDefault = mFrameMetrics.IsDefault();
 
   mLastContentPaintMetrics = aLayerMetrics;
 
   mFrameMetrics.SetScrollParentId(aLayerMetrics.GetScrollParentId());
-  APZC_LOG_FM(aLayerMetrics, "%p got a NotifyLayersUpdated with aIsFirstPaint=%d", this, aIsFirstPaint);
+  APZC_LOG_FM(aLayerMetrics, "%p got a NotifyLayersUpdated with aIsFirstPaint=%d, aThisLayerTreeUpdated=%d",
+    this, aIsFirstPaint, aThisLayerTreeUpdated);
 
   if (mCheckerboardEvent) {
     std::string str;
-    if (!aLayerMetrics.GetPaintRequestTime().IsNull()) {
-      TimeDuration paintTime = TimeStamp::Now() - aLayerMetrics.GetPaintRequestTime();
-      std::stringstream info;
-      info << " painttime " << paintTime.ToMilliseconds();
-      str = info.str();
+    if (aThisLayerTreeUpdated) {
+      if (!aLayerMetrics.GetPaintRequestTime().IsNull()) {
+        // Note that we might get the paint request time as non-null, but with
+        // aThisLayerTreeUpdated false. That can happen if we get a layer transaction
+        // from a different process right after we get the layer transaction with
+        // aThisLayerTreeUpdated == true. In this case we want to ignore the
+        // paint request time because it was already dumped in the previous layer
+        // transaction.
+        TimeDuration paintTime = TimeStamp::Now() - aLayerMetrics.GetPaintRequestTime();
+        std::stringstream info;
+        info << " painttime " << paintTime.ToMilliseconds();
+        str = info.str();
+      } else {
+        // This might be indicative of a wasted paint particularly if it happens
+        // during a checkerboard event.
+        str = " (this layertree updated)";
+      }
     }
     mCheckerboardEvent->UpdateRendertraceProperty(
         CheckerboardEvent::Page, aLayerMetrics.GetScrollableRect());
     mCheckerboardEvent->UpdateRendertraceProperty(
         CheckerboardEvent::PaintedDisplayPort,
         aLayerMetrics.GetDisplayPort() + aLayerMetrics.GetScrollOffset(),
         str);
     if (!aLayerMetrics.GetCriticalDisplayPort().IsEmpty()) {
@@ -3185,17 +3201,17 @@ void AsyncPanZoomController::NotifyLayer
         && (aLayerMetrics.GetScrollGeneration() != mFrameMetrics.GetScrollGeneration());
 
   bool smoothScrollRequested = aLayerMetrics.GetDoSmoothScroll()
        && (aLayerMetrics.GetScrollGeneration() != mFrameMetrics.GetScrollGeneration());
 
   // TODO if we're in a drag and scrollOffsetUpdated is set then we want to
   // ignore it
 
-  if (aIsFirstPaint || isDefault) {
+  if ((aIsFirstPaint && aThisLayerTreeUpdated) || isDefault) {
     // Initialize our internal state to something sane when the content
     // that was just painted is something we knew nothing about previously
     CancelAnimation();
 
     mFrameMetrics = aLayerMetrics;
     if (scrollOffsetUpdated) {
       AcknowledgeScrollUpdate();
     }
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -178,17 +178,18 @@ public:
 
   /**
    * A shadow layer update has arrived. |aLayerMetrics| is the new FrameMetrics
    * for the container layer corresponding to this APZC.
    * |aIsFirstPaint| is a flag passed from the shadow
    * layers code indicating that the frame metrics being sent with this call are
    * the initial metrics and the initial paint of the frame has just happened.
    */
-  void NotifyLayersUpdated(const FrameMetrics& aLayerMetrics, bool aIsFirstPaint);
+  void NotifyLayersUpdated(const FrameMetrics& aLayerMetrics, bool aIsFirstPaint,
+                           bool aThisLayerTreeUpdated);
 
   /**
    * The platform implementation must set the compositor parent so that we can
    * request composites.
    */
   void SetCompositorParent(CompositorParent* aCompositorParent);
 
   /**
--- a/gfx/layers/apz/test/gtest/TestAsyncPanZoomController.cpp
+++ b/gfx/layers/apz/test/gtest/TestAsyncPanZoomController.cpp
@@ -1176,23 +1176,23 @@ TEST_F(APZCBasicTester, ComplexTransform
   ParentLayerPoint pointOut;
   AsyncTransform viewTransformOut;
 
   // Both the parent and child layer should behave exactly the same here, because
   // the CSS transform on the child layer does not affect the SampleContentTransformForFrame code
 
   // initial transform
   apzc->SetFrameMetrics(metrics);
-  apzc->NotifyLayersUpdated(metrics, true);
+  apzc->NotifyLayersUpdated(metrics, true, true);
   apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
   EXPECT_EQ(AsyncTransform(LayerToParentLayerScale(1), ParentLayerPoint()), viewTransformOut);
   EXPECT_EQ(ParentLayerPoint(60, 60), pointOut);
 
   childApzc->SetFrameMetrics(childMetrics);
-  childApzc->NotifyLayersUpdated(childMetrics, true);
+  childApzc->NotifyLayersUpdated(childMetrics, true, true);
   childApzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
   EXPECT_EQ(AsyncTransform(LayerToParentLayerScale(1), ParentLayerPoint()), viewTransformOut);
   EXPECT_EQ(ParentLayerPoint(60, 60), pointOut);
 
   // do an async scroll by 5 pixels and check the transform
   metrics.ScrollBy(CSSPoint(5, 0));
   apzc->SetFrameMetrics(metrics);
   apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);