Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(589)

Side by Side Diff: cc/resources/picture_layer_tiling.cc

Issue 183663003: cc: Add tiling raster tile iterators. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698