Input tasks are not always routed by the main thread, but the

blink scheduler still needs to know about them because we
want it to enter low latency mode when the user is
interacting with the device.  To facilitate that this patch
adds an didReceiveInputEvent API function.

BUG=391005

Review URL: https://codereview.chromium.org/554693004

git-svn-id: svn://svn.chromium.org/blink/trunk@181830 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 55ff8e62
...@@ -49,4 +49,9 @@ void WebSchedulerProxy::postCompositorTask(const WebTraceLocation& webLocation, ...@@ -49,4 +49,9 @@ void WebSchedulerProxy::postCompositorTask(const WebTraceLocation& webLocation,
m_scheduler->postCompositorTask(location, bind(&runTask, adoptPtr(task))); m_scheduler->postCompositorTask(location, bind(&runTask, adoptPtr(task)));
} }
void WebSchedulerProxy::didReceiveInputEvent()
{
m_scheduler->didReceiveInputEvent();
}
} // namespace blink } // namespace blink
...@@ -163,6 +163,11 @@ void Scheduler::postInputTask(const TraceLocation& location, const Task& task) ...@@ -163,6 +163,11 @@ void Scheduler::postInputTask(const TraceLocation& location, const Task& task)
TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "PendingHighPriorityTasks", m_highPriorityTaskCount); TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "PendingHighPriorityTasks", m_highPriorityTaskCount);
} }
void Scheduler::didReceiveInputEvent()
{
enterSchedulerPolicy(CompositorPriority);
}
void Scheduler::postCompositorTask(const TraceLocation& location, const Task& task) void Scheduler::postCompositorTask(const TraceLocation& location, const Task& task)
{ {
Locker<Mutex> lock(m_pendingTasksMutex); Locker<Mutex> lock(m_pendingTasksMutex);
......
...@@ -43,6 +43,10 @@ public: ...@@ -43,6 +43,10 @@ public:
void postTask(const TraceLocation&, const Task&); // For generic (low priority) tasks. void postTask(const TraceLocation&, const Task&); // For generic (low priority) tasks.
void postIdleTask(const TraceLocation&, const IdleTask&); // For non-critical tasks which may be reordered relative to other task types. void postIdleTask(const TraceLocation&, const IdleTask&); // For non-critical tasks which may be reordered relative to other task types.
// Tells the scheduler that the system received an input event. This causes the scheduler to go into
// Compositor Priority mode for a short duration.
void didReceiveInputEvent();
// Returns true if there is high priority work pending on the main thread // Returns true if there is high priority work pending on the main thread
// and the caller should yield to let the scheduler service that work. // and the caller should yield to let the scheduler service that work.
// Can be called on any thread. // Can be called on any thread.
......
...@@ -176,6 +176,13 @@ public: ...@@ -176,6 +176,13 @@ public:
m_scheduler->enterSchedulerPolicy(SchedulerForTest::Normal); m_scheduler->enterSchedulerPolicy(SchedulerForTest::Normal);
} }
virtual void TearDown() OVERRIDE
{
// If the Scheduler hasn't been shut down then explicitly flush the tasks.
if (Scheduler::shared())
runPendingTasks();
}
void runPendingTasks() void runPendingTasks()
{ {
m_platformSupport.runPendingTasks(); m_platformSupport.runPendingTasks();
...@@ -467,6 +474,13 @@ TEST_F(SchedulerTest, TestInputEventDoesNotTriggerShouldYield_InNormalMode) ...@@ -467,6 +474,13 @@ TEST_F(SchedulerTest, TestInputEventDoesNotTriggerShouldYield_InNormalMode)
EXPECT_FALSE(m_scheduler->shouldYieldForHighPriorityWork()); EXPECT_FALSE(m_scheduler->shouldYieldForHighPriorityWork());
} }
TEST_F(SchedulerTest, TestDidReceiveInputEventDoesNotTriggerShouldYield)
{
m_scheduler->didReceiveInputEvent();
EXPECT_FALSE(m_scheduler->shouldYieldForHighPriorityWork());
}
TEST_F(SchedulerTest, TestCompositorEventDoesNotTriggerShouldYield_InNormalMode) TEST_F(SchedulerTest, TestCompositorEventDoesNotTriggerShouldYield_InNormalMode)
{ {
m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&dummyTask)); m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&dummyTask));
...@@ -474,7 +488,17 @@ TEST_F(SchedulerTest, TestCompositorEventDoesNotTriggerShouldYield_InNormalMode) ...@@ -474,7 +488,17 @@ TEST_F(SchedulerTest, TestCompositorEventDoesNotTriggerShouldYield_InNormalMode)
EXPECT_FALSE(m_scheduler->shouldYieldForHighPriorityWork()); EXPECT_FALSE(m_scheduler->shouldYieldForHighPriorityWork());
} }
TEST_F(SchedulerTest, TestInputEventDoesTriggerShouldYield_InLowSchedulerPolicy) TEST_F(SchedulerTest, TestCompositorEventDoesTriggerShouldYieldAfterDidReceiveInputEvent)
{
m_scheduler->didReceiveInputEvent();
ASSERT_FALSE(m_scheduler->shouldYieldForHighPriorityWork());
m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&dummyTask));
EXPECT_TRUE(m_scheduler->shouldYieldForHighPriorityWork());
}
TEST_F(SchedulerTest, TestInputEventDoesTriggerShouldYield_InCompositorPriorityMode)
{ {
m_scheduler->enterSchedulerPolicy(SchedulerForTest::CompositorPriority); m_scheduler->enterSchedulerPolicy(SchedulerForTest::CompositorPriority);
m_scheduler->postInputTask(FROM_HERE, WTF::bind(&dummyTask)); m_scheduler->postInputTask(FROM_HERE, WTF::bind(&dummyTask));
...@@ -482,7 +506,7 @@ TEST_F(SchedulerTest, TestInputEventDoesTriggerShouldYield_InLowSchedulerPolicy) ...@@ -482,7 +506,7 @@ TEST_F(SchedulerTest, TestInputEventDoesTriggerShouldYield_InLowSchedulerPolicy)
EXPECT_TRUE(m_scheduler->shouldYieldForHighPriorityWork()); EXPECT_TRUE(m_scheduler->shouldYieldForHighPriorityWork());
} }
TEST_F(SchedulerTest, TestCompositorEventDoesTriggerShouldYield_InLowSchedulerPolicy) TEST_F(SchedulerTest, TestCompositorEventDoesTriggerShouldYield_InCompositorPriorityMode)
{ {
m_scheduler->enterSchedulerPolicy(SchedulerForTest::CompositorPriority); m_scheduler->enterSchedulerPolicy(SchedulerForTest::CompositorPriority);
m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&dummyTask)); m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&dummyTask));
...@@ -505,4 +529,21 @@ TEST_F(SchedulerTest, TestCompositorEvent_LowSchedulerPolicyDoesntLastLong) ...@@ -505,4 +529,21 @@ TEST_F(SchedulerTest, TestCompositorEvent_LowSchedulerPolicyDoesntLastLong)
EXPECT_FALSE(m_scheduler->shouldYieldForHighPriorityWork()); EXPECT_FALSE(m_scheduler->shouldYieldForHighPriorityWork());
} }
TEST_F(SchedulerTest, testDidReceiveInputEvent_DoesntTriggerLowLatencyModeForLong)
{
m_platformSupport.setMonotonicTimeForTest(1000.0);
// Note the latency mode gets reset by executeHighPriorityTasks, so we need a dummy task here
// to make sure runPendingTasks triggers executeHighPriorityTasks.
m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&dummyTask));
m_scheduler->didReceiveInputEvent();
m_platformSupport.setMonotonicTimeForTest(1000.5);
runPendingTasks();
ASSERT_FALSE(m_scheduler->shouldYieldForHighPriorityWork());
m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&dummyTask));
EXPECT_FALSE(m_scheduler->shouldYieldForHighPriorityWork());
}
} // namespace } // namespace
...@@ -27,6 +27,9 @@ public: ...@@ -27,6 +27,9 @@ public:
// ownership of |Task|. Can be called from any thread. // ownership of |Task|. Can be called from any thread.
BLINK_PLATFORM_EXPORT void postCompositorTask(const WebTraceLocation&, WebThread::Task*); BLINK_PLATFORM_EXPORT void postCompositorTask(const WebTraceLocation&, WebThread::Task*);
// Tells the scheduler that the system received an input event and it should go into low latency mode for a while.
BLINK_PLATFORM_EXPORT void didReceiveInputEvent();
private: private:
WebSchedulerProxy(); WebSchedulerProxy();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment