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/resources/picture_layer_tiling.h" | 5 #include "cc/resources/picture_layer_tiling.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 #include <limits> | 9 #include <limits> |
10 | 10 |
11 #include "base/debug/trace_event.h" | 11 #include "base/debug/trace_event.h" |
12 #include "cc/base/math_util.h" | 12 #include "cc/base/math_util.h" |
13 #include "cc/resources/tile.h" | |
14 #include "cc/resources/tile_priority.h" | |
13 #include "ui/gfx/point_conversions.h" | 15 #include "ui/gfx/point_conversions.h" |
14 #include "ui/gfx/rect_conversions.h" | 16 #include "ui/gfx/rect_conversions.h" |
15 #include "ui/gfx/safe_integer_conversions.h" | 17 #include "ui/gfx/safe_integer_conversions.h" |
16 #include "ui/gfx/size_conversions.h" | 18 #include "ui/gfx/size_conversions.h" |
17 | 19 |
18 namespace cc { | 20 namespace cc { |
19 | 21 |
20 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( | 22 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( |
21 float contents_scale, | 23 float contents_scale, |
22 const gfx::Size& layer_bounds, | 24 const gfx::Size& layer_bounds, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
57 } | 59 } |
58 | 60 |
59 gfx::Rect PictureLayerTiling::ContentRect() const { | 61 gfx::Rect PictureLayerTiling::ContentRect() const { |
60 return gfx::Rect(tiling_data_.total_size()); | 62 return gfx::Rect(tiling_data_.total_size()); |
61 } | 63 } |
62 | 64 |
63 gfx::SizeF PictureLayerTiling::ContentSizeF() const { | 65 gfx::SizeF PictureLayerTiling::ContentSizeF() const { |
64 return gfx::ScaleSize(layer_bounds_, contents_scale_); | 66 return gfx::ScaleSize(layer_bounds_, contents_scale_); |
65 } | 67 } |
66 | 68 |
67 Tile* PictureLayerTiling::TileAt(int i, int j) const { | |
68 TileMap::const_iterator iter = tiles_.find(TileMapKey(i, j)); | |
69 if (iter == tiles_.end()) | |
70 return NULL; | |
71 return iter->second.get(); | |
72 } | |
73 | |
74 void PictureLayerTiling::CreateTile(int i, | 69 void PictureLayerTiling::CreateTile(int i, |
75 int j, | 70 int j, |
76 const PictureLayerTiling* twin_tiling) { | 71 const PictureLayerTiling* twin_tiling) { |
77 TileMapKey key(i, j); | 72 TileMapKey key(i, j); |
78 DCHECK(tiles_.find(key) == tiles_.end()); | 73 DCHECK(tiles_.find(key) == tiles_.end()); |
79 | 74 |
80 gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j); | 75 gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j); |
81 gfx::Rect tile_rect = paint_rect; | 76 gfx::Rect tile_rect = paint_rect; |
82 tile_rect.set_size(tiling_data_.max_texture_size()); | 77 tile_rect.set_size(tiling_data_.max_texture_size()); |
83 | 78 |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
423 ContentRect(), | 418 ContentRect(), |
424 &expansion_cache_); | 419 &expansion_cache_); |
425 | 420 |
426 DCHECK(eventually_rect.IsEmpty() || ContentRect().Contains(eventually_rect)); | 421 DCHECK(eventually_rect.IsEmpty() || ContentRect().Contains(eventually_rect)); |
427 | 422 |
428 SetLiveTilesRect(eventually_rect); | 423 SetLiveTilesRect(eventually_rect); |
429 | 424 |
430 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; | 425 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; |
431 last_visible_rect_in_content_space_ = visible_rect_in_content_space; | 426 last_visible_rect_in_content_space_ = visible_rect_in_content_space; |
432 | 427 |
433 // Assign now priority to all visible tiles. | 428 current_skewport_ = skewport; |
429 current_eventually_rect_ = eventually_rect; | |
430 current_visible_rect_in_content_space_ = visible_rect_in_content_space; | |
431 | |
434 TilePriority now_priority(resolution_, TilePriority::NOW, 0); | 432 TilePriority now_priority(resolution_, TilePriority::NOW, 0); |
435 for (TilingData::Iterator iter(&tiling_data_, visible_rect_in_content_space); | |
436 iter; | |
437 ++iter) { | |
438 TileMap::iterator find = tiles_.find(iter.index()); | |
439 if (find == tiles_.end()) | |
440 continue; | |
441 Tile* tile = find->second.get(); | |
442 | |
443 tile->SetPriority(tree, now_priority); | |
444 } | |
445 | |
446 // Assign soon priority to all tiles in the skewport that are not visible. | |
447 float content_to_screen_scale = | 433 float content_to_screen_scale = |
448 1.0f / (contents_scale_ * layer_contents_scale); | 434 1.0f / (contents_scale_ * layer_contents_scale); |
449 for (TilingData::DifferenceIterator iter( | 435 |
450 &tiling_data_, skewport, visible_rect_in_content_space); | 436 for (TilingRasterTileIterator it(this); it; ++it) { |
451 iter; | 437 Tile* tile = *it; |
452 ++iter) { | 438 if (it.get_type() == TilingRasterTileIterator::VISIBLE) { |
453 TileMap::iterator find = tiles_.find(iter.index()); | 439 tile->SetPriority(tree, now_priority); |
454 if (find == tiles_.end()) | |
455 continue; | 440 continue; |
456 Tile* tile = find->second.get(); | 441 } |
457 | 442 |
458 gfx::Rect tile_bounds = | 443 TilePriority::PriorityBin bin = |
459 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); | 444 (it.get_type() == TilingRasterTileIterator::SKEWPORT) |
445 ? TilePriority::SOON | |
446 : TilePriority::EVENTUALLY; | |
447 | |
448 gfx::Rect tile_bounds = it.TileBounds(); | |
460 | 449 |
461 float distance_to_visible = | 450 float distance_to_visible = |
462 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) * | 451 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) * |
463 content_to_screen_scale; | 452 content_to_screen_scale; |
464 | 453 |
465 TilePriority priority(resolution_, TilePriority::SOON, distance_to_visible); | 454 TilePriority priority(resolution_, bin, distance_to_visible); |
466 tile->SetPriority(tree, priority); | 455 tile->SetPriority(tree, priority); |
467 } | 456 } |
468 | 457 last_update_tree_ = tree; |
469 // Assign eventually priority to all tiles in the eventually rect that are not | |
470 // in the skewport. | |
471 for (TilingData::DifferenceIterator iter( | |
472 &tiling_data_, eventually_rect, skewport); | |
473 iter; | |
474 ++iter) { | |
475 TileMap::iterator find = tiles_.find(iter.index()); | |
476 if (find == tiles_.end()) | |
477 continue; | |
478 Tile* tile = find->second.get(); | |
479 | |
480 gfx::Rect tile_bounds = | |
481 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); | |
482 | |
483 float distance_to_visible = | |
484 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) * | |
485 content_to_screen_scale; | |
486 TilePriority priority( | |
487 resolution_, TilePriority::EVENTUALLY, distance_to_visible); | |
488 tile->SetPriority(tree, priority); | |
489 } | |
490 } | 458 } |
491 | 459 |
492 void PictureLayerTiling::SetLiveTilesRect( | 460 void PictureLayerTiling::SetLiveTilesRect( |
493 const gfx::Rect& new_live_tiles_rect) { | 461 const gfx::Rect& new_live_tiles_rect) { |
494 DCHECK(new_live_tiles_rect.IsEmpty() || | 462 DCHECK(new_live_tiles_rect.IsEmpty() || |
495 ContentRect().Contains(new_live_tiles_rect)); | 463 ContentRect().Contains(new_live_tiles_rect)); |
496 if (live_tiles_rect_ == new_live_tiles_rect) | 464 if (live_tiles_rect_ == new_live_tiles_rect) |
497 return; | 465 return; |
498 | 466 |
499 // Iterate to delete all tiles outside of our new live_tiles rect. | 467 // Iterate to delete all tiles outside of our new live_tiles rect. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
549 client_->UpdatePile(it->second.get()); | 517 client_->UpdatePile(it->second.get()); |
550 } | 518 } |
551 } | 519 } |
552 | 520 |
553 void PictureLayerTiling::UpdateTilesToCurrentPile() { | 521 void PictureLayerTiling::UpdateTilesToCurrentPile() { |
554 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 522 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
555 client_->UpdatePile(it->second.get()); | 523 client_->UpdatePile(it->second.get()); |
556 } | 524 } |
557 } | 525 } |
558 | 526 |
527 size_t PictureLayerTiling::RequiredGPUMemoryInBytes() const { | |
528 size_t amount = 0; | |
529 for (TilingData::Iterator iter(&tiling_data_, | |
530 last_visible_rect_in_content_space_); | |
531 iter; | |
532 ++iter) { | |
533 TileMap::const_iterator find = tiles_.find(iter.index()); | |
534 if (find == tiles_.end()) | |
535 continue; | |
536 Tile* tile = find->second.get(); | |
537 amount += tile->GPUMemoryUsageInBytes(); | |
538 } | |
539 return amount; | |
540 } | |
541 | |
559 scoped_ptr<base::Value> PictureLayerTiling::AsValue() const { | 542 scoped_ptr<base::Value> PictureLayerTiling::AsValue() const { |
560 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 543 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
561 state->SetInteger("num_tiles", tiles_.size()); | 544 state->SetInteger("num_tiles", tiles_.size()); |
562 state->SetDouble("content_scale", contents_scale_); | 545 state->SetDouble("content_scale", contents_scale_); |
563 state->Set("content_bounds", | 546 state->Set("content_bounds", |
564 MathUtil::AsValue(ContentRect().size()).release()); | 547 MathUtil::AsValue(ContentRect().size()).release()); |
565 return state.PassAs<base::Value>(); | 548 return state.PassAs<base::Value>(); |
566 } | 549 } |
567 | 550 |
568 size_t PictureLayerTiling::GPUMemoryUsageInBytes() const { | 551 size_t PictureLayerTiling::GPUMemoryUsageInBytes() const { |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
716 if (delta < event.distance) | 699 if (delta < event.distance) |
717 break; | 700 break; |
718 } | 701 } |
719 | 702 |
720 gfx::Rect result(origin_x, origin_y, width, height); | 703 gfx::Rect result(origin_x, origin_y, width, height); |
721 if (cache) | 704 if (cache) |
722 cache->previous_result = result; | 705 cache->previous_result = result; |
723 return result; | 706 return result; |
724 } | 707 } |
725 | 708 |
709 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator() | |
710 : tiling_(NULL), current_tile_(NULL) {} | |
711 | |
712 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator( | |
713 PictureLayerTiling* tiling) | |
714 : tiling_(tiling), | |
715 type_(VISIBLE), | |
716 current_tile_(NULL), | |
717 visible_iterator_(&tiling->tiling_data_, | |
718 tiling->current_visible_rect_in_content_space_), | |
719 spiral_iterator_(&tiling->tiling_data_, | |
720 tiling->current_skewport_, | |
721 tiling->current_visible_rect_in_content_space_, | |
722 tiling->current_visible_rect_in_content_space_) { | |
723 if (!visible_iterator_) { | |
724 AdvancePhase(); | |
725 return; | |
726 } | |
727 | |
728 current_tile_ = | |
729 tiling_->TileAt(visible_iterator_.index_x(), visible_iterator_.index_y()); | |
730 if (!current_tile_) | |
731 ++(*this); | |
732 } | |
733 | |
734 PictureLayerTiling::TilingRasterTileIterator::~TilingRasterTileIterator() {} | |
735 | |
736 void PictureLayerTiling::TilingRasterTileIterator::AdvancePhase() { | |
737 DCHECK_LT(type_, EVENTUALLY); | |
738 | |
739 do { | |
740 type_ = static_cast<Type>(type_ + 1); | |
741 if (type_ == EVENTUALLY) { | |
742 spiral_iterator_ = TilingData::SpiralDifferenceIterator( | |
743 &tiling_->tiling_data_, | |
744 tiling_->current_eventually_rect_, | |
745 tiling_->current_skewport_, | |
746 tiling_->current_visible_rect_in_content_space_); | |
747 } | |
748 | |
749 while (spiral_iterator_) { | |
750 current_tile_ = tiling_->TileAt(spiral_iterator_.index_x(), | |
751 spiral_iterator_.index_y()); | |
752 if (current_tile_) | |
753 break; | |
754 ++spiral_iterator_; | |
755 } | |
756 | |
757 if (!spiral_iterator_ && type_ == EVENTUALLY) | |
758 break; | |
759 } while (!spiral_iterator_); | |
760 } | |
761 | |
762 PictureLayerTiling::TilingRasterTileIterator& | |
763 PictureLayerTiling::TilingRasterTileIterator:: | |
764 operator++() { | |
epennerAtGoogle
2014/03/05 00:16:03
General question regarding final design: Is this e
vmpstr
2014/03/05 00:37:21
Yeah, the priority will be set lazily. I think her
| |
765 current_tile_ = NULL; | |
766 while (!current_tile_) { | |
767 std::pair<int, int> next_index; | |
768 switch (type_) { | |
769 case VISIBLE: | |
770 ++visible_iterator_; | |
771 if (!visible_iterator_) { | |
772 AdvancePhase(); | |
773 return *this; | |
774 } | |
775 next_index = visible_iterator_.index(); | |
776 break; | |
777 case SKEWPORT: | |
778 ++spiral_iterator_; | |
779 if (!spiral_iterator_) { | |
780 AdvancePhase(); | |
781 return *this; | |
782 } | |
783 next_index = spiral_iterator_.index(); | |
784 break; | |
785 case EVENTUALLY: | |
786 ++spiral_iterator_; | |
787 if (!spiral_iterator_) | |
788 return *this; | |
789 next_index = spiral_iterator_.index(); | |
790 break; | |
791 } | |
792 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); | |
793 } | |
794 return *this; | |
795 } | |
796 | |
726 } // namespace cc | 797 } // namespace cc |
OLD | NEW |