De-Client CommandBuffer interface

This removes the CommandBufferClient interface from mojo.CommandBuffer.
It had two methods on it:

*) DidDestroy() which is redundant with the pipe closing, removed.
*) DidLoseContext(uint32 reason) which is used to signal an error code
prior to the pipe closing. Replaced with an observer interface.

BUG=451319
R=sky@chromium.org

Review URL: https://codereview.chromium.org/868203003
diff --git a/mojo/gles2/command_buffer_client_impl.cc b/mojo/gles2/command_buffer_client_impl.cc
index 502757f..e8d3690 100644
--- a/mojo/gles2/command_buffer_client_impl.cc
+++ b/mojo/gles2/command_buffer_client_impl.cc
@@ -116,13 +116,13 @@
     const MojoAsyncWaiter* async_waiter,
     mojo::ScopedMessagePipeHandle command_buffer_handle)
     : delegate_(delegate),
+      observer_binding_(this),
       shared_state_(NULL),
       last_put_offset_(-1),
       next_transfer_buffer_id_(0),
       async_waiter_(async_waiter) {
   command_buffer_.Bind(command_buffer_handle.Pass(), async_waiter);
   command_buffer_.set_error_handler(this);
-  command_buffer_.set_client(this);
 }
 
 CommandBufferClientImpl::~CommandBufferClientImpl() {}
@@ -147,7 +147,11 @@
   sync_point_client_impl_.reset(
       new SyncPointClientImpl(&sync_point_client, async_waiter_));
 
-  command_buffer_->Initialize(sync_client.Pass(), sync_point_client.Pass(),
+  mojo::CommandBufferLostContextObserverPtr observer_ptr;
+  observer_binding_.Bind(GetProxy(&observer_ptr), async_waiter_);
+  command_buffer_->Initialize(sync_client.Pass(),
+                              sync_point_client.Pass(),
+                              observer_ptr.Pass(),
                               duped.Pass());
 
   // Wait for DidInitialize to come on the sync client pipe.
@@ -290,11 +294,7 @@
   return 0;
 }
 
-void CommandBufferClientImpl::DidDestroy() {
-  LostContext(gpu::error::kUnknown);
-}
-
-void CommandBufferClientImpl::LostContext(int32_t lost_reason) {
+void CommandBufferClientImpl::DidLoseContext(int32_t lost_reason) {
   last_state_.error = gpu::error::kLostContext;
   last_state_.context_lost_reason =
       static_cast<gpu::error::ContextLostReason>(lost_reason);
@@ -302,7 +302,7 @@
 }
 
 void CommandBufferClientImpl::OnConnectionError() {
-  LostContext(gpu::error::kUnknown);
+  DidLoseContext(gpu::error::kUnknown);
 }
 
 void CommandBufferClientImpl::TryUpdateState() {
@@ -317,7 +317,7 @@
   if (!state) {
     VLOG(1) << "Channel encountered error while waiting for command buffer";
     // TODO(piman): is it ok for this to re-enter?
-    DidDestroy();
+    DidLoseContext(gpu::error::kUnknown);
     return;
   }
 
diff --git a/mojo/gles2/command_buffer_client_impl.h b/mojo/gles2/command_buffer_client_impl.h
index b37da0a..dcedb52 100644
--- a/mojo/gles2/command_buffer_client_impl.h
+++ b/mojo/gles2/command_buffer_client_impl.h
@@ -28,7 +28,7 @@
   virtual void ContextLost();
 };
 
-class CommandBufferClientImpl : public mojo::CommandBufferClient,
+class CommandBufferClientImpl : public mojo::CommandBufferLostContextObserver,
                                 public mojo::ErrorHandler,
                                 public gpu::CommandBuffer,
                                 public gpu::GpuControl {
@@ -75,11 +75,10 @@
   class SyncClientImpl;
   class SyncPointClientImpl;
 
-  // CommandBufferClient implementation:
-  void DidDestroy() override;
-  void LostContext(int32_t lost_reason) override;
+  // mojo::CommandBufferLostContextObserver implementation:
+  void DidLoseContext(int32_t lost_reason) override;
 
-  // ErrorHandler implementation:
+  // mojo::ErrorHandler implementation:
   void OnConnectionError() override;
 
   void TryUpdateState();
@@ -88,6 +87,7 @@
   gpu::CommandBufferSharedState* shared_state() const { return shared_state_; }
 
   CommandBufferDelegate* delegate_;
+  mojo::Binding<mojo::CommandBufferLostContextObserver> observer_binding_;
   mojo::CommandBufferPtr command_buffer_;
   scoped_ptr<SyncClientImpl> sync_client_impl_;
   scoped_ptr<SyncPointClientImpl> sync_point_client_impl_;
diff --git a/mojo/services/gpu/public/interfaces/command_buffer.mojom b/mojo/services/gpu/public/interfaces/command_buffer.mojom
index a31b3dd..aa2c556 100644
--- a/mojo/services/gpu/public/interfaces/command_buffer.mojom
+++ b/mojo/services/gpu/public/interfaces/command_buffer.mojom
@@ -25,10 +25,19 @@
   DidInsertSyncPoint(uint32 sync_point);
 };
 
-[Client=CommandBufferClient]
+interface CommandBufferLostContextObserver {
+  DidLoseContext(int32 context_lost_reason);
+};
+
 interface CommandBuffer {
+  // Initialize attempts to initialize the command buffer. Success or failure
+  // will be communicated via the CommandBufferSyncClient DidInitialize() call.
+  // If the context is lost after creation the LostContext method on the
+  // CommandBufferLostContextObserver's will be called then this pipe will be
+  // closed.
   Initialize(CommandBufferSyncClient sync_client,
              CommandBufferSyncPointClient sync_point_client,
+             CommandBufferLostContextObserver lost_observer,
              handle<shared_buffer> shared_state);
   SetGetBuffer(int32 buffer);
   Flush(int32 put_offset);
@@ -43,11 +52,4 @@
   InsertSyncPoint(bool retire);
   RetireSyncPoint(uint32 sync_point);
   Echo() => ();
-
-  // TODO(piman): sync points
-};
-
-interface CommandBufferClient {
-  DidDestroy();
-  LostContext(int32 lost_reason);  // TODO(piman): enum
 };
diff --git a/services/gles2/command_buffer_driver.cc b/services/gles2/command_buffer_driver.cc
index 5d159b4..98b8578 100644
--- a/services/gles2/command_buffer_driver.cc
+++ b/services/gles2/command_buffer_driver.cc
@@ -81,13 +81,14 @@
     bool have_context = decoder_->MakeCurrent();
     decoder_->Destroy(have_context);
   }
