Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
cc: Activate when going invisible.
Browse files Browse the repository at this point in the history
This patch ensures that we always activate when we become invisible.
The reason being is that when we come back to being visible again,
we don't need to rasterize both active and pending trees. We can
just rasterize what used to be the pending tree.

Since we set RequiresHighResToDraw on becoming visible, this also
ensures that we don't checkerboard on becoming visible.

BUG=410000, 417598
TBR=danakj, enne, brianderson

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

Cr-Commit-Position: refs/heads/master@{#297303}
(cherry picked from commit 6b968c0)

Conflicts:
	cc/trees/layer_tree_host_unittest.cc

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

Cr-Commit-Position: refs/branch-heads/2171@{#191}
Cr-Branched-From: 267aeeb-refs/heads/master@{#297060}
  • Loading branch information
vmpstr committed Oct 20, 2014
1 parent c1bc792 commit 618342b
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 49 deletions.
19 changes: 12 additions & 7 deletions cc/scheduler/scheduler_state_machine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -282,23 +282,28 @@ bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const {
return true;

// Additional states where we should abort draws.
// Note: We don't force activation in these cases because doing so would
// result in checkerboarding on resize, becoming visible, etc.
if (!can_draw_)
return true;
if (!visible_)
return true;
return false;
}

bool SchedulerStateMachine::PendingActivationsShouldBeForced() const {
// These are all the cases where, if we do not force activations to make
// forward progress, we might deadlock with the main thread.

// There is no output surface to trigger our activations.
// If we do not force activations to make forward progress, we might deadlock
// with the main thread.
if (output_surface_state_ == OUTPUT_SURFACE_LOST)
return true;

// If we're not visible, we should force activation.
// Since we set RequiresHighResToDraw when becoming visible, we ensure that we
// don't checkerboard until all visible resources are done. Furthermore, if we
// do keep the pending tree around, when becoming visible we might activate
// prematurely causing RequiresHighResToDraw flag to be reset. In all cases,
// we can simply activate on becoming invisible since we don't need to draw
// the active tree when we're in this state.
if (!visible_)
return true;

return false;
}

Expand Down
34 changes: 34 additions & 0 deletions cc/scheduler/scheduler_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1909,5 +1909,39 @@ TEST(SchedulerTest,
EXPECT_FALSE(scheduler->IsSyntheticBeginFrameSourceActive());
}

TEST(SchedulerTest, ScheduledActionActivateAfterBecomingInvisible) {
FakeSchedulerClient client;
SchedulerSettings scheduler_settings;
scheduler_settings.impl_side_painting = true;
TestScheduler* scheduler = client.CreateScheduler(scheduler_settings);
scheduler->SetCanStart();
scheduler->SetVisible(true);
scheduler->SetCanDraw(true);

EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
InitializeOutputSurfaceAndFirstCommit(scheduler, &client);

// SetNeedsCommit should begin the frame.
client.Reset();
scheduler->SetNeedsCommit();
EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);

client.Reset();
client.AdvanceFrame();
EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());

client.Reset();
scheduler->NotifyBeginMainFrameStarted();
scheduler->NotifyReadyToCommit();
EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);

client.Reset();
scheduler->SetVisible(false);
// Sync tree should be forced to activate.
EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client);
}

} // namespace
} // namespace cc
56 changes: 14 additions & 42 deletions cc/trees/layer_tree_host_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5028,88 +5028,60 @@ class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {

MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting);

class LayerTreeHostTestInvisibleDoesntActivate : public LayerTreeHostTest {
class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest {
public:
LayerTreeHostTestInvisibleDoesntActivate() : activation_count_(0) {}
LayerTreeHostTestActivateOnInvisible()
: activation_count_(0), visible_(true) {}

virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
settings->impl_side_painting = true;
}

virtual void SetupTree() OVERRIDE {
scoped_refptr<Layer> root_layer = Layer::Create();
root_layer->SetBounds(gfx::Size(1000, 1000));

// Set up a non-solid layer with a bunch of tiles.
client_.set_fill_with_nonsolid_color(true);
picture_layer_ = FakePictureLayer::Create(&client_);
picture_layer_->SetBounds(gfx::Size(1000, 1000));
picture_layer_->SetIsDrawable(true);
picture_layer_->SetNeedsDisplayRect(gfx::Rect(1000, 1000));
root_layer->AddChild(picture_layer_.get());

layer_tree_host()->SetRootLayer(root_layer);
LayerTreeHostTest::SetupTree();
}

virtual void BeginTest() OVERRIDE {
// Kick off the test with a commit.
PostSetNeedsCommitToMainThread();
}

virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
// Make sure we don't activate before going invisible.
// Make sure we don't activate using the notify signal from tile manager.
host_impl->BlockNotifyReadyToActivateForTesting(true);
}

virtual void DidCommit() OVERRIDE { layer_tree_host()->SetVisible(false); }

virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
bool visible) OVERRIDE {
visible_ = visible;

// Once invisible, we can go visible again.
if (!visible) {
// Allow activation from now on.
host_impl->BlockNotifyReadyToActivateForTesting(false);
PostSetVisibleToMainThread(true);
} else {
EXPECT_TRUE(host_impl->active_tree()->RequiresHighResToDraw());
EndTest();
}
}

virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
++activation_count_;
std::vector<Tile*> tiles = host_impl->tile_manager()->AllTilesForTesting();
EXPECT_GT(tiles.size(), 0u);
// When activating, ensure that all tiles are ready to draw with a mode
// other than rasterize on demand.
int resource_tiles_count = 0;
for (std::vector<Tile*>::iterator it = tiles.begin(); it != tiles.end();
++it) {
Tile* tile = *it;
const ManagedTileState::TileVersion& tile_version =
tile->GetTileVersionForDrawing();
EXPECT_TRUE(tile_version.IsReadyToDraw());
EXPECT_NE(ManagedTileState::TileVersion::PICTURE_PILE_MODE,
tile_version.mode());
resource_tiles_count +=
tile_version.mode() == ManagedTileState::TileVersion::RESOURCE_MODE;
}
EXPECT_GT(resource_tiles_count, 0);

EndTest();
EXPECT_FALSE(visible_);
}

virtual void AfterTest() OVERRIDE {
// Double check that we activated once.
// Ensure we activated even though the signal was blocked.
EXPECT_EQ(1, activation_count_);
EXPECT_TRUE(visible_);
}

private:
int activation_count_;
bool visible_;

FakeContentLayerClient client_;
scoped_refptr<FakePictureLayer> picture_layer_;
};

// TODO(vmpstr): Enable with single thread impl-side painting.
MULTI_THREAD_TEST_F(LayerTreeHostTestInvisibleDoesntActivate);
MULTI_THREAD_TEST_F(LayerTreeHostTestActivateOnInvisible);

} // namespace cc

0 comments on commit 618342b

Please sign in to comment.