| 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
|
| index 8a461232cbfbc536016a620317bef4e6f235ebb8..7b6840c55571a546141e617c7f90fb47984c949e 100644
|
| --- a/cc/raster/task_graph_work_queue.h
|
| +++ b/cc/raster/task_graph_work_queue.h
|
| @@ -5,6 +5,7 @@
|
| #ifndef CC_RASTER_TASK_GRAPH_WORK_QUEUE_H_
|
| #define CC_RASTER_TASK_GRAPH_WORK_QUEUE_H_
|
|
|
| +#include <algorithm>
|
| #include <map>
|
| #include <vector>
|
|
|
| @@ -16,6 +17,11 @@ 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.
|
| +//
|
| +// Tasks in the queue are divided into categories. Tasks from a single graph may
|
| +// be put into different categories, each of which is prioritized independently
|
| +// from the others. It is up to the implementation of TaskGraphRunner to
|
| +// define the meaning of the categories and handle them appropriately.
|
| class CC_EXPORT TaskGraphWorkQueue {
|
| public:
|
| struct TaskNamespace;
|
| @@ -23,12 +29,19 @@ class CC_EXPORT TaskGraphWorkQueue {
|
| struct PrioritizedTask {
|
| typedef std::vector<PrioritizedTask> Vector;
|
|
|
| - PrioritizedTask(Task* task, TaskNamespace* task_namespace, size_t priority)
|
| - : task(task), task_namespace(task_namespace), priority(priority) {}
|
| + PrioritizedTask(Task* task,
|
| + TaskNamespace* task_namespace,
|
| + uint16_t category,
|
| + uint16_t priority)
|
| + : task(task),
|
| + task_namespace(task_namespace),
|
| + category(category),
|
| + priority(priority) {}
|
|
|
| Task* task;
|
| TaskNamespace* task_namespace;
|
| - size_t priority;
|
| + uint16_t category;
|
| + uint16_t priority;
|
| };
|
|
|
| // Helper classes and static methods used by dependent classes.
|
| @@ -41,8 +54,9 @@ class CC_EXPORT TaskGraphWorkQueue {
|
| // Current task graph.
|
| TaskGraph graph;
|
|
|
| - // Ordered set of tasks that are ready to run.
|
| - PrioritizedTask::Vector ready_to_run_tasks;
|
| + // Map from category to a vector of tasks that are ready to run for that
|
| + // category.
|
| + std::map<uint16_t, PrioritizedTask::Vector> ready_to_run_tasks;
|
|
|
| // Completed tasks not yet collected by origin thread.
|
| Task::Vector completed_tasks;
|
| @@ -62,8 +76,8 @@ class CC_EXPORT TaskGraphWorkQueue {
|
| // 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();
|
| + // Returns the next task to run for the given category.
|
| + PrioritizedTask GetNextTaskToRun(uint16_t category);
|
|
|
| // Marks a task as completed, adding it to its namespace's list of completed
|
| // tasks and updating the list of |ready_to_run_namespaces|.
|
| @@ -84,13 +98,35 @@ class CC_EXPORT TaskGraphWorkQueue {
|
| return &it->second;
|
| }
|
|
|
| + static bool HasReadyToRunTasksInNamespace(
|
| + const TaskNamespace* task_namespace) {
|
| + return std::find_if(task_namespace->ready_to_run_tasks.begin(),
|
| + task_namespace->ready_to_run_tasks.end(),
|
| + [](const std::pair<uint16_t, PrioritizedTask::Vector>&
|
| + ready_to_run_tasks) {
|
| + return !ready_to_run_tasks.second.empty();
|
| + }) != task_namespace->ready_to_run_tasks.end();
|
| + }
|
| +
|
| static bool HasFinishedRunningTasksInNamespace(
|
| const TaskNamespace* task_namespace) {
|
| return task_namespace->running_tasks.empty() &&
|
| - task_namespace->ready_to_run_tasks.empty();
|
| + !HasReadyToRunTasksInNamespace(task_namespace);
|
| }
|
|
|
| - bool HasReadyToRunTasks() const { return !ready_to_run_namespaces_.empty(); }
|
| + bool HasReadyToRunTasks() const {
|
| + return std::find_if(ready_to_run_namespaces_.begin(),
|
| + ready_to_run_namespaces_.end(),
|
| + [](const std::pair<uint16_t, TaskNamespace::Vector>&
|
| + ready_to_run_namespaces) {
|
| + return !ready_to_run_namespaces.second.empty();
|
| + }) != ready_to_run_namespaces_.end();
|
| + }
|
| +
|
| + bool HasReadyToRunTasksForCategory(uint16_t category) const {
|
| + auto found = ready_to_run_namespaces_.find(category);
|
| + return found != ready_to_run_namespaces_.end() && !found->second.empty();
|
| + }
|
|
|
| bool HasAnyNamespaces() const { return !namespaces_.empty(); }
|
|
|
| @@ -102,6 +138,11 @@ class CC_EXPORT TaskGraphWorkQueue {
|
| }) == namespaces_.end();
|
| }
|
|
|
| + const std::map<uint16_t, TaskNamespace::Vector>& ready_to_run_namespaces()
|
| + const {
|
| + return ready_to_run_namespaces_;
|
| + }
|
| +
|
| // Helper function which ensures that graph dependencies were correctly
|
| // configured.
|
| static bool DependencyMismatch(const TaskGraph* graph);
|
| @@ -116,29 +157,13 @@ class CC_EXPORT TaskGraphWorkQueue {
|
| }
|
| };
|
|
|
| - 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_;
|
| +
|
| + // Map from category to a vector of ready to run namespaces for that category.
|
| + std::map<uint16_t, TaskNamespace::Vector> ready_to_run_namespaces_;
|
|
|
| // Provides a unique id to each NamespaceToken.
|
| int next_namespace_id_;
|
|
|