OLD | NEW |
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/picture_layer_tiling.h" | 5 #include "cc/picture_layer_tiling.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "cc/math_util.h" | 8 #include "cc/math_util.h" |
9 #include "ui/gfx/point_conversions.h" | 9 #include "ui/gfx/point_conversions.h" |
10 #include "ui/gfx/rect_conversions.h" | 10 #include "ui/gfx/rect_conversions.h" |
11 #include "ui/gfx/safe_integer_conversions.h" | 11 #include "ui/gfx/safe_integer_conversions.h" |
12 #include "ui/gfx/size_conversions.h" | 12 #include "ui/gfx/size_conversions.h" |
13 | 13 |
14 namespace cc { | 14 namespace cc { |
15 | 15 |
16 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( | 16 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( |
17 float contents_scale) { | 17 float contents_scale) { |
18 return make_scoped_ptr(new PictureLayerTiling(contents_scale)); | 18 return make_scoped_ptr(new PictureLayerTiling(contents_scale)); |
19 } | 19 } |
20 | 20 |
21 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Clone() const { | 21 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Clone() const { |
22 return make_scoped_ptr(new PictureLayerTiling(*this)); | 22 PictureLayerTiling* new_tiling = new PictureLayerTiling(*this); |
| 23 |
| 24 // The live_tiles_ list was shallow-copied, restore it explicitly. |
| 25 new_tiling->live_tiles_.clear(); |
| 26 for (TileList::const_iterator it = live_tiles_.begin(); |
| 27 it != live_tiles_.end(); ++it) { |
| 28 const TileHandle* tile_handle = *it; |
| 29 TileMap::iterator find = new_tiling->tiles_.find(tile_handle->key()); |
| 30 DCHECK(find != new_tiling->tiles_.end()); |
| 31 TileHandle* new_tile_handle = &find->second; |
| 32 new_tile_handle->AddToLiveTileList(new_tiling); |
| 33 } |
| 34 |
| 35 return make_scoped_ptr(new_tiling); |
23 } | 36 } |
24 | 37 |
25 PictureLayerTiling::PictureLayerTiling(float contents_scale) | 38 PictureLayerTiling::PictureLayerTiling(float contents_scale) |
26 : client_(NULL), | 39 : client_(NULL), |
27 contents_scale_(contents_scale), | 40 contents_scale_(contents_scale), |
28 tiling_data_(gfx::Size(), gfx::Size(), true), | 41 tiling_data_(gfx::Size(), gfx::Size(), true), |
29 resolution_(NON_IDEAL_RESOLUTION), | 42 resolution_(NON_IDEAL_RESOLUTION), |
30 last_source_frame_number_(0), | 43 last_source_frame_number_(0), |
31 last_impl_frame_time_(0) { | 44 last_impl_frame_time_(0) { |
32 } | 45 } |
33 | 46 |
34 PictureLayerTiling::~PictureLayerTiling() { | 47 PictureLayerTiling::~PictureLayerTiling() { |
| 48 tiles_.clear(); |
| 49 DCHECK(live_tiles_.empty()); |
35 } | 50 } |
36 | 51 |
37 void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) { | 52 void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) { |
38 client_ = client; | 53 client_ = client; |
39 } | 54 } |
40 | 55 |
41 gfx::Rect PictureLayerTiling::ContentRect() const { | 56 gfx::Rect PictureLayerTiling::ContentRect() const { |
42 return gfx::Rect(tiling_data_.total_size()); | 57 return gfx::Rect(tiling_data_.total_size()); |
43 } | 58 } |
44 | 59 |
45 gfx::SizeF PictureLayerTiling::ContentSizeF() const { | 60 gfx::SizeF PictureLayerTiling::ContentSizeF() const { |
46 return gfx::ScaleSize(layer_bounds_, contents_scale_); | 61 return gfx::ScaleSize(layer_bounds_, contents_scale_); |
47 } | 62 } |
48 | 63 |
49 Tile* PictureLayerTiling::TileAt(int i, int j) const { | 64 Tile* PictureLayerTiling::TileAt(int i, int j) const { |
50 TileMap::const_iterator iter = tiles_.find(TileMapKey(i, j)); | 65 TileMap::const_iterator iter = tiles_.find(TileMapKey(i, j)); |
51 if (iter == tiles_.end()) | 66 if (iter == tiles_.end()) |
52 return NULL; | 67 return NULL; |
53 return iter->second.tile(); | 68 return iter->second.tile(); |
54 } | 69 } |
55 | 70 |
56 void PictureLayerTiling::CreateTile(int i, int j) { | 71 void PictureLayerTiling::CreateTile(int i, int j) { |
57 gfx::Rect tile_rect = tiling_data_.TileBoundsWithBorder(i, j); | 72 gfx::Rect tile_rect = tiling_data_.TileBoundsWithBorder(i, j); |
58 tile_rect.set_size(tiling_data_.max_texture_size()); | 73 tile_rect.set_size(tiling_data_.max_texture_size()); |
59 TileMapKey key(i, j); | 74 TileMapKey key(i, j); |
60 DCHECK(tiles_.find(key) == tiles_.end()); | 75 DCHECK(tiles_.find(key) == tiles_.end()); |
61 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); | 76 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); |
62 if (tile) | 77 if (tile) |
63 tiles_.insert(make_pair(key, TileHandle(tile))); | 78 tiles_.insert(make_pair(key, TileHandle(key, tile))); |
64 } | 79 } |
65 | 80 |
66 Region PictureLayerTiling::OpaqueRegionInContentRect( | 81 Region PictureLayerTiling::OpaqueRegionInContentRect( |
67 const gfx::Rect& content_rect) const { | 82 const gfx::Rect& content_rect) const { |
68 Region opaque_region; | 83 Region opaque_region; |
69 // TODO(enne): implement me | 84 // TODO(enne): implement me |
70 return opaque_region; | 85 return opaque_region; |
71 } | 86 } |
72 | 87 |
73 void PictureLayerTiling::SetLayerBounds(gfx::Size layer_bounds) { | 88 void PictureLayerTiling::SetLayerBounds(gfx::Size layer_bounds) { |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
394 gfx::Rect inflated_rect = viewport_in_content_space; | 409 gfx::Rect inflated_rect = viewport_in_content_space; |
395 float adjusted_inset = TilePriority::kMaxDistanceInContentSpace / | 410 float adjusted_inset = TilePriority::kMaxDistanceInContentSpace / |
396 std::max(contents_scale_, 1.f); | 411 std::max(contents_scale_, 1.f); |
397 inflated_rect.Inset( | 412 inflated_rect.Inset( |
398 -adjusted_inset, | 413 -adjusted_inset, |
399 -adjusted_inset, | 414 -adjusted_inset, |
400 -adjusted_inset, | 415 -adjusted_inset, |
401 -adjusted_inset); | 416 -adjusted_inset); |
402 inflated_rect.Intersect(ContentRect()); | 417 inflated_rect.Intersect(ContentRect()); |
403 | 418 |
404 // Iterate through all of the tiles that were live last frame but will | 419 // Mark all tiles in the inflated rect as live. |
405 // not be live this frame, and mark them as being dead. | 420 for (TilingData::Iterator iter(&tiling_data_, inflated_rect); |
406 for (TilingData::DifferenceIterator iter(&tiling_data_, | 421 iter; ++iter) { |
407 last_prioritized_rect_, | |
408 inflated_rect); | |
409 iter; | |
410 ++iter) { | |
411 TileMap::iterator find = tiles_.find(iter.index()); | 422 TileMap::iterator find = tiles_.find(iter.index()); |
412 if (find == tiles_.end()) | 423 if (find == tiles_.end()) |
413 continue; | 424 continue; |
| 425 TileHandle* tile_handle = &find->second; |
| 426 tile_handle->set_should_be_live(true); |
| 427 tile_handle->AddToLiveTileList(this); |
| 428 } |
414 | 429 |
415 TilePriority priority; | 430 // Iterate through all of the tiles that were live last frame but will |
416 DCHECK(!priority.is_live); | 431 // not be live this frame, and mark them as being dead. |
417 TileHandle* tile_handle = &find->second; | 432 // TODO(ccameron): merge this loop with the loops below. |
418 Tile* tile = tile_handle->tile(); | 433 for (TileList::iterator it = live_tiles_.begin(); |
419 tile->set_priority(tree, priority); | 434 it != live_tiles_.end(); ) { |
420 tile_handle->UnregisterFromTileManager(); | 435 TileHandle* tile_handle = *it; |
| 436 TileList::iterator it_next = it; |
| 437 it_next++; |
| 438 if (!tile_handle->should_be_live() && |
| 439 !tile_handle->tile()->GetResourceId()) { |
| 440 TilePriority priority; |
| 441 DCHECK(!priority.is_live); |
| 442 tile_handle->tile()->set_priority(tree, priority); |
| 443 tile_handle->RemoveFromLiveTileList(); |
| 444 tile_handle->UnregisterFromTileManager(); |
| 445 } else { |
| 446 tile_handle->RegisterWithTileManager(); |
| 447 // Mark the tile as not live for the next time through. |
| 448 tile_handle->set_should_be_live(false); |
| 449 } |
| 450 it = it_next; |
421 } | 451 } |
| 452 |
422 last_prioritized_rect_ = inflated_rect; | 453 last_prioritized_rect_ = inflated_rect; |
423 | 454 |
424 gfx::Rect view_rect(device_viewport); | 455 gfx::Rect view_rect(device_viewport); |
425 float current_scale = current_layer_contents_scale / contents_scale_; | 456 float current_scale = current_layer_contents_scale / contents_scale_; |
426 float last_scale = last_layer_contents_scale / contents_scale_; | 457 float last_scale = last_layer_contents_scale / contents_scale_; |
427 | 458 |
428 // Fast path tile priority calculation when both transforms are translations. | 459 // Fast path tile priority calculation when both transforms are translations. |
429 if (last_screen_transform.IsIdentityOrTranslation() && | 460 if (last_screen_transform.IsIdentityOrTranslation() && |
430 current_screen_transform.IsIdentityOrTranslation()) | 461 current_screen_transform.IsIdentityOrTranslation()) |
431 { | 462 { |
432 gfx::Vector2dF current_offset( | 463 gfx::Vector2dF current_offset( |
433 current_screen_transform.matrix().get(0, 3), | 464 current_screen_transform.matrix().get(0, 3), |
434 current_screen_transform.matrix().get(1, 3)); | 465 current_screen_transform.matrix().get(1, 3)); |
435 gfx::Vector2dF last_offset( | 466 gfx::Vector2dF last_offset( |
436 last_screen_transform.matrix().get(0, 3), | 467 last_screen_transform.matrix().get(0, 3), |
437 last_screen_transform.matrix().get(1, 3)); | 468 last_screen_transform.matrix().get(1, 3)); |
438 | 469 |
439 for (TilingData::Iterator iter(&tiling_data_, inflated_rect); | 470 for (TileList::iterator it = live_tiles_.begin(); |
440 iter; ++iter) { | 471 it != live_tiles_.end(); ++it) { |
441 TileMap::iterator find = tiles_.find(iter.index()); | 472 TileHandle* tile_handle = *it; |
442 if (find == tiles_.end()) | |
443 continue; | |
444 TileHandle* tile_handle = &find->second; | |
445 Tile* tile = tile_handle->tile(); | 473 Tile* tile = tile_handle->tile(); |
446 tile_handle->RegisterWithTileManager(); | |
447 | 474 |
448 gfx::Rect tile_bounds = | 475 gfx::Rect tile_bounds = |
449 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); | 476 tiling_data_.TileBounds(tile_handle->key().first, |
| 477 tile_handle->key().second); |
450 gfx::RectF current_screen_rect = gfx::ScaleRect( | 478 gfx::RectF current_screen_rect = gfx::ScaleRect( |
451 tile_bounds, | 479 tile_bounds, |
452 current_scale, | 480 current_scale, |
453 current_scale) + current_offset; | 481 current_scale) + current_offset; |
454 gfx::RectF last_screen_rect = gfx::ScaleRect( | 482 gfx::RectF last_screen_rect = gfx::ScaleRect( |
455 tile_bounds, | 483 tile_bounds, |
456 last_scale, | 484 last_scale, |
457 last_scale) + last_offset; | 485 last_scale) + last_offset; |
458 | 486 |
459 float distance_to_visible_in_pixels = | 487 float distance_to_visible_in_pixels = |
460 TilePriority::manhattanDistance(current_screen_rect, view_rect); | 488 TilePriority::manhattanDistance(current_screen_rect, view_rect); |
461 | 489 |
462 float time_to_visible_in_seconds = | 490 float time_to_visible_in_seconds = |
463 TilePriority::TimeForBoundsToIntersect( | 491 TilePriority::TimeForBoundsToIntersect( |
464 last_screen_rect, current_screen_rect, time_delta, view_rect); | 492 last_screen_rect, current_screen_rect, time_delta, view_rect); |
465 TilePriority priority( | 493 TilePriority priority( |
466 resolution_, | 494 resolution_, |
467 time_to_visible_in_seconds, | 495 time_to_visible_in_seconds, |
468 distance_to_visible_in_pixels); | 496 distance_to_visible_in_pixels); |
469 if (store_screen_space_quads_on_tiles) | 497 if (store_screen_space_quads_on_tiles) |
470 priority.set_current_screen_quad(gfx::QuadF(current_screen_rect)); | 498 priority.set_current_screen_quad(gfx::QuadF(current_screen_rect)); |
471 tile->set_priority(tree, priority); | 499 tile->set_priority(tree, priority); |
472 } | 500 } |
473 } else { | 501 } else { |
474 for (TilingData::Iterator iter(&tiling_data_, inflated_rect); | 502 for (TileList::iterator it = live_tiles_.begin(); |
475 iter; ++iter) { | 503 it != live_tiles_.end(); ++it) { |
476 TileMap::iterator find = tiles_.find(iter.index()); | 504 TileHandle* tile_handle = *it; |
477 if (find == tiles_.end()) | |
478 continue; | |
479 TileHandle* tile_handle = &find->second; | |
480 Tile* tile = tile_handle->tile(); | 505 Tile* tile = tile_handle->tile(); |
481 tile_handle->RegisterWithTileManager(); | |
482 | 506 |
483 gfx::Rect tile_bounds = | 507 gfx::Rect tile_bounds = |
484 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); | 508 tiling_data_.TileBounds(tile_handle->key().first, |
| 509 tile_handle->key().second); |
485 gfx::RectF current_layer_content_rect = gfx::ScaleRect( | 510 gfx::RectF current_layer_content_rect = gfx::ScaleRect( |
486 tile_bounds, | 511 tile_bounds, |
487 current_scale, | 512 current_scale, |
488 current_scale); | 513 current_scale); |
489 gfx::RectF current_screen_rect = MathUtil::mapClippedRect( | 514 gfx::RectF current_screen_rect = MathUtil::mapClippedRect( |
490 current_screen_transform, current_layer_content_rect); | 515 current_screen_transform, current_layer_content_rect); |
491 gfx::RectF last_layer_content_rect = gfx::ScaleRect( | 516 gfx::RectF last_layer_content_rect = gfx::ScaleRect( |
492 tile_bounds, | 517 tile_bounds, |
493 last_scale, | 518 last_scale, |
494 last_scale); | 519 last_scale); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 | 564 |
540 scoped_ptr<base::Value> PictureLayerTiling::AsValue() const { | 565 scoped_ptr<base::Value> PictureLayerTiling::AsValue() const { |
541 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 566 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
542 state->SetInteger("num_tiles", tiles_.size()); | 567 state->SetInteger("num_tiles", tiles_.size()); |
543 state->SetDouble("content_scale", contents_scale_); | 568 state->SetDouble("content_scale", contents_scale_); |
544 state->Set("content_bounds", | 569 state->Set("content_bounds", |
545 MathUtil::asValue(ContentRect().size()).release()); | 570 MathUtil::asValue(ContentRect().size()).release()); |
546 return state.PassAs<base::Value>(); | 571 return state.PassAs<base::Value>(); |
547 } | 572 } |
548 | 573 |
549 TileHandle::TileHandle(scoped_refptr<Tile> tile) : tile_(tile) { | 574 TileHandle::TileHandle(std::pair<int, int> key, scoped_refptr<Tile> tile) |
| 575 : key_(key), |
| 576 tile_(tile), |
| 577 should_be_live_(false), |
| 578 tiling_(NULL) { |
| 579 } |
| 580 |
| 581 TileHandle::TileHandle(const TileHandle& tile_handle) |
| 582 : key_(tile_handle.key_), |
| 583 tile_(tile_handle.tile_), |
| 584 managed_tile_state_(tile_handle.managed_tile_state_), |
| 585 should_be_live_(false), |
| 586 tiling_(NULL) { |
| 587 } |
| 588 |
| 589 TileHandle::~TileHandle() { |
| 590 RemoveFromLiveTileList(); |
550 } | 591 } |
551 | 592 |
552 void TileHandle::RegisterWithTileManager() { | 593 void TileHandle::RegisterWithTileManager() { |
553 if (managed_tile_state_.get()) | 594 if (managed_tile_state_.get()) |
554 return; | 595 return; |
555 managed_tile_state_ = tile_->tile_manager()->RegisterTile(tile_); | 596 managed_tile_state_ = tile_->tile_manager()->RegisterTile(tile_); |
556 } | 597 } |
557 | 598 |
558 void TileHandle::UnregisterFromTileManager() { | 599 void TileHandle::UnregisterFromTileManager() { |
559 managed_tile_state_ = NULL; | 600 managed_tile_state_ = NULL; |
560 } | 601 } |
561 | 602 |
| 603 void TileHandle::AddToLiveTileList(PictureLayerTiling* tiling) { |
| 604 if (tiling_) { |
| 605 DCHECK(tiling == tiling_); |
| 606 DCHECK(tiling_live_tile_list_iterator_ != tiling_->live_tiles_.end()); |
| 607 return; |
| 608 } |
| 609 tiling_ = tiling; |
| 610 tiling_live_tile_list_iterator_ = |
| 611 tiling_->live_tiles_.insert(tiling_->live_tiles_.begin(), this); |
| 612 } |
| 613 |
| 614 void TileHandle::RemoveFromLiveTileList() { |
| 615 if (!tiling_) |
| 616 return; |
| 617 tiling_->live_tiles_.erase(tiling_live_tile_list_iterator_); |
| 618 tiling_live_tile_list_iterator_ = tiling_->live_tiles_.end(); |
| 619 tiling_ = NULL; |
| 620 } |
| 621 |
562 } // namespace cc | 622 } // namespace cc |
OLD | NEW |