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

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

Powered by Google App Engine
This is Rietveld 408576698