Skip to content

Commit

Permalink
cc: Fix impl-side painting flashing due to missing tiles
Browse files Browse the repository at this point in the history
There was a bug where flashing could occur if a non-updated tiling was
used for activation.  As tiles only get created during
UpdateTilePriorities and null tiles are accepted for activation (under
the premise that there is nothing recorded there and tiles couldn't be
created), this could cause a premature activation and flashing content.

Fix this case by making sure that syncing a tiling always updates that
tiling if the tree is up to date and doesn't need update draw
properties.

Add checks to make sure that all tilings have been updated and the tree
itself is up to date when calling AreVisibleResourcesReady.

R=danakj@chromium.org
BUG=230540

Review URL: https://chromiumcodereview.appspot.com/14883003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@198219 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
enne@chromium.org committed May 3, 2013
1 parent 69da057 commit a283d31
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 2 deletions.
8 changes: 8 additions & 0 deletions cc/layers/picture_image_layer_impl_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_picture_layer_tiling_client.h"
#include "cc/test/impl_side_painting_settings.h"
#include "cc/trees/layer_tree_impl.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cc {
Expand Down Expand Up @@ -41,6 +42,10 @@ class PictureImageLayerImplTest : public testing::Test {
return make_scoped_ptr(layer);
}

void UpdateDrawProperties() {
host_impl_.pending_tree()->UpdateDrawProperties();
}

private:
FakeImplProxy proxy_;
FakeLayerTreeHostImpl host_impl_;
Expand All @@ -67,12 +72,15 @@ TEST_F(PictureImageLayerImplTest, AreVisibleResourcesReady) {
layer->SetBounds(gfx::Size(100, 200));
layer->SetDrawsContent(true);

UpdateDrawProperties();

float contents_scale_x;
float contents_scale_y;
gfx::Size content_bounds;
layer->CalculateContentsScale(2.f, false,
&contents_scale_x, &contents_scale_y,
&content_bounds);
layer->UpdateTilePriorities();

EXPECT_TRUE(layer->AreVisibleResourcesReady());
}
Expand Down
9 changes: 9 additions & 0 deletions cc/layers/picture_layer_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,13 @@ void PictureLayerImpl::SyncTiling(
if (!DrawsContent() || tiling->contents_scale() < MinimumContentsScale())
return;
tilings_->AddTiling(tiling->contents_scale());

// If this tree needs update draw properties, then the tiling will
// get updated prior to drawing or activation. If this tree does not
// need update draw properties, then its transforms are up to date and
// we can create tiles for this tiling immediately.
if (!layer_tree_impl()->needs_update_draw_properties())
UpdateTilePriorities();
}

void PictureLayerImpl::SetIsMask(bool is_mask) {
Expand Down Expand Up @@ -555,6 +562,7 @@ ResourceProvider::ResourceId PictureLayerImpl::ContentsResourceId() const {

bool PictureLayerImpl::AreVisibleResourcesReady() const {
DCHECK(layer_tree_impl()->IsPendingTree());
DCHECK(!layer_tree_impl()->needs_update_draw_properties());
DCHECK(ideal_contents_scale_);

if (!tilings_->num_tilings())
Expand Down Expand Up @@ -586,6 +594,7 @@ bool PictureLayerImpl::AreVisibleResourcesReady() const {
Region missing_region = rect;
for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
PictureLayerTiling* tiling = tilings_->tiling_at(i);
DCHECK(tiling->has_ever_been_updated());

if (tiling->contents_scale() < min_acceptable_scale)
continue;
Expand Down
9 changes: 7 additions & 2 deletions cc/resources/picture_layer_tiling.cc
Original file line number Diff line number Diff line change
Expand Up @@ -288,10 +288,15 @@ void PictureLayerTiling::UpdateTilePriorities(
double current_frame_time_in_seconds,
bool store_screen_space_quads_on_tiles,
size_t max_tiles_for_interest_area) {
if (ContentRect().IsEmpty())
if (!NeedsUpdateForFrameAtTime(current_frame_time_in_seconds)) {
// This should never be zero for the purposes of has_ever_been_updated().
DCHECK_NE(current_frame_time_in_seconds, 0.0);
return;
if (!NeedsUpdateForFrameAtTime(current_frame_time_in_seconds))
}
if (ContentRect().IsEmpty()) {
last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
return;
}

gfx::Rect viewport_in_content_space =
gfx::ToEnclosingRect(gfx::ScaleRect(viewport_in_layer_space,
Expand Down
4 changes: 4 additions & 0 deletions cc/resources/picture_layer_tiling.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ class CC_EXPORT PictureLayerTiling {
int64 target_area,
gfx::Rect bounding_rect);

bool has_ever_been_updated() const {
return last_impl_frame_time_in_seconds_ != 0.0;
}

protected:
typedef std::pair<int, int> TileMapKey;
typedef base::hash_map<TileMapKey, scoped_refptr<Tile> > TileMap;
Expand Down

0 comments on commit a283d31

Please sign in to comment.