Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / common / gpu / client / command_buffer_proxy_impl.cc
index 8ed2802..3364883 100644 (file)
 #include "content/common/child_process_messages.h"
 #include "content/common/gpu/client/gpu_channel_host.h"
 #include "content/common/gpu/client/gpu_video_decode_accelerator_host.h"
+#include "content/common/gpu/client/gpu_video_encode_accelerator_host.h"
 #include "content/common/gpu/gpu_messages.h"
 #include "content/common/view_messages.h"
+#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
 #include "gpu/command_buffer/common/cmd_buffer_common.h"
 #include "gpu/command_buffer/common/command_buffer_shared.h"
 #include "gpu/command_buffer/common/gpu_memory_allocation.h"
+#include "gpu/command_buffer/service/image_factory.h"
 #include "ui/gfx/size.h"
+#include "ui/gl/gl_bindings.h"
 
 namespace content {
 
@@ -41,12 +45,13 @@ bool CommandBufferProxyImpl::OnMessageReceived(const IPC::Message& message) {
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(CommandBufferProxyImpl, message)
     IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Destroyed, OnDestroyed);
-    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_EchoAck, OnEchoAck);
     IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_ConsoleMsg, OnConsoleMessage);
     IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetMemoryAllocation,
                         OnSetMemoryAllocation);
     IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalSyncPointAck,
                         OnSignalSyncPointAck);
+    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SwapBuffersCompleted,
+                        OnSwapBuffersCompleted);
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
 
@@ -74,13 +79,6 @@ void CommandBufferProxyImpl::OnDestroyed(gpu::error::ContextLostReason reason) {
   }
 }
 
