| Index: cc/raster/task_graph_work_queue.h
|
| diff --git a/cc/raster/task_graph_work_queue.h b/cc/raster/task_graph_work_queue.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8a461232cbfbc536016a620317bef4e6f235ebb8
|
| --- /dev/null
|
| +++ b/cc/raster/task_graph_work_queue.h
|
| @@ -0,0 +1,149 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef CC_RASTER_TASK_GRAPH_WORK_QUEUE_H_
|
| +#define CC_RASTER_TASK_GRAPH_WORK_QUEUE_H_
|
| +
|
| +#include <map>
|
| +#include <vector>
|
| +
|
| +#include "cc/base/cc_export.h"
|
| +#include "cc/raster/task_graph_runner.h"
|
| +
|
| +namespace cc {
|
| +
|
| +// Implements a queue of incoming TaskGraph work. Designed for use by
|
| +// implementations of TaskGraphRunner. Not thread safe, so the caller is
|
| +// responsible for all necessary locking.
|
| +class CC_EXPORT TaskGraphWorkQueue {
|
| + public:
|
| + struct TaskNamespace;
|
| +
|
| + struct PrioritizedTask {
|
| + typedef std::vector<PrioritizedTask> Vector;
|
| +
|
| + PrioritizedTask(Task* task, TaskNamespace* task_namespace, size_t priority)
|
| + : task(task), task_namespace(task_namespace), priority(priority) {}
|
| +
|
| + Task* task;
|
| + TaskNamespace* task_namespace;
|
| + size_t priority;
|
| + };
|
| +
|
| + // Helper classes and static methods used by dependent classes.
|
| + struct TaskNamespace {
|
| + typedef std::vector<TaskNamespace*> Vector;
|
| +
|
| + TaskNamespace();
|
| + ~TaskNamespace();
|
| +
|
| + // Current task graph.
|
| + TaskGraph graph;
|
| +
|
| + // Ordered set of tasks that are ready to run.
|
| + PrioritizedTask::Vector ready_to_run_tasks;
|
| +
|
| + // Completed tasks not yet collected by origin thread.
|
| + Task::Vector completed_tasks;
|
| +
|
| + // This set contains all currently running tasks.
|
| + Task::Vector running_tasks;
|
| + };
|
| +
|
| + TaskGraphWorkQueue();
|
| + virtual ~TaskGraphWorkQueue();
|
| +
|
| + // Gets a NamespaceToken which is guaranteed to be unique within this
|
| + // TaskGraphWorkQueue.
|
| + NamespaceToken GetNamespaceToken();
|
| +
|
| + // Updates a TaskNamespace with a new TaskGraph to run. This cancels any
|
| + // previous tasks in the graph being replaced.
|
| + void ScheduleTasks(NamespaceToken token, TaskGraph* graph);
|
| +
|
| + // Returns the next task to run paired with its namespace.
|
| + PrioritizedTask GetNextTaskToRun();
|
| +
|
| + // Marks a task as completed, adding it to its namespace's list of completed
|
| + // tasks and updating the list of |ready_to_run_namespaces|.
|
| + void CompleteTask(const PrioritizedTask& completed_task);
|
| +
|
| + // Helper which populates a vector of completed tasks from the provided
|
| + // namespace.
|
| + void CollectCompletedTasks(NamespaceToken token,
|
| + Task::Vector* completed_tasks);
|
| +
|
| + // Helper which returns the raw TaskNamespace* for the given token. Used to
|
| + // allow callers to re-use a TaskNamespace*, reducing the number of lookups
|
| + // needed.
|
| + TaskNamespace* GetNamespaceForToken(NamespaceToken token) {
|
| + auto it = namespaces_.find(token);
|
| + if (it == namespaces_.end())
|
| + return nullptr;
|
| + return &it->second;
|
| + }
|
| +
|
| + static bool HasFinishedRunningTasksInNamespace(
|
| + const TaskNamespace* task_namespace) {
|
| + return task_namespace->running_tasks.empty() &&
|
| + task_namespace->ready_to_run_tasks.empty();
|
| + }
|
| +
|
| + bool HasReadyToRunTasks() const { return !ready_to_run_namespaces_.empty(); }
|
| +
|
| + bool HasAnyNamespaces() const { return !namespaces_.empty(); }
|
| +
|
| + bool HasFinishedRunningTasksInAllNamespaces() {
|
| + return std::find_if(
|
| + namespaces_.begin(), namespaces_.end(),
|
| + [](const TaskNamespaceMap::value_type& entry) {
|
| + return !HasFinishedRunningTasksInNamespace(&entry.second);
|
| + }) == namespaces_.end();
|
| + }
|
| +
|
| + // Helper function which ensures that graph dependencies were correctly
|
| + // configured.
|
| + static bool DependencyMismatch(const TaskGraph* graph);
|
| +
|
| + private:
|
| + // Helper class used to provide NamespaceToken comparison to TaskNamespaceMap.
|
| + class CompareToken {
|
| + public:
|
| + bool operator()(const NamespaceToken& lhs,
|
| + const NamespaceToken& rhs) const {
|
| + return lhs.id_ < rhs.id_;
|
| + }
|
| + };
|
| +
|
| + static bool CompareTaskPriority(const PrioritizedTask& a,
|
| + const PrioritizedTask& b) {
|
| + // In this system, numerically lower priority is run first.
|
| + return a.priority > b.priority;
|
| + }
|
| +
|
| + static bool CompareTaskNamespacePriority(const TaskNamespace* a,
|
| + const TaskNamespace* b) {
|
| + DCHECK(!a->ready_to_run_tasks.empty());
|
| + DCHECK(!b->ready_to_run_tasks.empty());
|
| +
|
| + // Compare based on task priority of the ready_to_run_tasks heap .front()
|
| + // will hold the max element of the heap, except after pop_heap, when max
|
| + // element is moved to .back().
|
| + return CompareTaskPriority(a->ready_to_run_tasks.front(),
|
| + b->ready_to_run_tasks.front());
|
| + }
|
| +
|
| + using TaskNamespaceMap =
|
| + std::map<NamespaceToken, TaskNamespace, CompareToken>;
|
| +
|
| + TaskNamespaceMap namespaces_;
|
| + TaskNamespace::Vector ready_to_run_namespaces_;
|
| +
|
| + // Provides a unique id to each NamespaceToken.
|
| + int next_namespace_id_;
|
| +};
|
| +
|
| +} // namespace cc
|
| +
|
| +#endif // CC_RASTER_TASK_GRAPH_WORK_QUEUE_H_
|
|
|