| Index: cc/tiles/tile_manager.cc
|
| diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc
|
| index 08796a32f949f1064dec57a5b0a9883a89e990ab..9d17f1ce399f9ec1cf2e652bdeee1db0b7440d3a 100644
|
| --- a/cc/tiles/tile_manager.cc
|
| +++ b/cc/tiles/tile_manager.cc
|
| @@ -366,7 +366,8 @@ TileManager::TileManager(TileManagerClient* client,
|
| has_scheduled_tile_tasks_(false),
|
| prepare_tiles_count_(0u),
|
| next_tile_id_(0u),
|
| - task_set_finished_weak_ptr_factory_(this) {}
|
| + task_set_finished_weak_ptr_factory_(this),
|
| + ready_to_draw_callback_weak_ptr_factory_(this) {}
|
|
|
| TileManager::~TileManager() {
|
| FinishTasksAndCleanUp();
|
| @@ -394,6 +395,7 @@ void TileManager::FinishTasksAndCleanUp() {
|
| more_tiles_need_prepare_check_notifier_.Cancel();
|
| signals_check_notifier_.Cancel();
|
| task_set_finished_weak_ptr_factory_.InvalidateWeakPtrs();
|
| + ready_to_draw_callback_weak_ptr_factory_.InvalidateWeakPtrs();
|
|
|
| image_controller_.SetImageDecodeCache(nullptr);
|
| locked_image_tasks_.clear();
|
| @@ -418,6 +420,10 @@ void TileManager::SetResources(ResourcePool* resource_pool,
|
|
|
| void TileManager::Release(Tile* tile) {
|
| released_tiles_.push_back(tile);
|
| + auto found = std::find(pending_ready_for_draw_tiles_.begin(),
|
| + pending_ready_for_draw_tiles_.end(), tile);
|
| + if (found != pending_ready_for_draw_tiles_.end())
|
| + pending_ready_for_draw_tiles_.erase(found);
|
| }
|
|
|
| void TileManager::FreeResourcesForReleasedTiles() {
|
| @@ -512,6 +518,9 @@ bool TileManager::PrepareTiles(
|
| FreeResourcesForReleasedTiles();
|
| CleanUpReleasedTiles();
|
|
|
| + if (!pending_ready_for_draw_tiles_.empty())
|
| + pending_tile_requirements_dirty_ = true;
|
| +
|
| PrioritizedWorkToSchedule prioritized_work = AssignGpuMemoryToTiles();
|
|
|
| // Inform the client that will likely require a draw if the highest priority
|
| @@ -538,6 +547,7 @@ void TileManager::Flush() {
|
|
|
| tile_task_manager_->CheckForCompletedTasks();
|
| did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
|
| + CheckPendingReadyToDrawTiles(true /* issue_signals */);
|
|
|
| TRACE_EVENT_INSTANT1("cc", "DidFlush", TRACE_EVENT_SCOPE_THREAD, "stats",
|
| RasterTaskCompletionStatsAsValue(flush_stats_));
|
| @@ -781,7 +791,7 @@ void TileManager::FreeResourcesForTile(Tile* tile) {
|
| TileDrawInfo& draw_info = tile->draw_info();
|
| if (draw_info.resource_) {
|
| resource_pool_->ReleaseResource(draw_info.resource_);
|
| - draw_info.resource_ = nullptr;
|
| + draw_info.set_resource(nullptr);
|
| }
|
| }
|
|
|
| @@ -1036,14 +1046,15 @@ void TileManager::OnRasterTaskCompleted(
|
| resource_pool_->OnContentReplaced(resource->id(), tile->id());
|
| ++flush_stats_.completed_count;
|
|
|
| - draw_info.set_use_resource();
|
| - draw_info.resource_ = resource;
|
| + draw_info.set_resource(resource);
|
| draw_info.contents_swizzled_ = DetermineResourceRequiresSwizzle(tile);
|
| -
|
| - DCHECK(draw_info.IsReadyToDraw());
|
| - draw_info.set_was_ever_ready_to_draw();
|
| -
|
| - client_->NotifyTileStateChanged(tile);
|
| + if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY) {
|
| + draw_info.set_is_resource_ready_for_draw();
|
| + draw_info.set_was_ever_ready_to_draw();
|
| + client_->NotifyTileStateChanged(tile);
|
| + } else {
|
| + pending_ready_for_draw_tiles_.push_back(tile);
|
| + }
|
| }
|
|
|
| ScopedTilePtr TileManager::CreateTile(const Tile::CreateInfo& info,
|
| @@ -1089,14 +1100,16 @@ bool TileManager::AreRequiredTilesReadyToDraw(
|
|
|
| bool TileManager::IsReadyToActivate() const {
|
| TRACE_EVENT0("cc", "TileManager::IsReadyToActivate");
|
| - return AreRequiredTilesReadyToDraw(
|
| - RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION);
|
| + return !has_pending_ready_to_activate_resource_ &&
|
| + AreRequiredTilesReadyToDraw(
|
| + RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION);
|
| }
|
|
|
| bool TileManager::IsReadyToDraw() const {
|
| TRACE_EVENT0("cc", "TileManager::IsReadyToDraw");
|
| - return AreRequiredTilesReadyToDraw(
|
| - RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW);
|
| + return !has_pending_ready_to_draw_resources_ &&
|
| + AreRequiredTilesReadyToDraw(
|
| + RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW);
|
| }
|
|
|
| void TileManager::CheckAndIssueSignals() {
|
| @@ -1104,6 +1117,8 @@ void TileManager::CheckAndIssueSignals() {
|
| tile_task_manager_->CheckForCompletedTasks();
|
| did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
|
|
|
| + CheckPendingReadyToDrawTiles(false /* issue_signals */);
|
| +
|
| // Ready to activate.
|
| if (signals_.ready_to_activate && !signals_.did_notify_ready_to_activate) {
|
| signals_.ready_to_activate = false;
|
| @@ -1257,7 +1272,85 @@ bool TileManager::UsePartialRaster() const {
|
| raster_buffer_provider_->CanPartialRasterIntoProvidedResource();
|
| }
|
|
|
| -// Utility function that can be used to create a "Task set finished" task that
|
| +void TileManager::CheckPendingReadyToDrawTiles(bool issue_signals) {
|
| + // We are about to check all pending resources. We will re-set these to true
|
| + // if we encounter them.
|
| + has_pending_ready_to_draw_resources_ = false;
|
| + has_pending_ready_to_activate_resource_ = false;
|
| +
|
| + bool in_smoothness_mode =
|
| + global_state_.tree_priority == SMOOTHNESS_TAKES_PRIORITY;
|
| +
|
| + ResourceProvider::ResourceIdArray required_for_activation_ids;
|
| + ResourceProvider::ResourceIdArray required_for_draw_ids;
|
| + for (auto it = pending_ready_for_draw_tiles_.begin();
|
| + it != pending_ready_for_draw_tiles_.end();) {
|
| + Tile* tile = *it;
|
| + Resource* resource = tile->draw_info().resource_;
|
| + DCHECK(resource);
|
| +
|
| + if (!in_smoothness_mode ||
|
| + raster_buffer_provider_->IsResourceReadyToDraw(resource->id())) {
|
| + tile->draw_info().set_is_resource_ready_for_draw();
|
| + tile->draw_info().set_was_ever_ready_to_draw();
|
| + client_->NotifyTileStateChanged(tile);
|
| + it = pending_ready_for_draw_tiles_.erase(it);
|
| + continue;
|
| + }
|
| +
|
| + if (pending_tile_requirements_dirty_) {
|
| + tile->set_required_for_activation(
|
| + tile->tiling()->IsTileRequiredForActivation(tile));
|
| + tile->set_required_for_draw(tile->tiling()->IsTileRequiredForDraw(tile));
|
| + }
|
| +
|
| + if (tile->required_for_activation()) {
|
| + has_pending_ready_to_activate_resource_ = true;
|
| + required_for_activation_ids.push_back(resource->id());
|
| + }
|
| + if (tile->required_for_draw()) {
|
| + has_pending_ready_to_draw_resources_ = true;
|
| + required_for_draw_ids.push_back(resource->id());
|
| + }
|
| +
|
| + ++it;
|
| + }
|
| +
|
| + if (!required_for_activation_ids.empty()) {
|
| + pending_required_for_activation_callback_id_ =
|
| + raster_buffer_provider_->SetReadyToDrawCallback(
|
| + required_for_activation_ids,
|
| + base::Bind(&TileManager::ReadyToDrawCallback,
|
| + ready_to_draw_callback_weak_ptr_factory_.GetWeakPtr()),
|
| + pending_required_for_activation_callback_id_);
|
| + }
|
| +
|
| + if (!required_for_draw_ids.empty()) {
|
| + pending_required_for_activation_callback_id_ =
|
| + raster_buffer_provider_->SetReadyToDrawCallback(
|
| + required_for_draw_ids,
|
| + base::Bind(&TileManager::ReadyToDrawCallback,
|
| + ready_to_draw_callback_weak_ptr_factory_.GetWeakPtr()),
|
| + pending_required_for_activation_callback_id_);
|
| + }
|
| +
|
| + // Update our signals now that we know whether we have pending resources.
|
| + signals_.ready_to_activate = !has_pending_ready_to_activate_resource_;
|
| + signals_.ready_to_draw = !has_pending_ready_to_draw_resources_;
|
| +
|
| + if (issue_signals && (signals_.ready_to_activate || signals_.ready_to_draw))
|
| + signals_check_notifier_.Schedule();
|
| +
|
| + // We've just updated all pending tile requirements if necessary.
|
| + pending_tile_requirements_dirty_ = false;
|
| +}
|
| +
|
| +void TileManager::ReadyToDrawCallback(uint64_t callback_id) {
|
| + signals_check_notifier_.Schedule();
|
| +}
|
| +
|
| +// Utility function that can be used to create a "Task set finished" task
|
| +// that
|
| // posts |callback| to |task_runner| when run.
|
| scoped_refptr<TileTask> TileManager::CreateTaskSetFinishedTask(
|
| void (TileManager::*callback)()) {
|
| @@ -1273,9 +1366,12 @@ TileManager::MemoryUsage::MemoryUsage(size_t memory_bytes,
|
| size_t resource_count)
|
| : memory_bytes_(static_cast<int64_t>(memory_bytes)),
|
| resource_count_(static_cast<int>(resource_count)) {
|
| - // MemoryUsage is constructed using size_ts, since it deals with memory and
|
| - // the inputs are typically size_t. However, during the course of usage (in
|
| - // particular operator-=) can cause internal values to become negative. Thus,
|
| + // MemoryUsage is constructed using size_ts, since it deals with memory
|
| + // and
|
| + // the inputs are typically size_t. However, during the course of usage
|
| + // (in
|
| + // particular operator-=) can cause internal values to become negative.
|
| + // Thus,
|
| // member variables are signed.
|
| DCHECK_LE(memory_bytes,
|
| static_cast<size_t>(std::numeric_limits<int64_t>::max()));
|
| @@ -1288,7 +1384,8 @@ TileManager::MemoryUsage TileManager::MemoryUsage::FromConfig(
|
| const gfx::Size& size,
|
| ResourceFormat format) {
|
| // We can use UncheckedSizeInBytes here since this is used with a tile
|
| - // size which is determined by the compositor (it's at most max texture size).
|
| + // size which is determined by the compositor (it's at most max texture
|
| + // size).
|
| return MemoryUsage(ResourceUtil::UncheckedSizeInBytes<size_t>(size, format),
|
| 1);
|
| }
|
|
|