-void CommandBufferProxyImpl::OnEchoAck() {
-  DCHECK(!echo_tasks_.empty());
-  base::Closure callback = echo_tasks_.front();
-  echo_tasks_.pop();
-  callback.Run();
-}
-
 void CommandBufferProxyImpl::OnConsoleMessage(
     const GPUCommandBufferConsoleMessage& message) {
   if (!console_message_callback_.is_null()) {
@@ -127,6 +125,7 @@ void CommandBufferProxyImpl::SetChannelErrorCallback(
 }
 
 bool CommandBufferProxyImpl::Initialize() {
+  TRACE_EVENT0("gpu", "CommandBufferProxyImpl::Initialize");
   shared_state_shm_.reset(channel_->factory()->AllocateSharedMemory(
       sizeof(*shared_state())).release());
   if (!shared_state_shm_)
@@ -145,7 +144,7 @@ bool CommandBufferProxyImpl::Initialize() {
   if (!base::SharedMemory::IsHandleValid(handle))
     return false;
 
-  bool result;
+  bool result = false;
   if (!Send(new GpuCommandBufferMsg_Initialize(
       route_id_, handle, &result, &capabilities_))) {
     LOG(ERROR) << "Could not send GpuCommandBufferMsg_Initialize.";
@@ -157,23 +156,11 @@ bool CommandBufferProxyImpl::Initialize() {
     return false;
   }
 
-  capabilities_.map_image = true;
+  capabilities_.image = true;
 
   return true;
 }
 
-gpu::CommandBuffer::State CommandBufferProxyImpl::GetState() {
-  // Send will flag state with lost context if IPC fails.
-  if (last_state_.error == gpu::error::kNoError) {
-    gpu::CommandBuffer::State state;
-    if (Send(new GpuCommandBufferMsg_GetState(route_id_, &state)))
-      OnUpdateState(state);
-  }
-
-  TryUpdateState();
-  return last_state_;
-}
-
 gpu::CommandBuffer::State CommandBufferProxyImpl::GetLastState() {
   return last_state_;
 }
@@ -199,14 +186,20 @@ void CommandBufferProxyImpl::Flush(int32 put_offset) {
 
   Send(new GpuCommandBufferMsg_AsyncFlush(route_id_,
                                           put_offset,
-                                          ++flush_count_));
+                                          ++flush_count_,
+                                          latency_info_));
+  latency_info_.clear();
 }
 
 void CommandBufferProxyImpl::SetLatencyInfo(
     const std::vector<ui::LatencyInfo>& latency_info) {
-  if (last_state_.error != gpu::error::kNoError)
-    return;
-  Send(new GpuCommandBufferMsg_SetLatencyInfo(route_id_, latency_info));
+  for (size_t i = 0; i < latency_info.size(); i++)
+    latency_info_.push_back(latency_info[i]);
+}
+
+void CommandBufferProxyImpl::SetSwapBuffersCompletionCallback(
+    const SwapBuffersCompletionCallback& callback) {
+  swap_buffers_completion_callback_ = callback;
 }
 
 void CommandBufferProxyImpl::WaitForTokenInRange(int32 start, int32 end) {
@@ -217,13 +210,15 @@ void CommandBufferProxyImpl::WaitForTokenInRange(int32 start, int32 end) {
                "end",
                end);
   TryUpdateState();
-  while (!InRange(start, end, last_state_.token) &&
-         last_state_.error == gpu::error::kNoError) {
+  if (!InRange(start, end, last_state_.token) &&
+      last_state_.error == gpu::error::kNoError) {
     gpu::CommandBuffer::State state;
-    if (Send(new GpuCommandBufferMsg_GetStateFast(route_id_, &state)))
+    if (Send(new GpuCommandBufferMsg_WaitForTokenInRange(
+            route_id_, start, end, &state)))
       OnUpdateState(state);
-    TryUpdateState();
   }
+  DCHECK(InRange(start, end, last_state_.token) ||
+         last_state_.error != gpu::error::kNoError);
 }
 
 void CommandBufferProxyImpl::WaitForGetOffsetInRange(int32 start, int32 end) {
@@ -234,13 +229,15 @@ void CommandBufferProxyImpl::WaitForGetOffsetInRange(int32 start, int32 end) {
                "end",
                end);
   TryUpdateState();
-  while (!InRange(start, end, last_state_.get_offset) &&
-         last_state_.error == gpu::error::kNoError) {
+  if (!InRange(start, end, last_state_.get_offset) &&
+      last_state_.error == gpu::error::kNoError) {
     gpu::CommandBuffer::State state;
-    if (Send(new GpuCommandBufferMsg_GetStateFast(route_id_, &state)))
+    if (Send(new GpuCommandBufferMsg_WaitForGetOffsetInRange(
+            route_id_, start, end, &state)))
       OnUpdateState(state);
-    TryUpdateState();
   }
+  DCHECK(InRange(start, end, last_state_.get_offset) ||
+         last_state_.error != gpu::error::kNoError);
 }
 
 void CommandBufferProxyImpl::SetGetBuffer(int32 shm_id) {
@@ -251,11 +248,6 @@ void CommandBufferProxyImpl::SetGetBuffer(int32 shm_id) {
   last_put_offset_ = -1;
 }
 
-void CommandBufferProxyImpl::SetGetOffset(int32 get_offset) {
-  // Not implemented in proxy.
-  NOTREACHED();
-}
-
 scoped_refptr<gpu::Buffer> CommandBufferProxyImpl::CreateTransferBuffer(
     size_t size,
     int32* id) {
@@ -265,7 +257,6 @@ scoped_refptr<gpu::Buffer> CommandBufferProxyImpl::CreateTransferBuffer(
     return NULL;
 
   int32 new_id = channel_->ReserveTransferBufferId();
-  DCHECK(transfer_buffers_.find(new_id) == transfer_buffers_.end());
 
   scoped_ptr<base::SharedMemory> shared_memory(
       channel_->factory()->AllocateSharedMemory(size));
@@ -292,9 +283,8 @@ scoped_refptr<gpu::Buffer> CommandBufferProxyImpl::CreateTransferBuffer(
   }
 
   *id = new_id;
-  scoped_refptr<gpu::Buffer> buffer =
-      new gpu::Buffer(shared_memory.Pass(), size);
-  transfer_buffers_[new_id] = buffer;
+  scoped_refptr<gpu::Buffer> buffer(
+      gpu::MakeBufferFromSharedMemory(shared_memory.Pass(), size));
   return buffer;
 }
 
@@ -302,157 +292,94 @@ void CommandBufferProxyImpl::DestroyTransferBuffer(int32 id) {
   if (last_state_.error != gpu::error::kNoError)
     return;
 
-  // Remove the transfer buffer from the client side cache.
-  TransferBufferMap::iterator it = transfer_buffers_.find(id);
-  if (it != transfer_buffers_.end())
-    transfer_buffers_.erase(it);
-
   Send(new GpuCommandBufferMsg_DestroyTransferBuffer(route_id_, id));
 }
 
-scoped_refptr<gpu::Buffer> CommandBufferProxyImpl::GetTransferBuffer(int32 id) {
-  if (last_state_.error != gpu::error::kNoError)
-    return NULL;
-
-  // Check local cache to see if there is already a client side shared memory
-  // object for this id.
-  TransferBufferMap::iterator it = transfer_buffers_.find(id);
-  if (it != transfer_buffers_.end()) {
-    return it->second;
-  }
-
-  // Assuming we are in the renderer process, the service is responsible for
-  // duplicating the handle. This might not be true for NaCl.
-  base::SharedMemoryHandle handle = base::SharedMemoryHandle();
-  uint32 size;
-  if (!Send(new GpuCommandBufferMsg_GetTransferBuffer(route_id_,
-                                                      id,
-                                                      &handle,
-                                                      &size))) {
-    return NULL;
-  }
-
-  // Cache the transfer buffer shared memory object client side.
-  scoped_ptr<base::SharedMemory> shared_memory(
-      new base::SharedMemory(handle, false));
-
-  // Map the shared memory on demand.
-  if (!shared_memory->memory()) {
-    if (!shared_memory->Map(size))
-      return NULL;
-  }
-
-  scoped_refptr<gpu::Buffer> buffer =
-      new gpu::Buffer(shared_memory.Pass(), size);
-  transfer_buffers_[id] = buffer;
-
-  return buffer;
-}
-
-void CommandBufferProxyImpl::SetToken(int32 token) {
-  // Not implemented in proxy.
-  NOTREACHED();
-}
-
-void CommandBufferProxyImpl::SetParseError(
-    gpu::error::Error error) {
-  // Not implemented in proxy.
-  NOTREACHED();
-}
-
-void CommandBufferProxyImpl::SetContextLostReason(
-    gpu::error::ContextLostReason reason) {
-  // Not implemented in proxy.
-  NOTREACHED();
-}
-
 gpu::Capabilities CommandBufferProxyImpl::GetCapabilities() {
   return capabilities_;
 }
 
-gfx::GpuMemoryBuffer* CommandBufferProxyImpl::CreateGpuMemoryBuffer(
-    size_t width,
-    size_t height,
-    unsigned internalformat,
-    int32* id) {
-  *id = -1;
-
+int32_t CommandBufferProxyImpl::CreateImage(ClientBuffer buffer,
+                                            size_t width,
+                                            size_t height,
+                                            unsigned internalformat) {
   if (last_state_.error != gpu::error::kNoError)
-    return NULL;
-
-  int32 new_id = channel_->ReserveGpuMemoryBufferId();
-  DCHECK(gpu_memory_buffers_.find(new_id) == gpu_memory_buffers_.end());
+    return -1;
 
-  scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer(
-      channel_->factory()->AllocateGpuMemoryBuffer(width,
-                                                   height,
-                                                   internalformat));
-  if (!gpu_memory_buffer)
-    return NULL;
+  int32 new_id = channel_->ReserveImageId();
 
-  DCHECK(GpuChannelHost::IsValidGpuMemoryBuffer(
-             gpu_memory_buffer->GetHandle()));
+  gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager =
+      channel_->gpu_memory_buffer_manager();
+  gfx::GpuMemoryBuffer* gpu_memory_buffer =
+      gpu_memory_buffer_manager->GpuMemoryBufferFromClientBuffer(buffer);
+  DCHECK(gpu_memory_buffer);
 
   // This handle is owned by the GPU process and must be passed to it or it
   // will leak. In otherwords, do not early out on error between here and the
-  // sending of the RegisterGpuMemoryBuffer IPC below.
+  // sending of the CreateImage IPC below.
+  bool requires_sync_point = false;
   gfx::GpuMemoryBufferHandle handle =
-      channel_->ShareGpuMemoryBufferToGpuProcess(
-          gpu_memory_buffer->GetHandle());
-
-  if (!Send(new GpuCommandBufferMsg_RegisterGpuMemoryBuffer(
-                route_id_,
-                new_id,
-                handle,
-                width,
-                height,
-                internalformat))) {
-    return NULL;
+      channel_->ShareGpuMemoryBufferToGpuProcess(gpu_memory_buffer->GetHandle(),
+                                                 &requires_sync_point);
+
+  DCHECK(gpu::ImageFactory::IsImageFormatCompatibleWithGpuMemoryBufferFormat(
+      internalformat, gpu_memory_buffer->GetFormat()));
+  if (!Send(new GpuCommandBufferMsg_CreateImage(route_id_,
+                                                new_id,
+                                                handle,
+                                                gfx::Size(width, height),
+                                                gpu_memory_buffer->GetFormat(),
+                                                internalformat))) {
+    return -1;
   }
 
-  *id = new_id;
-  gpu_memory_buffers_[new_id] = gpu_memory_buffer.release();
-  return gpu_memory_buffers_[new_id];
+  if (requires_sync_point) {
+    gpu_memory_buffer_manager->SetDestructionSyncPoint(gpu_memory_buffer,
+                                                       InsertSyncPoint());
+  }
+
+  return new_id;
 }
 
-void CommandBufferProxyImpl::DestroyGpuMemoryBuffer(int32 id) {
+void CommandBufferProxyImpl::DestroyImage(int32 id) {
   if (last_state_.error != gpu::error::kNoError)
     return;
 
-  // Remove the gpu memory buffer from the client side cache.
-  GpuMemoryBufferMap::iterator it = gpu_memory_buffers_.find(id);
-  if (it != gpu_memory_buffers_.end()) {
-    delete it->second;
-    gpu_memory_buffers_.erase(it);
-  }
+  Send(new GpuCommandBufferMsg_DestroyImage(route_id_, id));
+}
 
-  Send(new GpuCommandBufferMsg_DestroyGpuMemoryBuffer(route_id_, id));
+int32_t CommandBufferProxyImpl::CreateGpuMemoryBufferImage(
+    size_t width,
+    size_t height,
+    unsigned internalformat,
+    unsigned usage) {
+  scoped_ptr<gfx::GpuMemoryBuffer> buffer(
+      channel_->gpu_memory_buffer_manager()->AllocateGpuMemoryBuffer(
+          gfx::Size(width, height),
+          gpu::ImageFactory::ImageFormatToGpuMemoryBufferFormat(internalformat),
+          gpu::ImageFactory::ImageUsageToGpuMemoryBufferUsage(usage)));
+  if (!buffer)
+    return -1;
+
+  return CreateImage(buffer->AsClientBuffer(), width, height, internalformat);
 }
 
 int CommandBufferProxyImpl::GetRouteID() const {
   return route_id_;
 }
 
-void CommandBufferProxyImpl::Echo(const base::Closure& callback) {
-  if (last_state_.error != gpu::error::kNoError) {
-    return;
-  }
-
-  if (!Send(new GpuCommandBufferMsg_Echo(
-           route_id_, GpuCommandBufferMsg_EchoAck(route_id_)))) {
-    return;
-  }
-
-  echo_tasks_.push(callback);
-}
-
 uint32 CommandBufferProxyImpl::CreateStreamTexture(uint32 texture_id) {
   if (last_state_.error != gpu::error::kNoError)
     return 0;
 
-  int32 stream_id = 0;
+  int32 stream_id = channel_->GenerateRouteID();
+  bool succeeded = false;
   Send(new GpuCommandBufferMsg_CreateStreamTexture(
-      route_id_, texture_id, &stream_id));
+      route_id_, texture_id, stream_id, &succeeded));
+  if (!succeeded) {
+    DLOG(ERROR) << "GpuCommandBufferMsg_CreateStreamTexture returned failure";
+    return 0;
+  }
   return stream_id;
 }
 
@@ -461,10 +388,26 @@ uint32 CommandBufferProxyImpl::InsertSyncPoint() {
     return 0;
 
   uint32 sync_point = 0;
-  Send(new GpuCommandBufferMsg_InsertSyncPoint(route_id_, &sync_point));
+  Send(new GpuCommandBufferMsg_InsertSyncPoint(route_id_, true, &sync_point));
+  return sync_point;
+}
+
+uint32_t CommandBufferProxyImpl::InsertFutureSyncPoint() {
+  if (last_state_.error != gpu::error::kNoError)
+    return 0;
+
+  uint32 sync_point = 0;
+  Send(new GpuCommandBufferMsg_InsertSyncPoint(route_id_, false, &sync_point));
   return sync_point;
 }
 
+void CommandBufferProxyImpl::RetireSyncPoint(uint32_t sync_point) {
+  if (last_state_.error != gpu::error::kNoError)
+    return;
+
+  Send(new GpuCommandBufferMsg_RetireSyncPoint(route_id_, sync_point));
+}
+
 void CommandBufferProxyImpl::SignalSyncPoint(uint32 sync_point,
                                              const base::Closure& callback) {
   if (last_state_.error != gpu::error::kNoError)
@@ -510,15 +453,6 @@ void CommandBufferProxyImpl::SetSurfaceVisible(bool visible) {
   Send(new GpuCommandBufferMsg_SetSurfaceVisible(route_id_, visible));
 }
 
-void CommandBufferProxyImpl::SendManagedMemoryStats(
-    const gpu::ManagedMemoryStats& stats) {
-  if (last_state_.error != gpu::error::kNoError)
-    return;
-
-  Send(new GpuCommandBufferMsg_SendClientManagedMemoryStats(route_id_,
-                                                            stats));
-}
-
 bool CommandBufferProxyImpl::ProduceFrontBuffer(const gpu::Mailbox& mailbox) {
   if (last_state_.error != gpu::error::kNoError)
     return false;
@@ -527,24 +461,19 @@ bool CommandBufferProxyImpl::ProduceFrontBuffer(const gpu::Mailbox& mailbox) {
 }
 
 scoped_ptr<media::VideoDecodeAccelerator>
-CommandBufferProxyImpl::CreateVideoDecoder(media::VideoCodecProfile profile) {
-  int decoder_route_id;
-  scoped_ptr<media::VideoDecodeAccelerator> vda;
-  if (!Send(new GpuCommandBufferMsg_CreateVideoDecoder(route_id_, profile,
-                                                       &decoder_route_id))) {
-    LOG(ERROR) << "Send(GpuCommandBufferMsg_CreateVideoDecoder) failed";
-    return vda.Pass();
-  }
-
-  if (decoder_route_id < 0) {
-    DLOG(ERROR) << "Failed to Initialize GPU decoder on profile: " << profile;
-    return vda.Pass();
-  }
+CommandBufferProxyImpl::CreateVideoDecoder() {
+  if (!channel_)
+    return scoped_ptr<media::VideoDecodeAccelerator>();
+  return scoped_ptr<media::VideoDecodeAccelerator>(
+      new GpuVideoDecodeAcceleratorHost(channel_, this));
+}
 
-  GpuVideoDecodeAcceleratorHost* decoder_host =
-      new GpuVideoDecodeAcceleratorHost(channel_, decoder_route_id, this);
-  vda.reset(decoder_host);
-  return vda.Pass();
+scoped_ptr<media::VideoEncodeAccelerator>
+CommandBufferProxyImpl::CreateVideoEncoder() {
+  if (!channel_)
+    return scoped_ptr<media::VideoEncodeAccelerator>();
+  return scoped_ptr<media::VideoEncodeAccelerator>(
+      new GpuVideoEncodeAcceleratorHost(channel_, this));
 }
 
 gpu::error::Error CommandBufferProxyImpl::GetLastError() {
@@ -592,4 +521,21 @@ void CommandBufferProxyImpl::TryUpdateState() {
     shared_state()->Read(&last_state_);
 }
 
+gpu::CommandBufferSharedState* CommandBufferProxyImpl::shared_state() const {
+  return reinterpret_cast<gpu::CommandBufferSharedState*>(
+      shared_state_shm_->memory());
+}
+
+void CommandBufferProxyImpl::OnSwapBuffersCompleted(
+    const std::vector<ui::LatencyInfo>& latency_info) {
+  if (!swap_buffers_completion_callback_.is_null()) {
+    if (!ui::LatencyInfo::Verify(
+            latency_info, "CommandBufferProxyImpl::OnSwapBuffersCompleted")) {
+      swap_buffers_completion_callback_.Run(std::vector<ui::LatencyInfo>());
+      return;
+    }
+    swap_buffers_completion_callback_.Run(latency_info);
+  }
+}
+
 }  // namespace content