| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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/tiles/tile_manager.h" | 5 #include "cc/tiles/tile_manager.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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 const RasterSource::PlaybackSettings& playback_settings, | 51 const RasterSource::PlaybackSettings& playback_settings, |
| 52 TileResolution tile_resolution, | 52 TileResolution tile_resolution, |
| 53 int layer_id, | 53 int layer_id, |
| 54 uint64_t source_prepare_tiles_id, | 54 uint64_t source_prepare_tiles_id, |
| 55 const void* tile, | 55 const void* tile, |
| 56 uint64_t new_content_id, | 56 uint64_t new_content_id, |
| 57 uint64_t previous_content_id, | 57 uint64_t previous_content_id, |
| 58 uint64_t resource_content_id, | 58 uint64_t resource_content_id, |
| 59 int source_frame_number, | 59 int source_frame_number, |
| 60 const base::Callback<void(bool)>& reply, | 60 const base::Callback<void(bool)>& reply, |
| 61 TileTask::Vector* dependencies) | 61 TileTask::Vector* dependencies, |
| 62 : TileTask(true, dependencies), | 62 bool supports_concurrent_execution) |
| 63 : TileTask(supports_concurrent_execution, dependencies), |
| 63 resource_(resource), | 64 resource_(resource), |
| 64 raster_source_(std::move(raster_source)), | 65 raster_source_(std::move(raster_source)), |
| 65 content_rect_(content_rect), | 66 content_rect_(content_rect), |
| 66 invalid_content_rect_(invalid_content_rect), | 67 invalid_content_rect_(invalid_content_rect), |
| 67 contents_scale_(contents_scale), | 68 contents_scale_(contents_scale), |
| 68 playback_settings_(playback_settings), | 69 playback_settings_(playback_settings), |
| 69 tile_resolution_(tile_resolution), | 70 tile_resolution_(tile_resolution), |
| 70 layer_id_(layer_id), | 71 layer_id_(layer_id), |
| 71 source_prepare_tiles_id_(source_prepare_tiles_id), | 72 source_prepare_tiles_id_(source_prepare_tiles_id), |
| 72 tile_(tile), | 73 tile_(tile), |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 uint64_t new_content_id_; | 125 uint64_t new_content_id_; |
| 125 uint64_t previous_content_id_; | 126 uint64_t previous_content_id_; |
| 126 uint64_t resource_content_id_; | 127 uint64_t resource_content_id_; |
| 127 int source_frame_number_; | 128 int source_frame_number_; |
| 128 const base::Callback<void(bool)> reply_; | 129 const base::Callback<void(bool)> reply_; |
| 129 std::unique_ptr<RasterBuffer> raster_buffer_; | 130 std::unique_ptr<RasterBuffer> raster_buffer_; |
| 130 | 131 |
| 131 DISALLOW_COPY_AND_ASSIGN(RasterTaskImpl); | 132 DISALLOW_COPY_AND_ASSIGN(RasterTaskImpl); |
| 132 }; | 133 }; |
| 133 | 134 |
| 135 TaskCategory TaskCategoryForTileTask(TileTask* task, |
| 136 bool use_foreground_category) { |
| 137 if (!task->supports_concurrent_execution()) |
| 138 return TASK_CATEGORY_NONCONCURRENT_FOREGROUND; |
| 139 |
| 140 if (use_foreground_category) |
| 141 return TASK_CATEGORY_FOREGROUND; |
| 142 |
| 143 return TASK_CATEGORY_BACKGROUND; |
| 144 } |
| 145 |
| 146 bool IsForegroundCategory(uint16_t category) { |
| 147 TaskCategory enum_category = static_cast<TaskCategory>(category); |
| 148 switch (enum_category) { |
| 149 case TASK_CATEGORY_NONCONCURRENT_FOREGROUND: |
| 150 case TASK_CATEGORY_FOREGROUND: |
| 151 return true; |
| 152 case TASK_CATEGORY_BACKGROUND: |
| 153 return false; |
| 154 } |
| 155 |
| 156 DCHECK(false); |
| 157 return false; |
| 158 } |
| 159 |
| 134 // Task priorities that make sure that the task set done tasks run before any | 160 // Task priorities that make sure that the task set done tasks run before any |
| 135 // other remaining tasks. | 161 // other remaining tasks. |
| 136 const size_t kRequiredForActivationDoneTaskPriority = 1u; | 162 const size_t kRequiredForActivationDoneTaskPriority = 1u; |
| 137 const size_t kRequiredForDrawDoneTaskPriority = 2u; | 163 const size_t kRequiredForDrawDoneTaskPriority = 2u; |
| 138 const size_t kAllDoneTaskPriority = 3u; | 164 const size_t kAllDoneTaskPriority = 3u; |
| 139 | 165 |
| 140 // For correctness, |kTileTaskPriorityBase| must be greater than | 166 // For correctness, |kTileTaskPriorityBase| must be greater than |
| 141 // all task set done task priorities. | 167 // all task set done task priorities. |
| 142 size_t kTileTaskPriorityBase = 10u; | 168 size_t kTileTaskPriorityBase = 10u; |
| 143 | 169 |
| 144 void InsertNodeForTask(TaskGraph* graph, | 170 void InsertNodeForTask(TaskGraph* graph, |
| 145 TileTask* task, | 171 TileTask* task, |
| 146 uint16_t category, | 172 uint16_t category, |
| 147 uint16_t priority, | 173 uint16_t priority, |
| 148 size_t dependencies) { | 174 size_t dependencies) { |
| 149 DCHECK(std::find_if(graph->nodes.begin(), graph->nodes.end(), | 175 DCHECK(std::find_if(graph->nodes.begin(), graph->nodes.end(), |
| 150 [task](const TaskGraph::Node& node) { | 176 [task](const TaskGraph::Node& node) { |
| 151 return node.task == task; | 177 return node.task == task; |
| 152 }) == graph->nodes.end()); | 178 }) == graph->nodes.end()); |
| 153 graph->nodes.push_back( | 179 graph->nodes.push_back( |
| 154 TaskGraph::Node(task, category, priority, dependencies)); | 180 TaskGraph::Node(task, category, priority, dependencies)); |
| 155 } | 181 } |
| 156 | 182 |
| 157 void InsertNodeForDecodeTask(TaskGraph* graph, | 183 void InsertNodeForDecodeTask(TaskGraph* graph, |
| 158 TileTask* task, | 184 TileTask* task, |
| 159 uint16_t category, | 185 bool use_foreground_category, |
| 160 uint16_t priority) { | 186 uint16_t priority) { |
| 161 uint32_t dependency_count = 0u; | 187 uint32_t dependency_count = 0u; |
| 162 if (task->dependencies().size()) { | 188 if (task->dependencies().size()) { |
| 163 DCHECK_EQ(task->dependencies().size(), 1u); | 189 DCHECK_EQ(task->dependencies().size(), 1u); |
| 164 auto* dependency = task->dependencies()[0].get(); | 190 auto* dependency = task->dependencies()[0].get(); |
| 165 if (!dependency->HasCompleted()) { | 191 if (!dependency->HasCompleted()) { |
| 166 InsertNodeForDecodeTask(graph, dependency, category, priority); | 192 InsertNodeForDecodeTask(graph, dependency, use_foreground_category, |
| 193 priority); |
| 167 graph->edges.push_back(TaskGraph::Edge(dependency, task)); | 194 graph->edges.push_back(TaskGraph::Edge(dependency, task)); |
| 168 dependency_count = 1u; | 195 dependency_count = 1u; |
| 169 } | 196 } |
| 170 } | 197 } |
| 171 InsertNodeForTask(graph, task, task->supports_concurrent_execution() | 198 InsertNodeForTask(graph, task, |
| 172 ? category | 199 TaskCategoryForTileTask(task, use_foreground_category), |
| 173 : TASK_CATEGORY_NONCONCURRENT_FOREGROUND, | |
| 174 priority, dependency_count); | 200 priority, dependency_count); |
| 175 } | 201 } |
| 176 | 202 |
| 177 void InsertNodesForRasterTask(TaskGraph* graph, | 203 void InsertNodesForRasterTask(TaskGraph* graph, |
| 178 TileTask* raster_task, | 204 TileTask* raster_task, |
| 179 const TileTask::Vector& decode_tasks, | 205 const TileTask::Vector& decode_tasks, |
| 180 size_t priority, | 206 size_t priority, |
| 181 bool use_gpu_rasterization, | 207 bool use_foreground_category) { |
| 182 bool high_priority) { | |
| 183 size_t dependencies = 0u; | 208 size_t dependencies = 0u; |
| 184 | 209 |
| 185 // Determine the TaskCategory for raster tasks - if a task uses GPU, it | |
| 186 // cannot run concurrently and is assigned | |
| 187 // TASK_CATEGORY_NONCONCURRENT_FOREGROUND, regardless of its priority. | |
| 188 // Otherwise its category is based on its priority. | |
| 189 TaskCategory raster_task_category; | |
| 190 if (use_gpu_rasterization) { | |
| 191 raster_task_category = TASK_CATEGORY_NONCONCURRENT_FOREGROUND; | |
| 192 } else { | |
| 193 raster_task_category = | |
| 194 high_priority ? TASK_CATEGORY_FOREGROUND : TASK_CATEGORY_BACKGROUND; | |
| 195 } | |
| 196 | |
| 197 // Determine the TaskCategory for decode tasks. This category is based on | |
| 198 // the priority of the raster task which depends on it. | |
| 199 TaskCategory decode_task_category = | |
| 200 high_priority ? TASK_CATEGORY_FOREGROUND : TASK_CATEGORY_BACKGROUND; | |
| 201 | |
| 202 // Insert image decode tasks. | 210 // Insert image decode tasks. |
| 203 for (TileTask::Vector::const_iterator it = decode_tasks.begin(); | 211 for (TileTask::Vector::const_iterator it = decode_tasks.begin(); |
| 204 it != decode_tasks.end(); ++it) { | 212 it != decode_tasks.end(); ++it) { |
| 205 TileTask* decode_task = it->get(); | 213 TileTask* decode_task = it->get(); |
| 206 | 214 |
| 207 // Skip if already decoded. | 215 // Skip if already decoded. |
| 208 if (decode_task->HasCompleted()) | 216 if (decode_task->HasCompleted()) |
| 209 continue; | 217 continue; |
| 210 | 218 |
| 211 dependencies++; | 219 dependencies++; |
| 212 | 220 |
| 213 // Add decode task if it doesn't already exists in graph. | 221 // Add decode task if it doesn't already exists in graph. |
| 214 TaskGraph::Node::Vector::iterator decode_it = | 222 TaskGraph::Node::Vector::iterator decode_it = |
| 215 std::find_if(graph->nodes.begin(), graph->nodes.end(), | 223 std::find_if(graph->nodes.begin(), graph->nodes.end(), |
| 216 [decode_task](const TaskGraph::Node& node) { | 224 [decode_task](const TaskGraph::Node& node) { |
| 217 return node.task == decode_task; | 225 return node.task == decode_task; |
| 218 }); | 226 }); |
| 219 | 227 |
| 220 // In rare circumstances, a low priority task may come in before a high | 228 // In rare circumstances, a background category task may come in before a |
| 221 // priority task. In these cases, upgrade any low-priority dependencies of | 229 // foreground category task. In these cases, upgrade any background category |
| 222 // the current task. | 230 // dependencies of the current task. |
| 223 // TODO(ericrk): Task iterators should be updated to avoid this. | 231 // TODO(ericrk): Task iterators should be updated to avoid this. |
| 224 // crbug.com/594851 | 232 // crbug.com/594851 |
| 225 if (decode_it != graph->nodes.end() && high_priority && | 233 // TODO(ericrk): This should handle dependencies recursively. |
| 226 decode_it->category != decode_task_category) { | 234 // crbug.com/605234 |
| 227 decode_it->category = decode_task_category; | 235 if (decode_it != graph->nodes.end() && use_foreground_category && |
| 236 !IsForegroundCategory(decode_it->category)) { |
| 237 decode_it->category = TASK_CATEGORY_FOREGROUND; |
| 228 } | 238 } |
| 229 | 239 |
| 230 if (decode_it == graph->nodes.end()) { | 240 if (decode_it == graph->nodes.end()) { |
| 231 InsertNodeForDecodeTask(graph, decode_task, decode_task_category, | 241 InsertNodeForDecodeTask(graph, decode_task, use_foreground_category, |
| 232 priority); | 242 priority); |
| 233 } | 243 } |
| 234 | 244 |
| 235 graph->edges.push_back(TaskGraph::Edge(decode_task, raster_task)); | 245 graph->edges.push_back(TaskGraph::Edge(decode_task, raster_task)); |
| 236 } | 246 } |
| 237 | 247 |
| 238 InsertNodeForTask(graph, raster_task, raster_task_category, priority, | 248 InsertNodeForTask( |
| 239 dependencies); | 249 graph, raster_task, |
| 250 TaskCategoryForTileTask(raster_task, use_foreground_category), priority, |
| 251 dependencies); |
| 240 } | 252 } |
| 241 | 253 |
| 242 class TaskSetFinishedTaskImpl : public TileTask { | 254 class TaskSetFinishedTaskImpl : public TileTask { |
| 243 public: | 255 public: |
| 244 explicit TaskSetFinishedTaskImpl( | 256 explicit TaskSetFinishedTaskImpl( |
| 245 base::SequencedTaskRunner* task_runner, | 257 base::SequencedTaskRunner* task_runner, |
| 246 const base::Closure& on_task_set_finished_callback) | 258 const base::Closure& on_task_set_finished_callback) |
| 247 : TileTask(true), | 259 : TileTask(true), |
| 248 task_runner_(task_runner), | 260 task_runner_(task_runner), |
| 249 on_task_set_finished_callback_(on_task_set_finished_callback) {} | 261 on_task_set_finished_callback_(on_task_set_finished_callback) {} |
| (...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 791 TaskGraph::Edge(task, required_for_activation_done_task.get())); | 803 TaskGraph::Edge(task, required_for_activation_done_task.get())); |
| 792 } | 804 } |
| 793 if (tile->required_for_draw()) { | 805 if (tile->required_for_draw()) { |
| 794 required_for_draw_count++; | 806 required_for_draw_count++; |
| 795 graph_.edges.push_back( | 807 graph_.edges.push_back( |
| 796 TaskGraph::Edge(task, required_for_draw_done_task.get())); | 808 TaskGraph::Edge(task, required_for_draw_done_task.get())); |
| 797 } | 809 } |
| 798 all_count++; | 810 all_count++; |
| 799 graph_.edges.push_back(TaskGraph::Edge(task, all_done_task.get())); | 811 graph_.edges.push_back(TaskGraph::Edge(task, all_done_task.get())); |
| 800 | 812 |
| 801 // A tile is high priority if it is either blocking future compositing | 813 // A tile should use a foreground task cateogry if it is either blocking |
| 802 // (required for draw or required for activation), or if it has a priority | 814 // future compositing (required for draw or required for activation), or if |
| 803 // bin of NOW for another reason (low resolution tiles). | 815 // it has a priority bin of NOW for another reason (low resolution tiles). |
| 804 bool high_priority = | 816 bool use_foreground_category = |
| 805 tile->required_for_draw() || tile->required_for_activation() || | 817 tile->required_for_draw() || tile->required_for_activation() || |
| 806 prioritized_tile.priority().priority_bin == TilePriority::NOW; | 818 prioritized_tile.priority().priority_bin == TilePriority::NOW; |
| 807 InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++, | 819 InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++, |
| 808 use_gpu_rasterization_, high_priority); | 820 use_foreground_category); |
| 809 } | 821 } |
| 810 | 822 |
| 811 // Insert nodes for our task completion tasks. We enqueue these using | 823 // Insert nodes for our task completion tasks. We enqueue these using |
| 812 // NONCONCURRENT_FOREGROUND priority as this is the highest prioirty and we'd | 824 // NONCONCURRENT_FOREGROUND category this is the highest prioirty category and |
| 813 // like to run these tasks as soon as possible. | 825 // we'd like to run these tasks as soon as possible. |
| 814 InsertNodeForTask(&graph_, required_for_activation_done_task.get(), | 826 InsertNodeForTask(&graph_, required_for_activation_done_task.get(), |
| 815 TASK_CATEGORY_NONCONCURRENT_FOREGROUND, | 827 TASK_CATEGORY_NONCONCURRENT_FOREGROUND, |
| 816 kRequiredForActivationDoneTaskPriority, | 828 kRequiredForActivationDoneTaskPriority, |
| 817 required_for_activate_count); | 829 required_for_activate_count); |
| 818 InsertNodeForTask(&graph_, required_for_draw_done_task.get(), | 830 InsertNodeForTask(&graph_, required_for_draw_done_task.get(), |
| 819 TASK_CATEGORY_NONCONCURRENT_FOREGROUND, | 831 TASK_CATEGORY_NONCONCURRENT_FOREGROUND, |
| 820 kRequiredForDrawDoneTaskPriority, required_for_draw_count); | 832 kRequiredForDrawDoneTaskPriority, required_for_draw_count); |
| 821 InsertNodeForTask(&graph_, all_done_task.get(), | 833 InsertNodeForTask(&graph_, all_done_task.get(), |
| 822 TASK_CATEGORY_NONCONCURRENT_FOREGROUND, | 834 TASK_CATEGORY_NONCONCURRENT_FOREGROUND, |
| 823 kAllDoneTaskPriority, all_count); | 835 kAllDoneTaskPriority, all_count); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 893 *it, prepare_tiles_count_, &task); | 905 *it, prepare_tiles_count_, &task); |
| 894 if (task) | 906 if (task) |
| 895 decode_tasks.push_back(task); | 907 decode_tasks.push_back(task); |
| 896 | 908 |
| 897 if (need_to_unref_when_finished) | 909 if (need_to_unref_when_finished) |
| 898 ++it; | 910 ++it; |
| 899 else | 911 else |
| 900 it = images.erase(it); | 912 it = images.erase(it); |
| 901 } | 913 } |
| 902 | 914 |
| 915 bool supports_concurrent_execution = !use_gpu_rasterization_; |
| 903 return make_scoped_refptr(new RasterTaskImpl( | 916 return make_scoped_refptr(new RasterTaskImpl( |
| 904 resource, prioritized_tile.raster_source(), tile->content_rect(), | 917 resource, prioritized_tile.raster_source(), tile->content_rect(), |
| 905 tile->invalidated_content_rect(), tile->contents_scale(), | 918 tile->invalidated_content_rect(), tile->contents_scale(), |
| 906 playback_settings, prioritized_tile.priority().resolution, | 919 playback_settings, prioritized_tile.priority().resolution, |
| 907 tile->layer_id(), prepare_tiles_count_, static_cast<const void*>(tile), | 920 tile->layer_id(), prepare_tiles_count_, static_cast<const void*>(tile), |
| 908 tile->id(), tile->invalidated_id(), resource_content_id, | 921 tile->id(), tile->invalidated_id(), resource_content_id, |
| 909 tile->source_frame_number(), | 922 tile->source_frame_number(), |
| 910 base::Bind(&TileManager::OnRasterTaskCompleted, base::Unretained(this), | 923 base::Bind(&TileManager::OnRasterTaskCompleted, base::Unretained(this), |
| 911 tile->id(), resource), | 924 tile->id(), resource), |
| 912 &decode_tasks)); | 925 &decode_tasks, supports_concurrent_execution)); |
| 913 } | 926 } |
| 914 | 927 |
| 915 void TileManager::OnRasterTaskCompleted( | 928 void TileManager::OnRasterTaskCompleted( |
| 916 Tile::Id tile_id, | 929 Tile::Id tile_id, |
| 917 Resource* resource, | 930 Resource* resource, |
| 918 bool was_canceled) { | 931 bool was_canceled) { |
| 919 DCHECK(tiles_.find(tile_id) != tiles_.end()); | 932 DCHECK(tiles_.find(tile_id) != tiles_.end()); |
| 920 | 933 |
| 921 Tile* tile = tiles_[tile_id]; | 934 Tile* tile = tiles_[tile_id]; |
| 922 TileDrawInfo& draw_info = tile->draw_info(); | 935 TileDrawInfo& draw_info = tile->draw_info(); |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1239 void TileManager::Signals::reset() { | 1252 void TileManager::Signals::reset() { |
| 1240 ready_to_activate = false; | 1253 ready_to_activate = false; |
| 1241 did_notify_ready_to_activate = false; | 1254 did_notify_ready_to_activate = false; |
| 1242 ready_to_draw = false; | 1255 ready_to_draw = false; |
| 1243 did_notify_ready_to_draw = false; | 1256 did_notify_ready_to_draw = false; |
| 1244 all_tile_tasks_completed = false; | 1257 all_tile_tasks_completed = false; |
| 1245 did_notify_all_tile_tasks_completed = false; | 1258 did_notify_all_tile_tasks_completed = false; |
| 1246 } | 1259 } |
| 1247 | 1260 |
| 1248 } // namespace cc | 1261 } // namespace cc |
| OLD | NEW |