-  client_->DidDestroy();
 }
 
 void CommandBufferDriver::Initialize(
     mojo::CommandBufferSyncClientPtr sync_client,
+    mojo::CommandBufferLostContextObserverPtr loss_observer,
     mojo::ScopedSharedBufferHandle shared_state) {
   sync_client_ = sync_client.Pass();
+  loss_observer_ = loss_observer.Pass();
   bool success = DoInitialize(shared_state.Pass());
   mojo::GpuCapabilitiesPtr capabilities =
       success ? mojo::GpuCapabilities::From(decoder_->GetCapabilities())
@@ -238,7 +239,8 @@
 }
 
 void CommandBufferDriver::OnContextLost(uint32_t reason) {
-  client_->LostContext(reason);
+  loss_observer_->DidLoseContext(reason);
+  client_->DidLoseContext();
 }
 
 void CommandBufferDriver::OnUpdateVSyncParameters(
diff --git a/services/gles2/command_buffer_driver.h b/services/gles2/command_buffer_driver.h
index f157ca6..3c855a7 100644
--- a/services/gles2/command_buffer_driver.h
+++ b/services/gles2/command_buffer_driver.h
@@ -37,13 +37,10 @@
  public:
   class Client {
    public:
-    virtual void DidDestroy() = 0;
+    virtual ~Client();
     virtual void UpdateVSyncParameters(base::TimeTicks timebase,
                                        base::TimeDelta interval) = 0;
-    virtual void LostContext(int32_t lost_reason) = 0;
-
-   protected:
-    virtual ~Client();
+    virtual void DidLoseContext() = 0;
   };
   // Offscreen.
   CommandBufferDriver(gfx::GLShareGroup* share_group,
@@ -57,9 +54,10 @@
                       gpu::SyncPointManager* sync_point_manager);
   ~CommandBufferDriver();
 
-  void set_client(Client* client) { client_ = client; }
+  void set_client(scoped_ptr<Client> client) { client_ = client.Pass(); }
 
   void Initialize(mojo::CommandBufferSyncClientPtr sync_client,
+                  mojo::CommandBufferLostContextObserverPtr loss_observer,
                   mojo::ScopedSharedBufferHandle shared_state);
   void SetGetBuffer(int32_t buffer);
   void Flush(int32_t put_offset);
@@ -80,8 +78,9 @@
   void OnUpdateVSyncParameters(const base::TimeTicks timebase,
                                const base::TimeDelta interval);
 
-  Client* client_;
+  scoped_ptr<Client> client_;
   mojo::CommandBufferSyncClientPtr sync_client_;
+  mojo::CommandBufferLostContextObserverPtr loss_observer_;
   gfx::AcceleratedWidget widget_;
   gfx::Size size_;
   scoped_ptr<gpu::CommandBufferService> command_buffer_;
diff --git a/services/gles2/command_buffer_impl.cc b/services/gles2/command_buffer_impl.cc
index 129238c..c370068 100644
--- a/services/gles2/command_buffer_impl.cc
+++ b/services/gles2/command_buffer_impl.cc
@@ -28,8 +28,6 @@
         control_task_runner_(control_task_runner) {}
 
  private:
-  void DidDestroy() override { delete this; }
-
   void UpdateVSyncParameters(base::TimeTicks timebase,
                              base::TimeDelta interval) override {
     control_task_runner_->PostTask(
@@ -37,10 +35,10 @@
                               command_buffer_, timebase, interval));
   }
 
