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 { | 69 Tile* PictureLayerTiling::CreateTile(int i, |
68 TileMap::const_iterator iter = tiles_.find(TileMapKey(i, j)); | 70 int j, |
69 if (iter == tiles_.end()) | 71 const PictureLayerTiling* twin_tiling) { |
70 return NULL; | |
71 return iter->second.get(); | |
72 } | |
73 | |
74 void PictureLayerTiling::CreateTile(int i, | |
75 int j, | |
76 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 |
84 // Check our twin for a valid tile. | 79 // Check our twin for a valid tile. |
85 if (twin_tiling && | 80 if (twin_tiling && |
86 tiling_data_.max_texture_size() == | 81 tiling_data_.max_texture_size() == |
87 twin_tiling->tiling_data_.max_texture_size()) { | 82 twin_tiling->tiling_data_.max_texture_size()) { |
88 if (Tile* candidate_tile = twin_tiling->TileAt(i, j)) { | 83 if (Tile* candidate_tile = twin_tiling->TileAt(i, j)) { |
89 gfx::Rect rect = | 84 gfx::Rect rect = |
90 gfx::ScaleToEnclosingRect(paint_rect, 1.0f / contents_scale_); | 85 gfx::ScaleToEnclosingRect(paint_rect, 1.0f / contents_scale_); |
91 if (!client_->GetInvalidation()->Intersects(rect)) { | 86 if (!client_->GetInvalidation()->Intersects(rect)) { |
92 tiles_[key] = candidate_tile; | 87 tiles_[key] = candidate_tile; |
93 return; | 88 return candidate_tile; |
94 } | 89 } |
95 } | 90 } |
96 } | 91 } |
97 | 92 |
98 // Create a new tile because our twin didn't have a valid one. | 93 // Create a new tile because our twin didn't have a valid one. |
99 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); | 94 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); |
100 if (tile.get()) | 95 if (tile.get()) |
101 tiles_[key] = tile; | 96 tiles_[key] = tile; |
97 return tile.get(); | |
102 } | 98 } |
103 | 99 |
104 Region PictureLayerTiling::OpaqueRegionInContentRect( | 100 Region PictureLayerTiling::OpaqueRegionInContentRect( |
105 const gfx::Rect& content_rect) const { | 101 const gfx::Rect& content_rect) const { |
106 Region opaque_region; | 102 Region opaque_region; |
107 // TODO(enne): implement me | 103 // TODO(enne): implement me |
108 return opaque_region; | 104 return opaque_region; |
109 } | 105 } |
110 | 106 |
111 void PictureLayerTiling::SetCanUseLCDText(bool can_use_lcd_text) { | 107 void PictureLayerTiling::SetCanUseLCDText(bool can_use_lcd_text) { |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
423 ContentRect(), | 419 ContentRect(), |
424 &expansion_cache_); | 420 &expansion_cache_); |
425 | 421 |
426 DCHECK(eventually_rect.IsEmpty() || ContentRect().Contains(eventually_rect)); | 422 DCHECK(eventually_rect.IsEmpty() || ContentRect().Contains(eventually_rect)); |
427 | 423 |
428 SetLiveTilesRect(eventually_rect); | 424 SetLiveTilesRect(eventually_rect); |
429 | 425 |
430 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; | 426 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; |
431 last_visible_rect_in_content_space_ = visible_rect_in_content_space; | 427 last_visible_rect_in_content_space_ = visible_rect_in_content_space; |
432 | 428 |
429 current_skewport_ = skewport; | |
430 current_eventually_rect_ = eventually_rect; | |
431 current_visible_rect_in_content_space_ = visible_rect_in_content_space; | |
432 | |
433 TilePriority now_priority(resolution_, TilePriority::NOW, 0); | |
434 float content_to_screen_scale = | |
435 1.0f / (contents_scale_ * layer_contents_scale); | |
436 | |
433 // Assign now priority to all visible tiles. | 437 // Assign now priority to all visible tiles. |
434 TilePriority now_priority(resolution_, TilePriority::NOW, 0); | |
435 for (TilingData::Iterator iter(&tiling_data_, visible_rect_in_content_space); | 438 for (TilingData::Iterator iter(&tiling_data_, visible_rect_in_content_space); |
436 iter; | 439 iter; |
437 ++iter) { | 440 ++iter) { |
438 TileMap::iterator find = tiles_.find(iter.index()); | 441 TileMap::const_iterator find = tiles_.find(iter.index()); |
enne (OOO)
2014/03/06 02:30:45
I realize that technically the iterator is const b
vmpstr
2014/03/07 18:22:23
Not really, I just prefer const_iterator when it c
| |
439 if (find == tiles_.end()) | 442 if (find == tiles_.end()) |
440 continue; | 443 continue; |
441 Tile* tile = find->second.get(); | 444 Tile* tile = find->second.get(); |
442 | 445 |
443 tile->SetPriority(tree, now_priority); | 446 tile->SetPriority(tree, now_priority); |
444 } | 447 } |
445 | 448 |
446 // Assign soon priority to all tiles in the skewport that are not visible. | 449 // Assign soon priority to skewport tiles. |
447 float content_to_screen_scale = | |
448 1.0f / (contents_scale_ * layer_contents_scale); | |
449 for (TilingData::DifferenceIterator iter( | 450 for (TilingData::DifferenceIterator iter( |
450 &tiling_data_, skewport, visible_rect_in_content_space); | 451 &tiling_data_, skewport, visible_rect_in_content_space); |
451 iter; | 452 iter; |
452 ++iter) { | 453 ++iter) { |
453 TileMap::iterator find = tiles_.find(iter.index()); | 454 TileMap::const_iterator find = tiles_.find(iter.index()); |
454 if (find == tiles_.end()) | 455 if (find == tiles_.end()) |
455 continue; | 456 continue; |
456 Tile* tile = find->second.get(); | 457 Tile* tile = find->second.get(); |
457 | 458 |
458 gfx::Rect tile_bounds = | 459 gfx::Rect tile_bounds = |
459 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); | 460 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); |
460 | 461 |
461 float distance_to_visible = | 462 float distance_to_visible = |
462 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) * | 463 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) * |
463 content_to_screen_scale; | 464 content_to_screen_scale; |
464 | 465 |
465 TilePriority priority(resolution_, TilePriority::SOON, distance_to_visible); | 466 TilePriority priority(resolution_, TilePriority::SOON, distance_to_visible); |
466 tile->SetPriority(tree, priority); | 467 tile->SetPriority(tree, priority); |
467 } | 468 } |
468 | 469 |
469 // Assign eventually priority to all tiles in the eventually rect that are not | 470 // Assign eventually priority to interest rect tiles. |
470 // in the skewport. | |
471 for (TilingData::DifferenceIterator iter( | 471 for (TilingData::DifferenceIterator iter( |
472 &tiling_data_, eventually_rect, skewport); | 472 &tiling_data_, eventually_rect, skewport); |
473 iter; | 473 iter; |
474 ++iter) { | 474 ++iter) { |
475 TileMap::iterator find = tiles_.find(iter.index()); | 475 TileMap::const_iterator find = tiles_.find(iter.index()); |
476 if (find == tiles_.end()) | 476 if (find == tiles_.end()) |
477 continue; | 477 continue; |
478 Tile* tile = find->second.get(); | 478 Tile* tile = find->second.get(); |
479 | 479 |
480 gfx::Rect tile_bounds = | 480 gfx::Rect tile_bounds = |
481 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); | 481 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); |
482 | 482 |
483 float distance_to_visible = | 483 float distance_to_visible = |
484 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) * | 484 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) * |
485 content_to_screen_scale; | 485 content_to_screen_scale; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
549 client_->UpdatePile(it->second.get()); | 549 client_->UpdatePile(it->second.get()); |
550 } | 550 } |
551 } | 551 } |
552 | 552 |
553 void PictureLayerTiling::UpdateTilesToCurrentPile() { | 553 void PictureLayerTiling::UpdateTilesToCurrentPile() { |
554 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 554 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
555 client_->UpdatePile(it->second.get()); | 555 client_->UpdatePile(it->second.get()); |
556 } | 556 } |
557 } | 557 } |
558 | 558 |
559 size_t PictureLayerTiling::RequiredGPUMemoryInBytes() const { | |
epenner
2014/03/06 10:21:40
Could this be replaced with math? If not, or this
vmpstr
2014/03/07 18:22:23
Do you mean something like visible_tiles_count * s
| |
560 size_t amount = 0; | |
561 for (TilingData::Iterator iter(&tiling_data_, | |
562 last_visible_rect_in_content_space_); | |
563 iter; | |
564 ++iter) { | |
565 TileMap::const_iterator find = tiles_.find(iter.index()); | |
566 if (find == tiles_.end()) | |
567 continue; | |
568 Tile* tile = find->second.get(); | |
569 amount += tile->GPUMemoryUsageInBytes(); | |
570 } | |
571 return amount; | |
572 } | |
573 | |
559 scoped_ptr<base::Value> PictureLayerTiling::AsValue() const { | 574 scoped_ptr<base::Value> PictureLayerTiling::AsValue() const { |
560 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 575 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
561 state->SetInteger("num_tiles", tiles_.size()); | 576 state->SetInteger("num_tiles", tiles_.size()); |
562 state->SetDouble("content_scale", contents_scale_); | 577 state->SetDouble("content_scale", contents_scale_); |
563 state->Set("content_bounds", | 578 state->Set("content_bounds", |
564 MathUtil::AsValue(ContentRect().size()).release()); | 579 MathUtil::AsValue(ContentRect().size()).release()); |
565 return state.PassAs<base::Value>(); | 580 return state.PassAs<base::Value>(); |
566 } | 581 } |
567 | 582 |
568 size_t PictureLayerTiling::GPUMemoryUsageInBytes() const { | 583 size_t PictureLayerTiling::GPUMemoryUsageInBytes() const { |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
716 if (delta < event.distance) | 731 if (delta < event.distance) |
717 break; | 732 break; |
718 } | 733 } |
719 | 734 |
720 gfx::Rect result(origin_x, origin_y, width, height); | 735 gfx::Rect result(origin_x, origin_y, width, height); |
721 if (cache) | 736 if (cache) |
722 cache->previous_result = result; | 737 cache->previous_result = result; |
723 return result; | 738 return result; |
724 } | 739 } |
725 | 740 |
741 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator() | |
742 : tiling_(NULL), current_tile_(NULL) {} | |
743 | |
744 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator( | |
745 PictureLayerTiling* tiling, | |
746 WhichTree tree) | |
747 : tiling_(tiling), | |
748 type_(VISIBLE), | |
749 tree_(tree), | |
750 current_tile_(NULL), | |
751 visible_iterator_(&tiling->tiling_data_, | |
752 tiling->current_visible_rect_in_content_space_), | |
753 spiral_iterator_(&tiling->tiling_data_, | |
754 tiling->current_skewport_, | |
755 tiling->current_visible_rect_in_content_space_, | |
756 tiling->current_visible_rect_in_content_space_) { | |
757 if (!visible_iterator_) { | |
758 AdvancePhase(); | |
759 return; | |
760 } | |
761 | |
762 current_tile_ = | |
763 tiling_->TileAt(visible_iterator_.index_x(), visible_iterator_.index_y()); | |
764 if (!current_tile_ || !TileNeedsRaster(current_tile_)) | |
765 ++(*this); | |
766 } | |
767 | |
768 PictureLayerTiling::TilingRasterTileIterator::~TilingRasterTileIterator() {} | |
769 | |
770 void PictureLayerTiling::TilingRasterTileIterator::AdvancePhase() { | |
771 DCHECK_LT(type_, EVENTUALLY); | |
772 | |
773 do { | |
774 type_ = static_cast<Type>(type_ + 1); | |
775 if (type_ == EVENTUALLY) { | |
776 spiral_iterator_ = TilingData::SpiralDifferenceIterator( | |
777 &tiling_->tiling_data_, | |
778 tiling_->current_eventually_rect_, | |
779 tiling_->current_skewport_, | |
780 tiling_->current_visible_rect_in_content_space_); | |
781 } | |
782 | |
783 while (spiral_iterator_) { | |
epenner
2014/03/06 10:21:40
This is just for advancing past rastered tiles rig
vmpstr
2014/03/07 18:22:23
So I was just going to call ++(*this); here in a s
| |
784 current_tile_ = tiling_->TileAt(spiral_iterator_.index_x(), | |
785 spiral_iterator_.index_y()); | |
786 if (current_tile_ && TileNeedsRaster(current_tile_)) | |
787 break; | |
788 ++spiral_iterator_; | |
789 } | |
790 | |
791 if (!spiral_iterator_ && type_ == EVENTUALLY) | |
792 break; | |
793 } while (!spiral_iterator_); | |
794 } | |
795 | |
796 PictureLayerTiling::TilingRasterTileIterator& | |
797 PictureLayerTiling::TilingRasterTileIterator:: | |
798 operator++() { | |
799 current_tile_ = NULL; | |
800 while (!current_tile_ || !TileNeedsRaster(current_tile_)) { | |
801 std::pair<int, int> next_index; | |
802 switch (type_) { | |
803 case VISIBLE: | |
804 ++visible_iterator_; | |
805 if (!visible_iterator_) { | |
806 AdvancePhase(); | |
807 return *this; | |
808 } | |
809 next_index = visible_iterator_.index(); | |
810 break; | |
811 case SKEWPORT: | |
812 ++spiral_iterator_; | |
813 if (!spiral_iterator_) { | |
814 AdvancePhase(); | |
815 return *this; | |
816 } | |
817 next_index = spiral_iterator_.index(); | |
818 break; | |
819 case EVENTUALLY: | |
820 ++spiral_iterator_; | |
821 if (!spiral_iterator_) | |
822 return *this; | |
823 next_index = spiral_iterator_.index(); | |
824 break; | |
825 } | |
826 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); | |
827 } | |
828 return *this; | |
829 } | |
830 | |
726 } // namespace cc | 831 } // namespace cc |
OLD | NEW |