Cherry-pick: cc: Update Main RendererCapabilities on DeferredInitialize

Clean cherry-pick of crrev.com/r251853 with additional modifications.

Original change depends on crrev.com/r246957 and modified to remove this
dependency.

Original description:

Also update caps on ReleaseGL. The updated RendererCapabilities
are posted back to the main thread. Main thread layers will
receive OnOutputSurfaceCreated (should be renamed to
OnRendererCapabilitiesChanged) when this happens. Note this
is also called on first renderer initialization.

BUG: 13328348

Change-Id: I42a71879690d52a8e237bd86a1f7cfd99c851687
diff --git a/cc/test/fake_layer_tree_host_impl_client.h b/cc/test/fake_layer_tree_host_impl_client.h
index 17c50b9..58c9a88 100644
--- a/cc/test/fake_layer_tree_host_impl_client.h
+++ b/cc/test/fake_layer_tree_host_impl_client.h
@@ -13,6 +13,7 @@
 class FakeLayerTreeHostImplClient : public LayerTreeHostImplClient {
  public:
   // LayerTreeHostImplClient implementation.
+  virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE {}
   virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE {}
   virtual void DidSwapBuffersOnImplThread() OVERRIDE {}
   virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {}
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 818c2ff..8b26dce 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -1708,6 +1708,7 @@
     active_tree_->set_needs_update_draw_properties();
     if (pending_tree_)
       pending_tree_->set_needs_update_draw_properties();
+    client_->UpdateRendererCapabilitiesOnImplThread();
   }
 }
 
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index f705a66..058f394 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -58,6 +58,7 @@
 // LayerTreeHost->Proxy callback interface.
 class LayerTreeHostImplClient {
  public:
+  virtual void UpdateRendererCapabilitiesOnImplThread() = 0;
   virtual void DidLoseOutputSurfaceOnImplThread() = 0;
   virtual void DidSwapBuffersOnImplThread() = 0;
   virtual void OnSwapBuffersCompleteOnImplThread() = 0;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 4630adc..5af3ce1 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -103,6 +103,7 @@
 
   virtual void TearDown() OVERRIDE {}
 
+  virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE {}
   virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE {}
   virtual void DidSwapBuffersOnImplThread() OVERRIDE {}
   virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {}
@@ -4910,9 +4911,14 @@
     offscreen_context_provider_ = TestContextProvider::Create();
   }
 
+  virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE {
+    did_update_renderer_capabilities_ = true;
+  }
+
   FakeOutputSurface* output_surface_;
   scoped_refptr<TestContextProvider> onscreen_context_provider_;
   scoped_refptr<TestContextProvider> offscreen_context_provider_;
+  bool did_update_renderer_capabilities_;
 };
 
 
@@ -4924,20 +4930,24 @@
   EXPECT_FALSE(host_impl_->offscreen_context_provider());
 
   // DeferredInitialize and hardware draw.
+  did_update_renderer_capabilities_ = false;
   EXPECT_TRUE(output_surface_->InitializeAndSetContext3d(
       onscreen_context_provider_, offscreen_context_provider_));
   EXPECT_EQ(onscreen_context_provider_,
             host_impl_->output_surface()->context_provider());
   EXPECT_EQ(offscreen_context_provider_,
             host_impl_->offscreen_context_provider());
+  EXPECT_TRUE(did_update_renderer_capabilities_);
 
   // Defer intialized GL draw.
   DrawFrame();
 
   // Revert back to software.
+  did_update_renderer_capabilities_ = false;
   output_surface_->ReleaseGL();
   EXPECT_FALSE(host_impl_->output_surface()->context_provider());
   EXPECT_FALSE(host_impl_->offscreen_context_provider());
+  EXPECT_TRUE(did_update_renderer_capabilities_);
 
   // Software draw again.
   DrawFrame();
@@ -4955,15 +4965,20 @@
   EXPECT_FALSE(host_impl_->offscreen_context_provider());
 
   // DeferredInitialize fails.
+  did_update_renderer_capabilities_ = false;
   EXPECT_FALSE(output_surface_->InitializeAndSetContext3d(
       onscreen_context_provider_, offscreen_context_provider_));
   EXPECT_FALSE(host_impl_->output_surface()->context_provider());
   EXPECT_FALSE(host_impl_->offscreen_context_provider());
+  EXPECT_FALSE(did_update_renderer_capabilities_);
 
   // Software draw again.
   DrawFrame();
 }
 
