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_; |