Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / common / gpu / gpu_channel_manager.cc
index 86ea2bf..3507044 100644 (file)
@@ -7,6 +7,7 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "content/common/gpu/gpu_channel.h"
+#include "content/common/gpu/gpu_memory_buffer_factory.h"
 #include "content/common/gpu/gpu_memory_manager.h"
 #include "content/common/gpu/gpu_messages.h"
 #include "content/common/gpu/sync_point_manager.h"
 #include "gpu/command_buffer/service/gpu_switches.h"
 #include "gpu/command_buffer/service/mailbox_manager.h"
 #include "gpu/command_buffer/service/memory_program_cache.h"
+#include "gpu/command_buffer/service/shader_translator_cache.h"
+#include "ipc/message_filter.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_share_group.h"
 
 namespace content {
 
-GpuChannelManager::ImageOperation::ImageOperation(
-    int32 sync_point, base::Closure callback)
-    : sync_point(sync_point),
-      callback(callback) {
-}
+namespace {
 
-GpuChannelManager::ImageOperation::~ImageOperation() {
-}
+class GpuChannelManagerMessageFilter : public IPC::MessageFilter {
+ public:
+  GpuChannelManagerMessageFilter(
+      GpuMemoryBufferFactory* gpu_memory_buffer_factory)
+      : sender_(NULL), gpu_memory_buffer_factory_(gpu_memory_buffer_factory) {}
+
+  virtual void OnFilterAdded(IPC::Sender* sender) OVERRIDE {
+    DCHECK(!sender_);
+    sender_ = sender;
+  }
+
+  virtual void OnFilterRemoved() OVERRIDE {
+    DCHECK(sender_);
+    sender_ = NULL;
+  }
+
+  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
+    DCHECK(sender_);
+    bool handled = true;
+    IPC_BEGIN_MESSAGE_MAP(GpuChannelManagerMessageFilter, message)
+      IPC_MESSAGE_HANDLER(GpuMsg_CreateGpuMemoryBuffer, OnCreateGpuMemoryBuffer)
+      IPC_MESSAGE_UNHANDLED(handled = false)
+    IPC_END_MESSAGE_MAP()
+    return handled;
+  }
+
+ protected:
+  virtual ~GpuChannelManagerMessageFilter() {}
+
+  void OnCreateGpuMemoryBuffer(const gfx::GpuMemoryBufferHandle& handle,
+                               const gfx::Size& size,
+                               unsigned internalformat,
+                               unsigned usage) {
+    TRACE_EVENT2("gpu",
+                 "GpuChannelManagerMessageFilter::OnCreateGpuMemoryBuffer",
+                 "primary_id",
+                 handle.global_id.primary_id,
+                 "secondary_id",
+                 handle.global_id.secondary_id);
+    sender_->Send(new GpuHostMsg_GpuMemoryBufferCreated(
+        gpu_memory_buffer_factory_->CreateGpuMemoryBuffer(
+            handle, size, internalformat, usage)));
+  }
+
+  IPC::Sender* sender_;
+  GpuMemoryBufferFactory* gpu_memory_buffer_factory_;
+};
+
+}  // namespace
 
 GpuChannelManager::GpuChannelManager(MessageRouter* router,
                                      GpuWatchdog* watchdog,
                                      base::MessageLoopProxy* io_message_loop,
-                                     base::WaitableEvent* shutdown_event)
-    : weak_factory_(this),
-      io_message_loop_(io_message_loop),
+                                     base::WaitableEvent* shutdown_event,
+                                     IPC::SyncChannel* channel)
+    : io_message_loop_(io_message_loop),
       shutdown_event_(shutdown_event),
       router_(router),
       gpu_memory_manager_(
           this,
           GpuMemoryManager::kDefaultMaxSurfacesWithFrontbufferSoftLimit),
       watchdog_(watchdog),
