Bug 1314314 - Restrict when idle callbacks are fired. r=bkelly
authorAndreas Farre <farre@mozilla.com>
Thu, 03 Nov 2016 18:47:23 +0100
changeset 321067 3e2ce6e549e3c43ab11cce77839d7389b3c8a967
parent 321066 0797f7f58f2287952815196dece545faf5af14a1
child 321068 5bd71ef29d81f37ffec1c12f8c912a546ae3fadc
push id30915
push userphilringnalda@gmail.com
push dateSat, 05 Nov 2016 03:42:29 +0000
treeherdermozilla-central@a7c654513f2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbkelly
bugs1314314
milestone52.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 1314314 - Restrict when idle callbacks are fired. r=bkelly MozReview-Commit-ID: L9ZTVFeHGTw
layout/base/nsLayoutUtils.cpp
modules/libpref/init/all.js
xpcom/threads/MainThreadIdlePeriod.cpp
xpcom/threads/MainThreadIdlePeriod.h
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -151,17 +151,17 @@ using namespace mozilla::gfx;
 #define FLOAT_LOGICAL_VALUES_ENABLED_PREF_NAME "layout.css.float-logical-values.enabled"
 #define BG_CLIP_TEXT_ENABLED_PREF_NAME "layout.css.background-clip-text.enabled"
 
 // The time in number of frames that we estimate for a refresh driver
 // to be quiescent
 #define DEFAULT_QUIESCENT_FRAMES 2
 // The time (milliseconds) we estimate is needed between the end of an
 // idle time and the next Tick.
-#define DEFAULT_IDLE_PERIOD_TIME_LIMIT 3.0f
+#define DEFAULT_IDLE_PERIOD_TIME_LIMIT 1.0f
 
 #ifdef DEBUG
 // TODO: remove, see bug 598468.
 bool nsLayoutUtils::gPreventAssertInCompareTreePosition = false;
 #endif // DEBUG
 
 typedef FrameMetrics::ViewID ViewID;
 typedef nsStyleTransformMatrix::TransformReferenceBox TransformReferenceBox;
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -2688,17 +2688,17 @@ pref("layout.spammy_warnings.enabled", f
 pref("layout.float-fragments-inside-column.enabled", true);
 
 // The number of frames times the frame rate is the time required to
 // pass without painting used to guess that we'll not paint again soon
 pref("layout.idle_period.required_quiescent_frames", 2);
 
 // The amount of time (milliseconds) needed between an idle period's
 // end and the start of the next tick to avoid jank.
-pref("layout.idle_period.time_limit", 3);
+pref("layout.idle_period.time_limit", 1);
 
 // Is support for the Web Animations API enabled?
 // Before enabling this by default, make sure also CSSPseudoElement interface
 // has been spec'ed properly, or we should add a separate pref for
 // CSSPseudoElement interface. See Bug 1174575 for further details.
 #ifdef RELEASE_OR_BETA
 pref("dom.animations-api.core.enabled", false);
 #else
@@ -2745,16 +2745,24 @@ pref("dom.global_stop_script", true);
 pref("dom.archivereader.enabled", false);
 
 // Time (milliseconds) between throttled idle callbacks.
 pref("dom.idle_period.throttled_length", 10000);
 
 // The amount of idle time (milliseconds) reserved for a long idle period
 pref("idle_queue.long_period", 50);
 
+// The minimum amount of time (milliseconds) required for an idle
+// period to be scheduled on the main thread. N.B. that
+// layout.idle_period.time_limit adds padding at the end of the idle
+// period, which makes the point in time that we expect to become busy
+// again be:
+// now + idle_queue.min_period + layout.idle_period.time_limit
+pref("idle_queue.min_period", 3);
+
 // Hang monitor timeout after which we kill the browser, in seconds
 // (0 is disabled)
 // Disabled on all platforms per bug 705748 until the found issues are
 // resolved.
 pref("hangmonitor.timeout", 0);
 
 pref("plugins.load_appdir_plugins", false);
 // If true, plugins will be click to play
--- a/xpcom/threads/MainThreadIdlePeriod.cpp
+++ b/xpcom/threads/MainThreadIdlePeriod.cpp
@@ -6,44 +6,71 @@
 
 #include "MainThreadIdlePeriod.h"
 
 #include "mozilla/Maybe.h"
 #include "mozilla/Preferences.h"
 #include "nsRefreshDriver.h"
 
 #define DEFAULT_LONG_IDLE_PERIOD 50.0f
+#define DEFAULT_MIN_IDLE_PERIOD 3.0f
 
 namespace mozilla {
 
 NS_IMETHODIMP
 MainThreadIdlePeriod::GetIdlePeriodHint(TimeStamp* aIdleDeadline)
 {
+  MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aIdleDeadline);
 
   Maybe<TimeStamp> deadline = nsRefreshDriver::GetIdleDeadlineHint();
 
   if (deadline.isSome()) {
-    *aIdleDeadline = deadline.value();
+    // If the idle period is too small, then just return a null time
+    // to indicate we are busy. Otherwise return the actual deadline.
+    TimeDuration minIdlePeriod =
+      TimeDuration::FromMilliseconds(GetMinIdlePeriod());
+    bool busySoon = deadline.value().IsNull() ||
+                    (TimeStamp::Now() >= (deadline.value() - minIdlePeriod));
+    *aIdleDeadline = busySoon ? TimeStamp() : deadline.value();
   } else {
     *aIdleDeadline =
       TimeStamp::Now() + TimeDuration::FromMilliseconds(GetLongIdlePeriod());
   }
 
   return NS_OK;
 }
 
 /* static */ float
 MainThreadIdlePeriod::GetLongIdlePeriod()
 {
+  MOZ_ASSERT(NS_IsMainThread());
+
   static float sLongIdlePeriod = DEFAULT_LONG_IDLE_PERIOD;
   static bool sInitialized = false;
 
   if (!sInitialized && Preferences::IsServiceAvailable()) {
     sInitialized = true;
     Preferences::AddFloatVarCache(&sLongIdlePeriod, "idle_queue.long_period",
                                   DEFAULT_LONG_IDLE_PERIOD);
   }
 
   return sLongIdlePeriod;
 }
 
+/* static */ float
+MainThreadIdlePeriod::GetMinIdlePeriod()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  static float sMinIdlePeriod = DEFAULT_MIN_IDLE_PERIOD;
+  static bool sInitialized = false;
+
+  if (!sInitialized && Preferences::IsServiceAvailable()) {
+    sInitialized = true;
+    Preferences::AddFloatVarCache(&sMinIdlePeriod, "idle_queue.min_period",
+                                  DEFAULT_MIN_IDLE_PERIOD);
+  }
+
+  return sMinIdlePeriod;
+}
+
 } // namespace mozilla
--- a/xpcom/threads/MainThreadIdlePeriod.h
+++ b/xpcom/threads/MainThreadIdlePeriod.h
@@ -13,15 +13,16 @@
 namespace mozilla {
 
 class MainThreadIdlePeriod final : public IdlePeriod
 {
 public:
   NS_DECL_NSIIDLEPERIOD
 
   static float GetLongIdlePeriod();
+  static float GetMinIdlePeriod();
 private:
   virtual ~MainThreadIdlePeriod() {}
 };
 
 } // namespace mozilla
 
 #endif // mozilla_dom_mainthreadidleperiod_h