Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3826)

Unified Diff: cc/trees/layer_tree_host_unittest_context.cc

Issue 23503003: cc: Add readback and forced draw states to the Scheduler (Closed) Base URL: http://git.chromium.org/chromium/src.git@schedReorg3
Patch Set: Address enne's commetns Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: cc/trees/layer_tree_host_unittest_context.cc
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc
index c250b0c6bb9154ff79f0f48bfd0b94fdc355c9c2..1674f5647150cd2be6229e60cd014f5d56edde95 100644
--- a/cc/trees/layer_tree_host_unittest_context.cc
+++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -1461,6 +1461,29 @@ class LayerTreeHostContextTestCompositeAndReadbackBeforeOutputSurfaceInit
EXPECT_EQ(1, times_output_surface_created_);
}
+ virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ bool result) OVERRIDE {
+ EXPECT_GE(host_impl->active_tree()->source_frame_number(), 0);
+ EXPECT_LE(host_impl->active_tree()->source_frame_number(), 1);
+ return true;
+ }
+
+ virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ // We should only draw for the readback and the replacement commit.
+ // The replacement commit will also be the first commit after output
+ // surface initialization.
+ EXPECT_GE(host_impl->active_tree()->source_frame_number(), 0);
+ EXPECT_LE(host_impl->active_tree()->source_frame_number(), 1);
+ }
+
+ virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
+ bool result) OVERRIDE {
+ // We should only swap for the replacement commit.
+ EXPECT_EQ(host_impl->active_tree()->source_frame_number(), 1);
+ EndTest();
+ }
+
private:
int times_output_surface_created_;
};
@@ -1468,6 +1491,164 @@ class LayerTreeHostContextTestCompositeAndReadbackBeforeOutputSurfaceInit
SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostContextTestCompositeAndReadbackBeforeOutputSurfaceInit);
+// This test verifies that losing an output surface right during a
+// simultaneous readback and forced redraw works and does not deadlock.
+class LayerTreeHostContextTestLoseOutputSurfaceDuringReadbackAndForcedDraw
+ : public LayerTreeHostContextTest {
+ protected:
+ static const int kCommitAfterFirstOutputSurfaceInitSourceFrameNumber = 0;
+ static const int kReadbackCommitSourceFrameNumber = 1;
+ static const int kReadbackReplacementCommitSourceFrameNumber = 2;
+ static const int kCommitAfterSecondOutputSurfaceInitSourceFrameNumber = 3;
+
+ virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
+ // This enables forced draws after a single prepare to draw failure.
+ settings->timeout_and_draw_when_animation_checkerboards = true;
+ settings->maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
+ }
+
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
+
+ virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ bool result) OVERRIDE {
+ EXPECT_TRUE(host_impl->active_tree()->source_frame_number() ==
+ kCommitAfterFirstOutputSurfaceInitSourceFrameNumber ||
+ host_impl->active_tree()->source_frame_number() ==
+ kCommitAfterSecondOutputSurfaceInitSourceFrameNumber ||
+ host_impl->active_tree()->source_frame_number() ==
+ kReadbackCommitSourceFrameNumber);
+
+ // Before we react to the failed draw by initiating the forced draw
+ // sequence, start a readback on the main thread and then lose the context
+ // to start output surface initialization all at the same time.
+ if (host_impl->active_tree()->source_frame_number() ==
+ kCommitAfterFirstOutputSurfaceInitSourceFrameNumber) {
+ PostReadbackToMainThread();
+ LoseContext();
+ }
+
+ // Returning false will eventually result in a forced draw.
+ return false;
+ }
+
+ virtual void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
+ bool success) OVERRIDE {
+ // -1 is for the first output surface initialization.
+ EXPECT_TRUE(host_impl->active_tree()->source_frame_number() == -1 ||
+ host_impl->active_tree()->source_frame_number() ==
+ kReadbackReplacementCommitSourceFrameNumber);
+ }
+
+ virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ // We should only draw the first commit after output surface initialization
+ // and attempt to draw the readback commit (which will fail).
+ // All others should abort because the output surface is lost.
+ EXPECT_TRUE(host_impl->active_tree()->source_frame_number() ==
+ kCommitAfterSecondOutputSurfaceInitSourceFrameNumber ||
+ host_impl->active_tree()->source_frame_number() ==
+ kReadbackCommitSourceFrameNumber);
+ }
+
+ virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
+ bool result) OVERRIDE {
+ // We should only swap the first commit after the second output surface
+ // initialization.
+ EXPECT_TRUE(host_impl->active_tree()->source_frame_number() ==
+ kCommitAfterSecondOutputSurfaceInitSourceFrameNumber);
+ EndTest();
+ }
+
+ virtual void AfterTest() OVERRIDE {}
+};
+
+MULTI_THREAD_TEST_F(
+ LayerTreeHostContextTestLoseOutputSurfaceDuringReadbackAndForcedDraw);
+
+// This test verifies that losing an output surface right before a
+// simultaneous readback and forced redraw works and does not deadlock.
+class LayerTreeHostContextTestReadbackWithForcedDrawAndOutputSurfaceInit
+ : public LayerTreeHostContextTest {
+ protected:
+ static const int kCommitAfterFirstOutputSurfaceInitSourceFrameNumber = 0;
+ static const int kReadbackCommitSourceFrameNumber = 1;
+ static const int kReadbackReplacementCommitSourceFrameNumber = 2;
+ static const int kForcedDrawCommitSourceFrameNumber = 2;
+ static const int kCommitAfterSecondOutputSurfaceInitSourceFrameNumber = 2;
+
+ virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
+ // This enables forced draws after a single prepare to draw failure.
+ settings->timeout_and_draw_when_animation_checkerboards = true;
+ settings->maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
+ }
+
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
+
+ virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ bool result) OVERRIDE {
+ EXPECT_TRUE(host_impl->active_tree()->source_frame_number() ==
+ kCommitAfterFirstOutputSurfaceInitSourceFrameNumber ||
+ host_impl->active_tree()->source_frame_number() ==
+ kCommitAfterSecondOutputSurfaceInitSourceFrameNumber ||
+ host_impl->active_tree()->source_frame_number() ==
+ kReadbackCommitSourceFrameNumber);
+
+ // Before we react to the failed draw by initiating the forced draw
+ // sequence, start a readback on the main thread and then lose the context
+ // to start output surface initialization all at the same time.
+ if (host_impl->active_tree()->source_frame_number() ==
+ kCommitAfterFirstOutputSurfaceInitSourceFrameNumber) {
+ LoseContext();
+ }
+
+ // Returning false will eventually result in a forced draw.
+ return false;
+ }
+
+ virtual void DidInitializeOutputSurface(bool succeeded) OVERRIDE {
+ EXPECT_TRUE(succeeded);
+ if (layer_tree_host()->source_frame_number() > 0) {
+ // Perform a readback right after the second output surface
+ // initialization.
+ char pixels[4];
+ layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
+ }
+ }
+
+ virtual void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
+ bool success) OVERRIDE {
+ // -1 is for the first output surface initialization.
+ EXPECT_TRUE(host_impl->active_tree()->source_frame_number() == -1 ||
+ host_impl->active_tree()->source_frame_number() ==
+ kCommitAfterFirstOutputSurfaceInitSourceFrameNumber);
+ }
+
+ virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ // We should only draw the first commit after output surface initialization
+ // and attempt to draw the readback commit (which will fail).
+ // All others should abort because the output surface is lost.
+ EXPECT_TRUE(host_impl->active_tree()->source_frame_number() ==
+ kForcedDrawCommitSourceFrameNumber ||
+ host_impl->active_tree()->source_frame_number() ==
+ kReadbackCommitSourceFrameNumber);
+ }
+
+ virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
+ bool result) OVERRIDE {
+ // We should only swap the first commit after the second output surface
+ // initialization.
+ EXPECT_TRUE(host_impl->active_tree()->source_frame_number() ==
+ kForcedDrawCommitSourceFrameNumber);
+ EndTest();
+ }
+
+ virtual void AfterTest() OVERRIDE {}
+};
+
+MULTI_THREAD_TEST_F(
+ LayerTreeHostContextTestReadbackWithForcedDrawAndOutputSurfaceInit);
+
class ImplSidePaintingLayerTreeHostContextTest
: public LayerTreeHostContextTest {
public:

Powered by Google App Engine
This is Rietveld 408576698