| 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_visible_rect_in_content_space_ = visible_rect_in_content_space; |
| 430 current_skewport_ = skewport; |
| 431 current_eventually_rect_ = eventually_rect; |
| 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::iterator find = tiles_.find(iter.index()); |
| 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::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::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 = |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 if (delta < event.distance) | 716 if (delta < event.distance) |
| 717 break; | 717 break; |
| 718 } | 718 } |
| 719 | 719 |
| 720 gfx::Rect result(origin_x, origin_y, width, height); | 720 gfx::Rect result(origin_x, origin_y, width, height); |
| 721 if (cache) | 721 if (cache) |
| 722 cache->previous_result = result; | 722 cache->previous_result = result; |
| 723 return result; | 723 return result; |
| 724 } | 724 } |
| 725 | 725 |
| 726 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator() |
| 727 : tiling_(NULL), current_tile_(NULL) {} |
| 728 |
| 729 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator( |
| 730 PictureLayerTiling* tiling, |
| 731 WhichTree tree) |
| 732 : tiling_(tiling), |
| 733 type_(VISIBLE), |
| 734 visible_rect_in_content_space_( |
| 735 tiling_->current_visible_rect_in_content_space_), |
| 736 skewport_in_content_space_(tiling_->current_skewport_), |
| 737 eventually_rect_in_content_space_(tiling_->current_eventually_rect_), |
| 738 tree_(tree), |
| 739 current_tile_(NULL), |
| 740 visible_iterator_(&tiling->tiling_data_, visible_rect_in_content_space_), |
| 741 spiral_iterator_(&tiling->tiling_data_, |
| 742 skewport_in_content_space_, |
| 743 visible_rect_in_content_space_, |
| 744 visible_rect_in_content_space_) { |
| 745 if (!visible_iterator_) { |
| 746 AdvancePhase(); |
| 747 return; |
| 748 } |
| 749 |
| 750 current_tile_ = |
| 751 tiling_->TileAt(visible_iterator_.index_x(), visible_iterator_.index_y()); |
| 752 if (!current_tile_ || !TileNeedsRaster(current_tile_)) |
| 753 ++(*this); |
| 754 } |
| 755 |
| 756 PictureLayerTiling::TilingRasterTileIterator::~TilingRasterTileIterator() {} |
| 757 |
| 758 void PictureLayerTiling::TilingRasterTileIterator::AdvancePhase() { |
| 759 DCHECK_LT(type_, EVENTUALLY); |
| 760 |
| 761 do { |
| 762 type_ = static_cast<Type>(type_ + 1); |
| 763 if (type_ == EVENTUALLY) { |
| 764 spiral_iterator_ = TilingData::SpiralDifferenceIterator( |
| 765 &tiling_->tiling_data_, |
| 766 eventually_rect_in_content_space_, |
| 767 skewport_in_content_space_, |
| 768 visible_rect_in_content_space_); |
| 769 } |
| 770 |
| 771 while (spiral_iterator_) { |
| 772 current_tile_ = tiling_->TileAt(spiral_iterator_.index_x(), |
| 773 spiral_iterator_.index_y()); |
| 774 if (current_tile_ && TileNeedsRaster(current_tile_)) |
| 775 break; |
| 776 ++spiral_iterator_; |
| 777 } |
| 778 |
| 779 if (!spiral_iterator_ && type_ == EVENTUALLY) |
| 780 break; |
| 781 } while (!spiral_iterator_); |
| 782 } |
| 783 |
| 784 PictureLayerTiling::TilingRasterTileIterator& |
| 785 PictureLayerTiling::TilingRasterTileIterator:: |
| 786 operator++() { |
| 787 current_tile_ = NULL; |
| 788 while (!current_tile_ || !TileNeedsRaster(current_tile_)) { |
| 789 std::pair<int, int> next_index; |
| 790 switch (type_) { |
| 791 case VISIBLE: |
| 792 ++visible_iterator_; |
| 793 if (!visible_iterator_) { |
| 794 AdvancePhase(); |
| 795 return *this; |
| 796 } |
| 797 next_index = visible_iterator_.index(); |
| 798 break; |
| 799 case SKEWPORT: |
| 800 ++spiral_iterator_; |
| 801 if (!spiral_iterator_) { |
| 802 AdvancePhase(); |
| 803 return *this; |
| 804 } |
| 805 next_index = spiral_iterator_.index(); |
| 806 break; |
| 807 case EVENTUALLY: |
| 808 ++spiral_iterator_; |
| 809 if (!spiral_iterator_) |
| 810 return *this; |
| 811 next_index = spiral_iterator_.index(); |
| 812 break; |
| 813 } |
| 814 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); |
| 815 } |
| 816 return *this; |
| 817 } |
| 818 |
| 726 } // namespace cc | 819 } // namespace cc |
| OLD | NEW |