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

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

Powered by Google App Engine
This is Rietveld 408576698