-      sync_point_manager_(new SyncPointManager) {
+      sync_point_manager_(new SyncPointManager),
+      gpu_memory_buffer_factory_(GpuMemoryBufferFactory::Create()),
+      channel_(channel),
+      filter_(new GpuChannelManagerMessageFilter(
+          gpu_memory_buffer_factory_.get())),
+      weak_factory_(this) {
   DCHECK(router_);
   DCHECK(io_message_loop);
   DCHECK(shutdown_event);
+  channel_->AddFilter(filter_.get());
 }
 
 GpuChannelManager::~GpuChannelManager() {
@@ -53,7 +105,6 @@ GpuChannelManager::~GpuChannelManager() {
     default_offscreen_surface_->Destroy();
     default_offscreen_surface_ = NULL;
   }
-  DCHECK(image_operations_.empty());
 }
 
 gpu::gles2::ProgramCache* GpuChannelManager::program_cache() {
@@ -67,6 +118,13 @@ gpu::gles2::ProgramCache* GpuChannelManager::program_cache() {
   return program_cache_.get();
 }
 
+gpu::gles2::ShaderTranslatorCache*
+GpuChannelManager::shader_translator_cache() {
+  if (!shader_translator_cache_.get())
+    shader_translator_cache_ = new gpu::gles2::ShaderTranslatorCache;
+  return shader_translator_cache_.get();
+}
+
 void GpuChannelManager::RemoveChannel(int client_id) {
   Send(new GpuHostMsg_DestroyChannel(client_id));
   gpu_channels_.erase(client_id);
@@ -90,28 +148,28 @@ GpuChannel* GpuChannelManager::LookupChannel(int32 client_id) {
   if (iter == gpu_channels_.end())
     return NULL;
   else
-    return iter->second.get();
+    return iter->second;
 }
 
 bool GpuChannelManager::OnMessageReceived(const IPC::Message& msg) {
-  bool msg_is_ok = true;
   bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP_EX(GpuChannelManager, msg, msg_is_ok)
+  IPC_BEGIN_MESSAGE_MAP(GpuChannelManager, msg)
     IPC_MESSAGE_HANDLER(GpuMsg_EstablishChannel, OnEstablishChannel)
     IPC_MESSAGE_HANDLER(GpuMsg_CloseChannel, OnCloseChannel)
     IPC_MESSAGE_HANDLER(GpuMsg_CreateViewCommandBuffer,
                         OnCreateViewCommandBuffer)
-    IPC_MESSAGE_HANDLER(GpuMsg_CreateImage, OnCreateImage)
-    IPC_MESSAGE_HANDLER(GpuMsg_DeleteImage, OnDeleteImage)
+    IPC_MESSAGE_HANDLER(GpuMsg_DestroyGpuMemoryBuffer, OnDestroyGpuMemoryBuffer)
     IPC_MESSAGE_HANDLER(GpuMsg_LoadedShader, OnLoadedShader)
     IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP_EX()
+  IPC_END_MESSAGE_MAP()
   return handled;
 }
 
 bool GpuChannelManager::Send(IPC::Message* msg) { return router_->Send(msg); }
 
-void GpuChannelManager::OnEstablishChannel(int client_id, bool share_context) {
+void GpuChannelManager::OnEstablishChannel(int client_id,
+                                           bool share_context,
+                                           bool allow_future_sync_points) {
   IPC::ChannelHandle channel_handle;
 
   gfx::GLShareGroup* share_group = NULL;
@@ -126,14 +184,14 @@ void GpuChannelManager::OnEstablishChannel(int client_id, bool share_context) {
     mailbox_manager = mailbox_manager_.get();
   }
 
-  scoped_refptr<GpuChannel> channel = new GpuChannel(this,
-                                                     watchdog_,
-                                                     share_group,
-                                                     mailbox_manager,
-                                                     client_id,
-                                                     false);
+  scoped_ptr<GpuChannel> channel(new GpuChannel(this,
+                                                watchdog_,
+                                                share_group,
+                                                mailbox_manager,
+                                                client_id,
+                                                false,
+                                                allow_future_sync_points));
   channel->Init(io_message_loop_.get(), shutdown_event_);
-  gpu_channels_[client_id] = channel;
   channel_handle.name = channel->GetChannelName();
 
 #if defined(OS_POSIX)
@@ -144,6 +202,8 @@ void GpuChannelManager::OnEstablishChannel(int client_id, bool share_context) {
   channel_handle.socket = base::FileDescriptor(renderer_fd, true);
 #endif
 
+  gpu_channels_.set(client_id, channel.Pass());
+
   Send(new GpuHostMsg_ChannelEstablished(channel_handle));
 }
 
@@ -162,91 +222,44 @@ void GpuChannelManager::OnCreateViewCommandBuffer(
     const gfx::GLSurfaceHandle& window,
     int32 surface_id,
     int32 client_id,
-    const GPUCreateCommandBufferConfig& init_params) {
+    const GPUCreateCommandBufferConfig& init_params,
+    int32 route_id) {
   DCHECK(surface_id);
-  int32 route_id = MSG_ROUTING_NONE;
-
-  GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
-  if (iter != gpu_channels_.end()) {
-    iter->second->CreateViewCommandBuffer(
-        window, surface_id, init_params, &route_id);
-  }
-
-  Send(new GpuHostMsg_CommandBufferCreated(route_id));
-}
-
-void GpuChannelManager::CreateImage(
-    gfx::PluginWindowHandle window, int32 client_id, int32 image_id) {
-  gfx::Size size;
+  CreateCommandBufferResult result = CREATE_COMMAND_BUFFER_FAILED;
 
   GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
   if (iter != gpu_channels_.end()) {
-    iter->second->CreateImage(window, image_id, &size);
+    result = iter->second->CreateViewCommandBuffer(
+        window, surface_id, init_params, route_id);
   }
 
-  Send(new GpuHostMsg_ImageCreated(size));
+  Send(new GpuHostMsg_CommandBufferCreated(result));
 }
-
-void GpuChannelManager::OnCreateImage(
-    gfx::PluginWindowHandle window, int32 client_id, int32 image_id) {
-  DCHECK(image_id);
-
-  if (image_operations_.empty()) {
-    CreateImage(window, client_id, image_id);
-  } else {
-    image_operations_.push_back(
-        new ImageOperation(0, base::Bind(&GpuChannelManager::CreateImage,
-                                         base::Unretained(this),
-                                         window,
-                                         client_id,
-                                         image_id)));
-  }
+void GpuChannelManager::DestroyGpuMemoryBuffer(
+    const gfx::GpuMemoryBufferHandle& handle) {
+  io_message_loop_->PostTask(
+      FROM_HERE,
+      base::Bind(&GpuChannelManager::DestroyGpuMemoryBufferOnIO,
+                 base::Unretained(this),
+                 handle));
 }
 
-void GpuChannelManager::DeleteImage(int32 client_id, int32 image_id) {
-  GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
-  if (iter != gpu_channels_.end()) {
-    iter->second->DeleteImage(image_id);
-  }
+void GpuChannelManager::DestroyGpuMemoryBufferOnIO(
+    const gfx::GpuMemoryBufferHandle& handle) {
+  gpu_memory_buffer_factory_->DestroyGpuMemoryBuffer(handle);
 }
 
-void GpuChannelManager::OnDeleteImage(
-    int32 client_id, int32 image_id, int32 sync_point) {
-  DCHECK(image_id);
-
-  if (!sync_point && image_operations_.empty()) {
-    DeleteImage(client_id, image_id);
+void GpuChannelManager::OnDestroyGpuMemoryBuffer(
+    const gfx::GpuMemoryBufferHandle& handle,
+    int32 sync_point) {
+  if (!sync_point) {
+    DestroyGpuMemoryBuffer(handle);
   } else {
-    image_operations_.push_back(
-        new ImageOperation(sync_point,
-                           base::Bind(&GpuChannelManager::DeleteImage,
-                                      base::Unretained(this),
-                                      client_id,
-                                      image_id)));
-    if (sync_point) {
-      sync_point_manager()->AddSyncPointCallback(
-          sync_point,
-          base::Bind(&GpuChannelManager::OnDeleteImageSyncPointRetired,
-                     base::Unretained(this),
-                     image_operations_.back()));
-    }
-  }
-}
-
-void GpuChannelManager::OnDeleteImageSyncPointRetired(
-    ImageOperation* image_operation) {
-  // Mark operation as no longer having a pending sync point.
-  image_operation->sync_point = 0;
-
-  // De-queue operations until we reach a pending sync point.
-  while (!image_operations_.empty()) {
-    // Check if operation has a pending sync point.
-    if (image_operations_.front()->sync_point)
-      return;
-
-    image_operations_.front()->callback.Run();
-    delete image_operations_.front();
-    image_operations_.pop_front();
+    sync_point_manager()->AddSyncPointCallback(
+        sync_point,
+        base::Bind(&GpuChannelManager::DestroyGpuMemoryBuffer,
+                   base::Unretained(this),
+                   handle));
   }
 }
 
@@ -292,7 +305,7 @@ void GpuChannelManager::OnLoseAllContexts() {
 gfx::GLSurface* GpuChannelManager::GetDefaultOffscreenSurface() {
   if (!default_offscreen_surface_.get()) {
     default_offscreen_surface_ =
-        gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1));
+        gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size());
   }
   return default_offscreen_surface_.get();
 }