Chromium Code Reviews| 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 |