Bug 956263 - Add a preference to control the compositor frame-rate. r=mstange
authorBenoit Girard <b56girard@gmail.com>
Wed, 29 Jan 2014 18:26:38 -0500
changeset 165883 6a5f29b7bd75e902c88444fcffbb844b3fbe3bef
parent 165882 0a6f5180a06cb582c7807609ddd8ad0ae20d7844
child 165884 f53d87699bc2f4e319c533b94f767c2150e17650
push id39063
push userb56girard@gmail.com
push dateThu, 30 Jan 2014 00:11:36 +0000
treeherdermozilla-inbound@6a5f29b7bd75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs956263
milestone29.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 956263 - Add a preference to control the compositor frame-rate. r=mstange
gfx/layers/ipc/CompositorParent.cpp
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxPlatform.h
modules/libpref/src/init/all.js
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -521,34 +521,46 @@ CompositorParent::NotifyShadowTreeTransa
     ScheduleComposition();
   }
 }
 
 // Used when layout.frame_rate is -1. Needs to be kept in sync with
 // DEFAULT_FRAME_RATE in nsRefreshDriver.cpp.
 static const int32_t kDefaultFrameRate = 60;
 
+static int32_t
+CalculateCompositionFrameRate()
+{
+  int32_t compositionFrameRatePref = gfxPlatform::GetPrefLayersCompositionFrameRate();
+  if (compositionFrameRatePref < 0) {
+    // Use the same frame rate for composition as for layout.
+    int32_t layoutFrameRatePref = gfxPlatform::GetPrefLayoutFrameRate();
+    if (layoutFrameRatePref < 0) {
+      // TODO: The main thread frame scheduling code consults the actual
+      // monitor refresh rate in this case. We should do the same.
+      return kDefaultFrameRate;
+    }
+    return layoutFrameRatePref;
+  }
+  return compositionFrameRatePref;
+}
+
 void
 CompositorParent::ScheduleComposition()
 {
-  if (mCurrentCompositeTask) {
+  if (mCurrentCompositeTask || mPaused) {
     return;
   }
 
   bool initialComposition = mLastCompose.IsNull();
   TimeDuration delta;
   if (!initialComposition)
     delta = TimeStamp::Now() - mLastCompose;
 
-  int32_t rate = gfxPlatform::GetPrefLayoutFrameRate();
-  if (rate < 0) {
-    // TODO: The main thread frame scheduling code consults the actual monitor
-    // refresh rate in this case. We should do the same.
-    rate = kDefaultFrameRate;
-  }
+  int32_t rate = CalculateCompositionFrameRate();
 
   // If rate == 0 (ASAP mode), minFrameDelta must be 0 so there's no delay.
   TimeDuration minFrameDelta = TimeDuration::FromMilliseconds(
     rate == 0 ? 0.0 : std::max(0.0, 1000.0 / rate));
 
 #ifdef COMPOSITOR_PERFORMANCE_WARNING
   mExpectedComposeTime = TimeStamp::Now() + minFrameDelta;
 #endif
@@ -625,16 +637,23 @@ CompositorParent::CompositeInTransaction
   }
 
 #ifdef COMPOSITOR_PERFORMANCE_WARNING
   if (mExpectedComposeTime + TimeDuration::FromMilliseconds(15) < TimeStamp::Now()) {
     printf_stderr("Compositor: Composite took %i ms.\n",
                   15 + (int)(TimeStamp::Now() - mExpectedComposeTime).ToMilliseconds());
   }
 #endif
+
+  // 0 -> Full-tilt composite
+  if (gfxPlatform::GetPrefLayersCompositionFrameRate() == 0) {
+    // Special full-tilt composite mode for performance testing
+    ScheduleComposition();
+  }
+
   profiler_tracing("Paint", "Composite", TRACING_INTERVAL_END);
 }
 
 void
 CompositorParent::ComposeToTarget(DrawTarget* aTarget)
 {
   PROFILER_LABEL("CompositorParent", "ComposeToTarget");
   AutoRestore<bool> override(mOverrideComposeReadiness);
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -2065,16 +2065,17 @@ static bool sPrefLayersAccelerationForce
 static bool sPrefLayersAccelerationDisabled = false;
 static bool sPrefLayersPreferOpenGL = false;
 static bool sPrefLayersPreferD3D9 = false;
 static bool sPrefLayersDump = false;
 static bool sPrefLayersScrollGraph = false;
 static bool sPrefLayersEnableTiles = false;
 static bool sLayersSupportsD3D9 = false;
 static int  sPrefLayoutFrameRate = -1;
+static int  sPrefLayersCompositionFrameRate = -1;
 static bool sBufferRotationEnabled = false;
 static bool sComponentAlphaEnabled = true;
 static bool sPrefBrowserTabsRemote = false;
 
 static bool sLayersAccelerationPrefsInitialized = false;
 
 void
 InitLayersAccelerationPrefs()
@@ -2093,16 +2094,17 @@ InitLayersAccelerationPrefs()
     sPrefLayersAccelerationForceEnabled = Preferences::GetBool("layers.acceleration.force-enabled", false);
     sPrefLayersAccelerationDisabled = Preferences::GetBool("layers.acceleration.disabled", false);
     sPrefLayersPreferOpenGL = Preferences::GetBool("layers.prefer-opengl", false);
     sPrefLayersPreferD3D9 = Preferences::GetBool("layers.prefer-d3d9", false);
     sPrefLayersDump = Preferences::GetBool("layers.dump", false);
     sPrefLayersScrollGraph = Preferences::GetBool("layers.scroll-graph", false);
     sPrefLayersEnableTiles = Preferences::GetBool("layers.enable-tiles", false);
     sPrefLayoutFrameRate = Preferences::GetInt("layout.frame_rate", -1);
+    sPrefLayersCompositionFrameRate = Preferences::GetInt("layers.offmainthreadcomposition.frame-rate", -1);
     sBufferRotationEnabled = Preferences::GetBool("layers.bufferrotation.enabled", true);
     sComponentAlphaEnabled = Preferences::GetBool("layers.componentalpha.enabled", true);
     sPrefBrowserTabsRemote = BrowserTabsRemote();
 
 #ifdef XP_WIN
     if (sPrefLayersAccelerationForceEnabled) {
       sLayersSupportsD3D9 = true;
     } else {
@@ -2212,16 +2214,23 @@ gfxPlatform::GetPrefLayersScrollGraph()
 
 bool
 gfxPlatform::GetPrefLayersEnableTiles()
 {
   InitLayersAccelerationPrefs();
   return sPrefLayersEnableTiles;
 }
 
+int
+gfxPlatform::GetPrefLayersCompositionFrameRate()
+{
+  InitLayersAccelerationPrefs();
+  return sPrefLayersCompositionFrameRate;
+}
+
 bool
 gfxPlatform::BufferRotationEnabled()
 {
   MutexAutoLock autoLock(*gGfxPlatformPrefsLock);
 
   InitLayersAccelerationPrefs();
   return sBufferRotationEnabled;
 }
--- a/gfx/thebes/gfxPlatform.h
+++ b/gfx/thebes/gfxPlatform.h
@@ -505,16 +505,17 @@ public:
     static bool GetPrefLayersOffMainThreadCompositionEnabled();
     static bool GetPrefLayersOffMainThreadCompositionForceEnabled();
     static bool GetPrefLayersAccelerationForceEnabled();
     static bool GetPrefLayersAccelerationDisabled();
     static bool GetPrefLayersPreferOpenGL();
     static bool GetPrefLayersPreferD3D9();
     static bool CanUseDirect3D9();
     static int  GetPrefLayoutFrameRate();
+    static int  GetPrefLayersCompositionFrameRate();
     static bool GetPrefLayersDump();
     static bool GetPrefLayersScrollGraph();
     static bool GetPrefLayersEnableTiles();
 
     static bool OffMainThreadCompositionRequired();
 
     /**
      * Is it possible to use buffer rotation
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -4088,16 +4088,21 @@ pref("layers.frame-counter", false);
 pref("layers.max-active", -1);
 // When a layer is moving it will add a scroll graph to measure the smoothness
 // of the movement. NOTE: This pref triggers composites to refresh
 // the graph.
 pref("layers.scroll-graph", false);
 
 // Set the default values, and then override per-platform as needed
 pref("layers.offmainthreadcomposition.enabled", false);
+// Compositor target frame rate. NOTE: If vsync is enabled the compositor
+// frame rate will still be capped.
+// -1 -> default (match layout.frame_rate or 60 FPS)
+// 0  -> full-tilt mode: Recomposite even if not transaction occured.
+pref("layers.offmainthreadcomposition.frame-rate", -1);
 // Whether to use the deprecated texture architecture rather than the new one.
 pref("layers.use-deprecated-textures", true);
 #ifndef XP_WIN
 // Asynchonous video compositing using the ImageBridge IPDL protocol.
 // requires off-main-thread compositing.
 // Never works on Windows, so no point pref'ing it on.
 pref("layers.async-video.enabled",false);
 #endif