+// TODO(boliu): After r239415, fails_OnscreenContext_1 and 2 are exactly the
+// same as 0. They were supposed to test makeCurrent failing in the
+// OutputSurface, LayerTreeHostImpl, and GLRenderer respectively.
 TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OnscreenContext_1) {
   // Software draw.
   DrawFrame();
@@ -4975,10 +4990,12 @@
 
   EXPECT_FALSE(host_impl_->output_surface()->context_provider());
   // DeferredInitialize fails.
+  did_update_renderer_capabilities_ = false;
   EXPECT_FALSE(output_surface_->InitializeAndSetContext3d(
       onscreen_context_provider_, offscreen_context_provider_));
   EXPECT_FALSE(host_impl_->output_surface()->context_provider());
   EXPECT_FALSE(host_impl_->offscreen_context_provider());
+  EXPECT_FALSE(did_update_renderer_capabilities_);
 }
 
 TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OnscreenContext_2) {
@@ -4991,10 +5008,12 @@
   onscreen_context_provider_->UnboundTestContext3d()->set_context_lost(true);
 
   // DeferredInitialize fails.
+  did_update_renderer_capabilities_ = false;
   EXPECT_FALSE(output_surface_->InitializeAndSetContext3d(
       onscreen_context_provider_, offscreen_context_provider_));
   EXPECT_FALSE(host_impl_->output_surface()->context_provider());
   EXPECT_FALSE(host_impl_->offscreen_context_provider());
+  EXPECT_FALSE(did_update_renderer_capabilities_);
 }
 
 TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OffscreenContext) {
@@ -5008,10 +5027,12 @@
   onscreen_context_provider_->UnboundTestContext3d()->set_context_lost(true);
 
   // DeferredInitialize fails.
+  did_update_renderer_capabilities_ = false;
   EXPECT_FALSE(output_surface_->InitializeAndSetContext3d(
       onscreen_context_provider_, offscreen_context_provider_));
   EXPECT_FALSE(host_impl_->output_surface()->context_provider());
   EXPECT_FALSE(host_impl_->offscreen_context_provider());
+  EXPECT_FALSE(did_update_renderer_capabilities_);
 }
 
 // Checks that we have a non-0 default allocation if we pass a context that
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc
index a313588..dcdeb01 100644
--- a/cc/trees/single_thread_proxy.cc
+++ b/cc/trees/single_thread_proxy.cc
@@ -146,11 +146,7 @@
     DCHECK(output_surface);
     initialized = layer_tree_host_impl_->InitializeRenderer(
         output_surface.Pass());
-    if (initialized) {
-      renderer_capabilities_for_main_thread_ =
-          layer_tree_host_impl_->GetRendererCapabilities()
-              .MainThreadCapabilities();
-    } else if (offscreen_context_provider.get()) {
+    if (!initialized && offscreen_context_provider.get()) {
       offscreen_context_provider->VerifyContexts();
       offscreen_context_provider = NULL;
     }
@@ -360,6 +356,12 @@
 
 bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
 
+void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
+  DCHECK(IsImplThread());
+  renderer_capabilities_for_main_thread_ =
+      layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities();
+}
+
 void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
   // Cause a commit so we can notice the lost context.
   SetNeedsCommitOnImplThread();
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h
index 463141c..7452377 100644
--- a/cc/trees/single_thread_proxy.h
+++ b/cc/trees/single_thread_proxy.h
@@ -53,6 +53,7 @@
   virtual bool CommitPendingForTesting() OVERRIDE;
 
   // LayerTreeHostImplClient implementation
+  virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE;
   virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE;
   virtual void DidSwapBuffersOnImplThread() OVERRIDE;
   virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE;
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
index 62e0ca2..25b5df3 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -311,6 +311,11 @@
   OnOutputSurfaceInitializeAttempted(success, capabilities);
 }
 
+void ThreadProxy::SetRendererCapabilitiesMainThreadCopy(
+    const RendererCapabilities& capabilities) {
+  renderer_capabilities_main_thread_copy_ = capabilities;
+}
+
 void ThreadProxy::OnOutputSurfaceInitializeAttempted(
     bool success,
     const RendererCapabilities& capabilities) {
@@ -384,6 +389,16 @@
   SendCommitRequestToImplThreadIfNeeded();
 }
 
+void ThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
+  DCHECK(IsImplThread());
+  Proxy::MainThreadTaskRunner()->PostTask(
+      FROM_HERE,
+      base::Bind(&ThreadProxy::SetRendererCapabilitiesMainThreadCopy,
+                 main_thread_weak_ptr_,
+                 layer_tree_host_impl_->GetRendererCapabilities()
+                     .MainThreadCapabilities()));
+}
+
 void ThreadProxy::DidLoseOutputSurfaceOnImplThread() {
   DCHECK(IsImplThread());
   TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread");
diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h
index cf041ed..c14f927 100644
--- a/cc/trees/thread_proxy.h
+++ b/cc/trees/thread_proxy.h
@@ -68,6 +68,7 @@
   virtual scoped_ptr<base::Value> SchedulerStateAsValueForTesting() OVERRIDE;
 
   // LayerTreeHostImplClient implementation
+  virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE;
   virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE;
   virtual void DidSwapBuffersOnImplThread() OVERRIDE {}
   virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE;
@@ -135,6 +136,8 @@
   };
 
   // Called on main thread.
+  void SetRendererCapabilitiesMainThreadCopy(
+      const RendererCapabilities& capabilities);
   void BeginMainFrame(
       scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state);
   void DidCommitAndDrawFrame();