diff options
-rw-r--r-- | cc/layers/nine_patch_layer_unittest.cc | 2 | ||||
-rw-r--r-- | cc/layers/scrollbar_layer_unittest.cc | 4 | ||||
-rw-r--r-- | cc/layers/tiled_layer_unittest.cc | 2 | ||||
-rw-r--r-- | cc/scheduler/scheduler.cc | 14 | ||||
-rw-r--r-- | cc/scheduler/scheduler.h | 9 | ||||
-rw-r--r-- | cc/scheduler/scheduler_state_machine.cc | 38 | ||||
-rw-r--r-- | cc/scheduler/scheduler_state_machine.h | 14 | ||||
-rw-r--r-- | cc/scheduler/scheduler_state_machine_unittest.cc | 172 | ||||
-rw-r--r-- | cc/scheduler/scheduler_unittest.cc | 58 | ||||
-rw-r--r-- | cc/test/fake_proxy.cc | 13 | ||||
-rw-r--r-- | cc/test/fake_proxy.h | 12 | ||||
-rw-r--r-- | cc/test/layer_tree_test.cc | 4 | ||||
-rw-r--r-- | cc/test/layer_tree_test.h | 2 | ||||
-rw-r--r-- | cc/trees/layer_tree_host.cc | 144 | ||||
-rw-r--r-- | cc/trees/layer_tree_host.h | 18 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_client.h | 3 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest.cc | 31 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest_context.cc | 225 | ||||
-rw-r--r-- | cc/trees/proxy.h | 20 | ||||
-rw-r--r-- | cc/trees/single_thread_proxy.cc | 100 | ||||
-rw-r--r-- | cc/trees/single_thread_proxy.h | 15 | ||||
-rw-r--r-- | cc/trees/thread_proxy.cc | 265 | ||||
-rw-r--r-- | cc/trees/thread_proxy.h | 44 |
23 files changed, 480 insertions, 729 deletions
diff --git a/cc/layers/nine_patch_layer_unittest.cc b/cc/layers/nine_patch_layer_unittest.cc index cf3b5a37..f120e51 100644 --- a/cc/layers/nine_patch_layer_unittest.cc +++ b/cc/layers/nine_patch_layer_unittest.cc @@ -65,7 +65,7 @@ TEST_F(NinePatchLayerTest, TriggerFullUploadOnceWhenChangingBitmap) { Mock::VerifyAndClearExpectations(layer_tree_host_.get()); EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get()); - layer_tree_host_->InitializeOutputSurfaceIfNeeded(); + layer_tree_host_->InitializeRendererIfNeeded(); PriorityCalculator calculator; ResourceUpdateQueue queue; diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc index 780be5e..148a202 100644 --- a/cc/layers/scrollbar_layer_unittest.cc +++ b/cc/layers/scrollbar_layer_unittest.cc @@ -287,6 +287,8 @@ class ScrollbarLayerTestMaxTextureSize : public LayerTreeTest { void SetScrollbarBounds(gfx::Size bounds) { bounds_ = bounds; } virtual void BeginTest() OVERRIDE { + layer_tree_host()->InitializeRendererIfNeeded(); + scoped_ptr<WebKit::WebScrollbar> scrollbar(FakeWebScrollbar::Create()); scrollbar_layer_ = ScrollbarLayer::Create(scrollbar.Pass(), @@ -368,7 +370,7 @@ class ScrollbarLayerTestResourceCreation : public testing::Test { layer_tree_root->AddChild(content_layer); layer_tree_root->AddChild(scrollbar_layer); - layer_tree_host_->InitializeOutputSurfaceIfNeeded(); + layer_tree_host_->InitializeRendererIfNeeded(); layer_tree_host_->contents_texture_manager()-> SetMaxMemoryLimitBytes(1024 * 1024); layer_tree_host_->SetRootLayer(layer_tree_root); diff --git a/cc/layers/tiled_layer_unittest.cc b/cc/layers/tiled_layer_unittest.cc index 7209ea8..6283bcb 100644 --- a/cc/layers/tiled_layer_unittest.cc +++ b/cc/layers/tiled_layer_unittest.cc @@ -60,7 +60,7 @@ class TiledLayerTest : public testing::Test { scoped_ptr<Thread>(NULL)); proxy_ = layer_tree_host_->proxy(); resource_manager_ = PrioritizedResourceManager::Create(proxy_); - layer_tree_host_->InitializeOutputSurfaceIfNeeded(); + layer_tree_host_->InitializeRendererIfNeeded(); layer_tree_host_->SetRootLayer(Layer::Create()); DebugScopedSetImplThreadAndMainThreadBlocked diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc index fb078e9..b088a0f 100644 --- a/cc/scheduler/scheduler.cc +++ b/cc/scheduler/scheduler.cc @@ -25,8 +25,8 @@ Scheduler::Scheduler(SchedulerClient* client, Scheduler::~Scheduler() { frame_rate_controller_->SetActive(false); } -void Scheduler::SetCanStart() { - state_machine_.SetCanStart(); +void Scheduler::SetCanBeginFrame(bool can) { + state_machine_.SetCanBeginFrame(can); ProcessScheduledActions(); } @@ -111,10 +111,10 @@ void Scheduler::DidLoseOutputSurface() { ProcessScheduledActions(); } -void Scheduler::DidCreateAndInitializeOutputSurface() { - TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); +void Scheduler::DidRecreateOutputSurface() { + TRACE_EVENT0("cc", "Scheduler::DidRecreateOutputSurface"); frame_rate_controller_->DidAbortAllPendingFrames(); - state_machine_.DidCreateAndInitializeOutputSurface(); + state_machine_.DidRecreateOutputSurface(); ProcessScheduledActions(); } @@ -184,8 +184,8 @@ void Scheduler::ProcessScheduledActions() { frame_rate_controller_->DidBeginFrame(); break; } - case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: - client_->ScheduledActionBeginOutputSurfaceCreation(); + case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_RECREATION: + client_->ScheduledActionBeginContextRecreation(); break; case SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: client_->ScheduledActionAcquireLayerTexturesForMainThread(); diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h index 548fdcc..08da4ad 100644 --- a/cc/scheduler/scheduler.h +++ b/cc/scheduler/scheduler.h @@ -39,7 +39,7 @@ class SchedulerClient { virtual void ScheduledActionCommit() = 0; virtual void ScheduledActionCheckForCompletedTileUploads() = 0; virtual void ScheduledActionActivatePendingTreeIfNeeded() = 0; - virtual void ScheduledActionBeginOutputSurfaceCreation() = 0; + virtual void ScheduledActionBeginContextRecreation() = 0; virtual void ScheduledActionAcquireLayerTexturesForMainThread() = 0; virtual void DidAnticipatedDrawTimeChange(base::TimeTicks time) = 0; @@ -59,7 +59,7 @@ class CC_EXPORT Scheduler : FrameRateControllerClient { virtual ~Scheduler(); - void SetCanStart(); + void SetCanBeginFrame(bool can); void SetVisible(bool visible); void SetCanDraw(bool can_draw); @@ -91,10 +91,7 @@ class CC_EXPORT Scheduler : FrameRateControllerClient { void DidSwapBuffersComplete(); void DidLoseOutputSurface(); - void DidCreateAndInitializeOutputSurface(); - bool HasInitializedOutputSurface() const { - return state_machine_.HasInitializedOutputSurface(); - } + void DidRecreateOutputSurface(); bool CommitPending() const { return state_machine_.CommitPending(); } bool RedrawPending() const { return state_machine_.RedrawPending(); } diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc index df935aa..c55631d 100644 --- a/cc/scheduler/scheduler_state_machine.cc +++ b/cc/scheduler/scheduler_state_machine.cc @@ -28,13 +28,12 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) main_thread_needs_layer_textures_(false), inside_vsync_(false), visible_(false), - can_start_(false), + can_begin_frame_(false), can_draw_(false), has_pending_tree_(false), draw_if_possible_failed_(false), texture_state_(LAYER_TEXTURE_STATE_UNLOCKED), - output_surface_state_(OUTPUT_SURFACE_LOST), - did_create_and_initialize_first_output_surface_(false) {} + output_surface_state_(OUTPUT_SURFACE_ACTIVE) {} std::string SchedulerStateMachine::ToString() { std::string str; @@ -80,7 +79,7 @@ std::string SchedulerStateMachine::ToString() { main_thread_needs_layer_textures_); base::StringAppendF(&str, "inside_vsync_ = %d; ", inside_vsync_); base::StringAppendF(&str, "visible_ = %d; ", visible_); - base::StringAppendF(&str, "can_start_ = %d; ", can_start_); + base::StringAppendF(&str, "can_begin_frame_ = %d; ", can_begin_frame_); base::StringAppendF(&str, "can_draw_ = %d; ", can_draw_); base::StringAppendF( &str, "draw_if_possible_failed_ = %d; ", draw_if_possible_failed_); @@ -181,9 +180,9 @@ SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { needs_forced_commit_) // TODO(enne): Should probably drop the active tree on force commit. return has_pending_tree_ ? ACTION_NONE : ACTION_BEGIN_FRAME; - if (output_surface_state_ == OUTPUT_SURFACE_LOST && can_start_) - return ACTION_BEGIN_OUTPUT_SURFACE_CREATION; - if (output_surface_state_ == OUTPUT_SURFACE_CREATING) + if (output_surface_state_ == OUTPUT_SURFACE_LOST) + return ACTION_BEGIN_OUTPUT_SURFACE_RECREATION; + if (output_surface_state_ == OUTPUT_SURFACE_RECREATING) return ACTION_NONE; if (ShouldCheckForCompletedTileUploads()) return ACTION_CHECK_FOR_COMPLETED_TILE_UPLOADS; @@ -194,8 +193,7 @@ SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { : ACTION_DRAW_IF_POSSIBLE; } if (needs_commit_ && - ((visible_ && output_surface_state_ == OUTPUT_SURFACE_ACTIVE) - || needs_forced_commit_)) + ((visible_ && can_begin_frame_) || needs_forced_commit_)) // TODO(enne): Should probably drop the active tree on force commit. return has_pending_tree_ ? ACTION_NONE : ACTION_BEGIN_FRAME; return ACTION_NONE; @@ -306,10 +304,10 @@ void SchedulerStateMachine::UpdateState(Action action) { texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; return; - case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: + case ACTION_BEGIN_OUTPUT_SURFACE_RECREATION: DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE); DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_LOST); - output_surface_state_ = OUTPUT_SURFACE_CREATING; + output_surface_state_ = OUTPUT_SURFACE_RECREATING; return; case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: @@ -411,7 +409,7 @@ void SchedulerStateMachine::BeginFrameAborted() { void SchedulerStateMachine::DidLoseOutputSurface() { if (output_surface_state_ == OUTPUT_SURFACE_LOST || - output_surface_state_ == OUTPUT_SURFACE_CREATING) + output_surface_state_ == OUTPUT_SURFACE_RECREATING) return; output_surface_state_ = OUTPUT_SURFACE_LOST; } @@ -422,20 +420,10 @@ void SchedulerStateMachine::SetHasPendingTree(bool has_pending_tree) { void SchedulerStateMachine::SetCanDraw(bool can) { can_draw_ = can; } -void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() { - DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING); +void SchedulerStateMachine::DidRecreateOutputSurface() { + DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_RECREATING); output_surface_state_ = OUTPUT_SURFACE_ACTIVE; - - if (did_create_and_initialize_first_output_surface_) { - // TODO(boliu): See if we can remove this when impl-side painting is always - // on. Does anything on the main thread need to update after recreate? - SetNeedsCommit(); - } - did_create_and_initialize_first_output_surface_ = true; -} - -bool SchedulerStateMachine::HasInitializedOutputSurface() const { - return output_surface_state_ == OUTPUT_SURFACE_ACTIVE; + SetNeedsCommit(); } void SchedulerStateMachine::SetMaximumNumberOfFailedDrawsBeforeDrawIsForced( diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h index fb3908b..55581a4 100644 --- a/cc/scheduler/scheduler_state_machine.h +++ b/cc/scheduler/scheduler_state_machine.h @@ -46,7 +46,7 @@ class CC_EXPORT SchedulerStateMachine { enum OutputSurfaceState { OUTPUT_SURFACE_ACTIVE, OUTPUT_SURFACE_LOST, - OUTPUT_SURFACE_CREATING, + OUTPUT_SURFACE_RECREATING, }; bool CommitPending() const { @@ -64,7 +64,7 @@ class CC_EXPORT SchedulerStateMachine { ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED, ACTION_DRAW_IF_POSSIBLE, ACTION_DRAW_FORCED, - ACTION_BEGIN_OUTPUT_SURFACE_CREATION, + ACTION_BEGIN_OUTPUT_SURFACE_RECREATION, ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD, }; Action NextAction() const; @@ -122,8 +122,8 @@ class CC_EXPORT SchedulerStateMachine { // textures to the impl thread by committing the layers. void SetMainThreadNeedsLayerTextures(); - // Set that we can create the first OutputSurface and start the scheduler. - void SetCanStart() { can_start_ = true; } + // Indicates whether we can successfully begin a frame at this time. + void SetCanBeginFrame(bool can) { can_begin_frame_ = can; } // Indicates whether drawing would, at this time, make sense. // CanDraw can be used to supress flashes or checkerboarding @@ -139,8 +139,7 @@ class CC_EXPORT SchedulerStateMachine { bool has_pending_tree() const { return has_pending_tree_; } void DidLoseOutputSurface(); - void DidCreateAndInitializeOutputSurface(); - bool HasInitializedOutputSurface() const; + void DidRecreateOutputSurface(); // Exposed for testing purposes. void SetMaximumNumberOfFailedDrawsBeforeDrawIsForced(int num_draws); @@ -182,13 +181,12 @@ class CC_EXPORT SchedulerStateMachine { bool main_thread_needs_layer_textures_; bool inside_vsync_; bool visible_; - bool can_start_; + bool can_begin_frame_; bool can_draw_; bool has_pending_tree_; bool draw_if_possible_failed_; TextureState texture_state_; OutputSurfaceState output_surface_state_; - bool did_create_and_initialize_first_output_surface_; DISALLOW_COPY_AND_ASSIGN(SchedulerStateMachine); }; diff --git a/cc/scheduler/scheduler_state_machine_unittest.cc b/cc/scheduler/scheduler_state_machine_unittest.cc index c4cdd84..6111b76 100644 --- a/cc/scheduler/scheduler_state_machine_unittest.cc +++ b/cc/scheduler/scheduler_state_machine_unittest.cc @@ -45,10 +45,8 @@ TEST(SchedulerStateMachineTest, TestNextActionBeginsFrameIfNeeded) { // If no commit needed, do nothing. { StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE); + state.SetCanBeginFrame(true); state.SetNeedsRedraw(false); state.SetVisible(true); @@ -81,7 +79,7 @@ TEST(SchedulerStateMachineTest, TestNextActionBeginsFrameIfNeeded) { { StateMachine state(default_scheduler_settings); state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE); - state.SetCanStart(); + state.SetCanBeginFrame(true); state.SetNeedsRedraw(false); state.SetVisible(true); EXPECT_FALSE(state.VSyncCallbackNeeded()); @@ -90,9 +88,7 @@ TEST(SchedulerStateMachineTest, TestNextActionBeginsFrameIfNeeded) { // Begin the frame, make sure needs_commit and commit_state update correctly. { StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(true); state.UpdateState(SchedulerStateMachine::ACTION_BEGIN_FRAME); EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, @@ -115,9 +111,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawSetsNeedsCommitAndDoesNotDrawAgain) { SchedulerSettings default_scheduler_settings; SchedulerStateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(true); state.SetCanDraw(true); state.SetNeedsRedraw(); @@ -144,10 +138,7 @@ TEST(SchedulerStateMachineTest, TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw) { SchedulerSettings default_scheduler_settings; SchedulerStateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); - + state.SetCanBeginFrame(true); state.SetVisible(true); state.SetCanDraw(true); state.SetNeedsRedraw(); @@ -177,9 +168,7 @@ TEST(SchedulerStateMachineTest, TestCommitAfterFailedDrawAllowsDrawInSameFrame) { SchedulerSettings default_scheduler_settings; SchedulerStateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(true); state.SetCanDraw(true); @@ -218,9 +207,7 @@ TEST(SchedulerStateMachineTest, TestCommitAfterFailedAndSuccessfulDrawDoesNotAllowDrawInSameFrame) { SchedulerSettings default_scheduler_settings; SchedulerStateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(true); state.SetCanDraw(true); @@ -270,9 +257,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawsWillEventuallyForceADrawAfterTheNextCommit) { SchedulerSettings default_scheduler_settings; SchedulerStateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(true); state.SetCanDraw(true); state.SetMaximumNumberOfFailedDrawsBeforeDrawIsForced(1); @@ -312,9 +297,7 @@ TEST(SchedulerStateMachineTest, TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedNextVSync) { SchedulerSettings default_scheduler_settings; SchedulerStateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(true); state.SetCanDraw(true); @@ -345,9 +328,6 @@ TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedNextVSync) { TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) { SchedulerSettings default_scheduler_settings; SchedulerStateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); state.SetVisible(true); state.SetCanDraw(true); state.SetNeedsRedraw(); @@ -382,9 +362,6 @@ TEST(SchedulerStateMachineTest, TestNextActionDrawsOnVSync) { for (size_t i = 0; i < num_commit_states; ++i) { for (size_t j = 0; j < 2; ++j) { StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); state.SetCommitState(all_commit_states[i]); bool visible = j; if (!visible) { @@ -410,9 +387,6 @@ TEST(SchedulerStateMachineTest, TestNextActionDrawsOnVSync) { for (size_t i = 0; i < num_commit_states; ++i) { for (size_t j = 0; j < 2; ++j) { StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); state.SetCanDraw(true); state.SetCommitState(all_commit_states[i]); bool forced_draw = j; @@ -455,9 +429,6 @@ TEST(SchedulerStateMachineTest, TestNoCommitStatesRedrawWhenInvisible) { // There shouldn't be any drawing regardless of vsync. for (size_t j = 0; j < 2; ++j) { StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); state.SetCommitState(all_commit_states[i]); state.SetVisible(false); state.SetNeedsRedraw(true); @@ -486,9 +457,6 @@ TEST(SchedulerStateMachineTest, TestCanRedraw_StopsDraw) { // There shouldn't be any drawing regardless of vsync. for (size_t j = 0; j < 2; ++j) { StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); state.SetCommitState(all_commit_states[i]); state.SetVisible(false); state.SetNeedsRedraw(true); @@ -507,11 +475,9 @@ TEST(SchedulerStateMachineTest, TestCanRedrawWithWaitingForFirstDrawMakesProgress) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); state.SetCommitState( SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW); + state.SetCanBeginFrame(true); state.SetNeedsCommit(); state.SetNeedsRedraw(true); state.SetVisible(true); @@ -522,9 +488,7 @@ TEST(SchedulerStateMachineTest, TEST(SchedulerStateMachineTest, TestsetNeedsCommitIsNotLost) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetNeedsCommit(); state.SetVisible(true); state.SetCanDraw(true); @@ -566,9 +530,7 @@ TEST(SchedulerStateMachineTest, TestsetNeedsCommitIsNotLost) { TEST(SchedulerStateMachineTest, TestFullCycle) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(true); state.SetCanDraw(true); @@ -614,9 +576,7 @@ TEST(SchedulerStateMachineTest, TestFullCycle) { TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(true); state.SetCanDraw(true); @@ -666,9 +626,6 @@ TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) { TEST(SchedulerStateMachineTest, TestRequestCommitInvisible) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); state.SetNeedsCommit(); EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); } @@ -676,9 +633,7 @@ TEST(SchedulerStateMachineTest, TestRequestCommitInvisible) { TEST(SchedulerStateMachineTest, TestGoesInvisibleBeforeBeginFrameCompletes) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(true); state.SetCanDraw(true); @@ -717,39 +672,16 @@ TEST(SchedulerStateMachineTest, TestGoesInvisibleBeforeBeginFrameCompletes) { state.CommitState()); } -TEST(SchedulerStateMachineTest, TestFirstContextCreation) { - SchedulerSettings default_scheduler_settings; - StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.SetVisible(true); - state.SetCanDraw(true); - - EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, - state.NextAction()); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); - EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); - - // Check that the first init does not SetNeedsCommit. - state.SetNeedsCommit(); - EXPECT_NE(SchedulerStateMachine::ACTION_NONE, state.NextAction()); -} - TEST(SchedulerStateMachineTest, TestContextLostWhenCompletelyIdle) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); - + state.SetCanBeginFrame(true); state.SetVisible(true); state.SetCanDraw(true); - EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, - state.NextAction()); state.DidLoseOutputSurface(); - EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, + EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_RECREATION, state.NextAction()); state.UpdateState(state.NextAction()); @@ -757,7 +689,7 @@ TEST(SchedulerStateMachineTest, TestContextLostWhenCompletelyIdle) { EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); // Recreate the context. - state.DidCreateAndInitializeOutputSurface(); + state.DidRecreateOutputSurface(); // When the context is recreated, we should begin a commit. EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.NextAction()); @@ -768,17 +700,13 @@ TEST(SchedulerStateMachineTest, TestContextLostWhenIdleAndCommitRequestedWhileRecreating) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(true); state.SetCanDraw(true); - EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, - state.NextAction()); state.DidLoseOutputSurface(); - EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, + EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_RECREATION, state.NextAction()); state.UpdateState(state.NextAction()); @@ -790,7 +718,7 @@ TEST(SchedulerStateMachineTest, EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); // Recreate the context - state.DidCreateAndInitializeOutputSurface(); + state.DidRecreateOutputSurface(); // When the context is recreated, we should begin a commit EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.NextAction()); @@ -810,9 +738,7 @@ TEST(SchedulerStateMachineTest, TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(true); state.SetCanDraw(true); @@ -848,10 +774,10 @@ TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) { // Expect to be told to begin context recreation, independent of vsync state. state.DidEnterVSync(); - EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, + EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_RECREATION, state.NextAction()); state.DidLeaveVSync(); - EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, + EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_RECREATION, state.NextAction()); } @@ -859,9 +785,7 @@ TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgressAndAnotherCommitRequested) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(true); state.SetCanDraw(true); @@ -898,19 +822,16 @@ TEST(SchedulerStateMachineTest, // Expect to be told to begin context recreation, independent of vsync state state.DidEnterVSync(); - EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, + EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_RECREATION, state.NextAction()); state.DidLeaveVSync(); - EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, + EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_RECREATION, state.NextAction()); } TEST(SchedulerStateMachineTest, TestFinishAllRenderingWhileContextLost) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); state.SetVisible(true); state.SetCanDraw(true); @@ -927,7 +848,7 @@ TEST(SchedulerStateMachineTest, TestFinishAllRenderingWhileContextLost) { state.SetNeedsForcedRedraw(false); // Expect to be told to begin context recreation, independent of vsync state - EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, + EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_RECREATION, state.NextAction()); state.UpdateState(state.NextAction()); @@ -941,9 +862,7 @@ TEST(SchedulerStateMachineTest, TestFinishAllRenderingWhileContextLost) { TEST(SchedulerStateMachineTest, TestBeginFrameWhenInvisibleAndForceCommit) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(false); state.SetNeedsCommit(); state.SetNeedsForcedCommit(); @@ -954,9 +873,6 @@ TEST(SchedulerStateMachineTest, TestBeginFrameWhenCanBeginFrameFalseAndForceCommit) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); state.SetVisible(true); state.SetCanDraw(true); state.SetNeedsCommit(); @@ -967,9 +883,7 @@ TEST(SchedulerStateMachineTest, TEST(SchedulerStateMachineTest, TestBeginFrameWhenCommitInProgress) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(false); state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS); state.SetNeedsCommit(); @@ -987,9 +901,7 @@ TEST(SchedulerStateMachineTest, TestBeginFrameWhenCommitInProgress) { TEST(SchedulerStateMachineTest, TestBeginFrameWhenForcedCommitInProgress) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(false); state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS); state.SetNeedsCommit(); @@ -1010,9 +922,7 @@ TEST(SchedulerStateMachineTest, TestBeginFrameWhenForcedCommitInProgress) { TEST(SchedulerStateMachineTest, TestBeginFrameWhenContextLost) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(true); state.SetCanDraw(true); state.SetNeedsCommit(); @@ -1024,9 +934,7 @@ TEST(SchedulerStateMachineTest, TestBeginFrameWhenContextLost) { TEST(SchedulerStateMachineTest, TestImmediateBeginFrame) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(true); state.SetCanDraw(true); @@ -1059,9 +967,7 @@ TEST(SchedulerStateMachineTest, TestImmediateBeginFrame) { TEST(SchedulerStateMachineTest, TestImmediateBeginFrameDuringCommit) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(true); state.SetCanDraw(true); @@ -1098,9 +1004,7 @@ TEST(SchedulerStateMachineTest, TestImmediateBeginFrameDuringCommit) { TEST(SchedulerStateMachineTest, ImmediateBeginFrameWhileInvisible) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(true); state.SetCanDraw(true); @@ -1144,9 +1048,7 @@ TEST(SchedulerStateMachineTest, ImmediateBeginFrameWhileInvisible) { TEST(SchedulerStateMachineTest, ImmediateBeginFrameWhileCantDraw) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetVisible(true); state.SetCanDraw(false); @@ -1203,9 +1105,7 @@ TEST(SchedulerStateMachineTest, ReportIfNotDrawing) { TEST(SchedulerStateMachineTest, ReportIfNotDrawingFromAcquiredTextures) { SchedulerSettings default_scheduler_settings; SchedulerStateMachine state(default_scheduler_settings); - state.SetCanStart(); - state.UpdateState(state.NextAction()); - state.DidCreateAndInitializeOutputSurface(); + state.SetCanBeginFrame(true); state.SetCanDraw(true); state.SetVisible(true); EXPECT_FALSE(state.DrawSuspendedUntilCommit()); diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc index 3a8e8e3..a2c968c 100644 --- a/cc/scheduler/scheduler_unittest.cc +++ b/cc/scheduler/scheduler_unittest.cc @@ -69,8 +69,8 @@ class FakeSchedulerClient : public SchedulerClient { virtual void ScheduledActionActivatePendingTreeIfNeeded() OVERRIDE { actions_.push_back("ScheduledActionActivatePendingTreeIfNeeded"); } - virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE { - actions_.push_back("ScheduledActionBeginOutputSurfaceCreation"); + virtual void ScheduledActionBeginContextRecreation() OVERRIDE { + actions_.push_back("ScheduledActionBeginContextRecreation"); } virtual void ScheduledActionAcquireLayerTexturesForMainThread() OVERRIDE { actions_.push_back("ScheduledActionAcquireLayerTexturesForMainThread"); @@ -92,15 +92,10 @@ TEST(SchedulerTest, RequestCommit) { Scheduler::Create(&client, make_scoped_ptr(new FrameRateController(time_source)), default_scheduler_settings); - scheduler->SetCanStart(); + scheduler->SetCanBeginFrame(true); scheduler->SetVisible(true); scheduler->SetCanDraw(true); - EXPECT_EQ(1, client.num_actions_()); - EXPECT_STREQ("ScheduledActionBeginOutputSurfaceCreation", client.Action(0)); - client.Reset(); - scheduler->DidCreateAndInitializeOutputSurface(); - // SetNeedsCommit should begin the frame. scheduler->SetNeedsCommit(); EXPECT_EQ(1, client.num_actions_()); @@ -134,15 +129,10 @@ TEST(SchedulerTest, RequestCommitAfterBeginFrame) { Scheduler::Create(&client, make_scoped_ptr(new FrameRateController(time_source)), default_scheduler_settings); - scheduler->SetCanStart(); + scheduler->SetCanBeginFrame(true); scheduler->SetVisible(true); scheduler->SetCanDraw(true); - EXPECT_EQ(1, client.num_actions_()); - EXPECT_STREQ("ScheduledActionBeginOutputSurfaceCreation", client.Action(0)); - client.Reset(); - scheduler->DidCreateAndInitializeOutputSurface(); - // SetNedsCommit should begin the frame. scheduler->SetNeedsCommit(); EXPECT_EQ(1, client.num_actions_()); @@ -176,15 +166,10 @@ TEST(SchedulerTest, TextureAcquisitionCollision) { Scheduler::Create(&client, make_scoped_ptr(new FrameRateController(time_source)), default_scheduler_settings); - scheduler->SetCanStart(); + scheduler->SetCanBeginFrame(true); scheduler->SetVisible(true); scheduler->SetCanDraw(true); - EXPECT_EQ(1, client.num_actions_()); - EXPECT_STREQ("ScheduledActionBeginOutputSurfaceCreation", client.Action(0)); - client.Reset(); - scheduler->DidCreateAndInitializeOutputSurface(); - scheduler->SetNeedsCommit(); scheduler->SetMainThreadNeedsLayerTextures(); EXPECT_EQ(2, client.num_actions_()); @@ -225,15 +210,10 @@ TEST(SchedulerTest, VisibilitySwitchWithTextureAcquisition) { Scheduler::Create(&client, make_scoped_ptr(new FrameRateController(time_source)), default_scheduler_settings); - scheduler->SetCanStart(); + scheduler->SetCanBeginFrame(true); scheduler->SetVisible(true); scheduler->SetCanDraw(true); - EXPECT_EQ(1, client.num_actions_()); - EXPECT_STREQ("ScheduledActionBeginOutputSurfaceCreation", client.Action(0)); - client.Reset(); - scheduler->DidCreateAndInitializeOutputSurface(); - scheduler->SetNeedsCommit(); scheduler->BeginFrameComplete(); scheduler->SetMainThreadNeedsLayerTextures(); @@ -277,7 +257,7 @@ class SchedulerClientThatsetNeedsDrawInsideDraw : public FakeSchedulerClient { } virtual void ScheduledActionCommit() OVERRIDE {} - virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {} + virtual void ScheduledActionBeginContextRecreation() OVERRIDE {} virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {} protected: @@ -297,10 +277,9 @@ TEST(SchedulerTest, RequestRedrawInsideDraw) { make_scoped_ptr(new FrameRateController(time_source)), default_scheduler_settings); client.SetScheduler(scheduler.get()); - scheduler->SetCanStart(); + scheduler->SetCanBeginFrame(true); scheduler->SetVisible(true); scheduler->SetCanDraw(true); - scheduler->DidCreateAndInitializeOutputSurface(); scheduler->SetNeedsRedraw(); EXPECT_TRUE(scheduler->RedrawPending()); @@ -328,11 +307,9 @@ TEST(SchedulerTest, RequestRedrawInsideFailedDraw) { make_scoped_ptr(new FrameRateController(time_source)), default_scheduler_settings); client.SetScheduler(scheduler.get()); - scheduler->SetCanStart(); + scheduler->SetCanBeginFrame(true); scheduler->SetVisible(true); scheduler->SetCanDraw(true); - scheduler->DidCreateAndInitializeOutputSurface(); - client.SetDrawWillHappen(false); scheduler->SetNeedsRedraw(); @@ -388,7 +365,7 @@ class SchedulerClientThatsetNeedsCommitInsideDraw : public FakeSchedulerClient { } virtual void ScheduledActionCommit() OVERRIDE {} - virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {} + virtual void ScheduledActionBeginContextRecreation() OVERRIDE {} virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {} protected: @@ -406,10 +383,9 @@ TEST(SchedulerTest, RequestCommitInsideDraw) { make_scoped_ptr(new FrameRateController(time_source)), default_scheduler_settings); client.SetScheduler(scheduler.get()); - scheduler->SetCanStart(); + scheduler->SetCanBeginFrame(true); scheduler->SetVisible(true); scheduler->SetCanDraw(true); - scheduler->DidCreateAndInitializeOutputSurface(); scheduler->SetNeedsRedraw(); EXPECT_TRUE(scheduler->RedrawPending()); @@ -438,11 +414,9 @@ TEST(SchedulerTest, RequestCommitInsideFailedDraw) { make_scoped_ptr(new FrameRateController(time_source)), default_scheduler_settings); client.SetScheduler(scheduler.get()); - scheduler->SetCanStart(); + scheduler->SetCanBeginFrame(true); scheduler->SetVisible(true); scheduler->SetCanDraw(true); - scheduler->DidCreateAndInitializeOutputSurface(); - client.SetDrawWillHappen(false); scheduler->SetNeedsRedraw(); @@ -488,10 +462,9 @@ TEST(SchedulerTest, NoBeginFrameWhenDrawFails) { controller.PassAs<FrameRateController>(), default_scheduler_settings); client.SetScheduler(scheduler.get()); - scheduler->SetCanStart(); + scheduler->SetCanBeginFrame(true); scheduler->SetVisible(true); scheduler->SetCanDraw(true); - scheduler->DidCreateAndInitializeOutputSurface(); EXPECT_EQ(0, controller_ptr->NumFramesPending()); @@ -557,10 +530,9 @@ TEST(SchedulerTest, RecreateOutputSurfaceClearsPendingDrawCount) { controller.PassAs<FrameRateController>(), default_scheduler_settings); - scheduler->SetCanStart(); + scheduler->SetCanBeginFrame(true); scheduler->SetVisible(true); scheduler->SetCanDraw(true); - scheduler->DidCreateAndInitializeOutputSurface(); // Draw successfully, this starts a new frame. scheduler->SetNeedsRedraw(); @@ -571,7 +543,7 @@ TEST(SchedulerTest, RecreateOutputSurfaceClearsPendingDrawCount) { // Verifying that it's 1 so that we know that it's reset on recreate. EXPECT_EQ(1, controller_ptr->NumFramesPending()); - scheduler->DidCreateAndInitializeOutputSurface(); + scheduler->DidRecreateOutputSurface(); EXPECT_EQ(0, controller_ptr->NumFramesPending()); } diff --git a/cc/test/fake_proxy.cc b/cc/test/fake_proxy.cc index 9a3fc9d..0ec3ab2 100644 --- a/cc/test/fake_proxy.cc +++ b/cc/test/fake_proxy.cc @@ -6,20 +6,17 @@ namespace cc { -void FakeProxy::SetLayerTreeHost(LayerTreeHost* host) { - layer_tree_host_ = host; -} - bool FakeProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) { return true; } bool FakeProxy::IsStarted() const { return true; } -void FakeProxy::CreateAndInitializeOutputSurface() { - DCHECK(layer_tree_host_); - layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(true); -} +bool FakeProxy::InitializeOutputSurface() { return true; } + +bool FakeProxy::InitializeRenderer() { return true; } + +bool FakeProxy::RecreateOutputSurface() { return true; } const RendererCapabilities& FakeProxy::GetRendererCapabilities() const { return capabilities_; diff --git a/cc/test/fake_proxy.h b/cc/test/fake_proxy.h index 712a70e..d94092f 100644 --- a/cc/test/fake_proxy.h +++ b/cc/test/fake_proxy.h @@ -14,17 +14,16 @@ namespace cc { class FakeProxy : public Proxy { public: explicit FakeProxy(scoped_ptr<Thread> impl_thread) - : Proxy(impl_thread.Pass()), - layer_tree_host_(NULL) {} - - void SetLayerTreeHost(LayerTreeHost* host); + : Proxy(impl_thread.Pass()) {} virtual bool CompositeAndReadback(void* pixels, gfx::Rect rect) OVERRIDE; virtual void FinishAllRendering() OVERRIDE {} virtual bool IsStarted() const OVERRIDE; + virtual bool InitializeOutputSurface() OVERRIDE; virtual void SetSurfaceReady() OVERRIDE {} virtual void SetVisible(bool visible) OVERRIDE {} - virtual void CreateAndInitializeOutputSurface() OVERRIDE; + virtual bool InitializeRenderer() OVERRIDE; + virtual bool RecreateOutputSurface() OVERRIDE; virtual const RendererCapabilities& GetRendererCapabilities() const OVERRIDE; virtual void SetNeedsAnimate() OVERRIDE {} virtual void SetNeedsCommit() OVERRIDE {} @@ -32,7 +31,7 @@ class FakeProxy : public Proxy { virtual void SetDeferCommits(bool defer_commits) OVERRIDE {} virtual void MainThreadHasStoppedFlinging() OVERRIDE {} virtual bool CommitRequested() const OVERRIDE; - virtual void Start(scoped_ptr<OutputSurface> first_output_surface) OVERRIDE {} + virtual void Start() OVERRIDE {} virtual void Stop() OVERRIDE {} virtual void ForceSerializeOnSwapBuffers() OVERRIDE {} virtual size_t MaxPartialTextureUpdates() const OVERRIDE; @@ -47,7 +46,6 @@ class FakeProxy : public Proxy { private: RendererCapabilities capabilities_; size_t max_partial_texture_updates_; - LayerTreeHost* layer_tree_host_; }; } // namespace cc diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index 3312687..3881f10 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc @@ -256,8 +256,8 @@ class LayerTreeHostClientForTesting : public LayerTreeHostClient { test_hooks_->DidRecreateOutputSurface(succeeded); } - virtual void DidFailToInitializeOutputSurface() OVERRIDE { - test_hooks_->DidFailToInitializeOutputSurface(); + virtual void WillRetryRecreateOutputSurface() OVERRIDE { + test_hooks_->WillRetryRecreateOutputSurface(); } virtual scoped_ptr<InputHandler> CreateInputHandler() OVERRIDE { diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h index be865c3..c1a4b67 100644 --- a/cc/test/layer_tree_test.h +++ b/cc/test/layer_tree_test.h @@ -53,7 +53,7 @@ class TestHooks : public WebKit::WebAnimationDelegate { virtual void Animate(base::TimeTicks monotonic_time) {} virtual void Layout() {} virtual void DidRecreateOutputSurface(bool succeeded) {} - virtual void DidFailToInitializeOutputSurface() {} + virtual void WillRetryRecreateOutputSurface() {} virtual void DidAddAnimation() {} virtual void DidCommit() {} virtual void DidCommitAndDrawFrame() {} diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 8eaf6e5..2a4c932 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc @@ -84,8 +84,9 @@ LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client, client_(client), commit_number_(0), rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()), - output_surface_can_be_initialized_(true), - output_surface_lost_(true), + renderer_can_be_initialized_(true), + renderer_initialized_(false), + output_surface_lost_(false), num_failed_recreate_attempts_(0), settings_(settings), debug_state_(settings.initial_debug_state), @@ -122,25 +123,18 @@ bool LayerTreeHost::InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing) { bool LayerTreeHost::InitializeProxy(scoped_ptr<Proxy> proxy) { TRACE_EVENT0("cc", "LayerTreeHost::InitializeForReal"); - scoped_ptr<OutputSurface> output_surface(CreateOutputSurface()); - if (!output_surface) - return false; - proxy_ = proxy.Pass(); - proxy_->Start(output_surface.Pass()); - return true; + proxy_->Start(); + return proxy_->InitializeOutputSurface(); } LayerTreeHost::~LayerTreeHost() { - TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost"); if (root_layer_) root_layer_->SetLayerTreeHost(NULL); - - if (proxy_) { - DCHECK(proxy_->IsMainThread()); - proxy_->Stop(); - } - + DCHECK(proxy_); + DCHECK(proxy_->IsMainThread()); + TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost"); + proxy_->Stop(); s_num_layer_tree_instances--; RateLimiterMap::iterator it = rate_limiters_.begin(); if (it != rate_limiters_.end()) @@ -158,65 +152,72 @@ void LayerTreeHost::SetSurfaceReady() { proxy_->SetSurfaceReady(); } -LayerTreeHost::CreateResult -LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(bool success) { - TRACE_EVENT1("cc", - "LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted", - "success", - success); +void LayerTreeHost::InitializeRenderer() { + TRACE_EVENT0("cc", "LayerTreeHost::InitializeRenderer"); + if (!proxy_->InitializeRenderer()) { + // Uh oh, better tell the client that we can't do anything with this output + // surface. + renderer_can_be_initialized_ = false; + client_->DidRecreateOutputSurface(false); + return; + } - DCHECK(output_surface_lost_); - if (success) { - output_surface_lost_ = false; + // Update settings_ based on capabilities that we got back from the renderer. + settings_.accelerate_painting = + proxy_->GetRendererCapabilities().using_accelerated_painting; + + // Update settings_ based on partial update capability. + size_t max_partial_texture_updates = 0; + if (proxy_->GetRendererCapabilities().allow_partial_texture_updates && + !settings_.impl_side_painting) { + max_partial_texture_updates = std::min( + settings_.max_partial_texture_updates, + proxy_->MaxPartialTextureUpdates()); + } + settings_.max_partial_texture_updates = max_partial_texture_updates; - // Update settings_ based on capabilities that we got back from the - // renderer. - settings_.accelerate_painting = - proxy_->GetRendererCapabilities().using_accelerated_painting; - - // Update settings_ based on partial update capability. - size_t max_partial_texture_updates = 0; - if (proxy_->GetRendererCapabilities().allow_partial_texture_updates && - !settings_.impl_side_painting) { - max_partial_texture_updates = std::min( - settings_.max_partial_texture_updates, - proxy_->MaxPartialTextureUpdates()); - } - settings_.max_partial_texture_updates = max_partial_texture_updates; + contents_texture_manager_ = PrioritizedResourceManager::Create(proxy_.get()); + surface_memory_placeholder_ = + contents_texture_manager_->CreateTexture(gfx::Size(), GL_RGBA); - if (!contents_texture_manager_) { - contents_texture_manager_ = - PrioritizedResourceManager::Create(proxy_.get()); - surface_memory_placeholder_ = - contents_texture_manager_->CreateTexture(gfx::Size(), GL_RGBA); - } + renderer_initialized_ = true; +} + +LayerTreeHost::RecreateResult LayerTreeHost::RecreateOutputSurface() { + TRACE_EVENT0("cc", "LayerTreeHost::RecreateOutputSurface"); + DCHECK(output_surface_lost_); + if (proxy_->RecreateOutputSurface()) { client_->DidRecreateOutputSurface(true); - return CreateSucceeded; + output_surface_lost_ = false; + return RecreateSucceeded; } - // Failure path. - - client_->DidFailToInitializeOutputSurface(); + client_->WillRetryRecreateOutputSurface(); // Tolerate a certain number of recreation failures to work around races // in the output-surface-lost machinery. - ++num_failed_recreate_attempts_; - if (num_failed_recreate_attempts_ >= 5) { - // We have tried too many times to recreate the output surface. Tell the - // host to fall back to software rendering. - output_surface_can_be_initialized_ = false; - client_->DidRecreateOutputSurface(false); - return CreateFailedAndGaveUp; + num_failed_recreate_attempts_++; + if (num_failed_recreate_attempts_ < 5) { + // FIXME: The single thread does not self-schedule output surface + // recreation. So force another recreation attempt to happen by requesting + // another commit. + if (!proxy_->HasImplThread()) + SetNeedsCommit(); + return RecreateFailedButTryAgain; } - return CreateFailedButTryAgain; + // We have tried too many times to recreate the output surface. Tell the + // host to fall back to software rendering. + renderer_can_be_initialized_ = false; + client_->DidRecreateOutputSurface(false); + return RecreateFailedAndGaveUp; } void LayerTreeHost::DeleteContentsTexturesOnImplThread( ResourceProvider* resource_provider) { DCHECK(proxy_->IsImplThread()); - if (contents_texture_manager_) + if (renderer_initialized_) contents_texture_manager_->ClearAllMemory(resource_provider); } @@ -498,12 +499,8 @@ scoped_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl( void LayerTreeHost::DidLoseOutputSurface() { TRACE_EVENT0("cc", "LayerTreeHost::DidLoseOutputSurface"); DCHECK(proxy_->IsMainThread()); - - if (output_surface_lost_) - return; - - num_failed_recreate_attempts_ = 0; output_surface_lost_ = true; + num_failed_recreate_attempts_ = 0; SetNeedsCommit(); } @@ -516,6 +513,8 @@ bool LayerTreeHost::CompositeAndReadback(void* pixels, } void LayerTreeHost::FinishAllRendering() { + if (!renderer_initialized_) + return; proxy_->FinishAllRendering(); } @@ -721,18 +720,27 @@ void LayerTreeHost::ScheduleComposite() { client_->ScheduleComposite(); } -bool LayerTreeHost::InitializeOutputSurfaceIfNeeded() { - if (!output_surface_can_be_initialized_) +bool LayerTreeHost::InitializeRendererIfNeeded() { + if (!renderer_can_be_initialized_) return false; - if (output_surface_lost_) - proxy_->CreateAndInitializeOutputSurface(); - return !output_surface_lost_; + if (!renderer_initialized_) { + InitializeRenderer(); + // If we couldn't initialize, then bail since we're returning to software + // mode. + if (!renderer_initialized_) + return false; + } + if (output_surface_lost_) { + if (RecreateOutputSurface() != RecreateSucceeded) + return false; + } + return true; } void LayerTreeHost::UpdateLayers(ResourceUpdateQueue* queue, size_t memory_allocation_limit_bytes) { - DCHECK(!output_surface_lost_); + DCHECK(renderer_initialized_); if (!root_layer()) return; diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index 13e03d2..f94066d 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h @@ -88,7 +88,6 @@ class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) { scoped_ptr<Thread> impl_thread); virtual ~LayerTreeHost(); - // TODO(boliu): Rename to SetLayerTreeHostClientReady. void SetSurfaceReady(); // Returns true if any LayerTreeHost is alive. @@ -118,19 +117,18 @@ class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) { virtual scoped_ptr<LayerTreeHostImpl> CreateLayerTreeHostImpl( LayerTreeHostImplClient* client); void DidLoseOutputSurface(); - bool output_surface_lost() const { return output_surface_lost_; } - enum CreateResult { - CreateSucceeded, - CreateFailedButTryAgain, - CreateFailedAndGaveUp, + enum RecreateResult { + RecreateSucceeded, + RecreateFailedButTryAgain, + RecreateFailedAndGaveUp, }; - CreateResult OnCreateAndInitializeOutputSurfaceAttempted(bool success); + RecreateResult RecreateOutputSurface(); void DidCommitAndDrawFrame() { client_->DidCommitAndDrawFrame(); } void DidCompleteSwapBuffers() { client_->DidCompleteSwapBuffers(); } void DeleteContentsTexturesOnImplThread(ResourceProvider* resource_provider); virtual void AcquireLayerTextures(); // Returns false if we should abort this frame due to initialization failure. - bool InitializeOutputSurfaceIfNeeded(); + bool InitializeRendererIfNeeded(); void UpdateLayers(ResourceUpdateQueue* queue, size_t contents_memory_limit_bytes); @@ -261,6 +259,7 @@ class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) { private: bool InitializeProxy(scoped_ptr<Proxy> proxy); + void InitializeRenderer(); bool PaintLayerContents(const LayerList& render_surface_layer_list, ResourceUpdateQueue* quue); @@ -293,7 +292,8 @@ class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) { int commit_number_; scoped_ptr<RenderingStatsInstrumentation> rendering_stats_instrumentation_; - bool output_surface_can_be_initialized_; + bool renderer_can_be_initialized_; + bool renderer_initialized_; bool output_surface_lost_; int num_failed_recreate_attempts_; diff --git a/cc/trees/layer_tree_host_client.h b/cc/trees/layer_tree_host_client.h index df68e47..4bc913c 100644 --- a/cc/trees/layer_tree_host_client.h +++ b/cc/trees/layer_tree_host_client.h @@ -28,7 +28,6 @@ class LayerTreeHostClient { virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta, float page_scale) = 0; virtual scoped_ptr<OutputSurface> CreateOutputSurface() = 0; - // TODO(boliu): Rename to DidInitializeOutputSurface. virtual void DidRecreateOutputSurface(bool success) = 0; virtual scoped_ptr<InputHandler> CreateInputHandler() = 0; virtual void WillCommit() = 0; @@ -47,7 +46,7 @@ class LayerTreeHostClient { OffscreenContextProviderForCompositorThread() = 0; // This hook is for testing. - virtual void DidFailToInitializeOutputSurface() {} + virtual void WillRetryRecreateOutputSurface() {} protected: virtual ~LayerTreeHostClient() {} diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index f32d0d8..08c2228 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc @@ -795,6 +795,9 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers layer_tree_host()->SetRootLayer(root_layer_); + ASSERT_TRUE(layer_tree_host()->InitializeRendererIfNeeded()); + ResourceUpdateQueue queue; + layer_tree_host()->UpdateLayers(&queue, std::numeric_limits<size_t>::max()); PostSetNeedsCommitToMainThread(); } @@ -1225,6 +1228,8 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFinishAllRendering); class LayerTreeHostTestCompositeAndReadbackCleanup : public LayerTreeHostTest { public: + LayerTreeHostTestCompositeAndReadbackCleanup() {} + virtual void BeginTest() OVERRIDE { Layer* root_layer = layer_tree_host()->root_layer(); @@ -1695,10 +1700,9 @@ class LayerTreeHostWithProxy : public LayerTreeHost { public: LayerTreeHostWithProxy(FakeLayerTreeHostClient* client, const LayerTreeSettings& settings, - scoped_ptr<FakeProxy> proxy) + scoped_ptr<Proxy> proxy) : LayerTreeHost(client, settings) { - proxy->SetLayerTreeHost(this); - EXPECT_TRUE(InitializeForTesting(proxy.PassAs<Proxy>())); + EXPECT_TRUE(InitializeForTesting(proxy.Pass())); } }; @@ -1715,8 +1719,8 @@ TEST(LayerTreeHostTest, LimitPartialUpdates) { LayerTreeSettings settings; settings.max_partial_texture_updates = 10; - LayerTreeHostWithProxy host(&client, settings, proxy.Pass()); - EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded()); + LayerTreeHostWithProxy host(&client, settings, proxy.PassAs<Proxy>()); + EXPECT_TRUE(host.InitializeRendererIfNeeded()); EXPECT_EQ(0u, host.settings().max_partial_texture_updates); } @@ -1734,8 +1738,8 @@ TEST(LayerTreeHostTest, LimitPartialUpdates) { LayerTreeSettings settings; settings.max_partial_texture_updates = 10; - LayerTreeHostWithProxy host(&client, settings, proxy.Pass()); - EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded()); + LayerTreeHostWithProxy host(&client, settings, proxy.PassAs<Proxy>()); + EXPECT_TRUE(host.InitializeRendererIfNeeded()); EXPECT_EQ(5u, host.settings().max_partial_texture_updates); } @@ -1753,8 +1757,8 @@ TEST(LayerTreeHostTest, LimitPartialUpdates) { LayerTreeSettings settings; settings.max_partial_texture_updates = 10; - LayerTreeHostWithProxy host(&client, settings, proxy.Pass()); - EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded()); + LayerTreeHostWithProxy host(&client, settings, proxy.PassAs<Proxy>()); + EXPECT_TRUE(host.InitializeRendererIfNeeded()); EXPECT_EQ(10u, host.settings().max_partial_texture_updates); } @@ -1768,7 +1772,7 @@ TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) { scoped_ptr<LayerTreeHost> host = LayerTreeHost::Create(&client, settings, scoped_ptr<Thread>()); - EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded()); + EXPECT_TRUE(host->InitializeRendererIfNeeded()); EXPECT_EQ(4u, host->settings().max_partial_texture_updates); } @@ -1780,7 +1784,7 @@ TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) { scoped_ptr<LayerTreeHost> host = LayerTreeHost::Create(&client, settings, scoped_ptr<Thread>()); - EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded()); + EXPECT_TRUE(host->InitializeRendererIfNeeded()); EXPECT_EQ(4u, host->settings().max_partial_texture_updates); } @@ -1792,7 +1796,7 @@ TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) { scoped_ptr<LayerTreeHost> host = LayerTreeHost::Create(&client, settings, scoped_ptr<Thread>()); - EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded()); + EXPECT_TRUE(host->InitializeRendererIfNeeded()); EXPECT_EQ(0u, host->settings().max_partial_texture_updates); } @@ -1805,7 +1809,7 @@ TEST(LayerTreeHostTest, scoped_ptr<LayerTreeHost> host = LayerTreeHost::Create(&client, settings, scoped_ptr<Thread>()); - EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded()); + EXPECT_TRUE(host->InitializeRendererIfNeeded()); EXPECT_EQ(0u, host->settings().max_partial_texture_updates); } @@ -1843,6 +1847,7 @@ class LayerTreeHostTestCapturePicture : public LayerTreeHostTest { layer_tree_host()->SetViewportSize(bounds_); layer_tree_host()->SetRootLayer(layer_); + EXPECT_TRUE(layer_tree_host()->InitializeRendererIfNeeded()); PostSetNeedsCommitToMainThread(); } diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc index 1658dea..20f5114 100644 --- a/cc/trees/layer_tree_host_unittest_context.cc +++ b/cc/trees/layer_tree_host_unittest_context.cc @@ -5,7 +5,6 @@ #include "cc/trees/layer_tree_host.h" #include "base/basictypes.h" -#include "cc/base/thread_impl.h" #include "cc/layers/content_layer.h" #include "cc/layers/heads_up_display_layer.h" #include "cc/layers/io_surface_layer.h" @@ -21,7 +20,6 @@ #include "cc/test/fake_context_provider.h" #include "cc/test/fake_delegated_renderer_layer.h" #include "cc/test/fake_delegated_renderer_layer_impl.h" -#include "cc/test/fake_layer_tree_host_client.h" #include "cc/test/fake_output_surface.h" #include "cc/test/fake_scrollbar_layer.h" #include "cc/test/fake_scrollbar_theme_painter.h" @@ -60,11 +58,10 @@ class LayerTreeHostContextTest : public LayerTreeTest { times_to_lose_on_recreate_(0), times_to_fail_create_offscreen_(0), times_to_fail_recreate_offscreen_(0), - times_to_expect_create_failed_(0), - times_create_failed_(0), + times_to_expect_recreate_retried_(0), + times_recreate_retried_(0), times_offscreen_created_(0), - committed_at_least_once_(false), - context_should_support_io_surface_(false) { + committed_at_least_once_(false) { media::InitializeMediaLibraryForTesting(); } @@ -81,29 +78,24 @@ class LayerTreeHostContextTest : public LayerTreeTest { virtual scoped_ptr<OutputSurface> CreateOutputSurface() OVERRIDE { if (times_to_fail_create_) { --times_to_fail_create_; - ExpectCreateToFail(); + ExpectRecreateToRetry(); return scoped_ptr<OutputSurface>(); } scoped_ptr<TestWebGraphicsContext3D> context3d = CreateContext3d(); context3d_ = context3d.get(); - if (context_should_support_io_surface_) { - context3d_->set_have_extension_io_surface(true); - context3d_->set_have_extension_egl_image(true); - } - if (times_to_fail_initialize_) { --times_to_fail_initialize_; // Make the context get lost during reinitialization. // The number of times MakeCurrent succeeds is not important, and // can be changed if needed to make this pass with future changes. context3d_->set_times_make_current_succeeds(2); - ExpectCreateToFail(); + ExpectRecreateToRetry(); } else if (times_to_lose_on_create_) { --times_to_lose_on_create_; LoseContext(); - ExpectCreateToFail(); + ExpectRecreateToRetry(); } return FakeOutputSurface::Create3d( @@ -118,7 +110,7 @@ class LayerTreeHostContextTest : public LayerTreeTest { if (times_to_fail_create_offscreen_) { --times_to_fail_create_offscreen_; - ExpectCreateToFail(); + ExpectRecreateToRetry(); return scoped_ptr<TestWebGraphicsContext3D>(); } @@ -161,8 +153,10 @@ class LayerTreeHostContextTest : public LayerTreeTest { virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame, - bool result) OVERRIDE { - EXPECT_TRUE(result); + bool result) + OVERRIDE { + bool expect_success = !frame->has_no_damage; + EXPECT_EQ(expect_success, result); if (!times_to_lose_during_draw_) return result; @@ -199,17 +193,18 @@ class LayerTreeHostContextTest : public LayerTreeTest { times_to_fail_recreate_offscreen_ = 0; } - virtual void DidFailToInitializeOutputSurface() OVERRIDE { - ++times_create_failed_; + virtual void WillRetryRecreateOutputSurface() OVERRIDE { + ++times_recreate_retried_; } virtual void TearDown() OVERRIDE { LayerTreeTest::TearDown(); - EXPECT_EQ(times_to_expect_create_failed_, times_create_failed_); + EXPECT_EQ(times_to_expect_recreate_retried_, times_recreate_retried_); } - void ExpectCreateToFail() { - ++times_to_expect_create_failed_; + void ExpectRecreateToRetry() { + if (committed_at_least_once_) + ++times_to_expect_recreate_retried_; } protected: @@ -224,11 +219,10 @@ class LayerTreeHostContextTest : public LayerTreeTest { int times_to_lose_on_recreate_; int times_to_fail_create_offscreen_; int times_to_fail_recreate_offscreen_; - int times_to_expect_create_failed_; - int times_create_failed_; + int times_to_expect_recreate_retried_; + int times_recreate_retried_; int times_offscreen_created_; bool committed_at_least_once_; - bool context_should_support_io_surface_; scoped_refptr<FakeContextProvider> offscreen_contexts_main_thread_; scoped_refptr<FakeContextProvider> offscreen_contexts_compositor_thread_; @@ -241,8 +235,7 @@ class LayerTreeHostContextTestLostContextSucceeds : LayerTreeHostContextTest(), test_case_(0), num_losses_(0), - recovered_context_(true), - first_initialized_(false) {} + recovered_context_(true) {} virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); @@ -250,12 +243,7 @@ class LayerTreeHostContextTestLostContextSucceeds virtual void DidRecreateOutputSurface(bool succeeded) OVERRIDE { EXPECT_TRUE(succeeded); - - if (first_initialized_) - ++num_losses_; - else - first_initialized_ = true; - + ++num_losses_; recovered_context_ = true; } @@ -393,7 +381,6 @@ class LayerTreeHostContextTestLostContextSucceeds size_t test_case_; int num_losses_; bool recovered_context_; - bool first_initialized_; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLostContextSucceeds); @@ -537,9 +524,6 @@ class LayerTreeHostContextTestOffscreenContextFails cc::ContextProvider* contexts = host_impl->resource_provider()->offscreen_context_provider(); EXPECT_FALSE(contexts); - - // This did not lead to create failure. - times_to_expect_create_failed_ = 0; EndTest(); } @@ -558,8 +542,7 @@ class LayerTreeHostContextTestLostContextFails public: LayerTreeHostContextTestLostContextFails() : LayerTreeHostContextTest(), - num_commits_(0), - first_initialized_(false) { + num_commits_(0) { times_to_lose_during_commit_ = 1; } @@ -568,12 +551,8 @@ class LayerTreeHostContextTestLostContextFails } virtual void DidRecreateOutputSurface(bool succeeded) OVERRIDE { - if (first_initialized_) { - EXPECT_FALSE(succeeded); - EndTest(); - } else { - first_initialized_ = true; - } + EXPECT_FALSE(succeeded); + EndTest(); } virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { @@ -598,7 +577,6 @@ class LayerTreeHostContextTestLostContextFails private: int num_commits_; - bool first_initialized_; }; TEST_F(LayerTreeHostContextTestLostContextFails, @@ -654,26 +632,18 @@ class LayerTreeHostContextTestFinishAllRenderingAfterLoss public: virtual void BeginTest() OVERRIDE { // Lose the context until the compositor gives up on it. - first_initialized_ = false; times_to_lose_during_commit_ = 1; times_to_fail_reinitialize_ = 10; PostSetNeedsCommitToMainThread(); } virtual void DidRecreateOutputSurface(bool succeeded) OVERRIDE { - if (first_initialized_) { - EXPECT_FALSE(succeeded); - layer_tree_host()->FinishAllRendering(); - EndTest(); - } else { - first_initialized_ = true; - } + EXPECT_FALSE(succeeded); + layer_tree_host()->FinishAllRendering(); + EndTest(); } virtual void AfterTest() OVERRIDE {} - - private: - bool first_initialized_; }; SINGLE_AND_MULTI_THREAD_TEST_F( @@ -920,6 +890,9 @@ class LayerTreeHostContextTestDontUseLostResources : public LayerTreeHostContextTest { public: virtual void SetupTree() OVERRIDE { + context3d_->set_have_extension_io_surface(true); + context3d_->set_have_extension_egl_image(true); + scoped_refptr<Layer> root_ = Layer::Create(); root_->SetBounds(gfx::Size(10, 10)); root_->SetAnchorPoint(gfx::PointF()); @@ -1009,7 +982,6 @@ class LayerTreeHostContextTestDontUseLostResources } virtual void BeginTest() OVERRIDE { - context_should_support_io_surface_ = true; PostSetNeedsCommitToMainThread(); } @@ -1129,112 +1101,36 @@ class LayerTreeHostContextTestDontUseLostResources SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestDontUseLostResources); -class LayerTreeHostContextTestLosesFirstOutputSurface +class LayerTreeHostContextTestFailsImmediately : public LayerTreeHostContextTest { public: - LayerTreeHostContextTestLosesFirstOutputSurface() { - // Always fail. This needs to be set before LayerTreeHost is created. - times_to_lose_on_create_ = 1000; - } + LayerTreeHostContextTestFailsImmediately() + : LayerTreeHostContextTest() {} - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } - - virtual void AfterTest() OVERRIDE {} - - virtual void DidRecreateOutputSurface(bool succeeded) OVERRIDE { - EXPECT_FALSE(succeeded); - - // If we make it this far without crashing, we pass! - EndTest(); - } - - virtual void DidCommitAndDrawFrame() OVERRIDE { - EXPECT_TRUE(false); - } -}; - -SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeHostContextTestLosesFirstOutputSurface); - -class LayerTreeHostContextTestRetriesFirstInitializationAndSucceeds - : public LayerTreeHostContextTest { - public: - virtual void AfterTest() OVERRIDE {} + virtual ~LayerTreeHostContextTestFailsImmediately() {} virtual void BeginTest() OVERRIDE { - times_to_fail_initialize_ = 2; PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { - EndTest(); - } -}; - -SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeHostContextTestRetriesFirstInitializationAndSucceeds); - -class LayerTreeHostContextTestRetryWorksWithForcedInit - : public LayerTreeHostContextTestRetriesFirstInitializationAndSucceeds { - public: - virtual void DidFailToInitializeOutputSurface() OVERRIDE { - LayerTreeHostContextTestRetriesFirstInitializationAndSucceeds - ::DidFailToInitializeOutputSurface(); - - if (times_create_failed_ == 1) { - // CompositeAndReadback force recreates the output surface, which should - // fail. - char pixels[4]; - EXPECT_FALSE(layer_tree_host()->CompositeAndReadback( - &pixels, gfx::Rect(1, 1))); - } - } -}; - -SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeHostContextTestRetryWorksWithForcedInit); - -class LayerTreeHostContextTestCompositeAndReadbackBeforeOutputSurfaceInit - : public LayerTreeHostContextTest { - public: - virtual void BeginTest() OVERRIDE { - // This must be called immediately after creating LTH, before the first - // OutputSurface is initialized. - ASSERT_TRUE(layer_tree_host()->output_surface_lost()); - - times_output_surface_created_ = 0; - - char pixels[4]; - EXPECT_TRUE(layer_tree_host()->CompositeAndReadback( - &pixels, gfx::Rect(1, 1))); - EXPECT_EQ(1, times_output_surface_created_); + virtual void AfterTest() OVERRIDE {} - PostSetNeedsCommitToMainThread(); + virtual scoped_ptr<TestWebGraphicsContext3D> CreateContext3d() OVERRIDE { + scoped_ptr<TestWebGraphicsContext3D> context = + LayerTreeHostContextTest::CreateContext3d(); + context->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, + GL_INNOCENT_CONTEXT_RESET_ARB); + return context.Pass(); } virtual void DidRecreateOutputSurface(bool succeeded) OVERRIDE { - EXPECT_TRUE(succeeded); - ++times_output_surface_created_; - } - - virtual void DidCommitAndDrawFrame() OVERRIDE { + EXPECT_FALSE(succeeded); + // If we make it this far without crashing, we pass! EndTest(); } - - virtual void AfterTest() OVERRIDE { - // Should not try to create output surface again after successfully - // created by CompositeAndReadback. - EXPECT_EQ(1, times_output_surface_created_); - } - - private: - int times_output_surface_created_; }; -SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeHostContextTestCompositeAndReadbackBeforeOutputSurfaceInit); +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestFailsImmediately); class ImplSidePaintingLayerTreeHostContextTest : public LayerTreeHostContextTest { @@ -1365,38 +1261,5 @@ class LayerTreeHostContextTestFailsToCreateSurface SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestFailsToCreateSurface); -// Not reusing LayerTreeTest because it expects creating LTH to always succeed. -class LayerTreeHostTestCannotCreateIfCannotCreateOutputSurface - : public testing::Test, - public FakeLayerTreeHostClient { - public: - LayerTreeHostTestCannotCreateIfCannotCreateOutputSurface() - : FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D) {} - - // FakeLayerTreeHostClient - virtual scoped_ptr<OutputSurface> CreateOutputSurface() { - return scoped_ptr<OutputSurface>(); - } - - void RunTest(bool threaded) { - scoped_ptr<base::Thread> impl_thread; - scoped_ptr<cc::Thread> impl_ccthread(NULL); - if (threaded) { - impl_thread.reset(new base::Thread("LayerTreeTest")); - impl_ccthread = cc::ThreadImpl::CreateForDifferentThread( - impl_thread->message_loop_proxy()); - ASSERT_TRUE(impl_ccthread); - } - - LayerTreeSettings settings; - scoped_ptr<LayerTreeHost> layer_tree_host = - LayerTreeHost::Create(this, settings, impl_ccthread.Pass()); - EXPECT_FALSE(layer_tree_host); - } -}; - -SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeHostTestCannotCreateIfCannotCreateOutputSurface); - } // namespace } // namespace cc diff --git a/cc/trees/proxy.h b/cc/trees/proxy.h index d2d678f..14c6f80 100644 --- a/cc/trees/proxy.h +++ b/cc/trees/proxy.h @@ -21,7 +21,6 @@ class Vector2d; namespace cc { -class OutputSurface; class Thread; struct RendererCapabilities; @@ -54,16 +53,24 @@ class CC_EXPORT Proxy { virtual bool IsStarted() const = 0; + // Attempts to initialize a context to use for rendering. Returns false if + // the context could not be created. The context will not be used and no + // frames may be produced until InitializeRenderer() is called. + virtual bool InitializeOutputSurface() = 0; + // Indicates that the compositing surface associated with our context is // ready to use. virtual void SetSurfaceReady() = 0; virtual void SetVisible(bool visible) = 0; - // Attempts to recreate the context and renderer synchronously after the - // output surface is lost. Calls - // LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted with the result. - virtual void CreateAndInitializeOutputSurface() = 0; + // Attempts to initialize the layer renderer. Returns false if the context + // isn't usable for compositing. + virtual bool InitializeRenderer() = 0; + + // Attempts to recreate the context and layer renderer after a context lost. + // Returns false if the renderer couldn't be reinitialized. + virtual bool RecreateOutputSurface() = 0; virtual const RendererCapabilities& GetRendererCapabilities() const = 0; @@ -80,8 +87,7 @@ class CC_EXPORT Proxy { virtual bool CommitRequested() const = 0; - // Must be called before using the proxy. - virtual void Start(scoped_ptr<OutputSurface> first_output_surface) = 0; + virtual void Start() = 0; // Must be called before using the proxy. virtual void Stop() = 0; // Must be called before deleting the proxy. // Forces 3D commands on all contexts to wait for all previous SwapBuffers diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc index 2ca82a4..f8ee95a 100644 --- a/cc/trees/single_thread_proxy.cc +++ b/cc/trees/single_thread_proxy.cc @@ -25,7 +25,9 @@ scoped_ptr<Proxy> SingleThreadProxy::Create(LayerTreeHost* layer_tree_host) { SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host) : Proxy(scoped_ptr<Thread>(NULL)), layer_tree_host_(layer_tree_host), + output_surface_lost_(false), created_offscreen_context_provider_(false), + renderer_initialized_(false), next_frame_is_newly_committed_frame_(false), inside_draw_(false) { TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy"); @@ -37,18 +39,16 @@ SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host) << "Threaded compositing must be enabled to use impl-side painting."; } -void SingleThreadProxy::Start(scoped_ptr<OutputSurface> first_output_surface) { - DCHECK(first_output_surface); +void SingleThreadProxy::Start() { DebugScopedSetImplThread impl(this); layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this); - first_output_surface_ = first_output_surface.Pass(); } SingleThreadProxy::~SingleThreadProxy() { TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy"); DCHECK(Proxy::IsMainThread()); - // Make sure Stop() got called or never Started. - DCHECK(!layer_tree_host_impl_); + DCHECK(!layer_tree_host_impl_.get() && + !layer_tree_host_); // make sure Stop() got called. } bool SingleThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) { @@ -90,6 +90,16 @@ bool SingleThreadProxy::IsStarted() const { return layer_tree_host_impl_; } +bool SingleThreadProxy::InitializeOutputSurface() { + DCHECK(Proxy::IsMainThread()); + scoped_ptr<OutputSurface> output_surface = + layer_tree_host_->CreateOutputSurface(); + if (!output_surface) + return false; + output_surface_before_initialization_ = output_surface.Pass(); + return true; +} + void SingleThreadProxy::SetSurfaceReady() { // Scheduling is controlled by the embedder in the single thread case, so // nothing to do. @@ -100,47 +110,51 @@ void SingleThreadProxy::SetVisible(bool visible) { layer_tree_host_impl_->SetVisible(visible); } -void SingleThreadProxy::CreateAndInitializeOutputSurface() { - TRACE_EVENT0( - "cc", "SingleThreadProxy::CreateAndInitializeOutputSurface"); +bool SingleThreadProxy::InitializeRenderer() { DCHECK(Proxy::IsMainThread()); + DCHECK(output_surface_before_initialization_.get()); + { + DebugScopedSetImplThread impl(this); + bool ok = layer_tree_host_impl_->InitializeRenderer( + output_surface_before_initialization_.Pass()); + if (ok) { + renderer_initialized_ = true; + renderer_capabilities_for_main_thread_ = + layer_tree_host_impl_->GetRendererCapabilities(); + } - scoped_ptr<OutputSurface> output_surface = first_output_surface_.Pass(); - if (!output_surface) - output_surface = layer_tree_host_->CreateOutputSurface(); - if (!output_surface) { - OnOutputSurfaceInitializeAttempted(false); - return; + return ok; } +} + +bool SingleThreadProxy::RecreateOutputSurface() { + TRACE_EVENT0("cc", "SingleThreadProxy::RecreateContext"); + DCHECK(Proxy::IsMainThread()); + DCHECK(output_surface_lost_); + scoped_ptr<OutputSurface> output_surface = + layer_tree_host_->CreateOutputSurface(); + if (!output_surface) + return false; scoped_refptr<cc::ContextProvider> offscreen_context_provider; if (created_offscreen_context_provider_) { offscreen_context_provider = layer_tree_host_->client()->OffscreenContextProviderForMainThread(); - if (!offscreen_context_provider) { - OnOutputSurfaceInitializeAttempted(false); - return; - } + if (!offscreen_context_provider) + return false; } + bool initialized; { DebugScopedSetMainThreadBlocked mainThreadBlocked(this); DebugScopedSetImplThread impl(this); layer_tree_host_->DeleteContentsTexturesOnImplThread( layer_tree_host_impl_->resource_provider()); - } - - bool initialized; - { - DebugScopedSetImplThread impl(this); - - DCHECK(output_surface); - initialized = layer_tree_host_impl_->InitializeRenderer( - output_surface.Pass()); + initialized = + layer_tree_host_impl_->InitializeRenderer(output_surface.Pass()); if (initialized) { renderer_capabilities_for_main_thread_ = layer_tree_host_impl_->GetRendererCapabilities(); - layer_tree_host_impl_->resource_provider()-> set_offscreen_context_provider(offscreen_context_provider); } else if (offscreen_context_provider) { @@ -148,21 +162,15 @@ void SingleThreadProxy::CreateAndInitializeOutputSurface() { } } - OnOutputSurfaceInitializeAttempted(initialized); -} + if (initialized) + output_surface_lost_ = false; -void SingleThreadProxy::OnOutputSurfaceInitializeAttempted(bool success) { - LayerTreeHost::CreateResult result = - layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success); - if (result == LayerTreeHost::CreateFailedButTryAgain) { - // Force another recreation attempt to happen by requesting another commit. - SetNeedsCommit(); - } + return initialized; } const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const { - DCHECK(Proxy::IsMainThread()); - DCHECK(!layer_tree_host_->output_surface_lost()); + DCHECK(renderer_initialized_); + // Note: this gets called during the commit by the "impl" thread. return renderer_capabilities_for_main_thread_; } @@ -360,10 +368,8 @@ scoped_ptr<base::Value> SingleThreadProxy::AsValue() const { void SingleThreadProxy::ForceSerializeOnSwapBuffers() { { DebugScopedSetImplThread impl(this); - if (layer_tree_host_impl_->renderer()) { - DCHECK(!layer_tree_host_->output_surface_lost()); + if (renderer_initialized_) layer_tree_host_impl_->renderer()->DoNoOp(); - } } } @@ -373,7 +379,7 @@ bool SingleThreadProxy::CommitAndComposite( LayerTreeHostImpl::FrameData* frame) { DCHECK(Proxy::IsMainThread()); - if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded()) + if (!layer_tree_host_->InitializeRendererIfNeeded()) return false; scoped_refptr<cc::ContextProvider> offscreen_context_provider; @@ -413,9 +419,7 @@ bool SingleThreadProxy::DoComposite( base::TimeTicks frame_begin_time, gfx::Rect device_viewport_damage_rect, LayerTreeHostImpl::FrameData* frame) { - DCHECK(!layer_tree_host_->output_surface_lost()); - - bool lost_output_surface = false; + DCHECK(!output_surface_lost_); { DebugScopedSetImplThread impl(this); base::AutoReset<bool> mark_inside(&inside_draw_, true); @@ -440,7 +444,7 @@ bool SingleThreadProxy::DoComposite( layer_tree_host_impl_->PrepareToDraw(frame, device_viewport_damage_rect); layer_tree_host_impl_->DrawLayers(frame, frame_begin_time); layer_tree_host_impl_->DidDrawAllLayers(*frame); - lost_output_surface = layer_tree_host_impl_->IsContextLost(); + output_surface_lost_ = layer_tree_host_impl_->IsContextLost(); bool start_ready_animations = true; layer_tree_host_impl_->UpdateAnimationState(start_ready_animations); @@ -448,7 +452,7 @@ bool SingleThreadProxy::DoComposite( layer_tree_host_impl_->BeginNextFrame(); } - if (lost_output_surface) { + if (output_surface_lost_) { cc::ContextProvider* offscreen_contexts = layer_tree_host_impl_-> resource_provider()->offscreen_context_provider(); if (offscreen_contexts) diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h index 06c843f..e290fb0 100644 --- a/cc/trees/single_thread_proxy.h +++ b/cc/trees/single_thread_proxy.h @@ -26,9 +26,11 @@ class SingleThreadProxy : public Proxy, LayerTreeHostImplClient { virtual bool CompositeAndReadback(void* pixels, gfx::Rect rect) OVERRIDE; virtual void FinishAllRendering() OVERRIDE; virtual bool IsStarted() const OVERRIDE; + virtual bool InitializeOutputSurface() OVERRIDE; virtual void SetSurfaceReady() OVERRIDE; virtual void SetVisible(bool visible) OVERRIDE; - virtual void CreateAndInitializeOutputSurface() OVERRIDE; + virtual bool InitializeRenderer() OVERRIDE; + virtual bool RecreateOutputSurface() OVERRIDE; virtual const RendererCapabilities& GetRendererCapabilities() const OVERRIDE; virtual void SetNeedsAnimate() OVERRIDE; virtual void SetNeedsCommit() OVERRIDE; @@ -36,7 +38,7 @@ class SingleThreadProxy : public Proxy, LayerTreeHostImplClient { virtual void SetDeferCommits(bool defer_commits) OVERRIDE; virtual bool CommitRequested() const OVERRIDE; virtual void MainThreadHasStoppedFlinging() OVERRIDE {} - virtual void Start(scoped_ptr<OutputSurface> first_output_surface) OVERRIDE; + virtual void Start() OVERRIDE; virtual void Stop() OVERRIDE; virtual size_t MaxPartialTextureUpdates() const OVERRIDE; virtual void AcquireLayerTextures() OVERRIDE {} @@ -79,7 +81,6 @@ class SingleThreadProxy : public Proxy, LayerTreeHostImplClient { private: explicit SingleThreadProxy(LayerTreeHost* layer_tree_host); - void OnOutputSurfaceInitializeAttempted(bool success); bool CommitAndComposite(base::TimeTicks frame_begin_time, gfx::Rect device_viewport_damage_rect, LayerTreeHostImpl::FrameData* frame); @@ -95,15 +96,17 @@ class SingleThreadProxy : public Proxy, LayerTreeHostImplClient { // Accessed on main thread only. LayerTreeHost* layer_tree_host_; + bool output_surface_lost_; bool created_offscreen_context_provider_; - // Holds the first output surface passed from Start. Should not be used for - // anything else. - scoped_ptr<OutputSurface> first_output_surface_; + // Holds on to the context between initializeContext() and + // InitializeRenderer() calls. Shouldn't be used for anything else. + scoped_ptr<OutputSurface> output_surface_before_initialization_; // Used on the Thread, but checked on main thread during // initialization/shutdown. scoped_ptr<LayerTreeHostImpl> layer_tree_host_impl_; + bool renderer_initialized_; RendererCapabilities renderer_capabilities_for_main_thread_; bool next_frame_is_newly_committed_frame_; diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc index 8e44bb4..b9dc6b7 100644 --- a/cc/trees/thread_proxy.cc +++ b/cc/trees/thread_proxy.cc @@ -46,6 +46,7 @@ ThreadProxy::ThreadProxy(LayerTreeHost* layer_tree_host, commit_request_sent_to_impl_thread_(false), created_offscreen_context_provider_(false), layer_tree_host_(layer_tree_host), + renderer_initialized_(false), started_(false), textures_acquired_(true), in_composite_and_readback_(false), @@ -67,7 +68,6 @@ ThreadProxy::ThreadProxy(LayerTreeHost* layer_tree_host, renew_tree_priority_on_impl_thread_pending_(false) { TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy"); DCHECK(IsMainThread()); - DCHECK(layer_tree_host_); } ThreadProxy::~ThreadProxy() { @@ -82,7 +82,7 @@ bool ThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) { DCHECK(layer_tree_host_); DCHECK(!defer_commits_); - if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded()) { + if (!layer_tree_host_->InitializeRendererIfNeeded()) { TRACE_EVENT0("cc", "CompositeAndReadback_EarlyOut_LR_Uninitialized"); return false; } @@ -149,6 +149,19 @@ bool ThreadProxy::IsStarted() const { return started_; } +bool ThreadProxy::InitializeOutputSurface() { + TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurface"); + scoped_ptr<OutputSurface> context = layer_tree_host_->CreateOutputSurface(); + if (!context) + return false; + + Proxy::ImplThread()->PostTask( + base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread, + impl_thread_weak_ptr_, + base::Passed(&context))); + return true; +} + void ThreadProxy::SetSurfaceReady() { TRACE_EVENT0("cc", "ThreadProxy::SetSurfaceReady"); Proxy::ImplThread()->PostTask(base::Bind( @@ -157,7 +170,7 @@ void ThreadProxy::SetSurfaceReady() { void ThreadProxy::SetSurfaceReadyOnImplThread() { TRACE_EVENT0("cc", "ThreadProxy::SetSurfaceReadyOnImplThread"); - scheduler_on_impl_thread_->SetCanStart(); + scheduler_on_impl_thread_->SetCanBeginFrame(true); } void ThreadProxy::SetVisible(bool visible) { @@ -179,79 +192,71 @@ void ThreadProxy::SetVisibleOnImplThread(CompletionEvent* completion, completion->Signal(); } -void ThreadProxy::DoCreateAndInitializeOutputSurface() { - TRACE_EVENT0("cc", "ThreadProxy::DoCreateAndInitializeOutputSurface"); - DCHECK(IsMainThread()); - - scoped_ptr<OutputSurface> output_surface = first_output_surface_.Pass(); - if (!output_surface) - output_surface = layer_tree_host_->CreateOutputSurface(); - +bool ThreadProxy::InitializeRenderer() { + TRACE_EVENT0("cc", "ThreadProxy::InitializeRenderer"); + // Make a blocking call to InitializeRendererOnImplThread. The results of that + // call are pushed into the initialize_succeeded and capabilities local + // variables. + CompletionEvent completion; + bool initialize_succeeded = false; RendererCapabilities capabilities; - bool success = !!output_surface; - if (!success) { - OnOutputSurfaceInitializeAttempted(false, capabilities); - return; + DebugScopedSetMainThreadBlocked main_thread_blocked(this); + Proxy::ImplThread()->PostTask( + base::Bind(&ThreadProxy::InitializeRendererOnImplThread, + impl_thread_weak_ptr_, + &completion, + &initialize_succeeded, + &capabilities)); + completion.Wait(); + + if (initialize_succeeded) { + renderer_initialized_ = true; + renderer_capabilities_main_thread_copy_ = capabilities; } + return initialize_succeeded; +} + +bool ThreadProxy::RecreateOutputSurface() { + TRACE_EVENT0("cc", "ThreadProxy::RecreateOutputSurface"); + DCHECK(IsMainThread()); - scoped_refptr<ContextProvider> offscreen_context_provider; + // Try to create the surface. + scoped_ptr<OutputSurface> output_surface = + layer_tree_host_->CreateOutputSurface(); + if (!output_surface) + return false; + scoped_refptr<cc::ContextProvider> offscreen_context_provider; if (created_offscreen_context_provider_) { offscreen_context_provider = layer_tree_host_->client()-> OffscreenContextProviderForCompositorThread(); - success = !!offscreen_context_provider; - if (!success) { - OnOutputSurfaceInitializeAttempted(false, capabilities); - return; - } + if (!offscreen_context_provider) + return false; } - success = false; - { - // Make a blocking call to InitializeOutputSurfaceOnImplThread. The results - // of that call are pushed into the success and capabilities local - // variables. - CompletionEvent completion; - DebugScopedSetMainThreadBlocked main_thread_blocked(this); - - Proxy::ImplThread()->PostTask( - base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread, - impl_thread_weak_ptr_, - &completion, - base::Passed(&output_surface), - offscreen_context_provider, - &success, - &capabilities)); - completion.Wait(); - } - - OnOutputSurfaceInitializeAttempted(success, capabilities); -} - -void ThreadProxy::OnOutputSurfaceInitializeAttempted( - bool success, - const RendererCapabilities& capabilities) { - DCHECK(IsMainThread()); - DCHECK(layer_tree_host_); + // Make a blocking call to RecreateOutputSurfaceOnImplThread. The results of + // that call are pushed into the recreate_succeeded and capabilities local + // variables. + CompletionEvent completion; + bool recreate_succeeded = false; + RendererCapabilities capabilities; + DebugScopedSetMainThreadBlocked main_thread_blocked(this); + Proxy::ImplThread()->PostTask( + base::Bind(&ThreadProxy::RecreateOutputSurfaceOnImplThread, + impl_thread_weak_ptr_, + &completion, + base::Passed(&output_surface), + offscreen_context_provider, + &recreate_succeeded, + &capabilities)); + completion.Wait(); - if (success) { + if (recreate_succeeded) renderer_capabilities_main_thread_copy_ = capabilities; - } - - LayerTreeHost::CreateResult result = - layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success); - if (result == LayerTreeHost::CreateFailedButTryAgain) { - if (!output_surface_creation_callback_.callback().is_null()) { - Proxy::MainThread()->PostTask( - output_surface_creation_callback_.callback()); - } - } else { - output_surface_creation_callback_.Cancel(); - } + return recreate_succeeded; } const RendererCapabilities& ThreadProxy::GetRendererCapabilities() const { - DCHECK(IsMainThread()); - DCHECK(!layer_tree_host_->output_surface_lost()); + DCHECK(renderer_initialized_); return renderer_capabilities_main_thread_copy_; } @@ -509,10 +514,9 @@ void ThreadProxy::MainThreadHasStoppedFlinging() { input_handler_on_impl_thread_->MainThreadHasStoppedFlinging(); } -void ThreadProxy::Start(scoped_ptr<OutputSurface> first_output_surface) { +void ThreadProxy::Start() { DCHECK(IsMainThread()); DCHECK(Proxy::ImplThread()); - DCHECK(first_output_surface); // Create LayerTreeHostImpl. DebugScopedSetMainThreadBlocked main_thread_blocked(this); CompletionEvent completion; @@ -525,7 +529,6 @@ void ThreadProxy::Start(scoped_ptr<OutputSurface> first_output_surface) { completion.Wait(); main_thread_weak_ptr_ = weak_factory_.GetWeakPtr(); - first_output_surface_ = first_output_surface.Pass(); started_ = true; } @@ -566,7 +569,7 @@ void ThreadProxy::ForceSerializeOnSwapBuffers() { void ThreadProxy::ForceSerializeOnSwapBuffersOnImplThread( CompletionEvent* completion) { - if (layer_tree_host_impl_->renderer()) + if (renderer_initialized_) layer_tree_host_impl_->renderer()->DoNoOp(); completion->Signal(); } @@ -676,6 +679,11 @@ void ThreadProxy::BeginFrame( commit_requested_ = false; commit_request_sent_to_impl_thread_ = false; + if (!layer_tree_host_->InitializeRendererIfNeeded()) { + TRACE_EVENT0("cc", "EarlyOut_InitializeFailed"); + return; + } + scoped_ptr<ResourceUpdateQueue> queue = make_scoped_ptr(new ResourceUpdateQueue); layer_tree_host_->UpdateLayers( @@ -845,11 +853,10 @@ void ThreadProxy::ScheduledActionActivatePendingTreeIfNeeded() { layer_tree_host_impl_->ActivatePendingTreeIfNeeded(); } -void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() { +void ThreadProxy::ScheduledActionBeginContextRecreation() { DCHECK(IsImplThread()); Proxy::MainThread()->PostTask( - base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface, - main_thread_weak_ptr_)); + base::Bind(&ThreadProxy::BeginContextRecreation, main_thread_weak_ptr_)); } ScheduledActionDrawAndSwapResult @@ -1050,39 +1057,25 @@ void ThreadProxy::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events, layer_tree_host_->SetAnimationEvents(events.Pass(), wall_clock_time); } -void ThreadProxy::CreateAndInitializeOutputSurface() { - TRACE_EVENT0("cc", "ThreadProxy::CreateAndInitializeOutputSurface"); +void ThreadProxy::BeginContextRecreation() { + TRACE_EVENT0("cc", "ThreadProxy::BeginContextRecreation"); DCHECK(IsMainThread()); - - // Check that output surface has not been recreated by CompositeAndReadback - // after this task is posted but before it is run. - bool has_initialized_output_surface_on_impl_thread = true; - { - CompletionEvent completion; - Proxy::ImplThread()->PostTask( - base::Bind(&ThreadProxy::HasInitializedOutputSurfaceOnImplThread, - impl_thread_weak_ptr_, - &completion, - &has_initialized_output_surface_on_impl_thread)); - completion.Wait(); - } - if (has_initialized_output_surface_on_impl_thread) - return; - layer_tree_host_->DidLoseOutputSurface(); - output_surface_creation_callback_.Reset(base::Bind( - &ThreadProxy::DoCreateAndInitializeOutputSurface, - base::Unretained(this))); - output_surface_creation_callback_.callback().Run(); + output_surface_recreation_callback_.Reset(base::Bind( + &ThreadProxy::TryToRecreateOutputSurface, base::Unretained(this))); + Proxy::MainThread()->PostTask(output_surface_recreation_callback_.callback()); } -void ThreadProxy::HasInitializedOutputSurfaceOnImplThread( - CompletionEvent* completion, - bool* has_initialized_output_surface) { - DCHECK(IsImplThread()); - *has_initialized_output_surface = - scheduler_on_impl_thread_->HasInitializedOutputSurface(); - completion->Signal(); +void ThreadProxy::TryToRecreateOutputSurface() { + DCHECK(IsMainThread()); + DCHECK(layer_tree_host_); + LayerTreeHost::RecreateResult result = + layer_tree_host_->RecreateOutputSurface(); + if (result == LayerTreeHost::RecreateFailedButTryAgain) + Proxy::MainThread()->PostTask( + output_surface_recreation_callback_.callback()); + else if (result == LayerTreeHost::RecreateSucceeded) + output_surface_recreation_callback_.Cancel(); } void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion, @@ -1126,47 +1119,34 @@ void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion, } void ThreadProxy::InitializeOutputSurfaceOnImplThread( + scoped_ptr<OutputSurface> output_surface) { + TRACE_EVENT0("cc", "ThreadProxy::InitializeContextOnImplThread"); + DCHECK(IsImplThread()); + output_surface_before_initialization_on_impl_thread_ = output_surface.Pass(); +} + +void ThreadProxy::InitializeRendererOnImplThread( CompletionEvent* completion, - scoped_ptr<OutputSurface> output_surface, - scoped_refptr<ContextProvider> offscreen_context_provider, - bool* success, + bool* initialize_succeeded, RendererCapabilities* capabilities) { - TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread"); + TRACE_EVENT0("cc", "ThreadProxy::InitializeRendererOnImplThread"); DCHECK(IsImplThread()); - DCHECK(IsMainThreadBlocked()); - DCHECK(success); - DCHECK(capabilities); - - layer_tree_host_->DeleteContentsTexturesOnImplThread( - layer_tree_host_impl_->resource_provider()); - - *success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass()); - - if (offscreen_context_provider) - offscreen_context_provider->BindToCurrentThread(); - - if (*success) { + DCHECK(output_surface_before_initialization_on_impl_thread_.get()); + *initialize_succeeded = layer_tree_host_impl_->InitializeRenderer( + output_surface_before_initialization_on_impl_thread_.Pass()); + if (*initialize_succeeded) { *capabilities = layer_tree_host_impl_->GetRendererCapabilities(); scheduler_on_impl_thread_->SetSwapBuffersCompleteSupported( capabilities->using_swap_complete_callback); - OutputSurface* output_surface_ptr = layer_tree_host_impl_->output_surface(); - DCHECK(output_surface_ptr); - int max_frames_pending = - output_surface_ptr->capabilities().max_frames_pending; + int max_frames_pending = layer_tree_host_impl_->output_surface()-> + capabilities().max_frames_pending; if (max_frames_pending <= 0) max_frames_pending = FrameRateController::DEFAULT_MAX_FRAMES_PENDING; - if (output_surface_ptr->capabilities().has_parent_compositor) + if (layer_tree_host_impl_->output_surface()->capabilities(). + has_parent_compositor) max_frames_pending = 1; - scheduler_on_impl_thread_->SetMaxFramesPending(max_frames_pending); - - layer_tree_host_impl_->resource_provider()-> - set_offscreen_context_provider(offscreen_context_provider); - - scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface(); - } else if (offscreen_context_provider) { - offscreen_context_provider->VerifyContexts(); } completion->Signal(); @@ -1190,6 +1170,33 @@ size_t ThreadProxy::MaxPartialTextureUpdates() const { return ResourceUpdateController::MaxPartialTextureUpdates(); } +void ThreadProxy::RecreateOutputSurfaceOnImplThread( + CompletionEvent* completion, + scoped_ptr<OutputSurface> output_surface, + scoped_refptr<cc::ContextProvider> offscreen_context_provider, + bool* recreate_succeeded, + RendererCapabilities* capabilities) { + TRACE_EVENT0("cc", "ThreadProxy::RecreateOutputSurfaceOnImplThread"); + DCHECK(IsImplThread()); + + layer_tree_host_->DeleteContentsTexturesOnImplThread( + layer_tree_host_impl_->resource_provider()); + *recreate_succeeded = + layer_tree_host_impl_->InitializeRenderer(output_surface.Pass()); + if (offscreen_context_provider) + offscreen_context_provider->BindToCurrentThread(); + + if (*recreate_succeeded) { + *capabilities = layer_tree_host_impl_->GetRendererCapabilities(); + layer_tree_host_impl_->resource_provider()-> + set_offscreen_context_provider(offscreen_context_provider); + scheduler_on_impl_thread_->DidRecreateOutputSurface(); + } else if (offscreen_context_provider) { + offscreen_context_provider->VerifyContexts(); + } + completion->Signal(); +} + ThreadProxy::BeginFrameAndCommitState::BeginFrameAndCommitState() : memory_allocation_limit_bytes(0) {} diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h index 1523b77..30b08782 100644 --- a/cc/trees/thread_proxy.h +++ b/cc/trees/thread_proxy.h @@ -41,9 +41,11 @@ class ThreadProxy : public Proxy, virtual bool CompositeAndReadback(void* pixels, gfx::Rect rect) OVERRIDE; virtual void FinishAllRendering() OVERRIDE; virtual bool IsStarted() const OVERRIDE; + virtual bool InitializeOutputSurface() OVERRIDE; virtual void SetSurfaceReady() OVERRIDE; virtual void SetVisible(bool visible) OVERRIDE; - virtual void CreateAndInitializeOutputSurface() OVERRIDE; + virtual bool InitializeRenderer() OVERRIDE; + virtual bool RecreateOutputSurface() OVERRIDE; virtual const RendererCapabilities& GetRendererCapabilities() const OVERRIDE; virtual void SetNeedsAnimate() OVERRIDE; virtual void SetNeedsCommit() OVERRIDE; @@ -51,7 +53,7 @@ class ThreadProxy : public Proxy, virtual void SetDeferCommits(bool defer_commits) OVERRIDE; virtual bool CommitRequested() const OVERRIDE; virtual void MainThreadHasStoppedFlinging() OVERRIDE; - virtual void Start(scoped_ptr<OutputSurface> first_output_surface) OVERRIDE; + virtual void Start() OVERRIDE; virtual void Stop() OVERRIDE; virtual size_t MaxPartialTextureUpdates() const OVERRIDE; virtual void AcquireLayerTextures() OVERRIDE; @@ -97,7 +99,7 @@ class ThreadProxy : public Proxy, virtual void ScheduledActionCommit() OVERRIDE; virtual void ScheduledActionCheckForCompletedTileUploads() OVERRIDE; virtual void ScheduledActionActivatePendingTreeIfNeeded() OVERRIDE; - virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE; + virtual void ScheduledActionBeginContextRecreation() OVERRIDE; virtual void ScheduledActionAcquireLayerTexturesForMainThread() OVERRIDE; virtual void DidAnticipatedDrawTimeChange(base::TimeTicks time) OVERRIDE; @@ -130,11 +132,8 @@ class ThreadProxy : public Proxy, void DidCompleteSwapBuffers(); void SetAnimationEvents(scoped_ptr<AnimationEventsVector> queue, base::Time wall_clock_time); - void DoCreateAndInitializeOutputSurface(); - // |capabilities| is set only when |success| is true. - void OnOutputSurfaceInitializeAttempted( - bool success, - const RendererCapabilities& capabilities); + void BeginContextRecreation(); + void TryToRecreateOutputSurface(); // Called on impl thread. struct ReadbackRequest { @@ -159,19 +158,21 @@ class ThreadProxy : public Proxy, InputHandler* input_handler); void SetSurfaceReadyOnImplThread(); void SetVisibleOnImplThread(CompletionEvent* completion, bool visible); - void HasInitializedOutputSurfaceOnImplThread( - CompletionEvent* completion, - bool* has_initialized_output_surface); void InitializeOutputSurfaceOnImplThread( - CompletionEvent* completion, - scoped_ptr<OutputSurface> output_surface, - scoped_refptr<ContextProvider> offscreen_context_provider, - bool* success, - RendererCapabilities* capabilities); + scoped_ptr<OutputSurface> output_surface); + void InitializeRendererOnImplThread(CompletionEvent* completion, + bool* initialize_succeeded, + RendererCapabilities* capabilities); void LayerTreeHostClosedOnImplThread(CompletionEvent* completion); void ManageTilesOnImplThread(); void AcquireLayerTexturesForMainThreadOnImplThread( CompletionEvent* completion); + void RecreateOutputSurfaceOnImplThread( + CompletionEvent* completion, + scoped_ptr<OutputSurface> output_surface, + scoped_refptr<cc::ContextProvider> offscreen_context_provider, + bool* recreate_succeeded, + RendererCapabilities* capabilities); ScheduledActionDrawAndSwapResult ScheduledActionDrawAndSwapInternal( bool forced_draw); void ForceSerializeOnSwapBuffersOnImplThread(CompletionEvent* completion); @@ -196,8 +197,9 @@ class ThreadProxy : public Proxy, bool commit_request_sent_to_impl_thread_; // Set by BeginFrame bool created_offscreen_context_provider_; - base::CancelableClosure output_surface_creation_callback_; + base::CancelableClosure output_surface_recreation_callback_; LayerTreeHost* layer_tree_host_; + bool renderer_initialized_; RendererCapabilities renderer_capabilities_main_thread_copy_; bool started_; bool textures_acquired_; @@ -205,9 +207,6 @@ class ThreadProxy : public Proxy, bool manage_tiles_pending_; // Weak pointer to use when posting tasks to the impl thread. base::WeakPtr<ThreadProxy> impl_thread_weak_ptr_; - // Holds the first output surface passed from Start. Should not be used for - // anything else. - scoped_ptr<OutputSurface> first_output_surface_; base::WeakPtrFactory<ThreadProxy> weak_factory_on_impl_thread_; @@ -220,6 +219,11 @@ class ThreadProxy : public Proxy, scoped_ptr<Scheduler> scheduler_on_impl_thread_; + // Holds on to the context we might use for compositing in between + // InitializeContext() and InitializeRenderer() calls. + scoped_ptr<OutputSurface> + output_surface_before_initialization_on_impl_thread_; + // Set when the main thread is waiting on a ScheduledActionBeginFrame to be // issued. CompletionEvent* begin_frame_completion_event_on_impl_thread_; |