| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/raster/task_graph_work_queue.h" | 5 #include "cc/raster/task_graph_work_queue.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 // element is moved to .back(). | 38 // element is moved to .back(). |
| 39 return CompareTaskPriority(a->ready_to_run_tasks.at(category_).front(), | 39 return CompareTaskPriority(a->ready_to_run_tasks.at(category_).front(), |
| 40 b->ready_to_run_tasks.at(category_).front()); | 40 b->ready_to_run_tasks.at(category_).front()); |
| 41 } | 41 } |
| 42 | 42 |
| 43 private: | 43 private: |
| 44 uint16_t category_; | 44 uint16_t category_; |
| 45 }; | 45 }; |
| 46 } // namespace | 46 } // namespace |
| 47 | 47 |
| 48 TaskGraphWorkQueue::PrioritizedTask::PrioritizedTask( |
| 49 Task* task, |
| 50 TaskNamespace* task_namespace, |
| 51 uint16_t category, |
| 52 uint16_t priority) |
| 53 : task(task), |
| 54 task_namespace(task_namespace), |
| 55 category(category), |
| 56 priority(priority) {} |
| 57 |
| 58 TaskGraphWorkQueue::PrioritizedTask::~PrioritizedTask() {} |
| 59 |
| 48 TaskGraphWorkQueue::TaskNamespace::TaskNamespace() {} | 60 TaskGraphWorkQueue::TaskNamespace::TaskNamespace() {} |
| 49 | 61 |
| 50 TaskGraphWorkQueue::TaskNamespace::~TaskNamespace() {} | 62 TaskGraphWorkQueue::TaskNamespace::~TaskNamespace() {} |
| 51 | 63 |
| 52 TaskGraphWorkQueue::TaskGraphWorkQueue() : next_namespace_id_(1) {} | 64 TaskGraphWorkQueue::TaskGraphWorkQueue() : next_namespace_id_(1) {} |
| 53 TaskGraphWorkQueue::~TaskGraphWorkQueue() {} | 65 TaskGraphWorkQueue::~TaskGraphWorkQueue() {} |
| 54 | 66 |
| 55 NamespaceToken TaskGraphWorkQueue::GetNamespaceToken() { | 67 NamespaceToken TaskGraphWorkQueue::GetNamespaceToken() { |
| 56 NamespaceToken token(next_namespace_id_++); | 68 NamespaceToken token(next_namespace_id_++); |
| 57 DCHECK(namespaces_.find(token) == namespaces_.end()); | 69 DCHECK(namespaces_.find(token) == namespaces_.end()); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 | 102 |
| 91 // Task is not ready to run if dependencies are not yet satisfied. | 103 // Task is not ready to run if dependencies are not yet satisfied. |
| 92 if (node.dependencies) | 104 if (node.dependencies) |
| 93 continue; | 105 continue; |
| 94 | 106 |
| 95 // Skip if already finished running task. | 107 // Skip if already finished running task. |
| 96 if (node.task->HasFinishedRunning()) | 108 if (node.task->HasFinishedRunning()) |
| 97 continue; | 109 continue; |
| 98 | 110 |
| 99 // Skip if already running. | 111 // Skip if already running. |
| 100 if (std::find(task_namespace.running_tasks.begin(), | 112 if (std::any_of(task_namespace.running_tasks.begin(), |
| 101 task_namespace.running_tasks.end(), | 113 task_namespace.running_tasks.end(), |
| 102 node.task) != task_namespace.running_tasks.end()) | 114 [&node](const PrioritizedTask& task) { |
| 115 return task.task == node.task; |
| 116 })) |
| 103 continue; | 117 continue; |
| 104 | 118 |
| 105 task_namespace.ready_to_run_tasks[node.category].push_back(PrioritizedTask( | 119 task_namespace.ready_to_run_tasks[node.category].push_back(PrioritizedTask( |
| 106 node.task, &task_namespace, node.category, node.priority)); | 120 node.task, &task_namespace, node.category, node.priority)); |
| 107 } | 121 } |
| 108 | 122 |
| 109 // Rearrange the elements in each vector within |ready_to_run_tasks| in such a | 123 // Rearrange the elements in each vector within |ready_to_run_tasks| in such a |
| 110 // way that they form a heap. | 124 // way that they form a heap. |
| 111 for (auto& it : task_namespace.ready_to_run_tasks) { | 125 for (auto& it : task_namespace.ready_to_run_tasks) { |
| 112 auto& ready_to_run_tasks = it.second; | 126 auto& ready_to_run_tasks = it.second; |
| 113 std::make_heap(ready_to_run_tasks.begin(), ready_to_run_tasks.end(), | 127 std::make_heap(ready_to_run_tasks.begin(), ready_to_run_tasks.end(), |
| 114 CompareTaskPriority); | 128 CompareTaskPriority); |
| 115 } | 129 } |
| 116 | 130 |
| 117 // Swap task graph. | 131 // Swap task graph. |
| 118 task_namespace.graph.Swap(graph); | 132 task_namespace.graph.Swap(graph); |
| 119 | 133 |
| 120 // Determine what tasks in old graph need to be canceled. | 134 // Determine what tasks in old graph need to be canceled. |
| 121 for (TaskGraph::Node::Vector::iterator it = graph->nodes.begin(); | 135 for (TaskGraph::Node::Vector::iterator it = graph->nodes.begin(); |
| 122 it != graph->nodes.end(); ++it) { | 136 it != graph->nodes.end(); ++it) { |
| 123 TaskGraph::Node& node = *it; | 137 TaskGraph::Node& node = *it; |
| 124 | 138 |
| 125 // Skip if already finished running task. | 139 // Skip if already finished running task. |
| 126 if (node.task->HasFinishedRunning()) | 140 if (node.task->HasFinishedRunning()) |
| 127 continue; | 141 continue; |
| 128 | 142 |
| 129 // Skip if already running. | 143 // Skip if already running. |
| 130 if (std::find(task_namespace.running_tasks.begin(), | 144 if (std::any_of(task_namespace.running_tasks.begin(), |
| 131 task_namespace.running_tasks.end(), | 145 task_namespace.running_tasks.end(), |
| 132 node.task) != task_namespace.running_tasks.end()) | 146 [&node](const PrioritizedTask& task) { |
| 147 return task.task == node.task; |
| 148 })) |
| 133 continue; | 149 continue; |
| 134 | 150 |
| 135 DCHECK(std::find(task_namespace.completed_tasks.begin(), | 151 DCHECK(std::find(task_namespace.completed_tasks.begin(), |
| 136 task_namespace.completed_tasks.end(), | 152 task_namespace.completed_tasks.end(), |
| 137 node.task) == task_namespace.completed_tasks.end()); | 153 node.task) == task_namespace.completed_tasks.end()); |
| 138 task_namespace.completed_tasks.push_back(node.task); | 154 task_namespace.completed_tasks.push_back(node.task); |
| 139 } | 155 } |
| 140 | 156 |
| 141 // Build new "ready to run" task namespaces queue. | 157 // Build new "ready to run" task namespaces queue. |
| 142 for (auto& ready_to_run_namespaces_it : ready_to_run_namespaces_) { | 158 for (auto& ready_to_run_namespaces_it : ready_to_run_namespaces_) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 // Add task namespace back to |ready_to_run_namespaces| if not empty after | 204 // Add task namespace back to |ready_to_run_namespaces| if not empty after |
| 189 // taking top priority task. | 205 // taking top priority task. |
| 190 if (!ready_to_run_tasks.empty()) { | 206 if (!ready_to_run_tasks.empty()) { |
| 191 ready_to_run_namespaces.push_back(task_namespace); | 207 ready_to_run_namespaces.push_back(task_namespace); |
| 192 std::push_heap(ready_to_run_namespaces.begin(), | 208 std::push_heap(ready_to_run_namespaces.begin(), |
| 193 ready_to_run_namespaces.end(), | 209 ready_to_run_namespaces.end(), |
| 194 CompareTaskNamespacePriority(category)); | 210 CompareTaskNamespacePriority(category)); |
| 195 } | 211 } |
| 196 | 212 |
| 197 // Add task to |running_tasks|. | 213 // Add task to |running_tasks|. |
| 198 task_namespace->running_tasks.push_back(task.task); | 214 task_namespace->running_tasks.push_back(task); |
| 199 | 215 |
| 200 return task; | 216 return task; |
| 201 } | 217 } |
| 202 | 218 |
| 203 void TaskGraphWorkQueue::CompleteTask(const PrioritizedTask& completed_task) { | 219 void TaskGraphWorkQueue::CompleteTask(const PrioritizedTask& completed_task) { |
| 204 TaskNamespace* task_namespace = completed_task.task_namespace; | 220 TaskNamespace* task_namespace = completed_task.task_namespace; |
| 205 scoped_refptr<Task> task(completed_task.task); | 221 scoped_refptr<Task> task(completed_task.task); |
| 206 | 222 |
| 207 // Remove task from |running_tasks|. | 223 // Remove task from |running_tasks|. |
| 208 auto it = std::find(task_namespace->running_tasks.begin(), | 224 auto it = std::find_if(task_namespace->running_tasks.begin(), |
| 209 task_namespace->running_tasks.end(), task); | 225 task_namespace->running_tasks.end(), |
| 226 [&completed_task](const PrioritizedTask& task) { |
| 227 return task.task == completed_task.task; |
| 228 }); |
| 210 DCHECK(it != task_namespace->running_tasks.end()); | 229 DCHECK(it != task_namespace->running_tasks.end()); |
| 211 std::swap(*it, task_namespace->running_tasks.back()); | 230 std::swap(*it, task_namespace->running_tasks.back()); |
| 212 task_namespace->running_tasks.pop_back(); | 231 task_namespace->running_tasks.pop_back(); |
| 213 | 232 |
| 214 // Now iterate over all dependents to decrement dependencies and check if they | 233 // Now iterate over all dependents to decrement dependencies and check if they |
| 215 // are ready to run. | 234 // are ready to run. |
| 216 bool ready_to_run_namespaces_has_heap_properties = true; | 235 bool ready_to_run_namespaces_has_heap_properties = true; |
| 217 for (DependentIterator it(&task_namespace->graph, task.get()); it; ++it) { | 236 for (DependentIterator it(&task_namespace->graph, task.get()); it; ++it) { |
| 218 TaskGraph::Node& dependent_node = *it; | 237 TaskGraph::Node& dependent_node = *it; |
| 219 | 238 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 | 309 |
| 291 for (const TaskGraph::Node& node : graph->nodes) { | 310 for (const TaskGraph::Node& node : graph->nodes) { |
| 292 if (dependents[node.task] != node.dependencies) | 311 if (dependents[node.task] != node.dependencies) |
| 293 return true; | 312 return true; |
| 294 } | 313 } |
| 295 | 314 |
| 296 return false; | 315 return false; |
| 297 } | 316 } |
| 298 | 317 |
| 299 } // namespace cc | 318 } // namespace cc |
| OLD | NEW |