Chromium Code Reviews| 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <array> | |
| 8 #include <limits> | 9 #include <limits> |
| 9 #include <string> | 10 #include <string> |
| 10 | 11 |
| 11 #include "base/bind.h" | 12 #include "base/bind.h" |
| 12 #include "base/json/json_writer.h" | 13 #include "base/json/json_writer.h" |
| 13 #include "base/logging.h" | 14 #include "base/logging.h" |
| 14 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
| 15 #include "base/numerics/safe_conversions.h" | 16 #include "base/numerics/safe_conversions.h" |
| 16 #include "base/trace_event/trace_event_argument.h" | 17 #include "base/trace_event/trace_event_argument.h" |
| 17 #include "cc/base/histograms.h" | 18 #include "cc/base/histograms.h" |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 146 uint64_t resource_content_id_; | 147 uint64_t resource_content_id_; |
| 147 int source_frame_number_; | 148 int source_frame_number_; |
| 148 bool analyze_picture_; | 149 bool analyze_picture_; |
| 149 const base::Callback<void(const DisplayListRasterSource::SolidColorAnalysis&, | 150 const base::Callback<void(const DisplayListRasterSource::SolidColorAnalysis&, |
| 150 bool)> reply_; | 151 bool)> reply_; |
| 151 scoped_ptr<RasterBuffer> raster_buffer_; | 152 scoped_ptr<RasterBuffer> raster_buffer_; |
| 152 | 153 |
| 153 DISALLOW_COPY_AND_ASSIGN(RasterTaskImpl); | 154 DISALLOW_COPY_AND_ASSIGN(RasterTaskImpl); |
| 154 }; | 155 }; |
| 155 | 156 |
| 156 const char* TaskSetName(TaskSet task_set) { | 157 const char* TaskSetName(TileManager::TaskSet task_set) { |
| 157 switch (task_set) { | 158 switch (task_set) { |
| 158 case TileManager::ALL: | 159 case TileManager::ALL: |
| 159 return "ALL"; | 160 return "ALL"; |
| 160 case TileManager::REQUIRED_FOR_ACTIVATION: | 161 case TileManager::REQUIRED_FOR_ACTIVATION: |
| 161 return "REQUIRED_FOR_ACTIVATION"; | 162 return "REQUIRED_FOR_ACTIVATION"; |
| 162 case TileManager::REQUIRED_FOR_DRAW: | 163 case TileManager::REQUIRED_FOR_DRAW: |
| 163 return "REQUIRED_FOR_DRAW"; | 164 return "REQUIRED_FOR_DRAW"; |
| 164 } | 165 } |
| 165 | 166 |
| 166 NOTREACHED(); | 167 NOTREACHED(); |
| 167 return "Invalid TaskSet"; | 168 return "Invalid TaskSet"; |
| 168 } | 169 } |
| 169 | 170 |
| 171 // Task priorities that make sure task set finished tasks run before any | |
| 172 // other remaining tasks. This is combined with the task set type to ensure | |
| 173 // proper prioritization ordering between task set types. | |
| 174 size_t kTaskSetFinishedTaskPriorityBase = 1u; | |
| 175 // For correctness, |kTileTaskPriorityBase| must be greater than | |
| 176 // |kTaskSetFinishedTaskPriorityBase + kNumberOfTaskSets|. | |
| 177 size_t kTileTaskPriorityBase = 10u; | |
| 178 | |
| 179 void InsertNodeForTask(TaskGraph* graph, | |
| 180 TileTask* task, | |
| 181 size_t priority, | |
| 182 size_t dependencies) { | |
| 183 DCHECK(std::find_if(graph->nodes.begin(), graph->nodes.end(), | |
| 184 [task](const TaskGraph::Node& node) { | |
| 185 return node.task == task; | |
| 186 }) == graph->nodes.end()); | |
| 187 graph->nodes.push_back(TaskGraph::Node(task, priority, dependencies)); | |
| 188 } | |
| 189 | |
| 190 void InsertNodesForRasterTask(TaskGraph* graph, | |
| 191 RasterTask* raster_task, | |
| 192 const ImageDecodeTask::Vector& decode_tasks, | |
| 193 size_t priority) { | |
| 194 size_t dependencies = 0u; | |
| 195 | |
| 196 // Insert image decode tasks. | |
| 197 for (ImageDecodeTask::Vector::const_iterator it = decode_tasks.begin(); | |
| 198 it != decode_tasks.end(); ++it) { | |
| 199 ImageDecodeTask* decode_task = it->get(); | |
| 200 | |
| 201 // Skip if already decoded. | |
| 202 if (decode_task->HasCompleted()) | |
| 203 continue; | |
| 204 | |
| 205 dependencies++; | |
| 206 | |
| 207 // Add decode task if it doesn't already exists in graph. | |
| 208 TaskGraph::Node::Vector::iterator decode_it = | |
| 209 std::find_if(graph->nodes.begin(), graph->nodes.end(), | |
| 210 [decode_task](const TaskGraph::Node& node) { | |
| 211 return node.task == decode_task; | |
| 212 }); | |
| 213 if (decode_it == graph->nodes.end()) | |
| 214 InsertNodeForTask(graph, decode_task, priority, 0u); | |
| 215 | |
| 216 graph->edges.push_back(TaskGraph::Edge(decode_task, raster_task)); | |
| 217 } | |
| 218 | |
| 219 InsertNodeForTask(graph, raster_task, priority, dependencies); | |
| 220 } | |
| 221 | |
| 222 class TaskSetFinishedTaskImpl : public TileTask { | |
| 223 public: | |
| 224 explicit TaskSetFinishedTaskImpl( | |
| 225 base::SequencedTaskRunner* task_runner, | |
| 226 const base::Closure& on_task_set_finished_callback) | |
| 227 : task_runner_(task_runner), | |
| 228 on_task_set_finished_callback_(on_task_set_finished_callback) {} | |
| 229 | |
| 230 // Overridden from Task: | |
| 231 void RunOnWorkerThread() override { | |
| 232 TRACE_EVENT0("cc", "TaskSetFinishedTaskImpl::RunOnWorkerThread"); | |
| 233 TaskSetFinished(); | |
| 234 } | |
| 235 | |
| 236 // Overridden from TileTask: | |
| 237 void ScheduleOnOriginThread(TileTaskClient* client) override {} | |
| 238 void CompleteOnOriginThread(TileTaskClient* client) override {} | |
| 239 | |
| 240 protected: | |
| 241 ~TaskSetFinishedTaskImpl() override {} | |
| 242 | |
| 243 void TaskSetFinished() { | |
| 244 task_runner_->PostTask(FROM_HERE, on_task_set_finished_callback_); | |
| 245 } | |
| 246 | |
| 247 private: | |
| 248 scoped_refptr<base::SequencedTaskRunner> task_runner_; | |
| 249 const base::Closure on_task_set_finished_callback_; | |
| 250 | |
| 251 DISALLOW_COPY_AND_ASSIGN(TaskSetFinishedTaskImpl); | |
| 252 }; | |
| 253 | |
| 254 // Utility function that can be used to create a "Task set finished" task that | |
| 255 // posts |callback| to |task_runner| when run. | |
| 256 scoped_refptr<TileTask> CreateTaskSetFinishedTask( | |
|
reveman
2015/12/02 05:22:55
I'm generally not a fan of factory functions that
ericrk
2015/12/02 21:28:08
restructured things a bit - the function still exi
| |
| 257 base::SequencedTaskRunner* task_runner, | |
| 258 const base::Closure& on_task_set_finished_callback) { | |
| 259 return make_scoped_refptr( | |
| 260 new TaskSetFinishedTaskImpl(task_runner, on_task_set_finished_callback)); | |
| 261 } | |
| 262 | |
| 170 } // namespace | 263 } // namespace |
| 171 | 264 |
| 172 RasterTaskCompletionStats::RasterTaskCompletionStats() | 265 RasterTaskCompletionStats::RasterTaskCompletionStats() |
| 173 : completed_count(0u), canceled_count(0u) {} | 266 : completed_count(0u), canceled_count(0u) {} |
| 174 | 267 |
| 175 scoped_refptr<base::trace_event::ConvertableToTraceFormat> | 268 scoped_refptr<base::trace_event::ConvertableToTraceFormat> |
| 176 RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats) { | 269 RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats) { |
| 177 scoped_refptr<base::trace_event::TracedValue> state = | 270 scoped_refptr<base::trace_event::TracedValue> state = |
| 178 new base::trace_event::TracedValue(); | 271 new base::trace_event::TracedValue(); |
| 179 state->SetInteger("completed_count", | 272 state->SetInteger("completed_count", |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 209 did_oom_on_last_assign_(false), | 302 did_oom_on_last_assign_(false), |
| 210 more_tiles_need_prepare_check_notifier_( | 303 more_tiles_need_prepare_check_notifier_( |
| 211 task_runner_.get(), | 304 task_runner_.get(), |
| 212 base::Bind(&TileManager::CheckIfMoreTilesNeedToBePrepared, | 305 base::Bind(&TileManager::CheckIfMoreTilesNeedToBePrepared, |
| 213 base::Unretained(this))), | 306 base::Unretained(this))), |
| 214 signals_check_notifier_(task_runner_.get(), | 307 signals_check_notifier_(task_runner_.get(), |
| 215 base::Bind(&TileManager::CheckAndIssueSignals, | 308 base::Bind(&TileManager::CheckAndIssueSignals, |
| 216 base::Unretained(this))), | 309 base::Unretained(this))), |
| 217 has_scheduled_tile_tasks_(false), | 310 has_scheduled_tile_tasks_(false), |
| 218 prepare_tiles_count_(0u), | 311 prepare_tiles_count_(0u), |
| 219 next_tile_id_(0u) {} | 312 next_tile_id_(0u), |
| 313 task_set_finished_weak_ptr_factory_(this) {} | |
| 220 | 314 |
| 221 TileManager::~TileManager() { | 315 TileManager::~TileManager() { |
| 222 FinishTasksAndCleanUp(); | 316 FinishTasksAndCleanUp(); |
| 223 } | 317 } |
| 224 | 318 |
| 225 void TileManager::FinishTasksAndCleanUp() { | 319 void TileManager::FinishTasksAndCleanUp() { |
| 226 if (!tile_task_runner_) | 320 if (!tile_task_runner_) |
| 227 return; | 321 return; |
| 228 | 322 |
| 229 global_state_ = GlobalStateThatImpactsTilePriority(); | 323 global_state_ = GlobalStateThatImpactsTilePriority(); |
| 230 | 324 |
| 231 TileTaskQueue empty; | 325 // This cancels tasks if possible, finishes pending tasks, and release any |
| 232 tile_task_runner_->ScheduleTasks(&empty); | 326 // uninitialized resources. |
| 233 orphan_raster_tasks_.clear(); | 327 tile_task_runner_->Shutdown(); |
| 234 | 328 |
| 235 // This should finish all pending tasks and release any uninitialized | 329 // Now that all tasks have been finished, we can clear any |
| 236 // resources. | 330 // |orphan_tasks_|. |
| 237 tile_task_runner_->Shutdown(); | 331 orphan_tasks_.clear(); |
| 332 | |
| 238 tile_task_runner_->CheckForCompletedTasks(); | 333 tile_task_runner_->CheckForCompletedTasks(); |
| 239 | 334 |
| 240 FreeResourcesForReleasedTiles(); | 335 FreeResourcesForReleasedTiles(); |
| 241 CleanUpReleasedTiles(); | 336 CleanUpReleasedTiles(); |
| 242 | 337 |
| 243 tile_task_runner_ = nullptr; | 338 tile_task_runner_ = nullptr; |
| 244 resource_pool_ = nullptr; | 339 resource_pool_ = nullptr; |
| 245 more_tiles_need_prepare_check_notifier_.Cancel(); | 340 more_tiles_need_prepare_check_notifier_.Cancel(); |
| 246 signals_check_notifier_.Cancel(); | 341 signals_check_notifier_.Cancel(); |
| 342 task_set_finished_weak_ptr_factory_.InvalidateWeakPtrs(); | |
| 247 } | 343 } |
| 248 | 344 |
| 249 void TileManager::SetResources(ResourcePool* resource_pool, | 345 void TileManager::SetResources(ResourcePool* resource_pool, |
| 250 TileTaskRunner* tile_task_runner, | 346 TileTaskRunner* tile_task_runner, |
| 251 size_t scheduled_raster_task_limit) { | 347 size_t scheduled_raster_task_limit) { |
| 252 DCHECK(!tile_task_runner_); | 348 DCHECK(!tile_task_runner_); |
| 253 DCHECK(tile_task_runner); | 349 DCHECK(tile_task_runner); |
| 254 | 350 |
| 255 scheduled_raster_task_limit_ = scheduled_raster_task_limit; | 351 scheduled_raster_task_limit_ = scheduled_raster_task_limit; |
| 256 resource_pool_ = resource_pool; | 352 resource_pool_ = resource_pool; |
| 257 tile_task_runner_ = tile_task_runner; | 353 tile_task_runner_ = tile_task_runner; |
| 258 tile_task_runner_->SetClient(this); | |
| 259 } | 354 } |
| 260 | 355 |
| 261 void TileManager::Release(Tile* tile) { | 356 void TileManager::Release(Tile* tile) { |
| 262 released_tiles_.push_back(tile); | 357 released_tiles_.push_back(tile); |
| 263 } | 358 } |
| 264 | 359 |
| 265 void TileManager::FreeResourcesForReleasedTiles() { | 360 void TileManager::FreeResourcesForReleasedTiles() { |
| 266 for (auto* tile : released_tiles_) | 361 for (auto* tile : released_tiles_) |
| 267 FreeResourcesForTile(tile); | 362 FreeResourcesForTile(tile); |
| 268 } | 363 } |
| 269 | 364 |
| 270 void TileManager::CleanUpReleasedTiles() { | 365 void TileManager::CleanUpReleasedTiles() { |
| 271 std::vector<Tile*> tiles_to_retain; | 366 std::vector<Tile*> tiles_to_retain; |
| 272 for (auto* tile : released_tiles_) { | 367 for (auto* tile : released_tiles_) { |
| 273 if (tile->HasRasterTask()) { | 368 if (tile->HasRasterTask()) { |
| 274 tiles_to_retain.push_back(tile); | 369 tiles_to_retain.push_back(tile); |
| 275 continue; | 370 continue; |
| 276 } | 371 } |
| 277 | 372 |
| 278 DCHECK(!tile->draw_info().has_resource()); | 373 DCHECK(!tile->draw_info().has_resource()); |
| 279 DCHECK(tiles_.find(tile->id()) != tiles_.end()); | 374 DCHECK(tiles_.find(tile->id()) != tiles_.end()); |
| 280 tiles_.erase(tile->id()); | 375 tiles_.erase(tile->id()); |
| 281 | 376 |
| 282 image_decode_controller_.SubtractLayerUsedCount(tile->layer_id()); | 377 image_decode_controller_.SubtractLayerUsedCount(tile->layer_id()); |
| 283 delete tile; | 378 delete tile; |
| 284 } | 379 } |
| 285 released_tiles_.swap(tiles_to_retain); | 380 released_tiles_.swap(tiles_to_retain); |
| 286 } | 381 } |
| 287 | 382 |
| 288 void TileManager::DidFinishRunningTileTasks(TaskSet task_set) { | 383 void TileManager::DidFinishRunningTileTasks(TaskSet task_set) { |
|
reveman
2015/12/02 05:22:54
I think this would be much cleaner refactored as t
ericrk
2015/12/02 21:28:08
Done.
| |
| 289 TRACE_EVENT1("cc", "TileManager::DidFinishRunningTileTasks", "task_set", | 384 TRACE_EVENT1("cc", "TileManager::DidFinishRunningTileTasks", "task_set", |
| 290 TaskSetName(task_set)); | 385 TaskSetName(task_set)); |
| 291 DCHECK(resource_pool_); | 386 DCHECK(resource_pool_); |
| 292 DCHECK(tile_task_runner_); | 387 DCHECK(tile_task_runner_); |
| 293 | 388 |
| 389 DCHECK(tasks_pending_[task_set]); | |
| 390 tasks_pending_[task_set] = false; | |
| 391 | |
| 392 if (tasks_pending_.any()) { | |
| 393 TRACE_EVENT_ASYNC_STEP_INTO1("cc", "ScheduledTasks", this, "running", | |
| 394 "state", ScheduledTasksStateAsValue()); | |
| 395 } else { | |
| 396 TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this); | |
| 397 } | |
| 398 | |
| 294 switch (task_set) { | 399 switch (task_set) { |
| 295 case ALL: { | 400 case ALL: { |
| 296 has_scheduled_tile_tasks_ = false; | 401 has_scheduled_tile_tasks_ = false; |
| 297 | 402 |
| 298 bool memory_usage_above_limit = resource_pool_->memory_usage_bytes() > | 403 bool memory_usage_above_limit = resource_pool_->memory_usage_bytes() > |
| 299 global_state_.soft_memory_limit_in_bytes; | 404 global_state_.soft_memory_limit_in_bytes; |
| 300 | 405 |
| 301 if (all_tiles_that_need_to_be_rasterized_are_scheduled_ && | 406 if (all_tiles_that_need_to_be_rasterized_are_scheduled_ && |
| 302 !memory_usage_above_limit) { | 407 !memory_usage_above_limit) { |
| 303 // TODO(ericrk): We should find a better way to safely handle re-entrant | 408 // TODO(ericrk): We should find a better way to safely handle re-entrant |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 598 void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw( | 703 void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw( |
| 599 Tile* tile) { | 704 Tile* tile) { |
| 600 bool was_ready_to_draw = tile->draw_info().IsReadyToDraw(); | 705 bool was_ready_to_draw = tile->draw_info().IsReadyToDraw(); |
| 601 FreeResourcesForTile(tile); | 706 FreeResourcesForTile(tile); |
| 602 if (was_ready_to_draw) | 707 if (was_ready_to_draw) |
| 603 client_->NotifyTileStateChanged(tile); | 708 client_->NotifyTileStateChanged(tile); |
| 604 } | 709 } |
| 605 | 710 |
| 606 void TileManager::ScheduleTasks( | 711 void TileManager::ScheduleTasks( |
| 607 const PrioritizedTileVector& tiles_that_need_to_be_rasterized) { | 712 const PrioritizedTileVector& tiles_that_need_to_be_rasterized) { |
| 608 TRACE_EVENT1("cc", | 713 TRACE_EVENT1("cc", "TileManager::ScheduleTasks", "count", |
| 609 "TileManager::ScheduleTasks", | |
| 610 "count", | |
| 611 tiles_that_need_to_be_rasterized.size()); | 714 tiles_that_need_to_be_rasterized.size()); |
| 612 | 715 |
| 613 DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_); | 716 DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_); |
| 614 | 717 |
| 615 raster_queue_.Reset(); | 718 if (tasks_pending_.none()) { |
| 719 TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this); | |
| 720 } | |
| 721 | |
| 722 // Cancel existing OnTaskSetFinished callbacks. | |
| 723 task_set_finished_weak_ptr_factory_.InvalidateWeakPtrs(); | |
| 724 tasks_pending_.set(); | |
| 616 | 725 |
| 617 // Even when scheduling an empty set of tiles, the TTWP does some work, and | 726 // Even when scheduling an empty set of tiles, the TTWP does some work, and |
| 618 // will always trigger a DidFinishRunningTileTasks notification. Because of | 727 // will always trigger a DidFinishRunningTileTasks notification. Because of |
| 619 // this we unconditionally set |has_scheduled_tile_tasks_| to true. | 728 // this we unconditionally set |has_scheduled_tile_tasks_| to true. |
| 620 has_scheduled_tile_tasks_ = true; | 729 has_scheduled_tile_tasks_ = true; |
| 621 | 730 |
| 622 // Build a new task queue containing all task currently needed. Tasks | 731 scoped_ptr<TaskGraph> graph(new TaskGraph); |
|
reveman
2015/12/02 05:22:54
Before this we've swapped between two task graphs
ericrk
2015/12/02 21:28:08
from looking at the old code, it seems that we onl
| |
| 623 // are added in order of priority, highest priority task first. | 732 std::array<scoped_refptr<TileTask>, kNumberOfTaskSets> |
|
reveman
2015/12/02 05:22:54
are we allowed to use std::array now?
ericrk
2015/12/02 21:28:08
yup, went through the process of getting that appr
| |
| 624 for (auto& prioritized_tile : tiles_that_need_to_be_rasterized) { | 733 new_task_set_finished_tasks; |
| 625 Tile* tile = prioritized_tile.tile(); | 734 BuildTaskGraph(tiles_that_need_to_be_rasterized, graph.get(), |
| 626 | 735 &new_task_set_finished_tasks); |
| 627 DCHECK(tile->draw_info().requires_resource()); | |
| 628 DCHECK(!tile->draw_info().resource_); | |
| 629 | |
| 630 if (!tile->raster_task_.get()) | |
| 631 tile->raster_task_ = CreateRasterTask(prioritized_tile); | |
| 632 | |
| 633 TaskSetCollection task_sets; | |
| 634 if (tile->required_for_activation()) | |
| 635 task_sets.set(REQUIRED_FOR_ACTIVATION); | |
| 636 if (tile->required_for_draw()) | |
| 637 task_sets.set(REQUIRED_FOR_DRAW); | |
| 638 task_sets.set(ALL); | |
| 639 raster_queue_.items.push_back( | |
| 640 TileTaskQueue::Item(tile->raster_task_.get(), task_sets)); | |
| 641 } | |
| 642 | 736 |
| 643 // We must reduce the amount of unused resoruces before calling | 737 // We must reduce the amount of unused resoruces before calling |
| 644 // ScheduleTasks to prevent usage from rising above limits. | 738 // ScheduleTasks to prevent usage from rising above limits. |
| 645 resource_pool_->ReduceResourceUsage(); | 739 resource_pool_->ReduceResourceUsage(); |
| 646 | 740 |
| 647 // Schedule running of |raster_queue_|. This replaces any previously | 741 // Schedule running of |raster_queue_|. This replaces any previously |
| 648 // scheduled tasks and effectively cancels all tasks not present | 742 // scheduled tasks and effectively cancels all tasks not present |
| 649 // in |raster_queue_|. | 743 // in |raster_queue_|. |
| 650 tile_task_runner_->ScheduleTasks(&raster_queue_); | 744 tile_task_runner_->ScheduleTasks(graph.Pass()); |
| 651 | 745 |
| 652 // It's now safe to clean up orphan tasks as raster worker pool is not | 746 // It's now safe to clean up orphan tasks as raster worker pool is not |
| 653 // allowed to keep around unreferenced raster tasks after ScheduleTasks() has | 747 // allowed to keep around unreferenced raster tasks after ScheduleTasks() has |
| 654 // been called. | 748 // been called. |
| 655 orphan_raster_tasks_.clear(); | 749 orphan_tasks_.clear(); |
| 750 | |
| 751 // Our |new_task_set_finished_tasks| need to be kept alive while the | |
| 752 // TaskGraphRunner may be using them. | |
|
reveman
2015/12/02 05:22:54
They only need to be kept alive while scheduled. I
ericrk
2015/12/02 21:28:08
re-structured things along these lines.
| |
| 753 for (int task_set = 0; task_set < kNumberOfTaskSets; ++task_set) { | |
| 754 orphan_tasks_.push_back(std::move(new_task_set_finished_tasks[task_set])); | |
| 755 } | |
| 656 | 756 |
| 657 did_check_for_completed_tasks_since_last_schedule_tasks_ = false; | 757 did_check_for_completed_tasks_since_last_schedule_tasks_ = false; |
| 758 | |
| 759 TRACE_EVENT_ASYNC_STEP_INTO1("cc", "ScheduledTasks", this, "running", "state", | |
| 760 ScheduledTasksStateAsValue()); | |
| 658 } | 761 } |
| 659 | 762 |
| 660 scoped_refptr<RasterTask> TileManager::CreateRasterTask( | 763 scoped_refptr<RasterTask> TileManager::CreateRasterTask( |
| 661 const PrioritizedTile& prioritized_tile) { | 764 const PrioritizedTile& prioritized_tile) { |
| 662 Tile* tile = prioritized_tile.tile(); | 765 Tile* tile = prioritized_tile.tile(); |
| 663 uint64_t resource_content_id = 0; | 766 uint64_t resource_content_id = 0; |
| 664 Resource* resource = nullptr; | 767 Resource* resource = nullptr; |
| 665 if (use_partial_raster_ && tile->invalidated_id()) { | 768 if (use_partial_raster_ && tile->invalidated_id()) { |
| 666 // TODO(danakj): For resources that are in use, we should still grab them | 769 // TODO(danakj): For resources that are in use, we should still grab them |
| 667 // and copy from them instead of rastering everything. crbug.com/492754 | 770 // and copy from them instead of rastering everything. crbug.com/492754 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 702 | 805 |
| 703 void TileManager::OnRasterTaskCompleted( | 806 void TileManager::OnRasterTaskCompleted( |
| 704 Tile::Id tile_id, | 807 Tile::Id tile_id, |
| 705 Resource* resource, | 808 Resource* resource, |
| 706 const DisplayListRasterSource::SolidColorAnalysis& analysis, | 809 const DisplayListRasterSource::SolidColorAnalysis& analysis, |
| 707 bool was_canceled) { | 810 bool was_canceled) { |
| 708 DCHECK(tiles_.find(tile_id) != tiles_.end()); | 811 DCHECK(tiles_.find(tile_id) != tiles_.end()); |
| 709 | 812 |
| 710 Tile* tile = tiles_[tile_id]; | 813 Tile* tile = tiles_[tile_id]; |
| 711 DCHECK(tile->raster_task_.get()); | 814 DCHECK(tile->raster_task_.get()); |
| 712 orphan_raster_tasks_.push_back(tile->raster_task_); | 815 orphan_tasks_.push_back(tile->raster_task_); |
| 713 tile->raster_task_ = nullptr; | 816 tile->raster_task_ = nullptr; |
| 714 | 817 |
| 715 if (was_canceled) { | 818 if (was_canceled) { |
| 716 ++flush_stats_.canceled_count; | 819 ++flush_stats_.canceled_count; |
| 717 // TODO(ericrk): If more partial raster work is done in the future, it may | 820 // TODO(ericrk): If more partial raster work is done in the future, it may |
| 718 // be worth returning the resource to the pool with its previous ID (not | 821 // be worth returning the resource to the pool with its previous ID (not |
| 719 // currently tracked). crrev.com/1370333002/#ps40001 has a possible method | 822 // currently tracked). crrev.com/1370333002/#ps40001 has a possible method |
| 720 // of achieving this. | 823 // of achieving this. |
| 721 resource_pool_->ReleaseResource(resource, 0 /* content_id */); | 824 resource_pool_->ReleaseResource(resource, 0 /* content_id */); |
| 722 return; | 825 return; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 766 DCHECK(tiles_.find(tile->id()) == tiles_.end()); | 869 DCHECK(tiles_.find(tile->id()) == tiles_.end()); |
| 767 | 870 |
| 768 tiles_[tile->id()] = tile.get(); | 871 tiles_[tile->id()] = tile.get(); |
| 769 image_decode_controller_.AddLayerUsedCount(tile->layer_id()); | 872 image_decode_controller_.AddLayerUsedCount(tile->layer_id()); |
| 770 return tile; | 873 return tile; |
| 771 } | 874 } |
| 772 | 875 |
| 773 void TileManager::SetTileTaskRunnerForTesting( | 876 void TileManager::SetTileTaskRunnerForTesting( |
| 774 TileTaskRunner* tile_task_runner) { | 877 TileTaskRunner* tile_task_runner) { |
| 775 tile_task_runner_ = tile_task_runner; | 878 tile_task_runner_ = tile_task_runner; |
| 776 tile_task_runner_->SetClient(this); | |
| 777 } | 879 } |
| 778 | 880 |
| 779 bool TileManager::AreRequiredTilesReadyToDraw( | 881 bool TileManager::AreRequiredTilesReadyToDraw( |
| 780 RasterTilePriorityQueue::Type type) const { | 882 RasterTilePriorityQueue::Type type) const { |
| 781 scoped_ptr<RasterTilePriorityQueue> raster_priority_queue( | 883 scoped_ptr<RasterTilePriorityQueue> raster_priority_queue( |
| 782 client_->BuildRasterQueue(global_state_.tree_priority, type)); | 884 client_->BuildRasterQueue(global_state_.tree_priority, type)); |
| 783 // It is insufficient to check whether the raster queue we constructed is | 885 // It is insufficient to check whether the raster queue we constructed is |
| 784 // empty. The reason for this is that there are situations (rasterize on | 886 // empty. The reason for this is that there are situations (rasterize on |
| 785 // demand) when the tile both needs raster and it's ready to draw. Hence, we | 887 // demand) when the tile both needs raster and it's ready to draw. Hence, we |
| 786 // have to iterate the queue to check whether the required tiles are ready to | 888 // have to iterate the queue to check whether the required tiles are ready to |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 940 } | 1042 } |
| 941 | 1043 |
| 942 ResourceFormat TileManager::DetermineResourceFormat(const Tile* tile) const { | 1044 ResourceFormat TileManager::DetermineResourceFormat(const Tile* tile) const { |
| 943 return tile_task_runner_->GetResourceFormat(!tile->is_opaque()); | 1045 return tile_task_runner_->GetResourceFormat(!tile->is_opaque()); |
| 944 } | 1046 } |
| 945 | 1047 |
| 946 bool TileManager::DetermineResourceRequiresSwizzle(const Tile* tile) const { | 1048 bool TileManager::DetermineResourceRequiresSwizzle(const Tile* tile) const { |
| 947 return tile_task_runner_->GetResourceRequiresSwizzle(!tile->is_opaque()); | 1049 return tile_task_runner_->GetResourceRequiresSwizzle(!tile->is_opaque()); |
| 948 } | 1050 } |
| 949 | 1051 |
| 950 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { | 1052 scoped_refptr<base::trace_event::ConvertableToTraceFormat> |
| 1053 TileManager::ScheduledTasksStateAsValue() const { | |
| 1054 scoped_refptr<base::trace_event::TracedValue> state = | |
| 1055 new base::trace_event::TracedValue(); | |
| 1056 | |
| 1057 state->BeginArray("tasks_pending"); | |
| 1058 for (int task_set = 0; task_set < kNumberOfTaskSets; ++task_set) { | |
| 1059 state->AppendBoolean(tasks_pending_[task_set]); | |
| 1060 } | |
| 1061 state->EndArray(); | |
| 1062 return state; | |
| 951 } | 1063 } |
| 952 | 1064 |
| 1065 void TileManager::BuildTaskGraph( | |
| 1066 const PrioritizedTileVector& tiles_that_need_to_be_rasterized, | |
| 1067 TaskGraph* graph, | |
| 1068 std::array<scoped_refptr<TileTask>, kNumberOfTaskSets>* | |
| 1069 new_task_set_finished_tasks) { | |
| 1070 size_t task_count[kNumberOfTaskSets] = {0}; | |
| 1071 | |
| 1072 for (int task_set = 0; task_set < kNumberOfTaskSets; ++task_set) { | |
| 1073 (*new_task_set_finished_tasks)[task_set] = CreateTaskSetFinishedTask( | |
| 1074 task_runner_.get(), | |
| 1075 base::Bind(&TileManager::DidFinishRunningTileTasks, | |
| 1076 task_set_finished_weak_ptr_factory_.GetWeakPtr(), | |
| 1077 static_cast<TaskSet>(task_set))); | |
| 1078 } | |
| 1079 | |
| 1080 size_t priority = kTileTaskPriorityBase; | |
| 1081 | |
| 1082 // Build a new task queue containing all task currently needed. Tasks | |
| 1083 // are added in order of priority, highest priority task first. | |
| 1084 for (auto& prioritized_tile : tiles_that_need_to_be_rasterized) { | |
| 1085 Tile* tile = prioritized_tile.tile(); | |
| 1086 | |
| 1087 DCHECK(tile->draw_info().requires_resource()); | |
| 1088 DCHECK(!tile->draw_info().resource_); | |
| 1089 | |
| 1090 if (!tile->raster_task_.get()) | |
| 1091 tile->raster_task_ = CreateRasterTask(prioritized_tile); | |
| 1092 | |
| 1093 TaskSetCollection task_sets; | |
| 1094 if (tile->required_for_activation()) | |
| 1095 task_sets.set(REQUIRED_FOR_ACTIVATION); | |
| 1096 if (tile->required_for_draw()) | |
| 1097 task_sets.set(REQUIRED_FOR_DRAW); | |
| 1098 task_sets.set(ALL); | |
| 1099 | |
| 1100 RasterTask* task = tile->raster_task_.get(); | |
| 1101 DCHECK(!task->HasCompleted()); | |
| 1102 | |
| 1103 for (int task_set = 0; task_set < kNumberOfTaskSets; ++task_set) { | |
| 1104 if (!task_sets[task_set]) | |
| 1105 continue; | |
| 1106 | |
| 1107 ++task_count[task_set]; | |
| 1108 | |
| 1109 graph->edges.push_back(TaskGraph::Edge( | |
| 1110 task, (*new_task_set_finished_tasks)[task_set].get())); | |
| 1111 } | |
| 1112 | |
| 1113 InsertNodesForRasterTask(graph, task, task->dependencies(), priority++); | |
| 1114 } | |
| 1115 | |
| 1116 for (int task_set = 0; task_set < kNumberOfTaskSets; ++task_set) { | |
| 1117 InsertNodeForTask(graph, (*new_task_set_finished_tasks)[task_set].get(), | |
| 1118 kTaskSetFinishedTaskPriorityBase + task_set, | |
| 1119 task_count[task_set]); | |
| 1120 } | |
| 1121 } | |
| 1122 | |
| 1123 TileManager::MemoryUsage::MemoryUsage() | |
| 1124 : memory_bytes_(0), resource_count_(0) {} | |
| 1125 | |
| 953 TileManager::MemoryUsage::MemoryUsage(size_t memory_bytes, | 1126 TileManager::MemoryUsage::MemoryUsage(size_t memory_bytes, |
| 954 size_t resource_count) | 1127 size_t resource_count) |
| 955 : memory_bytes_(static_cast<int64>(memory_bytes)), | 1128 : memory_bytes_(static_cast<int64>(memory_bytes)), |
| 956 resource_count_(static_cast<int>(resource_count)) { | 1129 resource_count_(static_cast<int>(resource_count)) { |
| 957 // MemoryUsage is constructed using size_ts, since it deals with memory and | 1130 // MemoryUsage is constructed using size_ts, since it deals with memory and |
| 958 // the inputs are typically size_t. However, during the course of usage (in | 1131 // the inputs are typically size_t. However, during the course of usage (in |
| 959 // particular operator-=) can cause internal values to become negative. Thus, | 1132 // particular operator-=) can cause internal values to become negative. Thus, |
| 960 // member variables are signed. | 1133 // member variables are signed. |
| 961 DCHECK_LE(memory_bytes, | 1134 DCHECK_LE(memory_bytes, |
| 962 static_cast<size_t>(std::numeric_limits<int64>::max())); | 1135 static_cast<size_t>(std::numeric_limits<int64>::max())); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1017 void TileManager::Signals::reset() { | 1190 void TileManager::Signals::reset() { |
| 1018 ready_to_activate = false; | 1191 ready_to_activate = false; |
| 1019 did_notify_ready_to_activate = false; | 1192 did_notify_ready_to_activate = false; |
| 1020 ready_to_draw = false; | 1193 ready_to_draw = false; |
| 1021 did_notify_ready_to_draw = false; | 1194 did_notify_ready_to_draw = false; |
| 1022 all_tile_tasks_completed = false; | 1195 all_tile_tasks_completed = false; |
| 1023 did_notify_all_tile_tasks_completed = false; | 1196 did_notify_all_tile_tasks_completed = false; |
| 1024 } | 1197 } |
| 1025 | 1198 |
| 1026 } // namespace cc | 1199 } // namespace cc |
| OLD | NEW |