Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / mojo / gles2 / command_buffer_client_impl.cc
index 60fa366..233573f 100644 (file)
 
 #include "base/logging.h"
 #include "base/process/process_handle.h"
-#include "mojo/public/bindings/allocation_scope.h"
-#include "mojo/public/bindings/sync_dispatcher.h"
 #include "mojo/services/gles2/command_buffer_type_conversions.h"
+#include "mojo/services/gles2/mojo_buffer_backing.h"
 
 namespace mojo {
 namespace gles2 {
 
+namespace {
+
+bool CreateMapAndDupSharedBuffer(size_t size,
+                                 void** memory,
+                                 mojo::ScopedSharedBufferHandle* handle,
+                                 mojo::ScopedSharedBufferHandle* duped) {
+  MojoResult result = mojo::CreateSharedBuffer(NULL, size, handle);
+  if (result != MOJO_RESULT_OK)
+    return false;
+  DCHECK(handle->is_valid());
+
+  result = mojo::DuplicateBuffer(handle->get(), NULL, duped);
+  if (result != MOJO_RESULT_OK)
+    return false;
+  DCHECK(duped->is_valid());
+
+  result = mojo::MapBuffer(
+      handle->get(), 0, size, memory, MOJO_MAP_BUFFER_FLAG_NONE);
+  if (result != MOJO_RESULT_OK)
+    return false;
+  DCHECK(*memory);
+
+  return true;
+}
+
+}  // namespace
+
 CommandBufferDelegate::~CommandBufferDelegate() {}
 
 void CommandBufferDelegate::ContextLost() {}
-void CommandBufferDelegate::DrawAnimationFrame() {}
+
+class CommandBufferClientImpl::SyncClientImpl
+    : public InterfaceImpl<CommandBufferSyncClient> {
+ public:
+  SyncClientImpl() : initialized_successfully_(false) {}
+
+  bool WaitForInitialization() {
+    if (!WaitForIncomingMethodCall())
+      return false;
+    return initialized_successfully_;
+  }
+
+  CommandBufferStatePtr WaitForProgress() {
+    if (!WaitForIncomingMethodCall())
+      return CommandBufferStatePtr();
+    return command_buffer_state_.Pass();
+  }
+
+ private:
+  // CommandBufferSyncClient methods:
+  virtual void DidInitialize(bool success) OVERRIDE {
+    initialized_successfully_ = success;
+  }
+  virtual void DidMakeProgress(CommandBufferStatePtr state) OVERRIDE {
+    command_buffer_state_ = state.Pass();
+  }
+
+  bool initialized_successfully_;
+  CommandBufferStatePtr command_buffer_state_;
+};
 
 CommandBufferClientImpl::CommandBufferClientImpl(
     CommandBufferDelegate* delegate,
-    MojoAsyncWaiter* async_waiter,
-    ScopedCommandBufferHandle command_buffer_handle)
+    const MojoAsyncWaiter* async_waiter,
+    ScopedMessagePipeHandle command_buffer_handle)
     : delegate_(delegate),
-      command_buffer_(command_buffer_handle.Pass(), this, this, async_waiter),
+      shared_state_(NULL),
       last_put_offset_(-1),
       next_transfer_buffer_id_(0),
-      initialize_result_(false) {}
+      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() {}
 
 bool CommandBufferClientImpl::Initialize() {
-  shared_state_shm_.reset(new base::SharedMemory);
-  if (!shared_state_shm_->CreateAndMapAnonymous(
-           sizeof(gpu::CommandBufferSharedState)))
+  const size_t kSharedStateSize = sizeof(gpu::CommandBufferSharedState);
+  void* memory = NULL;
+  mojo::ScopedSharedBufferHandle duped;
+  bool result = CreateMapAndDupSharedBuffer(
+      kSharedStateSize, &memory, &shared_state_handle_, &duped);
+  if (!result)
     return false;
 
-  base::SharedMemoryHandle handle;
-  shared_state_shm_->ShareToProcess(base::GetCurrentProcessHandle(), &handle);
-  if (!base::SharedMemory::IsHandleValid(handle))
-    return false;
+  shared_state_ = static_cast<gpu::CommandBufferSharedState*>(memory);
 
   shared_state()->Initialize();
 
-  InterfacePipe<CommandBufferSyncClient, NoInterface> sync_pipe;
-  sync_dispatcher_.reset(new SyncDispatcher<CommandBufferSyncClient>(
-      sync_pipe.handle_to_peer.Pass(), this));
-  AllocationScope scope;
-  command_buffer_->Initialize(sync_pipe.handle_to_self.Pass(), handle);
+  CommandBufferSyncClientPtr sync_client;
+  sync_client_impl_.reset(
+      WeakBindToProxy(new SyncClientImpl(), &sync_client, async_waiter_));
+
+  command_buffer_->Initialize(sync_client.Pass(), duped.Pass());
+
   // Wait for DidInitialize to come on the sync client pipe.
-  if (!sync_dispatcher_->WaitAndDispatchOneMessage()) {
+  if (!sync_client_impl_->WaitForInitialization()) {
     VLOG(1) << "Channel encountered error while creating command buffer";
     return false;
   }
-  return initialize_result_;
-}
-
-gpu::CommandBuffer::State CommandBufferClientImpl::GetState() {
-  MakeProgressAndUpdateState();
-  return last_state_;
+  return true;
 }
 
 gpu::CommandBuffer::State CommandBufferClientImpl::GetLastState() {
@@ -80,15 +135,22 @@ void CommandBufferClientImpl::Flush(int32 put_offset) {
   command_buffer_->Flush(put_offset);
 }
 
-gpu::CommandBuffer::State CommandBufferClientImpl::FlushSync(
-    int32 put_offset,
-    int32 last_known_get) {
-  Flush(put_offset);
+void CommandBufferClientImpl::WaitForTokenInRange(int32 start, int32 end) {
   TryUpdateState();
-  if (last_known_get == last_state_.get_offset)
+  while (!InRange(start, end, last_state_.token) &&
+         last_state_.error == gpu::error::kNoError) {
     MakeProgressAndUpdateState();
+    TryUpdateState();
+  }
+}
 
-  return last_state_;
+void CommandBufferClientImpl::WaitForGetOffsetInRange(int32 start, int32 end) {
+  TryUpdateState();
+  while (!InRange(start, end, last_state_.get_offset) &&
+         last_state_.error == gpu::error::kNoError) {
+    MakeProgressAndUpdateState();
+    TryUpdateState();
+  }
 }
 
 void CommandBufferClientImpl::SetGetBuffer(int32 shm_id) {
@@ -96,75 +158,33 @@ void CommandBufferClientImpl::SetGetBuffer(int32 shm_id) {
   last_put_offset_ = -1;
 }
 
-void CommandBufferClientImpl::SetGetOffset(int32 get_offset) {
-  // Not implemented in proxy.
-  NOTREACHED();
-}
-
-gpu::Buffer CommandBufferClientImpl::CreateTransferBuffer(size_t size,
-                                                          int32* id) {
-  gpu::Buffer buffer;
+scoped_refptr<gpu::Buffer> CommandBufferClientImpl::CreateTransferBuffer(
+    size_t size,
+    int32* id) {
   if (size >= std::numeric_limits<uint32_t>::max())
-    return buffer;
-
-  scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
-  if (!shared_memory->CreateAndMapAnonymous(size))
-    return buffer;
+    return NULL;
 
-  base::SharedMemoryHandle handle;
-  shared_memory->ShareToProcess(base::GetCurrentProcessHandle(), &handle);
-  if (!base::SharedMemory::IsHandleValid(handle))
-    return buffer;
+  void* memory = NULL;
+  mojo::ScopedSharedBufferHandle handle;
+  mojo::ScopedSharedBufferHandle duped;
+  if (!CreateMapAndDupSharedBuffer(size, &memory, &handle, &duped))
+    return NULL;
 
   *id = ++next_transfer_buffer_id_;
-  DCHECK(transfer_buffers_.find(*id) == transfer_buffers_.end());
 
-  AllocationScope scope;
   command_buffer_->RegisterTransferBuffer(
-      *id, handle, static_cast<uint32_t>(size));
-
-  buffer.ptr = shared_memory->memory();
-  buffer.size = size;
-  buffer.shared_memory = shared_memory.release();
-  transfer_buffers_[*id] = buffer;
+      *id, duped.Pass(), static_cast<uint32_t>(size));
 
+  scoped_ptr<gpu::BufferBacking> backing(
+      new MojoBufferBacking(handle.Pass(), memory, size));
+  scoped_refptr<gpu::Buffer> buffer(new gpu::Buffer(backing.Pass()));
   return buffer;
 }
 
 void CommandBufferClientImpl::DestroyTransferBuffer(int32 id) {
-  TransferBufferMap::iterator it = transfer_buffers_.find(id);
-  if (it != transfer_buffers_.end()) {
-    delete it->second.shared_memory;
-    transfer_buffers_.erase(it);
-  }
   command_buffer_->DestroyTransferBuffer(id);
 }
 
-gpu::Buffer CommandBufferClientImpl::GetTransferBuffer(int32 id) {
-  TransferBufferMap::iterator it = transfer_buffers_.find(id);
-  if (it != transfer_buffers_.end()) {
-    return it->second;
-  } else {
-    return gpu::Buffer();
-  }
-}
-
-void CommandBufferClientImpl::SetToken(int32 token) {
-  // Not implemented in proxy.
-  NOTREACHED();
-}
-
-void CommandBufferClientImpl::SetParseError(gpu::error::Error error) {
-  // Not implemented in proxy.
-  NOTREACHED();
-}
-
-void CommandBufferClientImpl::SetContextLostReason(
-    gpu::error::ContextLostReason reason) {
-  // Not implemented in proxy.
-  NOTREACHED();
-}
-
 gpu::Capabilities CommandBufferClientImpl::GetCapabilities() {
   // TODO(piman)
   NOTIMPLEMENTED();
@@ -175,6 +195,7 @@ gfx::GpuMemoryBuffer* CommandBufferClientImpl::CreateGpuMemoryBuffer(
     size_t width,
     size_t height,
     unsigned internalformat,
+    unsigned usage,
     int32* id) {
   // TODO(piman)
   NOTIMPLEMENTED();
@@ -187,9 +208,20 @@ void CommandBufferClientImpl::DestroyGpuMemoryBuffer(int32 id) {
 }
 
 uint32 CommandBufferClientImpl::InsertSyncPoint() {
+  // TODO(jamesr): Optimize this.
+  WaitForGetOffsetInRange(last_put_offset_, last_put_offset_);
+  return 0;
+}
+
+uint32 CommandBufferClientImpl::InsertFutureSyncPoint() {
+  // TODO(jamesr): Optimize this.
+  WaitForGetOffsetInRange(last_put_offset_, last_put_offset_);
+  return 0;
+}
+
+void CommandBufferClientImpl::RetireSyncPoint(uint32 sync_point) {
   // TODO(piman)
   NOTIMPLEMENTED();
-  return 0;
 }
 
 void CommandBufferClientImpl::SignalSyncPoint(uint32 sync_point,
@@ -209,15 +241,8 @@ void CommandBufferClientImpl::SetSurfaceVisible(bool visible) {
   NOTIMPLEMENTED();
 }
 
-void CommandBufferClientImpl::SendManagedMemoryStats(
-    const gpu::ManagedMemoryStats& stats) {
-  // TODO(piman)
-  NOTIMPLEMENTED();
-}
-
 void CommandBufferClientImpl::Echo(const base::Closure& callback) {
-  echo_closures_.push(callback);
-  command_buffer_->Echo();
+  command_buffer_->Echo(callback);
 }
 
 uint32 CommandBufferClientImpl::CreateStreamTexture(uint32 texture_id) {
@@ -226,33 +251,10 @@ uint32 CommandBufferClientImpl::CreateStreamTexture(uint32 texture_id) {
   return 0;
 }
 
-void CommandBufferClientImpl::RequestAnimationFrames() {
-  command_buffer_->RequestAnimationFrames();
-}
-
-void CommandBufferClientImpl::CancelAnimationFrames() {
-  command_buffer_->CancelAnimationFrames();
-}
-
-void CommandBufferClientImpl::DidInitialize(bool success) {
-  initialize_result_ = success;
-}
-
-void CommandBufferClientImpl::DidMakeProgress(const CommandBufferState& state) {
-  if (state.generation() - last_state_.generation < 0x80000000U)
-    last_state_ = state;
-}
-
 void CommandBufferClientImpl::DidDestroy() {
   LostContext(gpu::error::kUnknown);
 }
 
-void CommandBufferClientImpl::EchoAck() {
-  base::Closure closure = echo_closures_.front();
-  echo_closures_.pop();
-  closure.Run();
-}
-
 void CommandBufferClientImpl::LostContext(int32_t lost_reason) {
   last_state_.error = gpu::error::kLostContext;
   last_state_.context_lost_reason =
@@ -260,7 +262,9 @@ void CommandBufferClientImpl::LostContext(int32_t lost_reason) {
   delegate_->ContextLost();
 }
 
-void CommandBufferClientImpl::OnError() { LostContext(gpu::error::kUnknown); }
+void CommandBufferClientImpl::OnConnectionError() {
+  LostContext(gpu::error::kUnknown);
+}
 
 void CommandBufferClientImpl::TryUpdateState() {
   if (last_state_.error == gpu::error::kNoError)
@@ -269,16 +273,17 @@ void CommandBufferClientImpl::TryUpdateState() {
 
 void CommandBufferClientImpl::MakeProgressAndUpdateState() {
   command_buffer_->MakeProgress(last_state_.get_offset);
-  if (!sync_dispatcher_->WaitAndDispatchOneMessage()) {
+
+  CommandBufferStatePtr state = sync_client_impl_->WaitForProgress();
+  if (!state) {
     VLOG(1) << "Channel encountered error while waiting for command buffer";
     // TODO(piman): is it ok for this to re-enter?
     DidDestroy();
     return;
   }
-}
 
-void CommandBufferClientImpl::DrawAnimationFrame() {
-  delegate_->DrawAnimationFrame();
+  if (state->generation - last_state_.generation < 0x80000000U)
+    last_state_ = state.To<State>();
 }
 
 }  // namespace gles2