Title: [175441] trunk/Source/WebCore
- Revision
- 175441
- Author
- [email protected]
- Date
- 2014-10-31 17:12:51 -0700 (Fri, 31 Oct 2014)
Log Message
Support throttling of DOMTimers using nested setTimeout() calls
https://bugs.webkit.org/show_bug.cgi?id=138262
Reviewed by Gavin Barraclough.
Extend DOMTimers throttling support to timers that are using nested
setTimeout() calls instead of a setInterval(). To achieve this, this
patch introduces a NestedTimersVector singleton class where nested
timers are appended, and for which we potentially update the next
firing time, after the parent timer is done executing.
I have verified this helps on cnn.com for example, which has timers
interacting with non-visible plugins that are scheduled using nested
setTimeout() calls with a frequency of 150 / 200 ms.
* page/DOMTimer.cpp:
(WebCore::NestedTimersVector::NestedTimersVector):
(WebCore::NestedTimersVector::~NestedTimersVector):
(WebCore::NestedTimersVector::registerTimer):
(WebCore::NestedTimersVector::begin):
(WebCore::NestedTimersVector::end):
(WebCore::DOMTimer::install):
(WebCore::DOMTimer::updateThrottlingStateIfNecessary):
(WebCore::DOMTimer::fired):
* page/DOMTimer.h:
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (175440 => 175441)
--- trunk/Source/WebCore/ChangeLog 2014-10-31 23:58:53 UTC (rev 175440)
+++ trunk/Source/WebCore/ChangeLog 2014-11-01 00:12:51 UTC (rev 175441)
@@ -1,5 +1,33 @@
2014-10-31 Chris Dumez <[email protected]>
+ Support throttling of DOMTimers using nested setTimeout() calls
+ https://bugs.webkit.org/show_bug.cgi?id=138262
+
+ Reviewed by Gavin Barraclough.
+
+ Extend DOMTimers throttling support to timers that are using nested
+ setTimeout() calls instead of a setInterval(). To achieve this, this
+ patch introduces a NestedTimersVector singleton class where nested
+ timers are appended, and for which we potentially update the next
+ firing time, after the parent timer is done executing.
+
+ I have verified this helps on cnn.com for example, which has timers
+ interacting with non-visible plugins that are scheduled using nested
+ setTimeout() calls with a frequency of 150 / 200 ms.
+
+ * page/DOMTimer.cpp:
+ (WebCore::NestedTimersVector::NestedTimersVector):
+ (WebCore::NestedTimersVector::~NestedTimersVector):
+ (WebCore::NestedTimersVector::registerTimer):
+ (WebCore::NestedTimersVector::begin):
+ (WebCore::NestedTimersVector::end):
+ (WebCore::DOMTimer::install):
+ (WebCore::DOMTimer::updateThrottlingStateIfNecessary):
+ (WebCore::DOMTimer::fired):
+ * page/DOMTimer.h:
+
+2014-10-31 Chris Dumez <[email protected]>
+
Move -webkit-marquee-increment property to the new StyleBuilder
https://bugs.webkit.org/show_bug.cgi?id=138208
Modified: trunk/Source/WebCore/page/DOMTimer.cpp (175440 => 175441)
--- trunk/Source/WebCore/page/DOMTimer.cpp 2014-10-31 23:58:53 UTC (rev 175440)
+++ trunk/Source/WebCore/page/DOMTimer.cpp 2014-11-01 00:12:51 UTC (rev 175441)
@@ -84,6 +84,42 @@
DOMTimerFireState* DOMTimerFireState::current = nullptr;
+struct NestedTimersVector {
+ typedef Vector<DOMTimer*, 1>::const_iterator const_iterator;
+
+ NestedTimersVector(ScriptExecutionContext* context)
+ : shouldSetCurrent(context->isDocument())
+ {
+ if (shouldSetCurrent) {
+ previous = current;
+ current = this;
+ }
+ }
+
+ ~NestedTimersVector()
+ {
+ if (shouldSetCurrent)
+ current = previous;
+ }
+
+ static NestedTimersVector* current;
+
+ void registerTimer(DOMTimer* timer)
+ {
+ nestedTimers.append(timer);
+ }
+
+ const_iterator begin() const { return nestedTimers.begin(); }
+ const_iterator end() const { return nestedTimers.end(); }
+
+private:
+ bool shouldSetCurrent;
+ NestedTimersVector* previous;
+ Vector<DOMTimer*, 1> nestedTimers;
+};
+
+NestedTimersVector* NestedTimersVector::current = nullptr;
+
static inline bool shouldForwardUserGesture(int interval, int nestingLevel)
{
return UserGestureIndicator::processingUserGesture()
@@ -133,6 +169,10 @@
timer->suspendIfNeeded();
InspectorInstrumentation::didInstallTimer(context, timer->m_timeoutId, timeout, singleShot);
+ // Keep track of nested timer installs.
+ if (NestedTimersVector::current)
+ NestedTimersVector::current->registerTimer(timer);
+
return timer->m_timeoutId;
}
@@ -148,6 +188,17 @@
context->removeTimeout(timeoutId);
}
+void DOMTimer::updateThrottlingStateIfNecessary(const DOMTimerFireState& fireState)
+{
+ if (fireState.scriptDidInteractWithUserObservablePlugin && m_throttleState != ShouldNotThrottle) {
+ m_throttleState = ShouldNotThrottle;
+ updateTimerIntervalIfNecessary();
+ } else if (fireState.scriptDidInteractWithNonUserObservablePlugin && m_throttleState == Undetermined) {
+ m_throttleState = ShouldThrottle;
+ updateTimerIntervalIfNecessary();
+ }
+}
+
void DOMTimer::scriptDidInteractWithPlugin(HTMLPlugInElement& pluginElement)
{
if (!DOMTimerFireState::current)
@@ -198,15 +249,8 @@
m_action->execute(context);
InspectorInstrumentation::didFireTimer(cookie);
+ updateThrottlingStateIfNecessary(fireState);
- if (fireState.scriptDidInteractWithUserObservablePlugin && m_throttleState != ShouldNotThrottle) {
- m_throttleState = ShouldNotThrottle;
- updateTimerIntervalIfNecessary();
- } else if (fireState.scriptDidInteractWithNonUserObservablePlugin && m_throttleState == Undetermined) {
- m_throttleState = ShouldThrottle;
- updateTimerIntervalIfNecessary();
- }
-
return;
}
@@ -229,6 +273,8 @@
}
#endif
+ // Keep track nested timer installs.
+ NestedTimersVector nestedTimers(context);
m_action->execute(context);
#if PLATFORM(IOS)
@@ -243,6 +289,12 @@
InspectorInstrumentation::didFireTimer(cookie);
+ // Check if we should throttle nested single-shot timers.
+ for (auto* timer : nestedTimers) {
+ if (!timer->repeatInterval())
+ timer->updateThrottlingStateIfNecessary(fireState);
+ }
+
context->setTimerNestingLevel(0);
}
Modified: trunk/Source/WebCore/page/DOMTimer.h (175440 => 175441)
--- trunk/Source/WebCore/page/DOMTimer.h 2014-10-31 23:58:53 UTC (rev 175440)
+++ trunk/Source/WebCore/page/DOMTimer.h 2014-11-01 00:12:51 UTC (rev 175441)
@@ -33,6 +33,7 @@
namespace WebCore {
+ struct DOMTimerFireState;
class HTMLPlugInElement;
class ScheduledAction;
@@ -54,6 +55,7 @@
private:
DOMTimer(ScriptExecutionContext*, std::unique_ptr<ScheduledAction>, int interval, bool singleShot);
double intervalClampedToMinimum() const;
+ void updateThrottlingStateIfNecessary(const DOMTimerFireState&);
// SuspendableTimer
virtual void fired() override;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes