summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorvmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-14 06:30:57 +0000
committervmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-14 06:30:57 +0000
commit82791e0818dfa575391a3ea87686704055913501 (patch)
treecff0f39e923326e6020ff1fdaed99c1f6cd7f5a2 /cc
parent508107c3c78d84fd479dd614bb377d5fb078d783 (diff)
downloadchromium_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.cc7
-rw-r--r--cc/base/tiling_data.h2
-rw-r--r--cc/resources/managed_tile_state.h5
-rw-r--r--cc/resources/picture_layer_tiling.cc127
-rw-r--r--cc/resources/picture_layer_tiling.h66
-rw-r--r--cc/resources/picture_layer_tiling_perftest.cc38
-rw-r--r--cc/resources/picture_layer_tiling_unittest.cc180
-rw-r--r--cc/resources/tile.cc25
-rw-r--r--cc/resources/tile.h21
-rw-r--r--cc/resources/tile_manager.cc21
-rw-r--r--cc/resources/tile_manager.h1
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);