diff options
author | vmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-14 06:30:57 +0000 |
---|---|---|
committer | vmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-14 06:30:57 +0000 |
commit | 82791e0818dfa575391a3ea87686704055913501 (patch) | |
tree | cff0f39e923326e6020ff1fdaed99c1f6cd7f5a2 /cc | |
parent | 508107c3c78d84fd479dd614bb377d5fb078d783 (diff) | |
download | chromium_src-82791e0818dfa575391a3ea87686704055913501.zip chromium_src-82791e0818dfa575391a3ea87686704055913501.tar.gz chromium_src-82791e0818dfa575391a3ea87686704055913501.tar.bz2 |
cc: Add tiling raster tile iterators.
This patch adds PictureLayerTiling::Tiling{Raster,Eviction}TileIterator
classes. This is required for a larger change to tile prioritization.
Currently, the classes are not used by anything except unit and perf
tests.
BUG=329686
R=enne@chromium.org, reveman@chromium.org
Review URL: https://codereview.chromium.org/183663003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@257041 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/base/tiling_data.cc | 7 | ||||
-rw-r--r-- | cc/base/tiling_data.h | 2 | ||||
-rw-r--r-- | cc/resources/managed_tile_state.h | 5 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling.cc | 127 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling.h | 66 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling_perftest.cc | 38 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling_unittest.cc | 180 | ||||
-rw-r--r-- | cc/resources/tile.cc | 25 | ||||
-rw-r--r-- | cc/resources/tile.h | 21 | ||||
-rw-r--r-- | cc/resources/tile_manager.cc | 21 | ||||
-rw-r--r-- | cc/resources/tile_manager.h | 1 |
11 files changed, 441 insertions, 52 deletions
diff --git a/cc/base/tiling_data.cc b/cc/base/tiling_data.cc index b369dde..1de106c 100644 --- a/cc/base/tiling_data.cc +++ b/cc/base/tiling_data.cc @@ -272,6 +272,8 @@ TilingData::BaseIterator::BaseIterator(const TilingData* tiling_data) index_y_(-1) { } +TilingData::Iterator::Iterator() : BaseIterator(NULL) { done(); } + TilingData::Iterator::Iterator(const TilingData* tiling_data, const gfx::Rect& tiling_rect) : BaseIterator(tiling_data), @@ -409,6 +411,11 @@ TilingData::DifferenceIterator& TilingData::DifferenceIterator::operator++() { return *this; } +TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator() + : BaseIterator(NULL) { + done(); +} + TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator( const TilingData* tiling_data, const gfx::Rect& consider_rect, diff --git a/cc/base/tiling_data.h b/cc/base/tiling_data.h index 70c465c..ee3a51e 100644 --- a/cc/base/tiling_data.h +++ b/cc/base/tiling_data.h @@ -89,6 +89,7 @@ class CC_EXPORT TilingData { // Iterate through all indices whose bounds + border intersect with |rect|. class CC_EXPORT Iterator : public BaseIterator { public: + Iterator(); Iterator(const TilingData* tiling_data, const gfx::Rect& tiling_rect); Iterator& operator++(); @@ -129,6 +130,7 @@ class CC_EXPORT TilingData { // order is a counterclockwise spiral around the given center. class CC_EXPORT SpiralDifferenceIterator : public BaseIterator { public: + SpiralDifferenceIterator(); SpiralDifferenceIterator(const TilingData* tiling_data, const gfx::Rect& consider_rect, const gfx::Rect& ignore_rect, diff --git a/cc/resources/managed_tile_state.h b/cc/resources/managed_tile_state.h index 6445623..e457983 100644 --- a/cc/resources/managed_tile_state.h +++ b/cc/resources/managed_tile_state.h @@ -69,10 +69,15 @@ class CC_EXPORT ManagedTileState { return mode_ == RESOURCE_MODE || mode_ == PICTURE_PILE_MODE; } + inline bool has_resource() const { return !!resource_; } + size_t GPUMemoryUsageInBytes() const; void SetSolidColorForTesting(SkColor color) { set_solid_color(color); } void SetHasTextForTesting(bool has_text) { has_text_ = has_text; } + void SetResourceForTesting(scoped_ptr<ScopedResource> resource) { + resource_ = resource.Pass(); + } private: friend class TileManager; diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc index 939e0b1..3604465 100644 --- a/cc/resources/picture_layer_tiling.cc +++ b/cc/resources/picture_layer_tiling.cc @@ -10,6 +10,8 @@ #include "base/debug/trace_event.h" #include "cc/base/math_util.h" +#include "cc/resources/tile.h" +#include "cc/resources/tile_priority.h" #include "ui/gfx/point_conversions.h" #include "ui/gfx/rect_conversions.h" #include "ui/gfx/safe_integer_conversions.h" @@ -64,16 +66,9 @@ gfx::SizeF PictureLayerTiling::ContentSizeF() const { return gfx::ScaleSize(layer_bounds_, contents_scale_); } -Tile* PictureLayerTiling::TileAt(int i, int j) const { - TileMap::const_iterator iter = tiles_.find(TileMapKey(i, j)); - if (iter == tiles_.end()) - return NULL; - return iter->second.get(); -} - -void PictureLayerTiling::CreateTile(int i, - int j, - const PictureLayerTiling* twin_tiling) { +Tile* PictureLayerTiling::CreateTile(int i, + int j, + const PictureLayerTiling* twin_tiling) { TileMapKey key(i, j); DCHECK(tiles_.find(key) == tiles_.end()); @@ -90,7 +85,7 @@ void PictureLayerTiling::CreateTile(int i, gfx::ScaleToEnclosingRect(paint_rect, 1.0f / contents_scale_); if (!client_->GetInvalidation()->Intersects(rect)) { tiles_[key] = candidate_tile; - return; + return candidate_tile; } } } @@ -99,6 +94,7 @@ void PictureLayerTiling::CreateTile(int i, scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); if (tile.get()) tiles_[key] = tile; + return tile.get(); } Region PictureLayerTiling::OpaqueRegionInContentRect( @@ -430,8 +426,15 @@ void PictureLayerTiling::UpdateTilePriorities( last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; last_visible_rect_in_content_space_ = visible_rect_in_content_space; - // Assign now priority to all visible tiles. + current_visible_rect_in_content_space_ = visible_rect_in_content_space; + current_skewport_ = skewport; + current_eventually_rect_ = eventually_rect; + TilePriority now_priority(resolution_, TilePriority::NOW, 0); + float content_to_screen_scale = + 1.0f / (contents_scale_ * layer_contents_scale); + + // Assign now priority to all visible tiles. for (TilingData::Iterator iter(&tiling_data_, visible_rect_in_content_space); iter; ++iter) { @@ -443,9 +446,7 @@ void PictureLayerTiling::UpdateTilePriorities( tile->SetPriority(tree, now_priority); } - // Assign soon priority to all tiles in the skewport that are not visible. - float content_to_screen_scale = - 1.0f / (contents_scale_ * layer_contents_scale); + // Assign soon priority to skewport tiles. for (TilingData::DifferenceIterator iter( &tiling_data_, skewport, visible_rect_in_content_space); iter; @@ -466,8 +467,7 @@ void PictureLayerTiling::UpdateTilePriorities( tile->SetPriority(tree, priority); } - // Assign eventually priority to all tiles in the eventually rect that are not - // in the skewport. + // Assign eventually priority to interest rect tiles. for (TilingData::DifferenceIterator iter( &tiling_data_, eventually_rect, skewport); iter; @@ -723,4 +723,97 @@ gfx::Rect PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy( return result; } +PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator() + : tiling_(NULL), current_tile_(NULL) {} + +PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator( + PictureLayerTiling* tiling, + WhichTree tree) + : tiling_(tiling), + type_(VISIBLE), + visible_rect_in_content_space_( + tiling_->current_visible_rect_in_content_space_), + skewport_in_content_space_(tiling_->current_skewport_), + eventually_rect_in_content_space_(tiling_->current_eventually_rect_), + tree_(tree), + current_tile_(NULL), + visible_iterator_(&tiling->tiling_data_, visible_rect_in_content_space_), + spiral_iterator_(&tiling->tiling_data_, + skewport_in_content_space_, + visible_rect_in_content_space_, + visible_rect_in_content_space_) { + if (!visible_iterator_) { + AdvancePhase(); + return; + } + + current_tile_ = + tiling_->TileAt(visible_iterator_.index_x(), visible_iterator_.index_y()); + if (!current_tile_ || !TileNeedsRaster(current_tile_)) + ++(*this); +} + +PictureLayerTiling::TilingRasterTileIterator::~TilingRasterTileIterator() {} + +void PictureLayerTiling::TilingRasterTileIterator::AdvancePhase() { + DCHECK_LT(type_, EVENTUALLY); + + do { + type_ = static_cast<Type>(type_ + 1); + if (type_ == EVENTUALLY) { + spiral_iterator_ = TilingData::SpiralDifferenceIterator( + &tiling_->tiling_data_, + eventually_rect_in_content_space_, + skewport_in_content_space_, + visible_rect_in_content_space_); + } + + while (spiral_iterator_) { + current_tile_ = tiling_->TileAt(spiral_iterator_.index_x(), + spiral_iterator_.index_y()); + if (current_tile_ && TileNeedsRaster(current_tile_)) + break; + ++spiral_iterator_; + } + + if (!spiral_iterator_ && type_ == EVENTUALLY) + break; + } while (!spiral_iterator_); +} + +PictureLayerTiling::TilingRasterTileIterator& +PictureLayerTiling::TilingRasterTileIterator:: +operator++() { + current_tile_ = NULL; + while (!current_tile_ || !TileNeedsRaster(current_tile_)) { + std::pair<int, int> next_index; + switch (type_) { + case VISIBLE: + ++visible_iterator_; + if (!visible_iterator_) { + AdvancePhase(); + return *this; + } + next_index = visible_iterator_.index(); + break; + case SKEWPORT: + ++spiral_iterator_; + if (!spiral_iterator_) { + AdvancePhase(); + return *this; + } + next_index = spiral_iterator_.index(); + break; + case EVENTUALLY: + ++spiral_iterator_; + if (!spiral_iterator_) + return *this; + next_index = spiral_iterator_.index(); + break; + } + current_tile_ = tiling_->TileAt(next_index.first, next_index.second); + } + return *this; +} + } // namespace cc diff --git a/cc/resources/picture_layer_tiling.h b/cc/resources/picture_layer_tiling.h index 407a2ad..e79aa00 100644 --- a/cc/resources/picture_layer_tiling.h +++ b/cc/resources/picture_layer_tiling.h @@ -45,6 +45,55 @@ class CC_EXPORT PictureLayerTilingClient { class CC_EXPORT PictureLayerTiling { public: + class CC_EXPORT TilingRasterTileIterator { + public: + enum Type { VISIBLE, SKEWPORT, EVENTUALLY }; + + TilingRasterTileIterator(); + TilingRasterTileIterator(PictureLayerTiling* tiling, WhichTree tree); + ~TilingRasterTileIterator(); + + operator bool() const { + return current_tile_ && TileNeedsRaster(current_tile_); + } + Tile* operator*() { return current_tile_; } + Type get_type() const { return type_; } + + TilingRasterTileIterator& operator++(); + + gfx::Rect TileBounds() const { + DCHECK(*this); + if (type_ == VISIBLE) { + return tiling_->tiling_data_.TileBounds(visible_iterator_.index_x(), + visible_iterator_.index_y()); + } + return tiling_->tiling_data_.TileBounds(spiral_iterator_.index_x(), + spiral_iterator_.index_y()); + } + + private: + void AdvancePhase(); + bool TileNeedsRaster(Tile* tile) const { + RasterMode mode = tile->DetermineRasterModeForTree(tree_); + return tile->NeedsRasterForMode(mode); + }; + + void UpdateCurrentTilePriority(); + + PictureLayerTiling* tiling_; + + Type type_; + gfx::Rect visible_rect_in_content_space_; + gfx::Rect skewport_in_content_space_; + gfx::Rect eventually_rect_in_content_space_; + WhichTree tree_; + + Tile* current_tile_; + bool current_tile_priority_updated_; + TilingData::Iterator visible_iterator_; + TilingData::SpiralDifferenceIterator spiral_iterator_; + }; + ~PictureLayerTiling(); // Create a tiling with no tiles. CreateTiles must be called to add some. @@ -69,6 +118,11 @@ class CC_EXPORT PictureLayerTiling { gfx::Size tile_size() const { return tiling_data_.max_texture_size(); } float contents_scale() const { return contents_scale_; } + Tile* TileAt(int i, int j) const { + TileMap::const_iterator iter = tiles_.find(TileMapKey(i, j)); + return (iter == tiles_.end()) ? NULL : iter->second.get(); + } + void CreateAllTilesForTesting() { SetLiveTilesRect(gfx::Rect(tiling_data_.total_size())); } @@ -81,8 +135,6 @@ class CC_EXPORT PictureLayerTiling { return all_tiles; } - Tile* TileAt(int i, int j) const; - // Iterate over all tiles to fill content_rect. Even if tiles are invalid // (i.e. no valid resource) this tiling should still iterate over them. // The union of all geometry_rect calls for each element iterated over should @@ -183,6 +235,8 @@ class CC_EXPORT PictureLayerTiling { } protected: + friend class TilingRasterTileIterator; + typedef std::pair<int, int> TileMapKey; typedef base::hash_map<TileMapKey, scoped_refptr<Tile> > TileMap; @@ -190,7 +244,7 @@ class CC_EXPORT PictureLayerTiling { const gfx::Size& layer_bounds, PictureLayerTilingClient* client); void SetLiveTilesRect(const gfx::Rect& live_tiles_rect); - void CreateTile(int i, int j, const PictureLayerTiling* twin_tiling); + Tile* CreateTile(int i, int j, const PictureLayerTiling* twin_tiling); // Computes a skewport. The calculation extrapolates the last visible // rect and the current visible rect to expand the skewport to where it @@ -213,7 +267,11 @@ class CC_EXPORT PictureLayerTiling { // State saved for computing velocities based upon finite differences. double last_impl_frame_time_in_seconds_; - gfx::RectF last_visible_rect_in_content_space_; + gfx::Rect last_visible_rect_in_content_space_; + + gfx::Rect current_visible_rect_in_content_space_; + gfx::Rect current_skewport_; + gfx::Rect current_eventually_rect_; friend class CoverageIterator; diff --git a/cc/resources/picture_layer_tiling_perftest.cc b/cc/resources/picture_layer_tiling_perftest.cc index 9253ce5..0e015b1 100644 --- a/cc/resources/picture_layer_tiling_perftest.cc +++ b/cc/resources/picture_layer_tiling_perftest.cc @@ -67,7 +67,6 @@ class PictureLayerTilingPerfTest : public testing::Test { start_time_ = base::TimeTicks(); num_runs_ = 0; - gfx::Size layer_bounds(50 * 256, 50 * 256); gfx::Rect viewport_rect(0, 0, 1024, 768); do { picture_layer_tiling_->UpdateTilePriorities( @@ -87,7 +86,6 @@ class PictureLayerTilingPerfTest : public testing::Test { start_time_ = base::TimeTicks(); num_runs_ = 0; - gfx::Size layer_bounds(50 * 256, 50 * 256); gfx::Size viewport_size(1024, 768); gfx::Rect viewport_rect(viewport_size); int xoffsets[] = {10, 0, -10, 0}; @@ -118,6 +116,35 @@ class PictureLayerTilingPerfTest : public testing::Test { true); } + void RunTilingRasterTileIteratorTest(const std::string& test_name, + int num_tiles, + const gfx::Rect& viewport) { + start_time_ = base::TimeTicks(); + num_runs_ = 0; + + gfx::Size bounds(10000, 10000); + picture_layer_tiling_ = + PictureLayerTiling::Create(1, bounds, &picture_layer_tiling_client_); + picture_layer_tiling_->UpdateTilePriorities( + ACTIVE_TREE, viewport, 1.0f, 1.0); + do { + int count = num_tiles; + for (PictureLayerTiling::TilingRasterTileIterator it( + picture_layer_tiling_.get(), ACTIVE_TREE); + it && count; + ++it) { + --count; + } + } while (DidRun()); + + perf_test::PrintResult("tiling_raster_tile_iterator", + "", + test_name, + num_runs_ / elapsed_.InSecondsF(), + "runs/s", + true); + } + private: FakePictureLayerTilingClient picture_layer_tiling_client_; scoped_ptr<PictureLayerTiling> picture_layer_tiling_; @@ -158,6 +185,13 @@ TEST_F(PictureLayerTilingPerfTest, UpdateTilePriorities) { RunUpdateTilePrioritiesScrollingTest("perspective", transform); } +TEST_F(PictureLayerTilingPerfTest, TilingRasterTileIterator) { + RunTilingRasterTileIteratorTest("32_100x100", 32, gfx::Rect(0, 0, 100, 100)); + RunTilingRasterTileIteratorTest("32_500x500", 32, gfx::Rect(0, 0, 500, 500)); + RunTilingRasterTileIteratorTest("64_100x100", 64, gfx::Rect(0, 0, 100, 100)); + RunTilingRasterTileIteratorTest("64_500x500", 64, gfx::Rect(0, 0, 500, 500)); +} + } // namespace } // namespace cc diff --git a/cc/resources/picture_layer_tiling_unittest.cc b/cc/resources/picture_layer_tiling_unittest.cc index 5fe1acd..837f647 100644 --- a/cc/resources/picture_layer_tiling_unittest.cc +++ b/cc/resources/picture_layer_tiling_unittest.cc @@ -5,10 +5,14 @@ #include "cc/resources/picture_layer_tiling.h" #include <limits> +#include <set> #include "cc/base/math_util.h" #include "cc/resources/picture_layer_tiling_set.h" +#include "cc/test/fake_output_surface.h" +#include "cc/test/fake_output_surface_client.h" #include "cc/test/fake_picture_layer_tiling_client.h" +#include "cc/test/test_context_provider.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/rect_conversions.h" #include "ui/gfx/size_conversions.h" @@ -492,16 +496,22 @@ TEST(PictureLayerTilingTest, ViewportDistanceWithScale) { TilePriority priority = tile->priority(ACTIVE_TREE); if (viewport_in_content_space.Intersects(tile->content_rect())) { - EXPECT_EQ(TilePriority::NOW, priority.priority_bin); - EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible); + EXPECT_EQ(TilePriority::NOW, priority.priority_bin) << "i: " << i + << " j: " << j; + EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible) << "i: " << i + << " j: " << j; have_now = true; } else if (skewport.Intersects(tile->content_rect())) { - EXPECT_EQ(TilePriority::SOON, priority.priority_bin); - EXPECT_GT(priority.distance_to_visible, 0.f); + EXPECT_EQ(TilePriority::SOON, priority.priority_bin) << "i: " << i + << " j: " << j; + EXPECT_GT(priority.distance_to_visible, 0.f) << "i: " << i + << " j: " << j; have_soon = true; } else { - EXPECT_EQ(TilePriority::EVENTUALLY, priority.priority_bin); - EXPECT_GT(priority.distance_to_visible, 0.f); + EXPECT_EQ(TilePriority::EVENTUALLY, priority.priority_bin) + << "i: " << i << " j: " << j; + EXPECT_GT(priority.distance_to_visible, 0.f) << "i: " << i + << " j: " << j; have_eventually = true; } } @@ -751,6 +761,164 @@ TEST(PictureLayerTilingTest, EmptyStartingRect) { EXPECT_TRUE(out.IsEmpty()); } +TEST(PictureLayerTilingTest, TilingRasterTileIteratorStaticViewport) { + FakePictureLayerTilingClient client; + scoped_ptr<TestablePictureLayerTiling> tiling; + + gfx::Rect viewport(50, 50, 100, 100); + gfx::Size layer_bounds(200, 200); + + client.SetTileSize(gfx::Size(30, 30)); + + tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client); + tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 1.0); + + PictureLayerTiling::TilingRasterTileIterator empty_iterator; + EXPECT_FALSE(empty_iterator); + + std::vector<Tile*> all_tiles = tiling->AllTilesForTesting(); + + // Sanity check. + EXPECT_EQ(64u, all_tiles.size()); + + // The explanation of each iteration is as follows: + // 1. First iteration tests that we can get all of the tiles correctly. + // 2. Second iteration ensures that we can get all of the tiles again (first + // iteration didn't change any tiles), as well set all tiles to be ready to + // draw. + // 3. Third iteration ensures that no tiles are returned, since they were all + // marked as ready to draw. + for (int i = 0; i < 3; ++i) { + PictureLayerTiling::TilingRasterTileIterator it(tiling.get(), ACTIVE_TREE); + + // There are 3 bins in TilePriority. + bool have_tiles[3] = {}; + + // On the third iteration, we should get no tiles since everything was + // marked as ready to draw. + if (i == 2) { + EXPECT_FALSE(it); + continue; + } + + EXPECT_TRUE(it); + std::set<Tile*> unique_tiles; + unique_tiles.insert(*it); + Tile* last_tile = *it; + have_tiles[last_tile->priority(ACTIVE_TREE).priority_bin] = true; + + // On the second iteration, mark everything as ready to draw (solid color). + if (i == 1) { + ManagedTileState::TileVersion& tile_version = + last_tile->GetTileVersionForTesting( + last_tile->DetermineRasterModeForTree(ACTIVE_TREE)); + tile_version.SetSolidColorForTesting(SK_ColorRED); + } + ++it; + int eventually_bin_order_correct_count = 0; + int eventually_bin_order_incorrect_count = 0; + while (it) { + Tile* new_tile = *it; + ++it; + unique_tiles.insert(new_tile); + + TilePriority last_priority = last_tile->priority(ACTIVE_TREE); + TilePriority new_priority = new_tile->priority(ACTIVE_TREE); + EXPECT_LE(last_priority.priority_bin, new_priority.priority_bin); + if (last_priority.priority_bin == new_priority.priority_bin) { + if (last_priority.priority_bin == TilePriority::EVENTUALLY) { + bool order_correct = last_priority.distance_to_visible <= + new_priority.distance_to_visible; + eventually_bin_order_correct_count += order_correct; + eventually_bin_order_incorrect_count += !order_correct; + } else { + EXPECT_LE(last_priority.distance_to_visible, + new_priority.distance_to_visible); + } + } + have_tiles[new_priority.priority_bin] = true; + + last_tile = new_tile; + + // On the second iteration, mark everything as ready to draw (solid + // color). + if (i == 1) { + ManagedTileState::TileVersion& tile_version = + last_tile->GetTileVersionForTesting( + last_tile->DetermineRasterModeForTree(ACTIVE_TREE)); + tile_version.SetSolidColorForTesting(SK_ColorRED); + } + } + + EXPECT_GT(eventually_bin_order_correct_count, + eventually_bin_order_incorrect_count); + + // We should have now and eventually tiles, but not soon tiles because the + // viewport is static. + EXPECT_TRUE(have_tiles[TilePriority::NOW]); + EXPECT_FALSE(have_tiles[TilePriority::SOON]); + EXPECT_TRUE(have_tiles[TilePriority::EVENTUALLY]); + + EXPECT_EQ(unique_tiles.size(), all_tiles.size()); + } +} + +TEST(PictureLayerTilingTest, TilingRasterTileIteratorMovingViewport) { + FakePictureLayerTilingClient client; + scoped_ptr<TestablePictureLayerTiling> tiling; + + gfx::Rect viewport(50, 0, 100, 100); + gfx::Rect moved_viewport(50, 0, 100, 250); + gfx::Size layer_bounds(500, 500); + + client.SetTileSize(gfx::Size(30, 30)); + + tiling = TestablePictureLayerTiling::Create(1.f, layer_bounds, &client); + tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 1.0); + tiling->UpdateTilePriorities(ACTIVE_TREE, moved_viewport, 1.0f, 2.0); + + // There are 3 bins in TilePriority. + bool have_tiles[3] = {}; + Tile* last_tile = NULL; + int eventually_bin_order_correct_count = 0; + int eventually_bin_order_incorrect_count = 0; + for (PictureLayerTiling::TilingRasterTileIterator it(tiling.get(), + ACTIVE_TREE); + it; + ++it) { + if (!last_tile) + last_tile = *it; + + Tile* new_tile = *it; + + TilePriority last_priority = last_tile->priority(ACTIVE_TREE); + TilePriority new_priority = new_tile->priority(ACTIVE_TREE); + + have_tiles[new_priority.priority_bin] = true; + + EXPECT_LE(last_priority.priority_bin, new_priority.priority_bin); + if (last_priority.priority_bin == new_priority.priority_bin) { + if (last_priority.priority_bin == TilePriority::EVENTUALLY) { + bool order_correct = last_priority.distance_to_visible <= + new_priority.distance_to_visible; + eventually_bin_order_correct_count += order_correct; + eventually_bin_order_incorrect_count += !order_correct; + } else { + EXPECT_LE(last_priority.distance_to_visible, + new_priority.distance_to_visible); + } + } + last_tile = new_tile; + } + + EXPECT_GT(eventually_bin_order_correct_count, + eventually_bin_order_incorrect_count); + + EXPECT_TRUE(have_tiles[TilePriority::NOW]); + EXPECT_TRUE(have_tiles[TilePriority::SOON]); + EXPECT_TRUE(have_tiles[TilePriority::EVENTUALLY]); +} + static void TileExists(bool exists, Tile* tile, const gfx::Rect& geometry_rect) { EXPECT_EQ(exists, tile != NULL) << geometry_rect.ToString(); diff --git a/cc/resources/tile.cc b/cc/resources/tile.cc index 7b1f00a..65a1738 100644 --- a/cc/resources/tile.cc +++ b/cc/resources/tile.cc @@ -4,6 +4,8 @@ #include "cc/resources/tile.h" +#include <algorithm> + #include "cc/base/math_util.h" #include "cc/debug/traced_value.h" #include "cc/resources/tile_manager.h" @@ -81,4 +83,27 @@ size_t Tile::GPUMemoryUsageInBytes() const { return total_size; } +RasterMode Tile::DetermineRasterModeForTree(WhichTree tree) const { + return DetermineRasterModeForResolution(priority(tree).resolution); +} + +RasterMode Tile::DetermineOverallRasterMode() const { + return DetermineRasterModeForResolution(managed_state_.resolution); +} + +RasterMode Tile::DetermineRasterModeForResolution( + TileResolution resolution) const { + RasterMode current_mode = managed_state_.raster_mode; + RasterMode raster_mode = HIGH_QUALITY_RASTER_MODE; + if (resolution == LOW_RESOLUTION) + raster_mode = LOW_QUALITY_RASTER_MODE; + else if (can_use_lcd_text()) + raster_mode = HIGH_QUALITY_RASTER_MODE; + else if (managed_state_.tile_versions[current_mode].has_text_ || + !managed_state_.tile_versions[current_mode].IsReadyToDraw()) + raster_mode = HIGH_QUALITY_NO_LCD_RASTER_MODE; + + return std::min(raster_mode, current_mode); +} + } // namespace cc diff --git a/cc/resources/tile.h b/cc/resources/tile.h index c0ed843..138cad5 100644 --- a/cc/resources/tile.h +++ b/cc/resources/tile.h @@ -79,6 +79,18 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> { return !!(flags_ & USE_GPU_RASTERIZATION); } + bool NeedsRasterForMode(RasterMode mode) const { + return !managed_state_.tile_versions[mode].IsReadyToDraw(); + } + + bool HasResources() const { + for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { + if (managed_state_.tile_versions[mode].has_resource()) + return true; + } + return false; + } + scoped_ptr<base::Value> AsValue() const; inline bool IsReadyToDraw() const { @@ -116,6 +128,12 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> { size_t GPUMemoryUsageInBytes() const; + gfx::Size size() const { return tile_size_.size(); } + + RasterMode DetermineRasterModeForTree(WhichTree tree) const; + RasterMode DetermineOverallRasterMode() const; + + // Functionality used in tests. RasterMode GetRasterModeForTesting() const { return managed_state().raster_mode; } @@ -123,8 +141,6 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> { return managed_state_.tile_versions[mode]; } - gfx::Size size() const { return tile_size_.size(); } - private: friend class TileManager; friend class PrioritizedTileSet; @@ -146,6 +162,7 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> { ManagedTileState& managed_state() { return managed_state_; } const ManagedTileState& managed_state() const { return managed_state_; } + RasterMode DetermineRasterModeForResolution(TileResolution resolution) const; TileManager* tile_manager_; scoped_refptr<PicturePileImpl> picture_pile_; diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc index cc2a5ab..8a47fc4 100644 --- a/cc/resources/tile_manager.cc +++ b/cc/resources/tile_manager.cc @@ -595,25 +595,6 @@ scoped_ptr<base::Value> TileManager::GetMemoryRequirementsAsValue() const { return requirements.PassAs<base::Value>(); } -RasterMode TileManager::DetermineRasterMode(const Tile* tile) const { - DCHECK(tile); - DCHECK(tile->picture_pile()); - - const ManagedTileState& mts = tile->managed_state(); - RasterMode current_mode = mts.raster_mode; - - RasterMode raster_mode = HIGH_QUALITY_RASTER_MODE; - if (tile->managed_state().resolution == LOW_RESOLUTION) - raster_mode = LOW_QUALITY_RASTER_MODE; - else if (tile->can_use_lcd_text()) - raster_mode = HIGH_QUALITY_RASTER_MODE; - else if (mts.tile_versions[current_mode].has_text_ || - !mts.tile_versions[current_mode].IsReadyToDraw()) - raster_mode = HIGH_QUALITY_NO_LCD_RASTER_MODE; - - return std::min(raster_mode, current_mode); -} - void TileManager::AssignGpuMemoryToTiles( PrioritizedTileSet* tiles, TileVector* tiles_that_need_to_be_rasterized) { @@ -673,7 +654,7 @@ void TileManager::AssignGpuMemoryToTiles( mts.scheduled_priority = schedule_priority++; - mts.raster_mode = DetermineRasterMode(tile); + mts.raster_mode = tile->DetermineOverallRasterMode(); ManagedTileState::TileVersion& tile_version = mts.tile_versions[mts.raster_mode]; diff --git a/cc/resources/tile_manager.h b/cc/resources/tile_manager.h index d691d035..dc6e777 100644 --- a/cc/resources/tile_manager.h +++ b/cc/resources/tile_manager.h @@ -174,7 +174,6 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient, raster_worker_pool_->GetResourceFormat()); } - RasterMode DetermineRasterMode(const Tile* tile) const; void FreeResourceForTile(Tile* tile, RasterMode mode); void FreeResourcesForTile(Tile* tile); void FreeUnusedResourcesForTile(Tile* tile); |