summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-20 22:23:22 +0000
committervmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-20 22:23:22 +0000
commit10f1b3a61e6a5cb41ea442c4922eb896622d35d9 (patch)
tree19a0b0e643d1b2276eec106e0c3e5d07d6c2a3a5
parenta5f6ce57a82c294c66ea1afc90dac65e6afe8e42 (diff)
downloadchromium_src-10f1b3a61e6a5cb41ea442c4922eb896622d35d9.zip
chromium_src-10f1b3a61e6a5cb41ea442c4922eb896622d35d9.tar.gz
chromium_src-10f1b3a61e6a5cb41ea442c4922eb896622d35d9.tar.bz2
cc: Add layer raster tile iterator
This patch continues to build on top of tiling raster tile iterators and introduces a layer raster tile iterator that uses the tiling one. Comes with a unittest and a perftest. The next step after this should be a raster iterator in the tile manager R=enne@chromium.org Review URL: https://codereview.chromium.org/195583002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@258437 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/cc_tests.gyp1
-rw-r--r--cc/layers/picture_layer_impl.cc104
-rw-r--r--cc/layers/picture_layer_impl.h30
-rw-r--r--cc/layers/picture_layer_impl_perftest.cc132
-rw-r--r--cc/layers/picture_layer_impl_unittest.cc94
-rw-r--r--cc/resources/picture_layer_tiling.h3
6 files changed, 361 insertions, 3 deletions
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp
index ed55846..73e4a06 100644
--- a/cc/cc_tests.gyp
+++ b/cc/cc_tests.gyp
@@ -300,6 +300,7 @@
],
'sources': [
'layers/layer_perftest.cc',
+ 'layers/picture_layer_impl_perftest.cc',
'resources/picture_layer_tiling_perftest.cc',
'resources/raster_worker_pool_perftest.cc',
'resources/task_graph_runner_perftest.cc',
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index a0fd950..c85e0c5 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -1273,4 +1273,108 @@ bool PictureLayerImpl::IsOnActiveOrPendingTree() const {
return !layer_tree_impl()->IsRecycleTree();
}
+PictureLayerImpl::LayerRasterTileIterator::LayerRasterTileIterator()
+ : layer_(NULL) {}
+
+PictureLayerImpl::LayerRasterTileIterator::LayerRasterTileIterator(
+ PictureLayerImpl* layer,
+ bool prioritize_low_res)
+ : layer_(layer), current_stage_(0) {
+ DCHECK(layer_);
+ if (!layer_->tilings_ || !layer_->tilings_->num_tilings())
+ return;
+
+ WhichTree tree =
+ layer_->layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE;
+
+ // Find high and low res tilings and initialize the iterators.
+ for (size_t i = 0; i < layer_->tilings_->num_tilings(); ++i) {
+ PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i);
+ if (tiling->resolution() == HIGH_RESOLUTION) {
+ iterators_[HIGH_RES] =
+ PictureLayerTiling::TilingRasterTileIterator(tiling, tree);
+ }
+
+ if (tiling->resolution() == LOW_RESOLUTION) {
+ iterators_[LOW_RES] =
+ PictureLayerTiling::TilingRasterTileIterator(tiling, tree);
+ }
+ }
+
+ if (prioritize_low_res) {
+ stages_[0].iterator_type = LOW_RES;
+ stages_[0].tile_type =
+ PictureLayerTiling::TilingRasterTileIterator::VISIBLE;
+
+ stages_[1].iterator_type = HIGH_RES;
+ stages_[1].tile_type =
+ PictureLayerTiling::TilingRasterTileIterator::VISIBLE;
+ } else {
+ stages_[0].iterator_type = HIGH_RES;
+ stages_[0].tile_type =
+ PictureLayerTiling::TilingRasterTileIterator::VISIBLE;
+
+ stages_[1].iterator_type = LOW_RES;
+ stages_[1].tile_type =
+ PictureLayerTiling::TilingRasterTileIterator::VISIBLE;
+ }
+
+ stages_[2].iterator_type = HIGH_RES;
+ stages_[2].tile_type = PictureLayerTiling::TilingRasterTileIterator::SKEWPORT;
+
+ stages_[3].iterator_type = HIGH_RES;
+ stages_[3].tile_type =
+ PictureLayerTiling::TilingRasterTileIterator::EVENTUALLY;
+
+ IteratorType index = stages_[current_stage_].iterator_type;
+ PictureLayerTiling::TilingRasterTileIterator::Type tile_type =
+ stages_[current_stage_].tile_type;
+ if (!iterators_[index] || iterators_[index].get_type() != tile_type)
+ ++(*this);
+}
+
+PictureLayerImpl::LayerRasterTileIterator::~LayerRasterTileIterator() {}
+
+PictureLayerImpl::LayerRasterTileIterator::operator bool() const {
+ return layer_ && static_cast<size_t>(current_stage_) < arraysize(stages_);
+}
+
+PictureLayerImpl::LayerRasterTileIterator&
+PictureLayerImpl::LayerRasterTileIterator::
+operator++() {
+ IteratorType index = stages_[current_stage_].iterator_type;
+ PictureLayerTiling::TilingRasterTileIterator::Type tile_type =
+ stages_[current_stage_].tile_type;
+
+ // First advance the iterator.
+ if (iterators_[index])
+ ++iterators_[index];
+
+ if (iterators_[index] && iterators_[index].get_type() == tile_type)
+ return *this;
+
+ // Next, advance the stage.
+ int stage_count = arraysize(stages_);
+ ++current_stage_;
+ while (current_stage_ < stage_count) {
+ index = stages_[current_stage_].iterator_type;
+ tile_type = stages_[current_stage_].tile_type;
+
+ if (iterators_[index] && iterators_[index].get_type() == tile_type)
+ break;
+ ++current_stage_;
+ }
+ return *this;
+}
+
+Tile* PictureLayerImpl::LayerRasterTileIterator::operator*() {
+ DCHECK(*this);
+
+ IteratorType index = stages_[current_stage_].iterator_type;
+ DCHECK(iterators_[index]);
+ DCHECK(iterators_[index].get_type() == stages_[current_stage_].tile_type);
+
+ return *iterators_[index];
+}
+
} // namespace cc
diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h
index 00c2066..4b997fa 100644
--- a/cc/layers/picture_layer_impl.h
+++ b/cc/layers/picture_layer_impl.h
@@ -22,11 +22,39 @@ namespace cc {
struct AppendQuadsData;
class QuadSink;
class MicroBenchmarkImpl;
+class Tile;
class CC_EXPORT PictureLayerImpl
: public LayerImpl,
NON_EXPORTED_BASE(public PictureLayerTilingClient) {
public:
+ class CC_EXPORT LayerRasterTileIterator {
+ public:
+ LayerRasterTileIterator();
+ LayerRasterTileIterator(PictureLayerImpl* layer, bool prioritize_low_res);
+ ~LayerRasterTileIterator();
+
+ Tile* operator*();
+ LayerRasterTileIterator& operator++();
+ operator bool() const;
+
+ private:
+ enum IteratorType { LOW_RES, HIGH_RES, NUM_ITERATORS };
+
+ PictureLayerImpl* layer_;
+
+ struct IterationStage {
+ IteratorType iterator_type;
+ PictureLayerTiling::TilingRasterTileIterator::Type tile_type;
+ };
+
+ int current_stage_;
+
+ // One low res stage, and three high res stages.
+ IterationStage stages_[4];
+ PictureLayerTiling::TilingRasterTileIterator iterators_[NUM_ITERATORS];
+ };
+
static scoped_ptr<PictureLayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
return make_scoped_ptr(new PictureLayerImpl(tree_impl, id));
}
@@ -87,6 +115,8 @@ class CC_EXPORT PictureLayerImpl
bool IsOnActiveOrPendingTree() const;
protected:
+ friend class LayerRasterTileIterator;
+
PictureLayerImpl(LayerTreeImpl* tree_impl, int id);
PictureLayerTiling* AddTiling(float contents_scale);
void RemoveTiling(float contents_scale);
diff --git a/cc/layers/picture_layer_impl_perftest.cc b/cc/layers/picture_layer_impl_perftest.cc
new file mode 100644
index 0000000..5279c92
--- /dev/null
+++ b/cc/layers/picture_layer_impl_perftest.cc
@@ -0,0 +1,132 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/layers/picture_layer_impl.h"
+
+#include "cc/test/fake_impl_proxy.h"
+#include "cc/test/fake_layer_tree_host_impl.h"
+#include "cc/test/fake_output_surface.h"
+#include "cc/test/fake_picture_layer_impl.h"
+#include "cc/test/fake_picture_pile_impl.h"
+#include "cc/test/impl_side_painting_settings.h"
+#include "cc/test/test_shared_bitmap_manager.h"
+#include "cc/trees/layer_tree_impl.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/perf/perf_test.h"
+
+namespace cc {
+namespace {
+
+static const int kTimeLimitMillis = 2000;
+static const int kWarmupRuns = 5;
+static const int kTimeCheckInterval = 10;
+
+class PictureLayerImplPerfTest : public testing::Test {
+ public:
+ PictureLayerImplPerfTest()
+ : num_runs_(0),
+ proxy_(base::MessageLoopProxy::current()),
+ host_impl_(ImplSidePaintingSettings(),
+ &proxy_,
+ &shared_bitmap_manager_) {}
+
+ virtual void SetUp() OVERRIDE {
+ host_impl_.InitializeRenderer(
+ FakeOutputSurface::Create3d().PassAs<OutputSurface>());
+ }
+
+ void SetupPendingTree(const gfx::Size& layer_bounds,
+ const gfx::Size& tile_size) {
+ scoped_refptr<FakePicturePileImpl> pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ host_impl_.CreatePendingTree();
+ LayerTreeImpl* pending_tree = host_impl_.pending_tree();
+ pending_tree->DetachLayerTree();
+
+ scoped_ptr<FakePictureLayerImpl> pending_layer =
+ FakePictureLayerImpl::CreateWithPile(pending_tree, 7, pile);
+ pending_layer->SetDrawsContent(true);
+ pending_tree->SetRootLayer(pending_layer.PassAs<LayerImpl>());
+
+ pending_layer_ = static_cast<FakePictureLayerImpl*>(
+ host_impl_.pending_tree()->LayerById(7));
+ pending_layer_->DoPostCommitInitializationIfNeeded();
+ }
+
+ void EndTest() { elapsed_ = base::TimeTicks::HighResNow() - start_time_; }
+
+ bool DidRun() {
+ ++num_runs_;
+ if (num_runs_ == kWarmupRuns)
+ start_time_ = base::TimeTicks::HighResNow();
+
+ if (!start_time_.is_null() && (num_runs_ % kTimeCheckInterval) == 0) {
+ base::TimeDelta elapsed = base::TimeTicks::HighResNow() - start_time_;
+ if (elapsed >= base::TimeDelta::FromMilliseconds(kTimeLimitMillis)) {
+ elapsed_ = elapsed;
+ return false;
+ }
+ }
+ return true;
+ }
+
+ void RunLayerRasterTileIteratorTest(const std::string& test_name,
+ int num_tiles,
+ const gfx::Size& viewport_size) {
+ start_time_ = base::TimeTicks();
+ num_runs_ = 0;
+
+ host_impl_.SetViewportSize(viewport_size);
+ host_impl_.pending_tree()->UpdateDrawProperties();
+
+ do {
+ int count = num_tiles;
+ for (PictureLayerImpl::LayerRasterTileIterator it(pending_layer_, false);
+ it && count;
+ ++it) {
+ --count;
+ }
+ } while (DidRun());
+
+ perf_test::PrintResult("layer_raster_tile_iterator",
+ "",
+ test_name,
+ num_runs_ / elapsed_.InSecondsF(),
+ "runs/s",
+ true);
+ }
+
+ protected:
+ base::TimeTicks start_time_;
+ base::TimeDelta elapsed_;
+ int num_runs_;
+
+ TestSharedBitmapManager shared_bitmap_manager_;
+ FakeImplProxy proxy_;
+ FakeLayerTreeHostImpl host_impl_;
+ FakePictureLayerImpl* pending_layer_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PictureLayerImplPerfTest);
+};
+
+TEST_F(PictureLayerImplPerfTest, LayerRasterTileIterator) {
+ SetupPendingTree(gfx::Size(10000, 10000), gfx::Size(256, 256));
+
+ float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
+
+ pending_layer_->AddTiling(low_res_factor);
+ pending_layer_->AddTiling(0.3f);
+ pending_layer_->AddTiling(0.7f);
+ pending_layer_->AddTiling(1.0f);
+ pending_layer_->AddTiling(2.0f);
+
+ RunLayerRasterTileIteratorTest("32_100x100", 32, gfx::Size(100, 100));
+ RunLayerRasterTileIteratorTest("32_500x500", 32, gfx::Size(500, 500));
+ RunLayerRasterTileIteratorTest("64_100x100", 64, gfx::Size(100, 100));
+ RunLayerRasterTileIteratorTest("64_500x500", 64, gfx::Size(500, 500));
+}
+
+} // namespace
+} // namespace cc
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index 1fa309b..c606be4 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -4,6 +4,7 @@
#include "cc/layers/picture_layer_impl.h"
+#include <set>
#include <utility>
#include "cc/layers/append_quads_data.h"
@@ -1690,5 +1691,98 @@ TEST_F(GpuRasterizationPictureLayerImplTest, Tiling) {
ASSERT_EQ(1u, pending_layer_->tilings()->num_tilings());
}
+TEST_F(PictureLayerImplTest, LayerRasterTileIterator) {
+ gfx::Size tile_size(100, 100);
+ gfx::Size layer_bounds(1000, 1000);
+
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+
+ SetupPendingTree(pending_pile);
+
+ ASSERT_TRUE(pending_layer_->CanHaveTilings());
+
+ float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
+
+ pending_layer_->AddTiling(low_res_factor);
+ pending_layer_->AddTiling(0.3f);
+ pending_layer_->AddTiling(0.7f);
+ PictureLayerTiling* high_res_tiling = pending_layer_->AddTiling(1.0f);
+ pending_layer_->AddTiling(2.0f);
+
+ host_impl_.SetViewportSize(gfx::Size(500, 500));
+ host_impl_.pending_tree()->UpdateDrawProperties();
+
+ PictureLayerImpl::LayerRasterTileIterator it;
+ EXPECT_FALSE(it);
+
+ std::set<Tile*> unique_tiles;
+ bool reached_prepaint = false;
+ size_t non_ideal_tile_count = 0u;
+ size_t low_res_tile_count = 0u;
+ size_t high_res_tile_count = 0u;
+ for (it = PictureLayerImpl::LayerRasterTileIterator(pending_layer_, false);
+ it;
+ ++it) {
+ Tile* tile = *it;
+ TilePriority priority = tile->priority(PENDING_TREE);
+
+ EXPECT_TRUE(tile);
+
+ // Non-high res tiles only get visible tiles. Also, prepaint should only
+ // come at the end of the iteration.
+ if (priority.resolution != HIGH_RESOLUTION)
+ EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
+ else if (reached_prepaint)
+ EXPECT_NE(TilePriority::NOW, priority.priority_bin);
+ else
+ reached_prepaint = priority.priority_bin != TilePriority::NOW;
+
+ non_ideal_tile_count += priority.resolution == NON_IDEAL_RESOLUTION;
+ low_res_tile_count += priority.resolution == LOW_RESOLUTION;
+ high_res_tile_count += priority.resolution == HIGH_RESOLUTION;
+
+ unique_tiles.insert(tile);
+ }
+
+ EXPECT_TRUE(reached_prepaint);
+ EXPECT_EQ(0u, non_ideal_tile_count);
+ EXPECT_EQ(1u, low_res_tile_count);
+ EXPECT_EQ(16u, high_res_tile_count);
+ EXPECT_EQ(low_res_tile_count + high_res_tile_count + non_ideal_tile_count,
+ unique_tiles.size());
+
+ std::vector<Tile*> high_res_tiles = high_res_tiling->AllTilesForTesting();
+ for (std::vector<Tile*>::iterator tile_it = high_res_tiles.begin();
+ tile_it != high_res_tiles.end();
+ ++tile_it) {
+ Tile* tile = *tile_it;
+ ManagedTileState::TileVersion& tile_version =
+ tile->GetTileVersionForTesting(
+ tile->DetermineRasterModeForTree(ACTIVE_TREE));
+ tile_version.SetSolidColorForTesting(SK_ColorRED);
+ }
+
+ non_ideal_tile_count = 0;
+ low_res_tile_count = 0;
+ high_res_tile_count = 0;
+ for (it = PictureLayerImpl::LayerRasterTileIterator(pending_layer_, false);
+ it;
+ ++it) {
+ Tile* tile = *it;
+ TilePriority priority = tile->priority(PENDING_TREE);
+
+ EXPECT_TRUE(tile);
+
+ non_ideal_tile_count += priority.resolution == NON_IDEAL_RESOLUTION;
+ low_res_tile_count += priority.resolution == LOW_RESOLUTION;
+ high_res_tile_count += priority.resolution == HIGH_RESOLUTION;
+ }
+
+ EXPECT_EQ(0u, non_ideal_tile_count);
+ EXPECT_EQ(1u, low_res_tile_count);
+ EXPECT_EQ(0u, high_res_tile_count);
+}
+
} // namespace
} // namespace cc
diff --git a/cc/resources/picture_layer_tiling.h b/cc/resources/picture_layer_tiling.h
index e79aa00..d27d39a 100644
--- a/cc/resources/picture_layer_tiling.h
+++ b/cc/resources/picture_layer_tiling.h
@@ -78,8 +78,6 @@ class CC_EXPORT PictureLayerTiling {
return tile->NeedsRasterForMode(mode);
};
- void UpdateCurrentTilePriority();
-
PictureLayerTiling* tiling_;
Type type_;
@@ -89,7 +87,6 @@ class CC_EXPORT PictureLayerTiling {
WhichTree tree_;
Tile* current_tile_;
- bool current_tile_priority_updated_;
TilingData::Iterator visible_iterator_;
TilingData::SpiralDifferenceIterator spiral_iterator_;
};