-  void LostContext(int32_t lost_reason) override {
+  void DidLoseContext() override {
     control_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&CommandBufferImpl::LostContext, command_buffer_,
-                              lost_reason));
+        FROM_HERE, base::Bind(&CommandBufferImpl::DidLoseContext,
+           command_buffer_));
   }
 
   base::WeakPtr<CommandBufferImpl> command_buffer_;
@@ -60,8 +58,8 @@
       viewport_parameter_listener_(listener.Pass()),
       binding_(this),
       weak_factory_(this) {
-  driver_->set_client(new CommandBufferDriverClientImpl(
-      weak_factory_.GetWeakPtr(), control_task_runner));
+  driver_->set_client(make_scoped_ptr(new CommandBufferDriverClientImpl(
+      weak_factory_.GetWeakPtr(), control_task_runner)));
 
   control_task_runner->PostTask(
       FROM_HERE, base::Bind(&CommandBufferImpl::BindToRequest,
@@ -69,7 +67,6 @@
 }
 
 CommandBufferImpl::~CommandBufferImpl() {
-  binding_.client()->DidDestroy();
   driver_task_runner_->PostTask(
       FROM_HERE, base::Bind(&DestroyDriver, base::Passed(&driver_)));
 }
@@ -77,12 +74,14 @@
 void CommandBufferImpl::Initialize(
     mojo::CommandBufferSyncClientPtr sync_client,
     mojo::CommandBufferSyncPointClientPtr sync_point_client,
+    mojo::CommandBufferLostContextObserverPtr loss_observer,
     mojo::ScopedSharedBufferHandle shared_state) {
   sync_point_client_ = sync_point_client.Pass();
   driver_task_runner_->PostTask(
       FROM_HERE,
       base::Bind(&CommandBufferDriver::Initialize,
                  base::Unretained(driver_.get()), base::Passed(&sync_client),
+                 base::Passed(&loss_observer),
                  base::Passed(&shared_state)));
 }
 
@@ -146,8 +145,8 @@
   binding_.Bind(request.Pass());
 }
 
-void CommandBufferImpl::LostContext(int32_t reason) {
-  binding_.client()->LostContext(reason);
+void CommandBufferImpl::DidLoseContext() {
+  binding_.OnConnectionError();
 }
 
 void CommandBufferImpl::UpdateVSyncParameters(base::TimeTicks timebase,
diff --git a/services/gles2/command_buffer_impl.h b/services/gles2/command_buffer_impl.h
index a165772..a6bf27d 100644
--- a/services/gles2/command_buffer_impl.h
+++ b/services/gles2/command_buffer_impl.h
@@ -35,6 +35,7 @@
 
   void Initialize(mojo::CommandBufferSyncClientPtr sync_client,
                   mojo::CommandBufferSyncPointClientPtr sync_point_client,
+                  mojo::CommandBufferLostContextObserverPtr loss_observer,
                   mojo::ScopedSharedBufferHandle shared_state) override;
   void SetGetBuffer(int32_t buffer) override;
   void Flush(int32_t put_offset) override;
@@ -47,7 +48,7 @@
   void RetireSyncPoint(uint32_t sync_point) override;
   void Echo(const mojo::Callback<void()>& callback) override;
 
-  void LostContext(int32_t reason);
+  void DidLoseContext();
   void UpdateVSyncParameters(base::TimeTicks timebase,
                              base::TimeDelta interval);