| Index: Source/platform/scheduler/Scheduler.cpp
|
| diff --git a/Source/platform/scheduler/Scheduler.cpp b/Source/platform/scheduler/Scheduler.cpp
|
| index e33f7132488807395ca7af8032e2fadf79e8709c..d1583e25a9c827bc2f2eb2b48edaf3d6c3fb7d57 100644
|
| --- a/Source/platform/scheduler/Scheduler.cpp
|
| +++ b/Source/platform/scheduler/Scheduler.cpp
|
| @@ -20,41 +20,40 @@ namespace {
|
| // The time we should stay in CompositorPriority mode for, after a touch event.
|
| double kLowSchedulerPolicyAfterTouchTimeSeconds = 0.1;
|
|
|
| -// Can be created from any thread.
|
| +} // namespace
|
| +
|
| +// Typically only created from compositor or render threads.
|
| // Note if the scheduler gets shutdown, this may be run after.
|
| -class MainThreadIdleTaskAdapter : public WebThread::Task {
|
| +class Scheduler::MainThreadPendingHighPriorityTaskRunner : public WebThread::Task {
|
| public:
|
| - MainThreadIdleTaskAdapter(const Scheduler::IdleTask& idleTask, double allottedTimeMs, const TraceLocation& location)
|
| - : m_idleTask(idleTask)
|
| - , m_allottedTimeMs(allottedTimeMs)
|
| - , m_location(location)
|
| + MainThreadPendingHighPriorityTaskRunner(
|
| + const Scheduler::Task& task, const TraceLocation& location, const char* traceName)
|
| + : m_task(internal::TracedStandardTask::Create(task, location, traceName))
|
| {
|
| + ASSERT(Scheduler::shared());
|
| }
|
|
|
| // WebThread::Task implementation.
|
| virtual void run() OVERRIDE
|
| {
|
| - TRACE_EVENT2("blink", "MainThreadIdleTaskAdapter::run",
|
| - "src_file", m_location.fileName(),
|
| - "src_func", m_location.functionName());
|
| - m_idleTask(m_allottedTimeMs);
|
| + m_task->run();
|
| + if (Scheduler* scheduler = Scheduler::shared()) {
|
| + scheduler->updatePolicy();
|
| + scheduler->didRunHighPriorityTask();
|
| + }
|
| }
|
|
|
| private:
|
| - Scheduler::IdleTask m_idleTask;
|
| - double m_allottedTimeMs;
|
| - TraceLocation m_location;
|
| + OwnPtr<internal::TracedStandardTask> m_task;
|
| };
|
|
|
| -} // namespace
|
| -
|
| -// Typically only created from compositor or render threads.
|
| +// Can be created from any thread.
|
| // Note if the scheduler gets shutdown, this may be run after.
|
| -class Scheduler::MainThreadPendingHighPriorityTaskRunner : public WebThread::Task {
|
| +class Scheduler::MainThreadPendingTaskRunner : public WebThread::Task {
|
| public:
|
| - MainThreadPendingHighPriorityTaskRunner(
|
| + MainThreadPendingTaskRunner(
|
| const Scheduler::Task& task, const TraceLocation& location, const char* traceName)
|
| - : m_task(task, location, traceName)
|
| + : m_task(internal::TracedStandardTask::Create(task, location, traceName))
|
| {
|
| ASSERT(Scheduler::shared());
|
| }
|
| @@ -62,24 +61,22 @@ public:
|
| // WebThread::Task implementation.
|
| virtual void run() OVERRIDE
|
| {
|
| - m_task.run();
|
| + m_task->run();
|
| if (Scheduler* scheduler = Scheduler::shared()) {
|
| scheduler->updatePolicy();
|
| - scheduler->didRunHighPriorityTask();
|
| }
|
| }
|
|
|
| private:
|
| - TracedTask m_task;
|
| + OwnPtr<internal::TracedStandardTask> m_task;
|
| };
|
|
|
| +
|
| // Can be created from any thread.
|
| // Note if the scheduler gets shutdown, this may be run after.
|
| -class Scheduler::MainThreadPendingTaskRunner : public WebThread::Task {
|
| +class Scheduler::MainThreadPendingIdleTaskRunner : public WebThread::Task {
|
| public:
|
| - MainThreadPendingTaskRunner(
|
| - const Scheduler::Task& task, const TraceLocation& location, const char* traceName)
|
| - : m_task(task, location, traceName)
|
| + MainThreadPendingIdleTaskRunner()
|
| {
|
| ASSERT(Scheduler::shared());
|
| }
|
| @@ -87,15 +84,16 @@ public:
|
| // WebThread::Task implementation.
|
| virtual void run() OVERRIDE
|
| {
|
| - m_task.run();
|
| if (Scheduler* scheduler = Scheduler::shared()) {
|
| - scheduler->updatePolicy();
|
| + scheduler->maybeRunPendingIdleTask();
|
| + // If possible, run the next idle task by reposting on the main thread.
|
| + scheduler->maybePostMainThreadPendingIdleTask();
|
| }
|
| }
|
|
|
| - TracedTask m_task;
|
| };
|
|
|
| +
|
| Scheduler* Scheduler::s_sharedScheduler = nullptr;
|
|
|
| void Scheduler::initializeOnMainThread()
|
| @@ -117,6 +115,7 @@ Scheduler* Scheduler::shared()
|
| Scheduler::Scheduler()
|
| : m_sharedTimerFunction(nullptr)
|
| , m_mainThread(blink::Platform::current()->currentThread())
|
| + , m_estimatedNextBeginFrameSeconds(0)
|
| , m_highPriorityTaskCount(0)
|
| , m_highPriorityTaskRunnerPosted(false)
|
| , m_compositorPriorityPolicyEndTimeSeconds(0)
|
| @@ -128,20 +127,19 @@ Scheduler::~Scheduler()
|
| {
|
| }
|
|
|
| -void Scheduler::willBeginFrame(const WebBeginFrameArgs& args)
|
| +void Scheduler::willBeginFrame(double estimatedNextBeginFrameSeconds)
|
| {
|
| - // TODO: Use frame deadline and interval to schedule idle tasks.
|
| + ASSERT(isMainThread());
|
| + m_currentFrameCommitted = false;
|
| + m_estimatedNextBeginFrameSeconds = estimatedNextBeginFrameSeconds;
|
| + // TODO: Schedule a deferred task here to run idle work if didCommitFrameToCompositor never gets called.
|
| }
|
|
|
| void Scheduler::didCommitFrameToCompositor()
|
| {
|
| - // TODO: Trigger the frame deadline immediately.
|
| -}
|
| -
|
| -void Scheduler::scheduleIdleTask(const TraceLocation& location, const IdleTask& idleTask)
|
| -{
|
| - // TODO: send a real allottedTime here.
|
| - m_mainThread->postTask(new MainThreadIdleTaskAdapter(idleTask, 0, location));
|
| + ASSERT(isMainThread());
|
| + m_currentFrameCommitted = true;
|
| + maybePostMainThreadPendingIdleTask();
|
| }
|
|
|
| void Scheduler::postHighPriorityTaskInternal(const TraceLocation& location, const Task& task, const char* traceName)
|
| @@ -157,6 +155,12 @@ void Scheduler::didRunHighPriorityTask()
|
| TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "PendingHighPriorityTasks", m_highPriorityTaskCount);
|
| }
|
|
|
| +void Scheduler::postIdleTaskInternal(const TraceLocation& location, const IdleTask& idleTask, const char* traceName)
|
| +{
|
| + Locker<Mutex> lock(m_pendingIdleTasksMutex);
|
| + m_pendingIdleTasks.append(internal::TracedIdleTask::Create(idleTask, location, traceName));
|
| +}
|
| +
|
| void Scheduler::postTask(const TraceLocation& location, const Task& task)
|
| {
|
| m_mainThread->postTask(new MainThreadPendingTaskRunner(task, location, "Scheduler::MainThreadTask"));
|
| @@ -188,7 +192,21 @@ void Scheduler::postIpcTask(const TraceLocation& location, const Task& task)
|
|
|
| void Scheduler::postIdleTask(const TraceLocation& location, const IdleTask& idleTask)
|
| {
|
| - scheduleIdleTask(location, idleTask);
|
| + postIdleTaskInternal(location, idleTask, "Scheduler::IdleTask");
|
| +}
|
| +
|
| +bool Scheduler::maybePostMainThreadPendingIdleTask()
|
| +{
|
| + ASSERT(isMainThread());
|
| + TRACE_EVENT0("blink", "Scheduler::maybePostMainThreadPendingIdleTask");
|
| + if (canRunIdleTask()) {
|
| + Locker<Mutex> lock(m_pendingIdleTasksMutex);
|
| + if (!m_pendingIdleTasks.isEmpty()) {
|
| + m_mainThread->postTask(new MainThreadPendingIdleTaskRunner());
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| }
|
|
|
| void Scheduler::tickSharedTimer()
|
| @@ -242,6 +260,38 @@ bool Scheduler::shouldYieldForHighPriorityWork() const
|
| return acquireLoad(&m_highPriorityTaskCount) != 0;
|
| }
|
|
|
| +bool Scheduler::maybeRunPendingIdleTask()
|
| +{
|
| + ASSERT(isMainThread());
|
| + if (!canRunIdleTask())
|
| + return false;
|
| +
|
| + takeFirstPendingIdleTask()->run();
|
| + return true;
|
| +}
|
| +
|
| +PassOwnPtr<internal::TracedIdleTask> Scheduler::takeFirstPendingIdleTask()
|
| +{
|
| + Locker<Mutex> lock(m_pendingIdleTasksMutex);
|
| + ASSERT(!m_pendingIdleTasks.isEmpty());
|
| + return m_pendingIdleTasks.takeFirst();
|
| +}
|
| +
|
| +double Scheduler::currentFrameDeadlineForIdleTasks() const
|
| +{
|
| + ASSERT(isMainThread());
|
| + // TODO: Make idle time more fine-grain chunks when in Compositor priority.
|
| + return m_estimatedNextBeginFrameSeconds;
|
| +}
|
| +
|
| +bool Scheduler::canRunIdleTask() const
|
| +{
|
| + ASSERT(isMainThread());
|
| + return m_currentFrameCommitted
|
| + && !shouldYieldForHighPriorityWork()
|
| + && (m_estimatedNextBeginFrameSeconds > Platform::current()->monotonicallyIncreasingTime());
|
| +}
|
| +
|
| Scheduler::SchedulerPolicy Scheduler::schedulerPolicy() const
|
| {
|
| ASSERT(isMainThread());
|
|
|