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

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

Issue 367833003: cc: Start using raster/eviction iterators. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 2 months 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_unittest.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 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 skia::RefPtr<SkPixelRef> pixel_ref_; 196 skia::RefPtr<SkPixelRef> pixel_ref_;
197 int layer_id_; 197 int layer_id_;
198 RenderingStatsInstrumentation* rendering_stats_; 198 RenderingStatsInstrumentation* rendering_stats_;
199 const base::Callback<void(bool was_canceled)> reply_; 199 const base::Callback<void(bool was_canceled)> reply_;
200 200
201 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); 201 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl);
202 }; 202 };
203 203
204 const size_t kScheduledRasterTasksLimit = 32u; 204 const size_t kScheduledRasterTasksLimit = 32u;
205 205
206 // Memory limit policy works by mapping some bin states to the NEVER bin.
207 const ManagedTileBin kBinPolicyMap[NUM_TILE_MEMORY_LIMIT_POLICIES][NUM_BINS] = {
208 // [ALLOW_NOTHING]
209 {NEVER_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
210 NEVER_BIN, // [NOW_BIN]
211 NEVER_BIN, // [SOON_BIN]
212 NEVER_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
213 NEVER_BIN, // [EVENTUALLY_BIN]
214 NEVER_BIN, // [AT_LAST_AND_ACTIVE_BIN]
215 NEVER_BIN, // [AT_LAST_BIN]
216 NEVER_BIN // [NEVER_BIN]
217 },
218 // [ALLOW_ABSOLUTE_MINIMUM]
219 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
220 NOW_BIN, // [NOW_BIN]
221 NEVER_BIN, // [SOON_BIN]
222 NEVER_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
223 NEVER_BIN, // [EVENTUALLY_BIN]
224 NEVER_BIN, // [AT_LAST_AND_ACTIVE_BIN]
225 NEVER_BIN, // [AT_LAST_BIN]
226 NEVER_BIN // [NEVER_BIN]
227 },
228 // [ALLOW_PREPAINT_ONLY]
229 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
230 NOW_BIN, // [NOW_BIN]
231 SOON_BIN, // [SOON_BIN]
232 NEVER_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
233 NEVER_BIN, // [EVENTUALLY_BIN]
234 NEVER_BIN, // [AT_LAST_AND_ACTIVE_BIN]
235 NEVER_BIN, // [AT_LAST_BIN]
236 NEVER_BIN // [NEVER_BIN]
237 },
238 // [ALLOW_ANYTHING]
239 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
240 NOW_BIN, // [NOW_BIN]
241 SOON_BIN, // [SOON_BIN]
242 EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
243 EVENTUALLY_BIN, // [EVENTUALLY_BIN]
244 AT_LAST_AND_ACTIVE_BIN, // [AT_LAST_AND_ACTIVE_BIN]
245 AT_LAST_BIN, // [AT_LAST_BIN]
246 NEVER_BIN // [NEVER_BIN]
247 }};
248
249 // Ready to draw works by mapping NOW_BIN to NOW_AND_READY_TO_DRAW_BIN.
250 const ManagedTileBin kBinReadyToDrawMap[2][NUM_BINS] = {
251 // Not ready
252 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
253 NOW_BIN, // [NOW_BIN]
254 SOON_BIN, // [SOON_BIN]
255 EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
256 EVENTUALLY_BIN, // [EVENTUALLY_BIN]
257 AT_LAST_AND_ACTIVE_BIN, // [AT_LAST_AND_ACTIVE_BIN]
258 AT_LAST_BIN, // [AT_LAST_BIN]
259 NEVER_BIN // [NEVER_BIN]
260 },
261 // Ready
262 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
263 NOW_AND_READY_TO_DRAW_BIN, // [NOW_BIN]
264 SOON_BIN, // [SOON_BIN]
265 EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
266 EVENTUALLY_BIN, // [EVENTUALLY_BIN]
267 AT_LAST_AND_ACTIVE_BIN, // [AT_LAST_AND_ACTIVE_BIN]
268 AT_LAST_BIN, // [AT_LAST_BIN]
269 NEVER_BIN // [NEVER_BIN]
270 }};
271
272 // Active works by mapping some bin stats to equivalent _ACTIVE_BIN state.
273 const ManagedTileBin kBinIsActiveMap[2][NUM_BINS] = {
274 // Inactive
275 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
276 NOW_BIN, // [NOW_BIN]
277 SOON_BIN, // [SOON_BIN]
278 EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
279 EVENTUALLY_BIN, // [EVENTUALLY_BIN]
280 AT_LAST_AND_ACTIVE_BIN, // [AT_LAST_AND_ACTIVE_BIN]
281 AT_LAST_BIN, // [AT_LAST_BIN]
282 NEVER_BIN // [NEVER_BIN]
283 },
284 // Active
285 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
286 NOW_BIN, // [NOW_BIN]
287 SOON_BIN, // [SOON_BIN]
288 EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
289 EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_BIN]
290 AT_LAST_AND_ACTIVE_BIN, // [AT_LAST_AND_ACTIVE_BIN]
291 AT_LAST_AND_ACTIVE_BIN, // [AT_LAST_BIN]
292 NEVER_BIN // [NEVER_BIN]
293 }};
294
295 // Determine bin based on three categories of tiles: things we need now,
296 // things we need soon, and eventually.
297 inline ManagedTileBin BinFromTilePriority(const TilePriority& prio) {
298 if (prio.priority_bin == TilePriority::NOW)
299 return NOW_BIN;
300
301 if (prio.priority_bin == TilePriority::SOON)
302 return SOON_BIN;
303
304 if (prio.distance_to_visible == std::numeric_limits<float>::infinity())
305 return NEVER_BIN;
306
307 return EVENTUALLY_BIN;
308 }
309
310 } // namespace 206 } // namespace
311 207
312 RasterTaskCompletionStats::RasterTaskCompletionStats() 208 RasterTaskCompletionStats::RasterTaskCompletionStats()
313 : completed_count(0u), canceled_count(0u) {} 209 : completed_count(0u), canceled_count(0u) {}
314 210
315 scoped_refptr<base::debug::ConvertableToTraceFormat> 211 scoped_refptr<base::debug::ConvertableToTraceFormat>
316 RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats) { 212 RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats) {
317 scoped_refptr<base::debug::TracedValue> state = 213 scoped_refptr<base::debug::TracedValue> state =
318 new base::debug::TracedValue(); 214 new base::debug::TracedValue();
319 state->SetInteger("completed_count", stats.completed_count); 215 state->SetInteger("completed_count", stats.completed_count);
(...skipping 18 matching lines...) Expand all
338 TileManager::TileManager( 234 TileManager::TileManager(
339 TileManagerClient* client, 235 TileManagerClient* client,
340 const scoped_refptr<base::SequencedTaskRunner>& task_runner, 236 const scoped_refptr<base::SequencedTaskRunner>& task_runner,
341 ResourcePool* resource_pool, 237 ResourcePool* resource_pool,
342 Rasterizer* rasterizer, 238 Rasterizer* rasterizer,
343 RenderingStatsInstrumentation* rendering_stats_instrumentation) 239 RenderingStatsInstrumentation* rendering_stats_instrumentation)
344 : client_(client), 240 : client_(client),
345 task_runner_(task_runner), 241 task_runner_(task_runner),
346 resource_pool_(resource_pool), 242 resource_pool_(resource_pool),
347 rasterizer_(rasterizer), 243 rasterizer_(rasterizer),
348 prioritized_tiles_dirty_(false), 244 all_tiles_that_need_to_be_rasterized_are_scheduled_(true),
349 all_tiles_that_need_to_be_rasterized_have_memory_(true),
350 all_tiles_required_for_activation_have_memory_(true),
351 bytes_releasable_(0),
352 resources_releasable_(0),
353 ever_exceeded_memory_budget_(false),
354 rendering_stats_instrumentation_(rendering_stats_instrumentation), 245 rendering_stats_instrumentation_(rendering_stats_instrumentation),
355 did_initialize_visible_tile_(false), 246 did_initialize_visible_tile_(false),
356 did_check_for_completed_tasks_since_last_schedule_tasks_(true), 247 did_check_for_completed_tasks_since_last_schedule_tasks_(true),
357 did_oom_on_last_assign_(false), 248 did_oom_on_last_assign_(false),
358 ready_to_activate_check_notifier_( 249 ready_to_activate_check_notifier_(
359 task_runner_.get(), 250 task_runner_.get(),
360 base::Bind(&TileManager::CheckIfReadyToActivate, 251 base::Bind(&TileManager::CheckIfReadyToActivate,
361 base::Unretained(this))) { 252 base::Unretained(this))) {
362 rasterizer_->SetClient(this); 253 rasterizer_->SetClient(this);
363 } 254 }
364 255
365 TileManager::~TileManager() { 256 TileManager::~TileManager() {
366 // Reset global state and manage. This should cause 257 // Reset global state and manage. This should cause
367 // our memory usage to drop to zero. 258 // our memory usage to drop to zero.
368 global_state_ = GlobalStateThatImpactsTilePriority(); 259 global_state_ = GlobalStateThatImpactsTilePriority();
369 260
370 RasterTaskQueue empty; 261 RasterTaskQueue empty;
371 rasterizer_->ScheduleTasks(&empty); 262 rasterizer_->ScheduleTasks(&empty);
372 orphan_raster_tasks_.clear(); 263 orphan_raster_tasks_.clear();
373 264
374 // This should finish all pending tasks and release any uninitialized 265 // This should finish all pending tasks and release any uninitialized
375 // resources. 266 // resources.
376 rasterizer_->Shutdown(); 267 rasterizer_->Shutdown();
377 rasterizer_->CheckForCompletedTasks(); 268 rasterizer_->CheckForCompletedTasks();
378 269
379 prioritized_tiles_.Clear();
380
381 FreeResourcesForReleasedTiles(); 270 FreeResourcesForReleasedTiles();
382 CleanUpReleasedTiles(); 271 CleanUpReleasedTiles();
383
384 DCHECK_EQ(0u, bytes_releasable_);
385 DCHECK_EQ(0u, resources_releasable_);
386 } 272 }
387 273
388 void TileManager::Release(Tile* tile) { 274 void TileManager::Release(Tile* tile) {
389 DCHECK(TilePriority() == tile->combined_priority());
390
391 prioritized_tiles_dirty_ = true;
392 released_tiles_.push_back(tile); 275 released_tiles_.push_back(tile);
393 } 276 }
394 277
395 void TileManager::DidChangeTilePriority(Tile* tile) {
396 prioritized_tiles_dirty_ = true;
397 }
398
399 TaskSetCollection TileManager::TasksThatShouldBeForcedToComplete() const { 278 TaskSetCollection TileManager::TasksThatShouldBeForcedToComplete() const {
400 TaskSetCollection tasks_that_should_be_forced_to_complete; 279 TaskSetCollection tasks_that_should_be_forced_to_complete;
401 if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY) 280 if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY)
402 tasks_that_should_be_forced_to_complete[REQUIRED_FOR_ACTIVATION] = true; 281 tasks_that_should_be_forced_to_complete[REQUIRED_FOR_ACTIVATION] = true;
403 return tasks_that_should_be_forced_to_complete; 282 return tasks_that_should_be_forced_to_complete;
404 } 283 }
405 284
406 void TileManager::FreeResourcesForReleasedTiles() { 285 void TileManager::FreeResourcesForReleasedTiles() {
407 for (std::vector<Tile*>::iterator it = released_tiles_.begin(); 286 for (std::vector<Tile*>::iterator it = released_tiles_.begin();
408 it != released_tiles_.end(); 287 it != released_tiles_.end();
409 ++it) { 288 ++it) {
410 Tile* tile = *it; 289 Tile* tile = *it;
411 FreeResourcesForTile(tile); 290 FreeResourcesForTile(tile);
412 } 291 }
413 } 292 }
414 293
415 void TileManager::CleanUpReleasedTiles() { 294 void TileManager::CleanUpReleasedTiles() {
416 // Make sure |prioritized_tiles_| doesn't contain any of the tiles
417 // we're about to delete.
418 DCHECK(prioritized_tiles_.IsEmpty());
419
420 std::vector<Tile*>::iterator it = released_tiles_.begin(); 295 std::vector<Tile*>::iterator it = released_tiles_.begin();
421 while (it != released_tiles_.end()) { 296 while (it != released_tiles_.end()) {
422 Tile* tile = *it; 297 Tile* tile = *it;
423 298
424 if (tile->HasRasterTask()) { 299 if (tile->HasRasterTask()) {
425 ++it; 300 ++it;
426 continue; 301 continue;
427 } 302 }
428 303
429 DCHECK(!tile->HasResources()); 304 DCHECK(!tile->HasResources());
430 DCHECK(tiles_.find(tile->id()) != tiles_.end()); 305 DCHECK(tiles_.find(tile->id()) != tiles_.end());
431 tiles_.erase(tile->id()); 306 tiles_.erase(tile->id());
432 307
433 LayerCountMap::iterator layer_it = 308 LayerCountMap::iterator layer_it =
434 used_layer_counts_.find(tile->layer_id()); 309 used_layer_counts_.find(tile->layer_id());
435 DCHECK_GT(layer_it->second, 0); 310 DCHECK_GT(layer_it->second, 0);
436 if (--layer_it->second == 0) { 311 if (--layer_it->second == 0) {
437 used_layer_counts_.erase(layer_it); 312 used_layer_counts_.erase(layer_it);
438 image_decode_tasks_.erase(tile->layer_id()); 313 image_decode_tasks_.erase(tile->layer_id());
439 } 314 }
440 315
441 delete tile; 316 delete tile;
442 it = released_tiles_.erase(it); 317 it = released_tiles_.erase(it);
443 } 318 }
444 } 319 }
445 320
446 void TileManager::UpdatePrioritizedTileSetIfNeeded() {
447 if (!prioritized_tiles_dirty_)
448 return;
449
450 prioritized_tiles_.Clear();
451
452 FreeResourcesForReleasedTiles();
453 CleanUpReleasedTiles();
454
455 GetTilesWithAssignedBins(&prioritized_tiles_);
456 prioritized_tiles_dirty_ = false;
457 }
458
459 void TileManager::DidFinishRunningTasks(TaskSet task_set) { 321 void TileManager::DidFinishRunningTasks(TaskSet task_set) {
460 if (task_set == ALL) { 322 if (task_set == ALL) {
461 TRACE_EVENT1("cc", "TileManager::DidFinishRunningTasks", "task_set", "ALL"); 323 TRACE_EVENT1("cc", "TileManager::DidFinishRunningTasks", "task_set", "ALL");
462 324
463 bool memory_usage_above_limit = resource_pool_->total_memory_usage_bytes() > 325 bool memory_usage_above_limit = resource_pool_->total_memory_usage_bytes() >
464 global_state_.soft_memory_limit_in_bytes; 326 global_state_.soft_memory_limit_in_bytes;
465 327
466 // When OOM, keep re-assigning memory until we reach a steady state 328 // When OOM, keep re-assigning memory until we reach a steady state
467 // where top-priority tiles are initialized. 329 // where top-priority tiles are initialized.
468 if (all_tiles_that_need_to_be_rasterized_have_memory_ && 330 if (all_tiles_that_need_to_be_rasterized_are_scheduled_ &&
469 !memory_usage_above_limit) 331 !memory_usage_above_limit)
470 return; 332 return;
471 333
472 rasterizer_->CheckForCompletedTasks(); 334 rasterizer_->CheckForCompletedTasks();
473 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; 335 did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
474 336
475 TileVector tiles_that_need_to_be_rasterized; 337 TileVector tiles_that_need_to_be_rasterized;
476 AssignGpuMemoryToTiles(&prioritized_tiles_, 338 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized);
477 &tiles_that_need_to_be_rasterized);
478 339
479 // |tiles_that_need_to_be_rasterized| will be empty when we reach a 340 // |tiles_that_need_to_be_rasterized| will be empty when we reach a
480 // steady memory state. Keep scheduling tasks until we reach this state. 341 // steady memory state. Keep scheduling tasks until we reach this state.
481 if (!tiles_that_need_to_be_rasterized.empty()) { 342 if (!tiles_that_need_to_be_rasterized.empty()) {
482 ScheduleTasks(tiles_that_need_to_be_rasterized); 343 ScheduleTasks(tiles_that_need_to_be_rasterized);
483 return; 344 return;
484 } 345 }
485 346
486 FreeResourcesForReleasedTiles(); 347 FreeResourcesForReleasedTiles();
487 348
488 resource_pool_->ReduceResourceUsage(); 349 resource_pool_->ReduceResourceUsage();
489 350
490 // We don't reserve memory for required-for-activation tiles during 351 // We don't reserve memory for required-for-activation tiles during
491 // accelerated gestures, so we just postpone activation when we don't 352 // accelerated gestures, so we just postpone activation when we don't
492 // have these tiles, and activate after the accelerated gesture. 353 // have these tiles, and activate after the accelerated gesture.
493 // Likewise if we don't allow any tiles (as is the case when we're 354 // Likewise if we don't allow any tiles (as is the case when we're
494 // invisible), if we have tiles that aren't ready, then we shouldn't 355 // invisible), if we have tiles that aren't ready, then we shouldn't
495 // activate as activation can cause checkerboards. 356 // activate as activation can cause checkerboards.
496 bool allow_rasterize_on_demand = 357 bool allow_rasterize_on_demand =
497 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY && 358 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY &&
498 global_state_.memory_limit_policy != ALLOW_NOTHING; 359 global_state_.memory_limit_policy != ALLOW_NOTHING;
499 360
500 // Use on-demand raster for any required-for-activation tiles that have not 361 // Use on-demand raster for any required-for-activation tiles that have not
501 // been been assigned memory after reaching a steady memory state. This 362 // been been assigned memory after reaching a steady memory state. This
502 // ensures that we activate even when OOM. 363 // ensures that we activate even when OOM. Note that we have to rebuilt the
503 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 364 // queue in case the last AssignGpuMemoryToTiles evicted some tiles that
504 Tile* tile = it->second; 365 // would otherwise not be picked up by the old raster queue.
366 raster_priority_queue_.Reset();
367 client_->BuildRasterQueue(&raster_priority_queue_,
368 global_state_.tree_priority);
369 while (!raster_priority_queue_.IsEmpty()) {
370 Tile* tile = raster_priority_queue_.Top();
505 ManagedTileState& mts = tile->managed_state(); 371 ManagedTileState& mts = tile->managed_state();
506 372
507 if (tile->required_for_activation() && !mts.draw_info.IsReadyToDraw()) { 373 if (tile->required_for_activation() && !mts.draw_info.IsReadyToDraw()) {
508 // If we can't raster on demand, give up early (and don't activate). 374 // If we can't raster on demand, give up early (and don't activate).
509 if (!allow_rasterize_on_demand) 375 if (!allow_rasterize_on_demand)
510 return; 376 return;
511 377
512 mts.draw_info.set_rasterize_on_demand(); 378 mts.draw_info.set_rasterize_on_demand();
513 client_->NotifyTileStateChanged(tile); 379 client_->NotifyTileStateChanged(tile);
514 } 380 }
381 raster_priority_queue_.Pop();
515 } 382 }
516 383
517 DCHECK(IsReadyToActivate()); 384 DCHECK(IsReadyToActivate());
518 ready_to_activate_check_notifier_.Schedule(); 385 ready_to_activate_check_notifier_.Schedule();
519 return; 386 return;
520 } 387 }
521 388
522 if (task_set == REQUIRED_FOR_ACTIVATION) { 389 if (task_set == REQUIRED_FOR_ACTIVATION) {
523 TRACE_EVENT2("cc", 390 TRACE_EVENT1("cc",
524 "TileManager::DidFinishRunningTasks", 391 "TileManager::DidFinishRunningTasks",
525 "task_set", 392 "task_set",
526 "REQUIRED_FOR_ACTIVATION", 393 "REQUIRED_FOR_ACTIVATION");
527 "all_tiles_required_for_activation_have_memory",
528 all_tiles_required_for_activation_have_memory_);
529 // This is only a true indication that all tiles required for
530 // activation are initialized when no tiles are OOM. We need to
531 // wait for DidFinishRunningTasks() to be called, try to re-assign
532 // memory and in worst case use on-demand raster when tiles
533 // required for activation are OOM.
534 if (!all_tiles_required_for_activation_have_memory_)
535 return;
536
537 ready_to_activate_check_notifier_.Schedule(); 394 ready_to_activate_check_notifier_.Schedule();
538 } 395 }
539 } 396 }
540 397
541 void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) {
542 TRACE_EVENT0("cc", "TileManager::GetTilesWithAssignedBins");
543
544 const TileMemoryLimitPolicy memory_policy = global_state_.memory_limit_policy;
545 const TreePriority tree_priority = global_state_.tree_priority;
546
547 // For each tree, bin into different categories of tiles.
548 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
549 Tile* tile = it->second;
550 ManagedTileState& mts = tile->managed_state();
551
552 bool tile_is_ready_to_draw = mts.draw_info.IsReadyToDraw();
553 bool tile_is_active = tile_is_ready_to_draw || mts.raster_task.get();
554
555 // Get the active priority and bin.
556 TilePriority active_priority = tile->priority(ACTIVE_TREE);
557 ManagedTileBin active_bin = BinFromTilePriority(active_priority);
558
559 // Get the pending priority and bin.
560 TilePriority pending_priority = tile->priority(PENDING_TREE);
561 ManagedTileBin pending_bin = BinFromTilePriority(pending_priority);
562
563 bool pending_is_low_res = pending_priority.resolution == LOW_RESOLUTION;
564 bool pending_is_non_ideal =
565 pending_priority.resolution == NON_IDEAL_RESOLUTION;
566 bool active_is_non_ideal =
567 active_priority.resolution == NON_IDEAL_RESOLUTION;
568
569 // Adjust bin state based on if ready to draw.
570 active_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][active_bin];
571 pending_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][pending_bin];
572
573 // Adjust bin state based on if active.
574 active_bin = kBinIsActiveMap[tile_is_active][active_bin];
575 pending_bin = kBinIsActiveMap[tile_is_active][pending_bin];
576
577 // We never want to paint new non-ideal tiles, as we always have
578 // a high-res tile covering that content (paint that instead).
579 if (!tile_is_ready_to_draw && active_is_non_ideal)
580 active_bin = NEVER_BIN;
581 if (!tile_is_ready_to_draw && pending_is_non_ideal)
582 pending_bin = NEVER_BIN;
583
584 ManagedTileBin tree_bin[NUM_TREES];
585 tree_bin[ACTIVE_TREE] = kBinPolicyMap[memory_policy][active_bin];
586 tree_bin[PENDING_TREE] = kBinPolicyMap[memory_policy][pending_bin];
587
588 // Adjust pending bin state for low res tiles. This prevents pending tree
589 // low-res tiles from being initialized before high-res tiles.
590 if (pending_is_low_res)
591 tree_bin[PENDING_TREE] = std::max(tree_bin[PENDING_TREE], EVENTUALLY_BIN);
592
593 TilePriority tile_priority;
594 switch (tree_priority) {
595 case SAME_PRIORITY_FOR_BOTH_TREES:
596 mts.bin = std::min(tree_bin[ACTIVE_TREE], tree_bin[PENDING_TREE]);
597 tile_priority = tile->combined_priority();
598 break;
599 case SMOOTHNESS_TAKES_PRIORITY:
600 mts.bin = tree_bin[ACTIVE_TREE];
601 tile_priority = active_priority;
602 break;
603 case NEW_CONTENT_TAKES_PRIORITY:
604 mts.bin = tree_bin[PENDING_TREE];
605 tile_priority = pending_priority;
606 break;
607 default:
608 NOTREACHED();
609 }
610
611 // Bump up the priority if we determined it's NEVER_BIN on one tree,
612 // but is still required on the other tree.
613 bool is_in_never_bin_on_both_trees = tree_bin[ACTIVE_TREE] == NEVER_BIN &&
614 tree_bin[PENDING_TREE] == NEVER_BIN;
615
616 if (mts.bin == NEVER_BIN && !is_in_never_bin_on_both_trees)
617 mts.bin = tile_is_active ? AT_LAST_AND_ACTIVE_BIN : AT_LAST_BIN;
618
619 mts.resolution = tile_priority.resolution;
620 mts.priority_bin = tile_priority.priority_bin;
621 mts.distance_to_visible = tile_priority.distance_to_visible;
622 mts.required_for_activation = tile_priority.required_for_activation;
623
624 mts.visible_and_ready_to_draw =
625 tree_bin[ACTIVE_TREE] == NOW_AND_READY_TO_DRAW_BIN;
626
627 // Tiles that are required for activation shouldn't be in NEVER_BIN unless
628 // smoothness takes priority or memory policy allows nothing to be
629 // initialized.
630 DCHECK(!mts.required_for_activation || mts.bin != NEVER_BIN ||
631 tree_priority == SMOOTHNESS_TAKES_PRIORITY ||
632 memory_policy == ALLOW_NOTHING);
633
634 // If the tile is in NEVER_BIN and it does not have an active task, then we
635 // can release the resources early. If it does have the task however, we
636 // should keep it in the prioritized tile set to ensure that AssignGpuMemory
637 // can visit it.
638 if (mts.bin == NEVER_BIN && !mts.raster_task.get()) {
639 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile);
640 continue;
641 }
642
643 // Insert the tile into a priority set.
644 tiles->InsertTile(tile, mts.bin);
645 }
646 }
647
648 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { 398 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) {
649 TRACE_EVENT0("cc", "TileManager::ManageTiles"); 399 TRACE_EVENT0("cc", "TileManager::ManageTiles");
650 400
651 // Update internal state. 401 global_state_ = state;
652 if (state != global_state_) {
653 global_state_ = state;
654 prioritized_tiles_dirty_ = true;
655 }
656 402
657 // We need to call CheckForCompletedTasks() once in-between each call 403 // We need to call CheckForCompletedTasks() once in-between each call
658 // to ScheduleTasks() to prevent canceled tasks from being scheduled. 404 // to ScheduleTasks() to prevent canceled tasks from being scheduled.
659 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { 405 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) {
660 rasterizer_->CheckForCompletedTasks(); 406 rasterizer_->CheckForCompletedTasks();
661 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; 407 did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
662 } 408 }
663 409
664 UpdatePrioritizedTileSetIfNeeded(); 410 FreeResourcesForReleasedTiles();
411 CleanUpReleasedTiles();
665 412
666 TileVector tiles_that_need_to_be_rasterized; 413 TileVector tiles_that_need_to_be_rasterized;
667 AssignGpuMemoryToTiles(&prioritized_tiles_, 414 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized);
668 &tiles_that_need_to_be_rasterized);
669 415
670 // Finally, schedule rasterizer tasks. 416 // Finally, schedule rasterizer tasks.
671 ScheduleTasks(tiles_that_need_to_be_rasterized); 417 ScheduleTasks(tiles_that_need_to_be_rasterized);
672 418
673 TRACE_EVENT_INSTANT1("cc", 419 TRACE_EVENT_INSTANT1("cc",
674 "DidManage", 420 "DidManage",
675 TRACE_EVENT_SCOPE_THREAD, 421 TRACE_EVENT_SCOPE_THREAD,
676 "state", 422 "state",
677 BasicStateAsValue()); 423 BasicStateAsValue());
678 424
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 } 457 }
712 458
713 void TileManager::BasicStateAsValueInto(base::debug::TracedValue* state) const { 459 void TileManager::BasicStateAsValueInto(base::debug::TracedValue* state) const {
714 state->SetInteger("tile_count", tiles_.size()); 460 state->SetInteger("tile_count", tiles_.size());
715 state->SetBoolean("did_oom_on_last_assign", did_oom_on_last_assign_); 461 state->SetBoolean("did_oom_on_last_assign", did_oom_on_last_assign_);
716 state->BeginDictionary("global_state"); 462 state->BeginDictionary("global_state");
717 global_state_.AsValueInto(state); 463 global_state_.AsValueInto(state);
718 state->EndDictionary(); 464 state->EndDictionary();
719 } 465 }
720 466
467 void TileManager::RebuildEvictionQueueIfNeeded() {
468 if (eviction_priority_queue_is_up_to_date_)
469 return;
470
471 eviction_priority_queue_.Reset();
472 client_->BuildEvictionQueue(&eviction_priority_queue_,
473 global_state_.tree_priority);
474 eviction_priority_queue_is_up_to_date_ = true;
475 }
476
477 bool TileManager::FreeTileResourcesUntilUsageIsWithinLimit(
478 const MemoryUsage& limit,
479 MemoryUsage* usage) {
480 while (usage->Exceeds(limit)) {
481 RebuildEvictionQueueIfNeeded();
482 if (eviction_priority_queue_.IsEmpty())
483 return false;
484
485 Tile* tile = eviction_priority_queue_.Top();
486 *usage -= MemoryUsage::FromTile(tile);
487 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile);
488 eviction_priority_queue_.Pop();
489 }
490 return true;
491 }
492
493 bool TileManager::FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit(
494 const MemoryUsage& limit,
495 const TilePriority& other_priority,
496 MemoryUsage* usage) {
497 while (usage->Exceeds(limit)) {
498 RebuildEvictionQueueIfNeeded();
499 if (eviction_priority_queue_.IsEmpty())
500 return false;
501
502 Tile* tile = eviction_priority_queue_.Top();
503 if (!other_priority.IsHigherPriorityThan(
504 tile->priority_for_tree_priority(global_state_.tree_priority))) {
505 return false;
506 }
507
508 *usage -= MemoryUsage::FromTile(tile);
509 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile);
510 eviction_priority_queue_.Pop();
511 }
512 return true;
513 }
514
515 bool TileManager::TilePriorityViolatesMemoryPolicy(
516 const TilePriority& priority) {
517 switch (global_state_.memory_limit_policy) {
518 case ALLOW_NOTHING:
519 return true;
520 case ALLOW_ABSOLUTE_MINIMUM:
521 return priority.priority_bin > TilePriority::NOW;
522 case ALLOW_PREPAINT_ONLY:
523 return priority.priority_bin > TilePriority::SOON;
524 case ALLOW_ANYTHING:
525 return priority.distance_to_visible ==
526 std::numeric_limits<float>::infinity();
527 }
528 NOTREACHED();
529 return true;
530 }
531
721 void TileManager::AssignGpuMemoryToTiles( 532 void TileManager::AssignGpuMemoryToTiles(
722 PrioritizedTileSet* tiles,
723 TileVector* tiles_that_need_to_be_rasterized) { 533 TileVector* tiles_that_need_to_be_rasterized) {
724 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); 534 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles");
725 535
726 // Maintain the list of released resources that can potentially be re-used 536 // Maintain the list of released resources that can potentially be re-used
727 // or deleted. 537 // or deleted.
728 // If this operation becomes expensive too, only do this after some 538 // If this operation becomes expensive too, only do this after some
729 // resource(s) was returned. Note that in that case, one also need to 539 // resource(s) was returned. Note that in that case, one also need to
730 // invalidate when releasing some resource from the pool. 540 // invalidate when releasing some resource from the pool.
731 resource_pool_->CheckBusyResources(); 541 resource_pool_->CheckBusyResources();
732 542
733 // Now give memory out to the tiles until we're out, and build 543 // Now give memory out to the tiles until we're out, and build
734 // the needs-to-be-rasterized queue. 544 // the needs-to-be-rasterized queue.
735 all_tiles_that_need_to_be_rasterized_have_memory_ = true; 545 unsigned schedule_priority = 1u;
736 all_tiles_required_for_activation_have_memory_ = true; 546 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true;
547 bool had_enough_memory_to_schedule_tiles_needed_now = true;
737 548
738 // Cast to prevent overflow. 549 MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes,
739 int64 soft_bytes_available = 550 global_state_.num_resources_limit);
740 static_cast<int64>(bytes_releasable_) + 551 MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes,
741 static_cast<int64>(global_state_.soft_memory_limit_in_bytes) - 552 global_state_.num_resources_limit);
742 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes()); 553 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(),
743 int64 hard_bytes_available = 554 resource_pool_->acquired_resource_count());
744 static_cast<int64>(bytes_releasable_) +
745 static_cast<int64>(global_state_.hard_memory_limit_in_bytes) -
746 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes());
747 int resources_available = resources_releasable_ +
748 global_state_.num_resources_limit -
749 resource_pool_->acquired_resource_count();
750 size_t soft_bytes_allocatable =
751 std::max(static_cast<int64>(0), soft_bytes_available);
752 size_t hard_bytes_allocatable =
753 std::max(static_cast<int64>(0), hard_bytes_available);
754 size_t resources_allocatable = std::max(0, resources_available);
755 555
756 size_t bytes_that_exceeded_memory_budget = 0; 556 eviction_priority_queue_is_up_to_date_ = false;
757 size_t soft_bytes_left = soft_bytes_allocatable; 557 raster_priority_queue_.Reset();
758 size_t hard_bytes_left = hard_bytes_allocatable; 558 client_->BuildRasterQueue(&raster_priority_queue_,
559 global_state_.tree_priority);
759 560
760 size_t resources_left = resources_allocatable; 561 while (!raster_priority_queue_.IsEmpty()) {
761 bool oomed_soft = false; 562 Tile* tile = raster_priority_queue_.Top();
762 bool oomed_hard = false; 563 TilePriority priority =
763 bool have_hit_soft_memory = false; // Soft memory comes after hard. 564 tile->priority_for_tree_priority(global_state_.tree_priority);
764 565
765 unsigned schedule_priority = 1u; 566 if (TilePriorityViolatesMemoryPolicy(priority))
766 for (PrioritizedTileSet::Iterator it(tiles, true); it; ++it) { 567 break;
767 Tile* tile = *it; 568
569 // We won't be able to schedule this tile, so break out early.
570 if (tiles_that_need_to_be_rasterized->size() >=
571 kScheduledRasterTasksLimit) {
572 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false;
573 break;
574 }
575
768 ManagedTileState& mts = tile->managed_state(); 576 ManagedTileState& mts = tile->managed_state();
769 mts.scheduled_priority = schedule_priority++; 577 mts.scheduled_priority = schedule_priority++;
770 578
771 // If this tile doesn't need a resource, then nothing to do. 579 DCHECK(mts.draw_info.mode() ==
772 if (!mts.draw_info.requires_resource()) 580 ManagedTileState::DrawInfo::PICTURE_PILE_MODE ||
773 continue; 581 !mts.draw_info.IsReadyToDraw());
774 582
775 // If the tile is not needed, free it up. 583 // If the tile already has a raster_task, then the memory used by it is
776 if (mts.bin == NEVER_BIN) { 584 // already accounted for in memory_usage. Otherwise, we'll have to acquire
777 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); 585 // more memory to create a raster task.
778 continue; 586 MemoryUsage memory_required_by_tile_to_be_scheduled;
587 if (!mts.raster_task.get()) {
588 memory_required_by_tile_to_be_scheduled = MemoryUsage::FromConfig(
589 tile->size(), resource_pool_->resource_format());
779 } 590 }
780 591
781 const bool tile_uses_hard_limit = mts.bin <= NOW_BIN; 592 bool tile_is_needed_now = priority.priority_bin == TilePriority::NOW;
782 const size_t bytes_if_allocated = BytesConsumedIfAllocated(tile);
783 const size_t tile_bytes_left =
784 (tile_uses_hard_limit) ? hard_bytes_left : soft_bytes_left;
785 593
786 // Hard-limit is reserved for tiles that would cause a calamity 594 // This is the memory limit that will be used by this tile. Depending on
787 // if they were to go away, so by definition they are the highest 595 // the tile priority, it will be one of hard_memory_limit or
788 // priority memory, and must be at the front of the list. 596 // soft_memory_limit.
789 DCHECK(!(have_hit_soft_memory && tile_uses_hard_limit)); 597 MemoryUsage& tile_memory_limit =
790 have_hit_soft_memory |= !tile_uses_hard_limit; 598 tile_is_needed_now ? hard_memory_limit : soft_memory_limit;
791 599
792 size_t tile_bytes = 0; 600 bool memory_usage_is_within_limit =
793 size_t tile_resources = 0; 601 FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit(
602 tile_memory_limit - memory_required_by_tile_to_be_scheduled,
603 priority,
604 &memory_usage);
794 605
795 // It costs to maintain a resource. 606 // If we couldn't fit the tile into our current memory limit, then we're
796 if (mts.draw_info.resource_) { 607 // done.
797 tile_bytes += bytes_if_allocated; 608 if (!memory_usage_is_within_limit) {
798 tile_resources++; 609 if (tile_is_needed_now)
610 had_enough_memory_to_schedule_tiles_needed_now = false;
611 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false;
612 break;
799 } 613 }
800 614
801 // Allow lower priority tiles with initialized resources to keep 615 memory_usage += memory_required_by_tile_to_be_scheduled;
802 // their memory by only assigning memory to new raster tasks if
803 // they can be scheduled.
804 bool reached_scheduled_raster_tasks_limit =
805 tiles_that_need_to_be_rasterized->size() >= kScheduledRasterTasksLimit;
806 if (!reached_scheduled_raster_tasks_limit) {
807 // If we don't have the required version, and it's not in flight
808 // then we'll have to pay to create a new task.
809 if (!mts.draw_info.resource_ && !mts.raster_task.get()) {
810 tile_bytes += bytes_if_allocated;
811 tile_resources++;
812 }
813 }
814
815 // Tile is OOM.
816 if (tile_bytes > tile_bytes_left || tile_resources > resources_left) {
817 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile);
818
819 // This tile was already on screen and now its resources have been
820 // released. In order to prevent checkerboarding, set this tile as
821 // rasterize on demand immediately.
822 if (mts.visible_and_ready_to_draw)
823 mts.draw_info.set_rasterize_on_demand();
824
825 oomed_soft = true;
826 if (tile_uses_hard_limit) {
827 oomed_hard = true;
828 bytes_that_exceeded_memory_budget += tile_bytes;
829 }
830 } else {
831 resources_left -= tile_resources;
832 hard_bytes_left -= tile_bytes;
833 soft_bytes_left =
834 (soft_bytes_left > tile_bytes) ? soft_bytes_left - tile_bytes : 0;
835 if (mts.draw_info.resource_)
836 continue;
837 }
838
839 DCHECK(!mts.draw_info.resource_);
840
841 // Tile shouldn't be rasterized if |tiles_that_need_to_be_rasterized|
842 // has reached it's limit or we've failed to assign gpu memory to this
843 // or any higher priority tile. Preventing tiles that fit into memory
844 // budget to be rasterized when higher priority tile is oom is
845 // important for two reasons:
846 // 1. Tile size should not impact raster priority.
847 // 2. Tiles with existing raster task could otherwise incorrectly
848 // be added as they are not affected by |bytes_allocatable|.
849 bool can_schedule_tile =
850 !oomed_soft && !reached_scheduled_raster_tasks_limit;
851
852 if (!can_schedule_tile) {
853 all_tiles_that_need_to_be_rasterized_have_memory_ = false;
854 if (tile->required_for_activation())
855 all_tiles_required_for_activation_have_memory_ = false;
856 it.DisablePriorityOrdering();
857 continue;
858 }
859
860 tiles_that_need_to_be_rasterized->push_back(tile); 616 tiles_that_need_to_be_rasterized->push_back(tile);
617 raster_priority_queue_.Pop();
861 } 618 }
862 619
863 // OOM reporting uses hard-limit, soft-OOM is normal depending on limit. 620 // Note that we should try and further reduce memory in case the above loop
864 ever_exceeded_memory_budget_ |= oomed_hard; 621 // didn't reduce memory. This ensures that we always release as many resources
865 if (ever_exceeded_memory_budget_) { 622 // as possible to stay within the memory limit.
866 TRACE_COUNTER_ID2("cc", 623 FreeTileResourcesUntilUsageIsWithinLimit(hard_memory_limit, &memory_usage);
867 "over_memory_budget", 624
868 this, 625 UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget",
869 "budget", 626 !had_enough_memory_to_schedule_tiles_needed_now);
870 global_state_.hard_memory_limit_in_bytes, 627 did_oom_on_last_assign_ = !had_enough_memory_to_schedule_tiles_needed_now;
871 "over", 628
872 bytes_that_exceeded_memory_budget);
873 }
874 did_oom_on_last_assign_ = oomed_hard;
875 UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget", oomed_hard);
876 memory_stats_from_last_assign_.total_budget_in_bytes = 629 memory_stats_from_last_assign_.total_budget_in_bytes =
877 global_state_.hard_memory_limit_in_bytes; 630 global_state_.hard_memory_limit_in_bytes;
878 memory_stats_from_last_assign_.bytes_allocated = 631 memory_stats_from_last_assign_.total_bytes_used = memory_usage.memory_bytes();
879 hard_bytes_allocatable - hard_bytes_left; 632 memory_stats_from_last_assign_.had_enough_memory =
880 memory_stats_from_last_assign_.bytes_unreleasable = 633 had_enough_memory_to_schedule_tiles_needed_now;
881 resource_pool_->acquired_memory_usage_bytes() - bytes_releasable_;
882 memory_stats_from_last_assign_.bytes_over = bytes_that_exceeded_memory_budget;
883 } 634 }
884 635
885 void TileManager::FreeResourcesForTile(Tile* tile) { 636 void TileManager::FreeResourcesForTile(Tile* tile) {
886 ManagedTileState& mts = tile->managed_state(); 637 ManagedTileState& mts = tile->managed_state();
887 if (mts.draw_info.resource_) { 638 if (mts.draw_info.resource_)
888 resource_pool_->ReleaseResource(mts.draw_info.resource_.Pass()); 639 resource_pool_->ReleaseResource(mts.draw_info.resource_.Pass());
889
890 DCHECK_GE(bytes_releasable_, BytesConsumedIfAllocated(tile));
891 DCHECK_GE(resources_releasable_, 1u);
892
893 bytes_releasable_ -= BytesConsumedIfAllocated(tile);
894 --resources_releasable_;
895 }
896 } 640 }
897 641
898 void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw( 642 void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(
899 Tile* tile) { 643 Tile* tile) {
900 bool was_ready_to_draw = tile->IsReadyToDraw(); 644 bool was_ready_to_draw = tile->IsReadyToDraw();
901 FreeResourcesForTile(tile); 645 FreeResourcesForTile(tile);
902 if (was_ready_to_draw) 646 if (was_ready_to_draw)
903 client_->NotifyTileStateChanged(tile); 647 client_->NotifyTileStateChanged(tile);
904 } 648 }
905 649
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 } 799 }
1056 800
1057 ++update_visible_tiles_stats_.completed_count; 801 ++update_visible_tiles_stats_.completed_count;
1058 802
1059 if (analysis.is_solid_color) { 803 if (analysis.is_solid_color) {
1060 mts.draw_info.set_solid_color(analysis.solid_color); 804 mts.draw_info.set_solid_color(analysis.solid_color);
1061 resource_pool_->ReleaseResource(resource.Pass()); 805 resource_pool_->ReleaseResource(resource.Pass());
1062 } else { 806 } else {
1063 mts.draw_info.set_use_resource(); 807 mts.draw_info.set_use_resource();
1064 mts.draw_info.resource_ = resource.Pass(); 808 mts.draw_info.resource_ = resource.Pass();
1065
1066 bytes_releasable_ += BytesConsumedIfAllocated(tile);
1067 ++resources_releasable_;
1068 } 809 }
1069 810
1070 if (tile->priority(ACTIVE_TREE).distance_to_visible == 0.f) 811 if (tile->priority(ACTIVE_TREE).distance_to_visible == 0.f)
1071 did_initialize_visible_tile_ = true; 812 did_initialize_visible_tile_ = true;
1072 813
1073 client_->NotifyTileStateChanged(tile); 814 client_->NotifyTileStateChanged(tile);
1074 } 815 }
1075 816
1076 scoped_refptr<Tile> TileManager::CreateTile(PicturePileImpl* picture_pile, 817 scoped_refptr<Tile> TileManager::CreateTile(PicturePileImpl* picture_pile,
1077 const gfx::Size& tile_size, 818 const gfx::Size& tile_size,
1078 const gfx::Rect& content_rect, 819 const gfx::Rect& content_rect,
1079 float contents_scale, 820 float contents_scale,
1080 int layer_id, 821 int layer_id,
1081 int source_frame_number, 822 int source_frame_number,
1082 int flags) { 823 int flags) {
1083 scoped_refptr<Tile> tile = make_scoped_refptr(new Tile(this, 824 scoped_refptr<Tile> tile = make_scoped_refptr(new Tile(this,
1084 picture_pile, 825 picture_pile,
1085 tile_size, 826 tile_size,
1086 content_rect, 827 content_rect,
1087 contents_scale, 828 contents_scale,
1088 layer_id, 829 layer_id,
1089 source_frame_number, 830 source_frame_number,
1090 flags)); 831 flags));
1091 DCHECK(tiles_.find(tile->id()) == tiles_.end()); 832 DCHECK(tiles_.find(tile->id()) == tiles_.end());
1092 833
1093 tiles_[tile->id()] = tile.get(); 834 tiles_[tile->id()] = tile.get();
1094 used_layer_counts_[tile->layer_id()]++; 835 used_layer_counts_[tile->layer_id()]++;
1095 prioritized_tiles_dirty_ = true;
1096 return tile; 836 return tile;
1097 } 837 }
1098 838
1099 void TileManager::SetRasterizerForTesting(Rasterizer* rasterizer) { 839 void TileManager::SetRasterizerForTesting(Rasterizer* rasterizer) {
1100 rasterizer_ = rasterizer; 840 rasterizer_ = rasterizer;
1101 rasterizer_->SetClient(this); 841 rasterizer_->SetClient(this);
1102 } 842 }
1103 843
1104 bool TileManager::IsReadyToActivate() const { 844 bool TileManager::IsReadyToActivate() const {
1105 const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers(); 845 const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers();
(...skipping 11 matching lines...) Expand all
1117 void TileManager::CheckIfReadyToActivate() { 857 void TileManager::CheckIfReadyToActivate() {
1118 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate"); 858 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate");
1119 859
1120 rasterizer_->CheckForCompletedTasks(); 860 rasterizer_->CheckForCompletedTasks();
1121 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; 861 did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
1122 862
1123 if (IsReadyToActivate()) 863 if (IsReadyToActivate())
1124 client_->NotifyReadyToActivate(); 864 client_->NotifyReadyToActivate();
1125 } 865 }
1126 866
867 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) {
868 }
869
870 TileManager::MemoryUsage::MemoryUsage(int64 memory_bytes, int resource_count)
871 : memory_bytes_(memory_bytes), resource_count_(resource_count) {
872 }
873
874 // static
875 TileManager::MemoryUsage TileManager::MemoryUsage::FromConfig(
876 const gfx::Size& size,
877 ResourceFormat format) {
878 return MemoryUsage(Resource::MemorySizeBytes(size, format), 1);
879 }
880
881 // static
882 TileManager::MemoryUsage TileManager::MemoryUsage::FromTile(const Tile* tile) {
883 const ManagedTileState& mts = tile->managed_state();
884 if (mts.draw_info.resource_) {
885 return MemoryUsage::FromConfig(tile->size(),
886 mts.draw_info.resource_->format());
887 }
888 return MemoryUsage();
889 }
890
891 TileManager::MemoryUsage& TileManager::MemoryUsage::operator+=(
892 const MemoryUsage& other) {
893 memory_bytes_ += other.memory_bytes_;
894 resource_count_ += other.resource_count_;
895 return *this;
896 }
897
898 TileManager::MemoryUsage& TileManager::MemoryUsage::operator-=(
899 const MemoryUsage& other) {
900 memory_bytes_ -= other.memory_bytes_;
901 resource_count_ -= other.resource_count_;
902 return *this;
903 }
904
905 TileManager::MemoryUsage TileManager::MemoryUsage::operator-(
906 const MemoryUsage& other) {
907 MemoryUsage result = *this;
908 result -= other;
909 return result;
910 }
911
912 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const {
913 return memory_bytes_ > limit.memory_bytes_ ||
914 resource_count_ > limit.resource_count_;
915 }
916
1127 } // namespace cc 917 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/tile_manager.h ('k') | cc/resources/tile_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698