Bug 1314314 - Restrict when idle callbacks are fired. r?bkelly
MozReview-Commit-ID: L9ZTVFeHGTw
--- 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
@@ -2684,17 +2684,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
@@ -2741,16 +2741,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