Commit 80aae3ab authored by vmpstr@chromium.org's avatar vmpstr@chromium.org

cc: Reset raster scale if we didn't sync high res tiling.

When we sync tilings, we always expect to sync the high res
tiling. However, in situations where our minimum contents scale
prevents us from syncing the high res tiling, we should instead
reset the raster contents scale, since those would be invalid
as well. This also ensures that we will create a new high res
tiling when we call ManageTilings.

BUG=374143
R=enne

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@271527 0039d316-1c4b-4281-b951-d872f2087c98
parent 91edf189
......@@ -691,14 +691,25 @@ void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) {
difference_region.Subtract(gfx::Rect(other->bounds()));
invalidation_.Union(difference_region);
bool synced_high_res_tiling = false;
if (CanHaveTilings()) {
tilings_->SyncTilings(
synced_high_res_tiling = tilings_->SyncTilings(
*other->tilings_, bounds(), invalidation_, MinimumContentsScale());
} else {
RemoveAllTilings();
}
SanityCheckTilingState();
// If our MinimumContentsScale has changed to prevent the twin's high res
// tiling from being synced, we should reset the raster scale and let it be
// recalculated (1) again. This can happen if our bounds shrink to the point
// where min contents scale grows.
// (1) - TODO(vmpstr) Instead of hoping that this will be recalculated, we
// should refactor this code a little bit and actually recalculate this.
// However, this is a larger undertaking, so this will work for now.
if (!synced_high_res_tiling)
ResetRasterScale();
else
SanityCheckTilingState();
}
void PictureLayerImpl::SyncTiling(
......
......@@ -1727,6 +1727,60 @@ TEST_F(PictureLayerImplTest, SyncTilingAfterReleaseResource) {
EXPECT_EQ(HIGH_RESOLUTION, high_res->resolution());
}
TEST_F(PictureLayerImplTest, HighResCreatedWhenBoundsShrink) {
SetupDefaultTrees(gfx::Size(10, 10));
host_impl_.active_tree()->UpdateDrawProperties();
EXPECT_FALSE(host_impl_.active_tree()->needs_update_draw_properties());
float result_scale_x;
float result_scale_y;
gfx::Size result_bounds;
active_layer_->CalculateContentsScale(0.5f,
0.5f,
0.5f,
0.5f,
false,
&result_scale_x,
&result_scale_y,
&result_bounds);
active_layer_->tilings()->RemoveAllTilings();
PictureLayerTiling* tiling = active_layer_->tilings()->AddTiling(0.5f);
active_layer_->tilings()->AddTiling(1.5f);
active_layer_->tilings()->AddTiling(0.25f);
tiling->set_resolution(HIGH_RESOLUTION);
// Sanity checks.
ASSERT_EQ(3u, active_layer_->tilings()->num_tilings());
ASSERT_EQ(tiling, active_layer_->tilings()->TilingAtScale(0.5f));
// Now, set the bounds to be 1x1 (so that minimum contents scale becomes
// 1.0f). Note that we should also ensure that the pending layer needs post
// commit initialization, since this is what would happen during commit. In
// other words we want the pending layer to sync from the active layer.
pending_layer_->SetBounds(gfx::Size(1, 1));
pending_layer_->SetNeedsPostCommitInitialization();
pending_layer_->set_twin_layer(NULL);
active_layer_->set_twin_layer(NULL);
EXPECT_TRUE(pending_layer_->needs_post_commit_initialization());
// Update the draw properties: sync from active tree should happen here.
host_impl_.pending_tree()->UpdateDrawProperties();
// Another sanity check.
ASSERT_EQ(1.f, pending_layer_->MinimumContentsScale());
// Now we should've synced 1.5f tiling, since that's the only one that doesn't
// violate minimum contents scale. At the same time, we should've created a
// new high res tiling at scale 1.0f.
EXPECT_EQ(2u, pending_layer_->tilings()->num_tilings());
ASSERT_TRUE(pending_layer_->tilings()->TilingAtScale(1.0f));
EXPECT_EQ(HIGH_RESOLUTION,
pending_layer_->tilings()->TilingAtScale(1.0f)->resolution());
ASSERT_TRUE(pending_layer_->tilings()->TilingAtScale(1.5f));
EXPECT_EQ(NON_IDEAL_RESOLUTION,
pending_layer_->tilings()->TilingAtScale(1.5f)->resolution());
}
TEST_F(PictureLayerImplTest, NoLowResTilingWithGpuRasterization) {
gfx::Size default_tile_size(host_impl_.settings().default_tile_size);
gfx::Size layer_bounds(default_tile_size.width() * 4,
......
......@@ -36,15 +36,14 @@ void PictureLayerTilingSet::SetClient(PictureLayerTilingClient* client) {
tilings_[i]->SetClient(client_);
}
void PictureLayerTilingSet::SyncTilings(
const PictureLayerTilingSet& other,
const gfx::Size& new_layer_bounds,
const Region& layer_invalidation,
float minimum_contents_scale) {
bool PictureLayerTilingSet::SyncTilings(const PictureLayerTilingSet& other,
const gfx::Size& new_layer_bounds,
const Region& layer_invalidation,
float minimum_contents_scale) {
if (new_layer_bounds.IsEmpty()) {
RemoveAllTilings();
layer_bounds_ = new_layer_bounds;
return;
return false;
}
tilings_.reserve(other.tilings_.size());
......@@ -60,6 +59,8 @@ void PictureLayerTilingSet::SyncTilings(
--i;
}
bool have_high_res_tiling = false;
// Add any missing tilings from |other| that meet the minimum.
for (size_t i = 0; i < other.tilings_.size(); ++i) {
float contents_scale = other.tilings_[i]->contents_scale();
......@@ -75,6 +76,8 @@ void PictureLayerTilingSet::SyncTilings(
this_tiling->UpdateTilesToCurrentPile();
this_tiling->CreateMissingTilesInLiveTilesRect();
if (this_tiling->resolution() == HIGH_RESOLUTION)
have_high_res_tiling = true;
DCHECK(this_tiling->tile_size() ==
client_->CalculateTileSize(this_tiling->TilingRect().size()));
......@@ -85,11 +88,14 @@ void PictureLayerTilingSet::SyncTilings(
new_layer_bounds,
client_);
new_tiling->set_resolution(other.tilings_[i]->resolution());
if (new_tiling->resolution() == HIGH_RESOLUTION)
have_high_res_tiling = true;
tilings_.push_back(new_tiling.Pass());
}
tilings_.sort(LargestToSmallestScaleFunctor());
layer_bounds_ = new_layer_bounds;
return have_high_res_tiling;
}
void PictureLayerTilingSet::RemoveTilesInRegion(const Region& region) {
......
......@@ -25,11 +25,11 @@ class CC_EXPORT PictureLayerTilingSet {
// Delete any tilings that don't meet |minimum_contents_scale|. Recreate
// any tiles that intersect |layer_invalidation|. Update the size of all
// tilings to |new_layer_bounds|.
void SyncTilings(
const PictureLayerTilingSet& other,
const gfx::Size& new_layer_bounds,
const Region& layer_invalidation,
float minimum_contents_scale);
// Returns true if we had at least one high res tiling synced.
bool SyncTilings(const PictureLayerTilingSet& other,
const gfx::Size& new_layer_bounds,
const Region& layer_invalidation,
float minimum_contents_scale);
void RemoveTilesInRegion(const Region& region);
......
......@@ -48,6 +48,10 @@ class FakePictureLayerImpl : public PictureLayerImpl {
using PictureLayerImpl::MinimumContentsScale;
using PictureLayerImpl::SanityCheckTilingState;
void SetNeedsPostCommitInitialization() {
needs_post_commit_initialization_ = true;
}
bool needs_post_commit_initialization() const {
return needs_post_commit_initialization_;
}
......
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