Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(864)

Side by Side Diff: cc/resources/tile_manager.cc

Issue 62283012: cc: Added tile bundles (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/resources/tile_manager.h ('k') | cc/resources/tile_manager_perftest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/resources/tile_manager.h" 5 #include "cc/resources/tile_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <string> 9 #include <string>
10 10
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 did_check_for_completed_tasks_since_last_schedule_tasks_(true) { 217 did_check_for_completed_tasks_since_last_schedule_tasks_(true) {
218 raster_worker_pool_->SetClient(this); 218 raster_worker_pool_->SetClient(this);
219 } 219 }
220 220
221 TileManager::~TileManager() { 221 TileManager::~TileManager() {
222 // Reset global state and manage. This should cause 222 // Reset global state and manage. This should cause
223 // our memory usage to drop to zero. 223 // our memory usage to drop to zero.
224 global_state_ = GlobalStateThatImpactsTilePriority(); 224 global_state_ = GlobalStateThatImpactsTilePriority();
225 225
226 CleanUpReleasedTiles(); 226 CleanUpReleasedTiles();
227 DCHECK_EQ(0u, bundles_.size());
227 DCHECK_EQ(0u, tiles_.size()); 228 DCHECK_EQ(0u, tiles_.size());
228 229
229 RasterWorkerPool::RasterTask::Queue empty; 230 RasterWorkerPool::RasterTask::Queue empty;
230 raster_worker_pool_->ScheduleTasks(&empty); 231 raster_worker_pool_->ScheduleTasks(&empty);
231 232
232 // This should finish all pending tasks and release any uninitialized 233 // This should finish all pending tasks and release any uninitialized
233 // resources. 234 // resources.
234 raster_worker_pool_->Shutdown(); 235 raster_worker_pool_->Shutdown();
235 raster_worker_pool_->CheckForCompletedTasks(); 236 raster_worker_pool_->CheckForCompletedTasks();
236 237
237 DCHECK_EQ(0u, bytes_releasable_); 238 DCHECK_EQ(0u, bytes_releasable_);
238 DCHECK_EQ(0u, resources_releasable_); 239 DCHECK_EQ(0u, resources_releasable_);
239 } 240 }
240 241
241 void TileManager::Release(Tile* tile) { 242 void TileManager::Release(Tile* tile) {
242 prioritized_tiles_dirty_ = true; 243 prioritized_tiles_dirty_ = true;
243 released_tiles_.push_back(tile); 244 released_tiles_.push_back(tile);
244 } 245 }
245 246
247 void TileManager::Release(TileBundle* bundle) {
248 released_tile_bundles_.push_back(bundle);
249 }
250
246 void TileManager::DidChangeTilePriority(Tile* tile) { 251 void TileManager::DidChangeTilePriority(Tile* tile) {
247 prioritized_tiles_dirty_ = true; 252 prioritized_tiles_dirty_ = true;
248 } 253 }
249 254
255 void TileManager::DidChangeTileBundlePriority(TileBundle* bundle) {
256 prioritized_tiles_dirty_ = true;
257 }
258
250 bool TileManager::ShouldForceTasksRequiredForActivationToComplete() const { 259 bool TileManager::ShouldForceTasksRequiredForActivationToComplete() const {
251 return global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY; 260 return global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY;
252 } 261 }
253 262
254 void TileManager::CleanUpReleasedTiles() { 263 void TileManager::CleanUpReleasedTiles() {
264 // Clean up bundles first, since they might have tiles that will become
265 // released as well.
266 for (std::vector<TileBundle*>::iterator it = released_tile_bundles_.begin();
267 it != released_tile_bundles_.end();
268 ++it) {
269 TileBundle* bundle = *it;
270 DCHECK(bundles_.find(bundle->id()) != bundles_.end());
271 bundles_.erase(bundle->id());
272 delete bundle;
273 }
274 released_tile_bundles_.clear();
275
255 for (std::vector<Tile*>::iterator it = released_tiles_.begin(); 276 for (std::vector<Tile*>::iterator it = released_tiles_.begin();
256 it != released_tiles_.end(); 277 it != released_tiles_.end();
257 ++it) { 278 ++it) {
258 Tile* tile = *it; 279 Tile* tile = *it;
259 280
260 FreeResourcesForTile(tile); 281 FreeResourcesForTile(tile);
261 282
262 DCHECK(tiles_.find(tile->id()) != tiles_.end()); 283 DCHECK(tiles_.find(tile->id()) != tiles_.end());
263 tiles_.erase(tile->id()); 284 tiles_.erase(tile->id());
264 285
265 LayerCountMap::iterator layer_it = 286 LayerCountMap::iterator layer_it =
266 used_layer_counts_.find(tile->layer_id()); 287 used_layer_counts_.find(tile->layer_id());
267 DCHECK_GT(layer_it->second, 0); 288 DCHECK_GT(layer_it->second, 0);
268 if (--layer_it->second == 0) { 289 if (--layer_it->second == 0) {
269 used_layer_counts_.erase(layer_it); 290 used_layer_counts_.erase(layer_it);
270 image_decode_tasks_.erase(tile->layer_id()); 291 image_decode_tasks_.erase(tile->layer_id());
271 } 292 }
272 293
273 delete tile; 294 delete tile;
274 } 295 }
275
276 released_tiles_.clear(); 296 released_tiles_.clear();
277 } 297 }
278 298
279 void TileManager::UpdatePrioritizedTileSetIfNeeded() { 299 void TileManager::UpdatePrioritizedTileSetIfNeeded() {
280 if (!prioritized_tiles_dirty_) 300 if (!prioritized_tiles_dirty_)
281 return; 301 return;
282 302
283 CleanUpReleasedTiles(); 303 CleanUpReleasedTiles();
284 304
285 prioritized_tiles_.Clear(); 305 prioritized_tiles_.Clear();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 TRACE_EVENT0("cc", "TileManager::GetTilesWithAssignedBins"); 371 TRACE_EVENT0("cc", "TileManager::GetTilesWithAssignedBins");
352 372
353 // Compute new stats to be return by GetMemoryStats(). 373 // Compute new stats to be return by GetMemoryStats().
354 memory_required_bytes_ = 0; 374 memory_required_bytes_ = 0;
355 memory_nice_to_have_bytes_ = 0; 375 memory_nice_to_have_bytes_ = 0;
356 376
357 const TileMemoryLimitPolicy memory_policy = global_state_.memory_limit_policy; 377 const TileMemoryLimitPolicy memory_policy = global_state_.memory_limit_policy;
358 const TreePriority tree_priority = global_state_.tree_priority; 378 const TreePriority tree_priority = global_state_.tree_priority;
359 379
360 // For each tree, bin into different categories of tiles. 380 // For each tree, bin into different categories of tiles.
361 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 381 for (TileBundleMap::iterator bundle_it = bundles_.begin();
362 Tile* tile = it->second; 382 bundle_it != bundles_.end();
363 ManagedTileState& mts = tile->managed_state(); 383 ++bundle_it) {
384 for (TileBundle::Iterator it(bundle_it->second); it; ++it) {
385 Tile* tile = *it;
386 ManagedTileState& mts = tile->managed_state();
364 387
365 const ManagedTileState::TileVersion& tile_version = 388 const ManagedTileState::TileVersion& tile_version =
366 tile->GetTileVersionForDrawing(); 389 tile->GetTileVersionForDrawing();
367 bool tile_is_ready_to_draw = tile_version.IsReadyToDraw(); 390 bool tile_is_ready_to_draw = tile_version.IsReadyToDraw();
368 bool tile_is_active = 391 bool tile_is_active =
369 tile_is_ready_to_draw || 392 tile_is_ready_to_draw ||
370 !mts.tile_versions[mts.raster_mode].raster_task_.is_null(); 393 !mts.tile_versions[mts.raster_mode].raster_task_.is_null();
371 394
372 // Get the active priority and bin. 395 // Get the active priority and bin.
373 TilePriority active_priority = tile->priority(ACTIVE_TREE); 396 TilePriority active_priority = it.priority(ACTIVE_TREE);
374 ManagedTileBin active_bin = BinFromTilePriority(active_priority); 397 ManagedTileBin active_bin = BinFromTilePriority(active_priority);
375 398
376 // Get the pending priority and bin. 399 // Get the pending priority and bin.
377 TilePriority pending_priority = tile->priority(PENDING_TREE); 400 TilePriority pending_priority = it.priority(PENDING_TREE);
378 ManagedTileBin pending_bin = BinFromTilePriority(pending_priority); 401 ManagedTileBin pending_bin = BinFromTilePriority(pending_priority);
379 402
380 bool pending_is_low_res = 403 bool pending_is_low_res =
381 pending_priority.resolution == LOW_RESOLUTION; 404 pending_priority.resolution == LOW_RESOLUTION;
382 bool pending_is_non_ideal = 405 bool pending_is_non_ideal =
383 pending_priority.resolution == NON_IDEAL_RESOLUTION; 406 pending_priority.resolution == NON_IDEAL_RESOLUTION;
384 bool active_is_non_ideal = 407 bool active_is_non_ideal =
385 active_priority.resolution == NON_IDEAL_RESOLUTION; 408 active_priority.resolution == NON_IDEAL_RESOLUTION;
386 409
387 // Adjust pending bin state for low res tiles. This prevents 410 // Adjust pending bin state for low res tiles. This prevents
388 // pending tree low-res tiles from being initialized before 411 // pending tree low-res tiles from being initialized before
389 // high-res tiles. 412 // high-res tiles.
390 if (pending_is_low_res) 413 if (pending_is_low_res)
391 pending_bin = std::max(pending_bin, EVENTUALLY_BIN); 414 pending_bin = std::max(pending_bin, EVENTUALLY_BIN);
392 415
393 // Adjust bin state based on if ready to draw. 416 // Adjust bin state based on if ready to draw.
394 active_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][active_bin]; 417 active_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][active_bin];
395 pending_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][pending_bin]; 418 pending_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][pending_bin];
396 419
397 // Adjust bin state based on if active. 420 // Adjust bin state based on if active.
398 active_bin = kBinIsActiveMap[tile_is_active][active_bin]; 421 active_bin = kBinIsActiveMap[tile_is_active][active_bin];
399 pending_bin = kBinIsActiveMap[tile_is_active][pending_bin]; 422 pending_bin = kBinIsActiveMap[tile_is_active][pending_bin];
400 423
401 // We never want to paint new non-ideal tiles, as we always have 424 // We never want to paint new non-ideal tiles, as we always have
402 // a high-res tile covering that content (paint that instead). 425 // a high-res tile covering that content (paint that instead).
403 if (!tile_is_ready_to_draw && active_is_non_ideal) 426 if (!tile_is_ready_to_draw && active_is_non_ideal)
404 active_bin = NEVER_BIN; 427 active_bin = NEVER_BIN;
405 if (!tile_is_ready_to_draw && pending_is_non_ideal) 428 if (!tile_is_ready_to_draw && pending_is_non_ideal)
406 pending_bin = NEVER_BIN; 429 pending_bin = NEVER_BIN;
407 430
408 // Compute combined bin. 431 // Compute combined bin.
409 ManagedTileBin combined_bin = std::min(active_bin, pending_bin); 432 ManagedTileBin combined_bin = std::min(active_bin, pending_bin);
410 433
411 ManagedTileBin tree_bin[NUM_TREES]; 434 ManagedTileBin tree_bin[NUM_TREES];
412 tree_bin[ACTIVE_TREE] = kBinPolicyMap[memory_policy][active_bin]; 435 tree_bin[ACTIVE_TREE] = kBinPolicyMap[memory_policy][active_bin];
413 tree_bin[PENDING_TREE] = kBinPolicyMap[memory_policy][pending_bin]; 436 tree_bin[PENDING_TREE] = kBinPolicyMap[memory_policy][pending_bin];
414 437
415 // The bin that the tile would have if the GPU memory manager had 438 // The bin that the tile would have if the GPU memory manager had
416 // a maximally permissive policy, send to the GPU memory manager 439 // a maximally permissive policy, send to the GPU memory manager
417 // to determine policy. 440 // to determine policy.
418 ManagedTileBin gpu_memmgr_stats_bin = NEVER_BIN; 441 ManagedTileBin gpu_memmgr_stats_bin = NEVER_BIN;
419 TilePriority tile_priority; 442 TilePriority tile_priority;
420 443
421 switch (tree_priority) { 444 switch (tree_priority) {
422 case SAME_PRIORITY_FOR_BOTH_TREES: 445 case SAME_PRIORITY_FOR_BOTH_TREES:
423 mts.bin = kBinPolicyMap[memory_policy][combined_bin]; 446 mts.bin = kBinPolicyMap[memory_policy][combined_bin];
424 gpu_memmgr_stats_bin = combined_bin; 447 gpu_memmgr_stats_bin = combined_bin;
425 tile_priority = tile->combined_priority(); 448 tile_priority = TilePriority(active_priority, pending_priority);
426 break; 449 break;
427 case SMOOTHNESS_TAKES_PRIORITY: 450 case SMOOTHNESS_TAKES_PRIORITY:
428 mts.bin = tree_bin[ACTIVE_TREE]; 451 mts.bin = tree_bin[ACTIVE_TREE];
429 gpu_memmgr_stats_bin = active_bin; 452 gpu_memmgr_stats_bin = active_bin;
430 tile_priority = active_priority; 453 tile_priority = active_priority;
431 break; 454 break;
432 case NEW_CONTENT_TAKES_PRIORITY: 455 case NEW_CONTENT_TAKES_PRIORITY:
433 mts.bin = tree_bin[PENDING_TREE]; 456 mts.bin = tree_bin[PENDING_TREE];
434 gpu_memmgr_stats_bin = pending_bin; 457 gpu_memmgr_stats_bin = pending_bin;
435 tile_priority = pending_priority; 458 tile_priority = pending_priority;
436 break; 459 break;
460 }
461
462 if (!tile_is_ready_to_draw || tile_version.requires_resource()) {
463 if ((gpu_memmgr_stats_bin == NOW_BIN) ||
464 (gpu_memmgr_stats_bin == NOW_AND_READY_TO_DRAW_BIN))
465 memory_required_bytes_ += BytesConsumedIfAllocated(tile);
466 if (gpu_memmgr_stats_bin != NEVER_BIN)
467 memory_nice_to_have_bytes_ += BytesConsumedIfAllocated(tile);
468 }
469
470 // Bump up the priority if we determined it's NEVER_BIN on one tree,
471 // but is still required on the other tree.
472 bool is_in_never_bin_on_both_trees =
473 tree_bin[ACTIVE_TREE] == NEVER_BIN &&
474 tree_bin[PENDING_TREE] == NEVER_BIN;
475
476 if (mts.bin == NEVER_BIN && !is_in_never_bin_on_both_trees)
477 mts.bin = tile_is_active ? AT_LAST_AND_ACTIVE_BIN : AT_LAST_BIN;
478
479 mts.resolution = tile_priority.resolution;
480 mts.time_to_needed_in_seconds = tile_priority.time_to_visible_in_seconds;
481 mts.distance_to_visible_in_pixels =
482 tile_priority.distance_to_visible_in_pixels;
483 mts.required_for_activation = tile_priority.required_for_activation;
484
485 mts.visible_and_ready_to_draw =
486 tree_bin[ACTIVE_TREE] == NOW_AND_READY_TO_DRAW_BIN;
487
488 if (mts.bin == NEVER_BIN) {
489 FreeResourcesForTile(tile);
490 continue;
491 }
492
493 // Note that if the tile is visible_and_ready_to_draw, then we always want
494 // the priority to be NOW_AND_READY_TO_DRAW_BIN, even if HIGH_PRIORITY_BIN
495 // is something different. The reason for this is that if we're
496 // prioritizing the pending tree, we still want visible tiles to take the
497 // highest priority.
498 ManagedTileBin priority_bin = mts.visible_and_ready_to_draw
499 ? NOW_AND_READY_TO_DRAW_BIN
500 : mts.bin;
501
502 // Insert the tile into a priority set.
503 tiles->InsertTile(tile, priority_bin);
437 } 504 }
438
439 if (!tile_is_ready_to_draw || tile_version.requires_resource()) {
440 if ((gpu_memmgr_stats_bin == NOW_BIN) ||
441 (gpu_memmgr_stats_bin == NOW_AND_READY_TO_DRAW_BIN))
442 memory_required_bytes_ += BytesConsumedIfAllocated(tile);
443 if (gpu_memmgr_stats_bin != NEVER_BIN)
444 memory_nice_to_have_bytes_ += BytesConsumedIfAllocated(tile);
445 }
446
447 // Bump up the priority if we determined it's NEVER_BIN on one tree,
448 // but is still required on the other tree.
449 bool is_in_never_bin_on_both_trees =
450 tree_bin[ACTIVE_TREE] == NEVER_BIN &&
451 tree_bin[PENDING_TREE] == NEVER_BIN;
452
453 if (mts.bin == NEVER_BIN && !is_in_never_bin_on_both_trees)
454 mts.bin = tile_is_active ? AT_LAST_AND_ACTIVE_BIN : AT_LAST_BIN;
455
456 mts.resolution = tile_priority.resolution;
457 mts.time_to_needed_in_seconds = tile_priority.time_to_visible_in_seconds;
458 mts.distance_to_visible_in_pixels =
459 tile_priority.distance_to_visible_in_pixels;
460 mts.required_for_activation = tile_priority.required_for_activation;
461
462 mts.visible_and_ready_to_draw =
463 tree_bin[ACTIVE_TREE] == NOW_AND_READY_TO_DRAW_BIN;
464
465 if (mts.bin == NEVER_BIN) {
466 FreeResourcesForTile(tile);
467 continue;
468 }
469
470 // Note that if the tile is visible_and_ready_to_draw, then we always want
471 // the priority to be NOW_AND_READY_TO_DRAW_BIN, even if HIGH_PRIORITY_BIN
472 // is something different. The reason for this is that if we're prioritizing
473 // the pending tree, we still want visible tiles to take the highest
474 // priority.
475 ManagedTileBin priority_bin = mts.visible_and_ready_to_draw
476 ? NOW_AND_READY_TO_DRAW_BIN
477 : mts.bin;
478
479 // Insert the tile into a priority set.
480 tiles->InsertTile(tile, priority_bin);
481 } 505 }
482 } 506 }
483 507
484 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { 508 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) {
485 TRACE_EVENT0("cc", "TileManager::ManageTiles"); 509 TRACE_EVENT0("cc", "TileManager::ManageTiles");
486 510
487 // Update internal state. 511 // Update internal state.
488 if (state != global_state_) { 512 if (state != global_state_) {
489 global_state_ = state; 513 global_state_ = state;
490 prioritized_tiles_dirty_ = true; 514 prioritized_tiles_dirty_ = true;
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 resource_pool_->ReleaseResource(resource.Pass()); 976 resource_pool_->ReleaseResource(resource.Pass());
953 } else { 977 } else {
954 tile_version.set_use_resource(); 978 tile_version.set_use_resource();
955 tile_version.resource_ = resource.Pass(); 979 tile_version.resource_ = resource.Pass();
956 980
957 bytes_releasable_ += BytesConsumedIfAllocated(tile); 981 bytes_releasable_ += BytesConsumedIfAllocated(tile);
958 ++resources_releasable_; 982 ++resources_releasable_;
959 } 983 }
960 984
961 FreeUnusedResourcesForTile(tile); 985 FreeUnusedResourcesForTile(tile);
962 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) 986 if (tile->is_visible())
963 did_initialize_visible_tile_ = true; 987 did_initialize_visible_tile_ = true;
964 } 988 }
965 989
966 scoped_refptr<Tile> TileManager::CreateTile(PicturePileImpl* picture_pile, 990 scoped_refptr<Tile> TileManager::CreateTile(PicturePileImpl* picture_pile,
967 gfx::Size tile_size, 991 gfx::Size tile_size,
968 gfx::Rect content_rect, 992 gfx::Rect content_rect,
969 gfx::Rect opaque_rect, 993 gfx::Rect opaque_rect,
970 float contents_scale, 994 float contents_scale,
971 int layer_id, 995 int layer_id,
972 int source_frame_number, 996 int source_frame_number,
973 int flags) { 997 int flags) {
974 scoped_refptr<Tile> tile = make_scoped_refptr(new Tile(this, 998 scoped_refptr<Tile> tile = make_scoped_refptr(new Tile(this,
975 picture_pile, 999 picture_pile,
976 tile_size, 1000 tile_size,
977 content_rect, 1001 content_rect,
978 opaque_rect, 1002 opaque_rect,
979 contents_scale, 1003 contents_scale,
980 layer_id, 1004 layer_id,
981 source_frame_number, 1005 source_frame_number,
982 flags)); 1006 flags));
983 DCHECK(tiles_.find(tile->id()) == tiles_.end()); 1007 DCHECK(tiles_.find(tile->id()) == tiles_.end());
984 1008
985 tiles_[tile->id()] = tile; 1009 tiles_[tile->id()] = tile;
986 used_layer_counts_[tile->layer_id()]++; 1010 used_layer_counts_[tile->layer_id()]++;
987 prioritized_tiles_dirty_ = true; 1011 prioritized_tiles_dirty_ = true;
988 return tile; 1012 return tile;
989 } 1013 }
990 1014
1015 scoped_refptr<TileBundle> TileManager::CreateTileBundle(int offset_x,
1016 int offset_y,
1017 int width,
1018 int height) {
1019 scoped_refptr<TileBundle> bundle = make_scoped_refptr(
1020 new TileBundle(this, offset_x, offset_y, width, height));
1021 bundles_[bundle->id()] = bundle;
1022 return bundle;
1023 }
1024
991 } // namespace cc 1025 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/tile_manager.h ('k') | cc/resources/tile_manager_perftest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698