Compositor performance warnings
authorBenoit Girard <b56girard@gmail.com>
Fri, 10 Feb 2012 18:06:17 -0500
changeset 92433 8822397fc42db6f1d27022cdc809e2ae88f13f3c
parent 92432 7fafa64fced9e0800ad643a1085900a19b13ab7b
child 92434 d957fe7de35637f0a66952c273d98bfe6382b692
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone13.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
Compositor performance warnings
gfx/layers/ipc/CompositorParent.cpp
gfx/layers/ipc/CompositorParent.h
gfx/layers/ipc/ShadowLayersParent.cpp
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -135,19 +135,26 @@ CompositorParent::ScheduleComposition()
     return;
   }
 
   bool initialComposition = mLastCompose.IsNull();
   TimeDuration delta;
   if (!initialComposition)
     delta = mozilla::TimeStamp::Now() - mLastCompose;
 
+#ifdef COMPOSITOR_PERFORMANCE_WARNING
+  mExpectedComposeTime = mozilla::TimeStamp::Now() + TimeDuration::FromMilliseconds(15);
+#endif
+
   printf_stderr("Schedule composition\n");
   mCurrentCompositeTask = NewRunnableMethod(this, &CompositorParent::Composite);
   if (!initialComposition && delta.ToMilliseconds() < 15) {
+#ifdef COMPOSITOR_PERFORMANCE_WARNING
+    mExpectedComposeTime = mozilla::TimeStamp::Now() + TimeDuration::FromMilliseconds(15 - delta.ToMilliseconds());
+#endif
     MessageLoop::current()->PostDelayedTask(FROM_HERE, mCurrentCompositeTask, 15 - delta.ToMilliseconds());
   } else {
     MessageLoop::current()->PostTask(FROM_HERE, mCurrentCompositeTask);
   }
 }
 
 void
 CompositorParent::SetTransformation(float aScale, nsIntPoint aScrollOffset)
@@ -157,16 +164,18 @@ CompositorParent::SetTransformation(floa
   mScrollOffset = aScrollOffset;
 }
 
 void
 CompositorParent::Composite()
 {
   mCurrentCompositeTask = NULL;
 
+  mLastCompose = mozilla::TimeStamp::Now();
+
   if (mPaused || !mLayerManager) {
     return;
   }
 
 #ifdef MOZ_WIDGET_ANDROID
   RequestViewTransform();
   Layer* layer = GetPrimaryScrollableLayer();
   printf_stderr("Correcting for position fixed %i, %i\n", -mScrollOffset.x, -mScrollOffset.y);
@@ -183,17 +192,23 @@ CompositorParent::Composite()
   gfx3DMatrix transform = layer->GetTransform();
   transform *= worldTransform;
   TransformLayerUserData* transformUserData = new TransformLayerUserData(transform);
   mLayerManager->SetUserData(nsGkAtoms::transform, transformUserData);
 #endif
 #endif
 
   mLayerManager->EndEmptyTransaction();
-  mLastCompose = mozilla::TimeStamp::Now();
+
+#ifdef COMPOSITOR_PERFORMANCE_WARNING
+  if (mExpectedComposeTime + TimeDuration::FromMilliseconds(15) < mozilla::TimeStamp::Now()) {
+    printf_stderr("Compositor: Compose frame took %i time then expected.\n",
+                  (int)(mozilla::TimeStamp::Now() - mExpectedComposeTime).ToMilliseconds());
+  }
+#endif
 }
 
 #ifdef MOZ_WIDGET_ANDROID
 // Do a breadth-first search to find the first layer in the tree with a
 // displayport set.
 Layer*
 CompositorParent::GetPrimaryScrollableLayer()
 {
--- a/gfx/layers/ipc/CompositorParent.h
+++ b/gfx/layers/ipc/CompositorParent.h
@@ -36,16 +36,24 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef mozilla_layers_CompositorParent_h
 #define mozilla_layers_CompositorParent_h
 
+// Enable this pref to turn on compositor performance warning.
+// This will print warnings if the compositor isn't meeting
+// it's responsiveness objectives:
+//    1) Compose a frame within 15ms of receiving a ScheduleCompositeCall
+//    2) Unless a frame was composited within the throttle threshold in
+//       which the deadline will be 15ms + throttle threshold
+#define COMPOSITOR_PERFORMANCE_WARNING
+
 #include "mozilla/layers/PCompositorParent.h"
 #include "mozilla/layers/PLayersParent.h"
 #include "base/thread.h"
 #include "ShadowLayersManager.h"
 
 class nsIWidget;
 
 namespace mozilla {
@@ -124,16 +132,19 @@ private:
    */
   Layer* GetPrimaryScrollableLayer();
 #endif
 
   nsRefPtr<LayerManager> mLayerManager;
   nsIWidget* mWidget;
   CancelableTask *mCurrentCompositeTask;
   TimeStamp mLastCompose;
+#ifdef COMPOSITOR_PERFORMANCE_WARNING
+  TimeStamp mExpectedComposeTime;
+#endif
 
   bool mPaused;
   float mXScale;
   float mYScale;
   nsIntPoint mScrollOffset;
 
   DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
 };
--- a/gfx/layers/ipc/ShadowLayersParent.cpp
+++ b/gfx/layers/ipc/ShadowLayersParent.cpp
@@ -144,16 +144,20 @@ ShadowLayersParent::Destroy()
     slp->Destroy();
   }
 }
 
 bool
 ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
                                InfallibleTArray<EditReply>* reply)
 {
+#ifdef COMPOSITOR_PERFORMANCE_WARNING
+  TimeStamp updateStart = TimeStamp::Now();
+#endif
+
   MOZ_LAYERS_LOG(("[ParentSide] received txn with %d edits", cset.Length()));
 
   if (mDestroyed || layer_manager()->IsDestroyed()) {
     return true;
   }
 
   EditReplyVector replyv;
 
@@ -380,16 +384,21 @@ ShadowLayersParent::RecvUpdate(const Inf
 
   // Ensure that any pending operations involving back and front
   // buffers have completed, so that neither process stomps on the
   // other's buffer contents.
   ShadowLayerManager::PlatformSyncBeforeReplyUpdate();
 
   mShadowLayersManager->ShadowLayersUpdated();
 
+#ifdef COMPOSITOR_PERFORMANCE_WARNING
+  printf_stderr("Compositor: Layers update took %i ms (blocking gecko).\n",
+                (int)(mozilla::TimeStamp::Now() - updateStart).ToMilliseconds());
+#endif
+
   return true;
 }
 
 PLayerParent*
 ShadowLayersParent::AllocPLayer()
 {
   return new ShadowLayerParent();
 }