Commit 55e6e906 authored by jbedley@chromium.org's avatar jbedley@chromium.org

Consider occluded tiles during eviction with occluded as Tile property.

This modifies the eviction order to consider occlusion so that the
LayerEvictionTileIterator and TileManager::EvictionTileIterator will
evict occluded tiles before unoccluded tiles in the same priority bin.

The current eviction order is to evict tiles that are:
1. In a lower priority bin
2. Not required for activation
3. At worse resolution
4. Farther away from visible

This patch adds occlusion to the order to evict tiles that are:
1. In a lower priority bin
2. Not required for activation
3. At worse resolution
4. Occluded
5. Farther away from visible

This patch depends on https://codereview.chromium.org/374653003/ which
tracks occlusion per tree and stores the info on the Tile.

BUG=178971

Review URL: https://codereview.chromium.org/377793003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@283842 0039d316-1c4b-4281-b951-d872f2087c98
parent 3e26d8e2
...@@ -2924,6 +2924,54 @@ class OcclusionTrackingPictureLayerImplTest : public PictureLayerImplTest { ...@@ -2924,6 +2924,54 @@ class OcclusionTrackingPictureLayerImplTest : public PictureLayerImplTest {
public: public:
OcclusionTrackingPictureLayerImplTest() OcclusionTrackingPictureLayerImplTest()
: PictureLayerImplTest(OcclusionTrackingSettings()) {} : PictureLayerImplTest(OcclusionTrackingSettings()) {}
void VerifyEvictionConsidersOcclusion(
PictureLayerImpl* layer,
size_t expected_occluded_tile_count[NUM_TREE_PRIORITIES]) {
for (int priority_count = 0; priority_count < NUM_TREE_PRIORITIES;
++priority_count) {
TreePriority tree_priority = static_cast<TreePriority>(priority_count);
size_t occluded_tile_count = 0u;
Tile* last_tile = NULL;
for (PictureLayerImpl::LayerEvictionTileIterator it =
PictureLayerImpl::LayerEvictionTileIterator(layer,
tree_priority);
it;
++it) {
Tile* tile = *it;
if (!last_tile)
last_tile = tile;
// The only way we will encounter an occluded tile after an unoccluded
// tile is if the priorty bin decreased, the tile is required for
// activation, or the scale changed.
bool tile_is_occluded =
tile->is_occluded_for_tree_priority(tree_priority);
if (tile_is_occluded) {
occluded_tile_count++;
bool last_tile_is_occluded =
last_tile->is_occluded_for_tree_priority(tree_priority);
if (!last_tile_is_occluded) {
TilePriority::PriorityBin tile_priority_bin =
tile->priority_for_tree_priority(tree_priority).priority_bin;
TilePriority::PriorityBin last_tile_priority_bin =
last_tile->priority_for_tree_priority(tree_priority)
.priority_bin;
EXPECT_TRUE(
(tile_priority_bin < last_tile_priority_bin) ||
tile->required_for_activation() ||
(tile->contents_scale() != last_tile->contents_scale()));
}
}
last_tile = tile;
}
EXPECT_EQ(expected_occluded_tile_count[priority_count],
occluded_tile_count);
}
}
}; };
#if defined(OS_WIN) #if defined(OS_WIN)
...@@ -3319,5 +3367,158 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) { ...@@ -3319,5 +3367,158 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) {
} }
} }
} }
TEST_F(OcclusionTrackingPictureLayerImplTest,
OccludedTilesConsideredDuringEviction) {
gfx::Size tile_size(102, 102);
gfx::Size layer_bounds(1000, 1000);
gfx::Size viewport_size(500, 500);
gfx::Point pending_occluding_layer_position(310, 0);
gfx::Point active_occluding_layer_position(0, 310);
gfx::Rect invalidation_rect(230, 230, 102, 102);
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
scoped_refptr<FakePicturePileImpl> active_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
SetupTrees(pending_pile, active_pile);
pending_layer_->set_fixed_tile_size(tile_size);
active_layer_->set_fixed_tile_size(tile_size);
float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
std::vector<PictureLayerTiling*> tilings;
tilings.push_back(pending_layer_->AddTiling(low_res_factor));
tilings.push_back(pending_layer_->AddTiling(0.3f));
tilings.push_back(pending_layer_->AddTiling(0.7f));
tilings.push_back(pending_layer_->AddTiling(1.0f));
tilings.push_back(pending_layer_->AddTiling(2.0f));
EXPECT_EQ(5u, pending_layer_->num_tilings());
EXPECT_EQ(5u, active_layer_->num_tilings());
// Partially occlude the pending layer.
pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 1));
LayerImpl* pending_occluding_layer = pending_layer_->children()[0];
pending_occluding_layer->SetBounds(layer_bounds);
pending_occluding_layer->SetContentBounds(layer_bounds);
pending_occluding_layer->SetDrawsContent(true);
pending_occluding_layer->SetContentsOpaque(true);
pending_occluding_layer->SetPosition(pending_occluding_layer_position);
// Partially occlude the active layer.
active_layer_->AddChild(LayerImpl::Create(host_impl_.active_tree(), 2));
LayerImpl* active_occluding_layer = active_layer_->children()[0];
active_occluding_layer->SetBounds(layer_bounds);
active_occluding_layer->SetContentBounds(layer_bounds);
active_occluding_layer->SetDrawsContent(true);
active_occluding_layer->SetContentsOpaque(true);
active_occluding_layer->SetPosition(active_occluding_layer_position);
// Partially invalidate the pending layer. Tiles inside the invalidation rect
// are not shared between trees.
pending_layer_->set_invalidation(invalidation_rect);
host_impl_.SetViewportSize(viewport_size);
host_impl_.active_tree()->UpdateDrawProperties();
host_impl_.pending_tree()->UpdateDrawProperties();
// The expected number of occluded tiles on each of the 5 tilings for each of
// the 3 tree priorities.
size_t expected_occluded_tile_count_on_both[] = {9u, 1u, 1u, 1u, 1u};
size_t expected_occluded_tile_count_on_active[] = {30u, 5u, 4u, 2u, 2u};
size_t expected_occluded_tile_count_on_pending[] = {30u, 5u, 4u, 2u, 2u};
// The total expected number of occluded tiles on all tilings for each of the
// 3 tree priorities.
size_t total_expected_occluded_tile_count[] = {13u, 43u, 43u};
ASSERT_EQ(arraysize(total_expected_occluded_tile_count), NUM_TREE_PRIORITIES);
// Verify number of occluded tiles on the pending layer for each tiling.
for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) {
PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i);
tiling->CreateAllTilesForTesting();
size_t occluded_tile_count_on_pending = 0u;
size_t occluded_tile_count_on_active = 0u;
size_t occluded_tile_count_on_both = 0u;
for (PictureLayerTiling::CoverageIterator iter(
tiling,
pending_layer_->contents_scale_x(),
gfx::Rect(layer_bounds));
iter;
++iter) {
Tile* tile = *iter;
if (tile->is_occluded(PENDING_TREE))
occluded_tile_count_on_pending++;
if (tile->is_occluded(ACTIVE_TREE))
occluded_tile_count_on_active++;
if (tile->is_occluded(PENDING_TREE) && tile->is_occluded(ACTIVE_TREE))
occluded_tile_count_on_both++;
}
EXPECT_EQ(expected_occluded_tile_count_on_pending[i],
occluded_tile_count_on_pending)
<< i;
EXPECT_EQ(expected_occluded_tile_count_on_active[i],
occluded_tile_count_on_active)
<< i;
EXPECT_EQ(expected_occluded_tile_count_on_both[i],
occluded_tile_count_on_both)
<< i;
}
// Verify number of occluded tiles on the active layer for each tiling.
for (size_t i = 0; i < active_layer_->num_tilings(); ++i) {
PictureLayerTiling* tiling = active_layer_->tilings()->tiling_at(i);
tiling->CreateAllTilesForTesting();
size_t occluded_tile_count_on_pending = 0u;
size_t occluded_tile_count_on_active = 0u;
size_t occluded_tile_count_on_both = 0u;
for (PictureLayerTiling::CoverageIterator iter(
tiling,
pending_layer_->contents_scale_x(),
gfx::Rect(layer_bounds));
iter;
++iter) {
Tile* tile = *iter;
if (tile->is_occluded(PENDING_TREE))
occluded_tile_count_on_pending++;
if (tile->is_occluded(ACTIVE_TREE))
occluded_tile_count_on_active++;
if (tile->is_occluded(PENDING_TREE) && tile->is_occluded(ACTIVE_TREE))
occluded_tile_count_on_both++;
}
EXPECT_EQ(expected_occluded_tile_count_on_pending[i],
occluded_tile_count_on_pending)
<< i;
EXPECT_EQ(expected_occluded_tile_count_on_active[i],
occluded_tile_count_on_active)
<< i;
EXPECT_EQ(expected_occluded_tile_count_on_both[i],
occluded_tile_count_on_both)
<< i;
}
std::vector<Tile*> all_tiles;
for (std::vector<PictureLayerTiling*>::iterator tiling_iterator =
tilings.begin();
tiling_iterator != tilings.end();
++tiling_iterator) {
std::vector<Tile*> tiles = (*tiling_iterator)->AllTilesForTesting();
std::copy(tiles.begin(), tiles.end(), std::back_inserter(all_tiles));
}
host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(all_tiles);
VerifyEvictionConsidersOcclusion(pending_layer_,
total_expected_occluded_tile_count);
VerifyEvictionConsidersOcclusion(active_layer_,
total_expected_occluded_tile_count);
}
} // namespace } // namespace
} // namespace cc } // namespace cc
...@@ -35,11 +35,23 @@ class TileEvictionOrder { ...@@ -35,11 +35,23 @@ class TileEvictionOrder {
const TilePriority& b_priority = const TilePriority& b_priority =
b->priority_for_tree_priority(tree_priority_); b->priority_for_tree_priority(tree_priority_);
if (a_priority.priority_bin == b_priority.priority_bin && // Evict a before b if their priority bins differ and a has the higher
a->required_for_activation() != b->required_for_activation()) { // priority bin.
if (a_priority.priority_bin != b_priority.priority_bin)
return a_priority.priority_bin > b_priority.priority_bin;
// Or if a is not required and b is required.
if (a->required_for_activation() != b->required_for_activation())
return b->required_for_activation(); return b->required_for_activation();
}
return b_priority.IsHigherPriorityThan(a_priority); // Or if a is occluded and b is unoccluded.
bool a_is_occluded = a->is_occluded_for_tree_priority(tree_priority_);
bool b_is_occluded = b->is_occluded_for_tree_priority(tree_priority_);
if (a_is_occluded != b_is_occluded)
return a_is_occluded;
// Or if a is farther away from visible.
return a_priority.distance_to_visible > b_priority.distance_to_visible;
} }
private: private:
......
...@@ -48,9 +48,10 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> { ...@@ -48,9 +48,10 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> {
return priority_[PENDING_TREE]; return priority_[PENDING_TREE];
case SAME_PRIORITY_FOR_BOTH_TREES: case SAME_PRIORITY_FOR_BOTH_TREES:
return combined_priority(); return combined_priority();
default:
NOTREACHED();
return TilePriority();
} }
NOTREACHED();
return TilePriority();
} }
TilePriority combined_priority() const { TilePriority combined_priority() const {
...@@ -60,6 +61,26 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> { ...@@ -60,6 +61,26 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> {
void SetPriority(WhichTree tree, const TilePriority& priority); void SetPriority(WhichTree tree, const TilePriority& priority);
void set_is_occluded(WhichTree tree, bool is_occluded) {
is_occluded_[tree] = is_occluded;
}
bool is_occluded(WhichTree tree) const { return is_occluded_[tree]; }
bool is_occluded_for_tree_priority(TreePriority tree_priority) const {
switch (tree_priority) {
case SMOOTHNESS_TAKES_PRIORITY:
return is_occluded_[ACTIVE_TREE];
case NEW_CONTENT_TAKES_PRIORITY:
return is_occluded_[PENDING_TREE];
case SAME_PRIORITY_FOR_BOTH_TREES:
return is_occluded_[ACTIVE_TREE] && is_occluded_[PENDING_TREE];
default:
NOTREACHED();
return false;
}
}
void MarkRequiredForActivation(); void MarkRequiredForActivation();
bool required_for_activation() const { bool required_for_activation() const {
...@@ -130,12 +151,6 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> { ...@@ -130,12 +151,6 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> {
return managed_state_.tile_versions[mode]; return managed_state_.tile_versions[mode];
} }
void set_is_occluded(WhichTree tree, bool is_occluded) {
is_occluded_[tree] = is_occluded;
}
bool is_occluded(WhichTree tree) const { return is_occluded_[tree]; }
private: private:
friend class TileManager; friend class TileManager;
friend class PrioritizedTileSet; friend class PrioritizedTileSet;
......
...@@ -596,6 +596,8 @@ void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) { ...@@ -596,6 +596,8 @@ void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) {
mts.bin = tree_bin[PENDING_TREE]; mts.bin = tree_bin[PENDING_TREE];
tile_priority = pending_priority; tile_priority = pending_priority;
break; break;
default:
NOTREACHED();
} }
// Bump up the priority if we determined it's NEVER_BIN on one tree, // Bump up the priority if we determined it's NEVER_BIN on one tree,
...@@ -1317,6 +1319,8 @@ TileManager::RasterTileIterator::PairedPictureLayerIterator::NextTileIterator( ...@@ -1317,6 +1319,8 @@ TileManager::RasterTileIterator::PairedPictureLayerIterator::NextTileIterator(
return std::make_pair(&active_iterator, ACTIVE_TREE); return std::make_pair(&active_iterator, ACTIVE_TREE);
return std::make_pair(&pending_iterator, PENDING_TREE); return std::make_pair(&pending_iterator, PENDING_TREE);
} }
default:
NOTREACHED();
} }
NOTREACHED(); NOTREACHED();
...@@ -1534,12 +1538,16 @@ bool TileManager::EvictionTileIterator::EvictionOrderComparator::operator()( ...@@ -1534,12 +1538,16 @@ bool TileManager::EvictionTileIterator::EvictionOrderComparator::operator()(
// Now we have to return true iff b is lower priority than a. // Now we have to return true iff b is lower priority than a.
// If the bin is the same but the resolution is not, then the order will be // If the priority bin differs, b is lower priority if it has the higher
// determined by whether we prioritize low res or not. // priority bin.
if (a_priority.priority_bin != b_priority.priority_bin)
return b_priority.priority_bin > a_priority.priority_bin;
// Otherwise if the resolution differs, then the order will be determined by
// whether we prioritize low res or not.
// TODO(vmpstr): Remove this when TilePriority is no longer a member of Tile // TODO(vmpstr): Remove this when TilePriority is no longer a member of Tile
// class but instead produced by the iterators. // class but instead produced by the iterators.
if (b_priority.priority_bin == a_priority.priority_bin && if (b_priority.resolution != a_priority.resolution) {
b_priority.resolution != a_priority.resolution) {
// Non ideal resolution should be sorted higher than other resolutions. // Non ideal resolution should be sorted higher than other resolutions.
if (a_priority.resolution == NON_IDEAL_RESOLUTION) if (a_priority.resolution == NON_IDEAL_RESOLUTION)
return false; return false;
...@@ -1552,7 +1560,15 @@ bool TileManager::EvictionTileIterator::EvictionOrderComparator::operator()( ...@@ -1552,7 +1560,15 @@ bool TileManager::EvictionTileIterator::EvictionOrderComparator::operator()(
return a_priority.resolution == HIGH_RESOLUTION; return a_priority.resolution == HIGH_RESOLUTION;
} }
return a_priority.IsHigherPriorityThan(b_priority);
// Otherwise if the occlusion differs, b is lower priority if it is occluded.
bool a_is_occluded = a_tile->is_occluded_for_tree_priority(tree_priority_);
bool b_is_occluded = b_tile->is_occluded_for_tree_priority(tree_priority_);
if (a_is_occluded != b_is_occluded)
return b_is_occluded;
// b is lower priorty if it is farther from visible.
return b_priority.distance_to_visible > a_priority.distance_to_visible;
} }
void TileManager::SetRasterizerForTesting(Rasterizer* rasterizer) { void TileManager::SetRasterizerForTesting(Rasterizer* rasterizer) {
......
...@@ -959,5 +959,150 @@ TEST_F(TileManagerTileIteratorTest, EvictionTileIterator) { ...@@ -959,5 +959,150 @@ TEST_F(TileManagerTileIteratorTest, EvictionTileIterator) {
EXPECT_EQ(tile_count, new_content_tiles.size()); EXPECT_EQ(tile_count, new_content_tiles.size());
EXPECT_EQ(all_tiles, new_content_tiles); EXPECT_EQ(all_tiles, new_content_tiles);
} }
TEST_F(TileManagerTileIteratorTest, EvictionTileIteratorWithOcclusion) {
gfx::Size tile_size(102, 102);
gfx::Size layer_bounds(1000, 1000);
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
SetupPendingTree(pending_pile);
pending_layer_->CreateDefaultTilingsAndTiles();
scoped_ptr<FakePictureLayerImpl> pending_child =
FakePictureLayerImpl::CreateWithPile(
host_impl_.pending_tree(), 2, pending_pile);
pending_layer_->AddChild(pending_child.PassAs<LayerImpl>());
FakePictureLayerImpl* pending_child_layer =
static_cast<FakePictureLayerImpl*>(pending_layer_->children()[0]);
pending_child_layer->SetDrawsContent(true);
pending_child_layer->DoPostCommitInitializationIfNeeded();
pending_child_layer->CreateDefaultTilingsAndTiles();
TileManager* tile_manager = TileManagerTileIteratorTest::tile_manager();
EXPECT_TRUE(tile_manager);
std::vector<TileManager::PairedPictureLayer> paired_layers;
tile_manager->GetPairedPictureLayers(&paired_layers);
EXPECT_EQ(2u, paired_layers.size());
std::set<Tile*> all_tiles;
size_t tile_count = 0;
for (TileManager::RasterTileIterator raster_it(tile_manager,
NEW_CONTENT_TAKES_PRIORITY);
raster_it;
++raster_it) {
++tile_count;
EXPECT_TRUE(*raster_it);
all_tiles.insert(*raster_it);
}
EXPECT_EQ(tile_count, all_tiles.size());
EXPECT_EQ(34u, tile_count);
pending_layer_->ResetAllTilesPriorities();
// Renew all of the tile priorities.
gfx::Rect viewport(layer_bounds);
pending_layer_->HighResTiling()->UpdateTilePriorities(
PENDING_TREE,
viewport,
1.0f,
1.0,
NULL,
pending_layer_->render_target(),
pending_layer_->draw_transform());
pending_layer_->LowResTiling()->UpdateTilePriorities(
PENDING_TREE,
viewport,
1.0f,
1.0,
NULL,
pending_layer_->render_target(),
pending_layer_->draw_transform());
pending_child_layer->HighResTiling()->UpdateTilePriorities(
PENDING_TREE,
viewport,
1.0f,
1.0,
NULL,
pending_child_layer->render_target(),
pending_child_layer->draw_transform());
pending_child_layer->LowResTiling()->UpdateTilePriorities(
PENDING_TREE,
viewport,
1.0f,
1.0,
NULL,
pending_child_layer->render_target(),
pending_child_layer->draw_transform());
// Populate all tiles directly from the tilings.
all_tiles.clear();
std::vector<Tile*> pending_high_res_tiles =
pending_layer_->HighResTiling()->AllTilesForTesting();
for (size_t i = 0; i < pending_high_res_tiles.size(); ++i)
all_tiles.insert(pending_high_res_tiles[i]);
std::vector<Tile*> pending_low_res_tiles =
pending_layer_->LowResTiling()->AllTilesForTesting();
for (size_t i = 0; i < pending_low_res_tiles.size(); ++i)
all_tiles.insert(pending_low_res_tiles[i]);
// Set all tiles on the pending_child_layer as occluded on the pending tree.
std::vector<Tile*> pending_child_high_res_tiles =
pending_child_layer->HighResTiling()->AllTilesForTesting();
for (size_t i = 0; i < pending_child_high_res_tiles.size(); ++i) {
pending_child_high_res_tiles[i]->set_is_occluded(PENDING_TREE, true);
all_tiles.insert(pending_child_high_res_tiles[i]);
}
std::vector<Tile*> pending_child_low_res_tiles =
pending_child_layer->LowResTiling()->AllTilesForTesting();
for (size_t i = 0; i < pending_child_low_res_tiles.size(); ++i) {
pending_child_low_res_tiles[i]->set_is_occluded(PENDING_TREE, true);
all_tiles.insert(pending_child_low_res_tiles[i]);
}
tile_manager->InitializeTilesWithResourcesForTesting(
std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
// Verify occlusion is considered by EvictionTileIterator.
TreePriority tree_priority = NEW_CONTENT_TAKES_PRIORITY;
size_t occluded_count = 0u;
Tile* last_tile = NULL;
for (TileManager::EvictionTileIterator it(tile_manager, tree_priority); it;
++it) {
Tile* tile = *it;
if (!last_tile)
last_tile = tile;
bool tile_is_occluded = tile->is_occluded_for_tree_priority(tree_priority);
// The only way we will encounter an occluded tile after an unoccluded
// tile is if the priorty bin decreased, the tile is required for
// activation, or the scale changed.
if (tile_is_occluded) {
occluded_count++;
bool last_tile_is_occluded =
last_tile->is_occluded_for_tree_priority(tree_priority);
if (!last_tile_is_occluded) {
TilePriority::PriorityBin tile_priority_bin =
tile->priority_for_tree_priority(tree_priority).priority_bin;
TilePriority::PriorityBin last_tile_priority_bin =
last_tile->priority_for_tree_priority(tree_priority).priority_bin;
EXPECT_TRUE((tile_priority_bin < last_tile_priority_bin) ||
tile->required_for_activation() ||
(tile->contents_scale() != last_tile->contents_scale()));
}
}
last_tile = tile;
}
size_t expected_occluded_count =
pending_child_high_res_tiles.size() + pending_child_low_res_tiles.size();
EXPECT_EQ(expected_occluded_count, occluded_count);
}
} // namespace } // namespace
} // namespace cc } // namespace cc
...@@ -94,10 +94,10 @@ scoped_ptr<base::Value> TreePriorityAsValue(TreePriority prio) { ...@@ -94,10 +94,10 @@ scoped_ptr<base::Value> TreePriorityAsValue(TreePriority prio) {
case NEW_CONTENT_TAKES_PRIORITY: case NEW_CONTENT_TAKES_PRIORITY:
return scoped_ptr<base::Value>(new base::StringValue( return scoped_ptr<base::Value>(new base::StringValue(
"NEW_CONTENT_TAKES_PRIORITY")); "NEW_CONTENT_TAKES_PRIORITY"));
default:
DCHECK(false) << "Unrecognized priority value " << prio;
return scoped_ptr<base::Value>(new base::StringValue("<unknown>"));
} }
DCHECK(false) << "Unrecognized priority value " << prio;
return scoped_ptr<base::Value>(new base::StringValue(
"<unknown>"));
} }
scoped_ptr<base::Value> GlobalStateThatImpactsTilePriority::AsValue() const { scoped_ptr<base::Value> GlobalStateThatImpactsTilePriority::AsValue() const {
......
...@@ -134,8 +134,8 @@ scoped_ptr<base::Value> TileMemoryLimitPolicyAsValue( ...@@ -134,8 +134,8 @@ scoped_ptr<base::Value> TileMemoryLimitPolicyAsValue(
enum TreePriority { enum TreePriority {
SAME_PRIORITY_FOR_BOTH_TREES, SAME_PRIORITY_FOR_BOTH_TREES,
SMOOTHNESS_TAKES_PRIORITY, SMOOTHNESS_TAKES_PRIORITY,
NEW_CONTENT_TAKES_PRIORITY NEW_CONTENT_TAKES_PRIORITY,
NUM_TREE_PRIORITIES
// Be sure to update TreePriorityAsValue when adding new fields. // Be sure to update TreePriorityAsValue when adding new fields.
}; };
scoped_ptr<base::Value> TreePriorityAsValue(TreePriority prio); scoped_ptr<base::Value> TreePriorityAsValue(TreePriority prio);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment