Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / renderer / pepper / ppb_graphics_3d_impl.cc
index 1ba14bc..d40f220 100644 (file)
@@ -8,11 +8,13 @@
 #include "base/command_line.h"
 #include "base/message_loop/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "content/common/gpu/client/command_buffer_proxy_impl.h"
+#include "content/common/gpu/client/gpu_channel_host.h"
 #include "content/public/common/content_switches.h"
 #include "content/renderer/pepper/host_globals.h"
-#include "content/renderer/pepper/pepper_platform_context_3d.h"
 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
 #include "content/renderer/pepper/plugin_module.h"
+#include "content/renderer/render_thread_impl.h"
 #include "content/renderer/render_view_impl.h"
 #include "gpu/command_buffer/client/gles2_implementation.h"
 #include "ppapi/c/ppp_graphics_3d.h"
 #include "third_party/WebKit/public/web/WebConsoleMessage.h"
 #include "third_party/WebKit/public/web/WebDocument.h"
 #include "third_party/WebKit/public/web/WebElement.h"
-#include "third_party/WebKit/public/web/WebFrame.h"
+#include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "third_party/WebKit/public/web/WebPluginContainer.h"
 #include "webkit/common/webpreferences.h"
 
 using ppapi::thunk::EnterResourceNoLock;
 using ppapi::thunk::PPB_Graphics3D_API;
 using blink::WebConsoleMessage;
-using blink::WebFrame;
+using blink::WebLocalFrame;
 using blink::WebPluginContainer;
 using blink::WebString;
 
@@ -38,33 +40,26 @@ namespace {
 const int32 kCommandBufferSize = 1024 * 1024;
 const int32 kTransferBufferSize = 1024 * 1024;
 
-PP_Bool BufferToHandle(scoped_refptr<gpu::Buffer> buffer,
-                    int* shm_handle,
-                    uint32_t* shm_size) {
-  if (!buffer || !shm_handle || !shm_size)
-    return PP_FALSE;
-#if defined(OS_POSIX)
-  *shm_handle = buffer->shared_memory()->handle().fd;
-#elif defined(OS_WIN)
-  *shm_handle = reinterpret_cast<int>(buffer->shared_memory()->handle());
-#else
-  #error "Platform not supported."
-#endif
-  *shm_size = buffer->size();
-  return PP_TRUE;
-}
-
 }  // namespace.
 
 PPB_Graphics3D_Impl::PPB_Graphics3D_Impl(PP_Instance instance)
     : PPB_Graphics3D_Shared(instance),
       bound_to_instance_(false),
       commit_pending_(false),
-      weak_ptr_factory_(this) {
-}
+      sync_point_(0),
+      has_alpha_(false),
+      command_buffer_(NULL),
+      weak_ptr_factory_(this) {}
 
 PPB_Graphics3D_Impl::~PPB_Graphics3D_Impl() {
   DestroyGLES2Impl();
+  if (command_buffer_) {
+    DCHECK(channel_.get());
+    channel_->DestroyCommandBuffer(command_buffer_);
+    command_buffer_ = NULL;
+  }
+
+  channel_ = NULL;
 }
 
 // static
@@ -108,14 +103,10 @@ PP_Bool PPB_Graphics3D_Impl::SetGetBuffer(int32_t transfer_buffer_id) {
   return PP_TRUE;
 }
 
-gpu::CommandBuffer::State PPB_Graphics3D_Impl::GetState() {
-  return GetCommandBuffer()->GetState();
-}
-
-int32_t PPB_Graphics3D_Impl::CreateTransferBuffer(uint32_t size) {
-  int32_t id = -1;
-  GetCommandBuffer()->CreateTransferBuffer(size, &id);
-  return id;
+scoped_refptr<gpu::Buffer> PPB_Graphics3D_Impl::CreateTransferBuffer(
+    uint32_t size,
+    int32_t* id) {
+  return GetCommandBuffer()->CreateTransferBuffer(size, id);
 }
 
 PP_Bool PPB_Graphics3D_Impl::DestroyTransferBuffer(int32_t id) {
@@ -123,13 +114,6 @@ PP_Bool PPB_Graphics3D_Impl::DestroyTransferBuffer(int32_t id) {
   return PP_TRUE;
 }
 
-PP_Bool PPB_Graphics3D_Impl::GetTransferBuffer(int32_t id,
-                                               int* shm_handle,
-                                               uint32_t* shm_size) {
-  scoped_refptr<gpu::Buffer> buffer = GetCommandBuffer()->GetTransferBuffer(id);
-  return BufferToHandle(buffer, shm_handle, shm_size);
-}
-
 PP_Bool PPB_Graphics3D_Impl::Flush(int32_t put_offset) {
   GetCommandBuffer()->Flush(put_offset);
   return PP_TRUE;
@@ -150,7 +134,7 @@ gpu::CommandBuffer::State PPB_Graphics3D_Impl::WaitForGetOffsetInRange(
 }
 
 uint32_t PPB_Graphics3D_Impl::InsertSyncPoint() {
-  return platform_context_->GetGpuControl()->InsertSyncPoint();
+  return command_buffer_->InsertSyncPoint();
 }
 
 bool PPB_Graphics3D_Impl::BindToInstance(bool bind) {
@@ -158,9 +142,7 @@ bool PPB_Graphics3D_Impl::BindToInstance(bool bind) {
   return true;
 }
 
-bool PPB_Graphics3D_Impl::IsOpaque() {
-  return platform_context_->IsOpaque();
-}
+bool PPB_Graphics3D_Impl::IsOpaque() { return !has_alpha_; }
 
 void PPB_Graphics3D_Impl::ViewInitiatedPaint() {
   commit_pending_ = false;
@@ -169,18 +151,23 @@ void PPB_Graphics3D_Impl::ViewInitiatedPaint() {
     SwapBuffersACK(PP_OK);
 }
 
-void PPB_Graphics3D_Impl::ViewFlushedPaint() {
+void PPB_Graphics3D_Impl::ViewFlushedPaint() {}
+
+int PPB_Graphics3D_Impl::GetCommandBufferRouteId() {
+  DCHECK(command_buffer_);
+  return command_buffer_->GetRouteID();
 }
 
 gpu::CommandBuffer* PPB_Graphics3D_Impl::GetCommandBuffer() {
-  return platform_context_->GetCommandBuffer();
+  return command_buffer_;
 }
 
 gpu::GpuControl* PPB_Graphics3D_Impl::GetGpuControl() {
-  return platform_context_->GetGpuControl();
+  return command_buffer_;
 }
 
 int32 PPB_Graphics3D_Impl::DoSwapBuffers() {
+  DCHECK(command_buffer_);
   // We do not have a GLES2 implementation when using an OOP proxy.
   // The plugin-side proxy is responsible for adding the SwapBuffers command
   // to the command buffer in that case.
@@ -189,7 +176,7 @@ int32 PPB_Graphics3D_Impl::DoSwapBuffers() {
 
   // Since the backing texture has been updated, a new sync point should be
   // inserted.
-  platform_context_->InsertSyncPointForBackingMailbox();
+  sync_point_ = command_buffer_->InsertSyncPoint();
 
   if (bound_to_instance_) {
     // If we are bound to the instance, we need to ask the compositor
@@ -203,11 +190,10 @@ int32 PPB_Graphics3D_Impl::DoSwapBuffers() {
     commit_pending_ = true;
   } else {
     // Wait for the command to complete on the GPU to allow for throttling.
-    platform_context_->Echo(base::Bind(&PPB_Graphics3D_Impl::OnSwapBuffers,
-                                       weak_ptr_factory_.GetWeakPtr()));
+    command_buffer_->Echo(base::Bind(&PPB_Graphics3D_Impl::OnSwapBuffers,
+                                     weak_ptr_factory_.GetWeakPtr()));
   }
 
-
   return PP_OK_COMPLETIONPENDING;
 }
 
@@ -216,18 +202,13 @@ bool PPB_Graphics3D_Impl::Init(PPB_Graphics3D_API* share_context,
   if (!InitRaw(share_context, attrib_list))
     return false;
 
-  gpu::CommandBuffer* command_buffer = GetCommandBuffer();
-  if (!command_buffer->Initialize())
-    return false;
-
   gpu::gles2::GLES2Implementation* share_gles2 = NULL;
   if (share_context) {
     share_gles2 =
         static_cast<PPB_Graphics3D_Shared*>(share_context)->gles2_impl();
   }
 
-  return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize,
-                         share_gles2);
+  return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize, share_gles2);
 }
 
 bool PPB_Graphics3D_Impl::InitRaw(PPB_Graphics3D_API* share_context,
@@ -237,50 +218,90 @@ bool PPB_Graphics3D_Impl::InitRaw(PPB_Graphics3D_API* share_context,
   if (!plugin_instance)
     return false;
 
-  const WebPreferences& prefs = static_cast<RenderViewImpl*>(plugin_instance->
-      GetRenderView())->webkit_preferences();
+  const WebPreferences& prefs =
+      static_cast<RenderViewImpl*>(plugin_instance->GetRenderView())
+          ->webkit_preferences();
   // 3D access might be disabled or blacklisted.
   if (!prefs.pepper_3d_enabled)
     return false;
-  // If accelerated compositing of plugins is disabled, fail to create a 3D
-  // context, because it won't be visible. This allows graceful fallback in the
-  // modules.
-  if (!prefs.accelerated_compositing_for_plugins_enabled)
+
+  RenderThreadImpl* render_thread = RenderThreadImpl::current();
+  if (!render_thread)
     return false;
 
-  platform_context_.reset(new PlatformContext3D);
-  if (!platform_context_)
+  channel_ = render_thread->EstablishGpuChannelSync(
+      CAUSE_FOR_GPU_LAUNCH_PEPPERPLATFORMCONTEXT3DIMPL_INITIALIZE);
+  if (!channel_.get())
     return false;
 
-  PlatformContext3D* share_platform_context = NULL;
+  gfx::Size surface_size;
+  std::vector<int32> attribs;
+  gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
+  // TODO(alokp): Change GpuChannelHost::CreateOffscreenCommandBuffer()
+  // interface to accept width and height in the attrib_list so that
+  // we do not need to filter for width and height here.
+  if (attrib_list) {
+    for (const int32_t* attr = attrib_list; attr[0] != PP_GRAPHICS3DATTRIB_NONE;
+         attr += 2) {
+      switch (attr[0]) {
+        case PP_GRAPHICS3DATTRIB_WIDTH:
+          surface_size.set_width(attr[1]);
+          break;
+        case PP_GRAPHICS3DATTRIB_HEIGHT:
+          surface_size.set_height(attr[1]);
+          break;
+        case PP_GRAPHICS3DATTRIB_GPU_PREFERENCE:
+          gpu_preference =
+              (attr[1] == PP_GRAPHICS3DATTRIB_GPU_PREFERENCE_LOW_POWER)
+                  ? gfx::PreferIntegratedGpu
+                  : gfx::PreferDiscreteGpu;
+          break;
+        case PP_GRAPHICS3DATTRIB_ALPHA_SIZE:
+          has_alpha_ = attr[1] > 0;
+        // fall-through
+        default:
+          attribs.push_back(attr[0]);
+          attribs.push_back(attr[1]);
+          break;
+      }
+    }
+    attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
+  }
+
+  CommandBufferProxyImpl* share_buffer = NULL;
   if (share_context) {
     PPB_Graphics3D_Impl* share_graphics =
         static_cast<PPB_Graphics3D_Impl*>(share_context);
-    share_platform_context = share_graphics->platform_context();
+    share_buffer = share_graphics->command_buffer_;
   }
 
-  if (!platform_context_->Init(attrib_list, share_platform_context))
+  command_buffer_ = channel_->CreateOffscreenCommandBuffer(
+      surface_size, share_buffer, attribs, GURL::EmptyGURL(), gpu_preference);
+  if (!command_buffer_)
+    return false;
+  if (!command_buffer_->Initialize())
+    return false;
+  mailbox_ = gpu::Mailbox::Generate();
+  if (!command_buffer_->ProduceFrontBuffer(mailbox_))
     return false;
+  sync_point_ = command_buffer_->InsertSyncPoint();
 
-  platform_context_->SetContextLostCallback(
-      base::Bind(&PPB_Graphics3D_Impl::OnContextLost,
-                 weak_ptr_factory_.GetWeakPtr()));
+  command_buffer_->SetChannelErrorCallback(base::Bind(
+      &PPB_Graphics3D_Impl::OnContextLost, weak_ptr_factory_.GetWeakPtr()));
 
-  platform_context_->SetOnConsoleMessageCallback(
-      base::Bind(&PPB_Graphics3D_Impl::OnConsoleMessage,
-                 weak_ptr_factory_.GetWeakPtr()));
+  command_buffer_->SetOnConsoleMessageCallback(base::Bind(
+      &PPB_Graphics3D_Impl::OnConsoleMessage, weak_ptr_factory_.GetWeakPtr()));
   return true;
 }
 
-void PPB_Graphics3D_Impl::OnConsoleMessage(const std::string& message,
-                                           int id) {
+void PPB_Graphics3D_Impl::OnConsoleMessage(const std::string& message, int id) {
   if (!bound_to_instance_)
     return;
   WebPluginContainer* container =
       HostGlobals::Get()->GetInstance(pp_instance())->container();
   if (!container)
     return;
-  WebFrame* frame = container->element().document().frame();
+  WebLocalFrame* frame = container->element().document().frame();
   if (!frame)
     return;
   WebConsoleMessage console_message = WebConsoleMessage(
@@ -301,8 +322,8 @@ void PPB_Graphics3D_Impl::OnContextLost() {
   // Don't need to check for NULL from GetPluginInstance since when we're
   // bound, we know our instance is valid.
   if (bound_to_instance_) {
-    HostGlobals::Get()->GetInstance(pp_instance())->BindGraphics(
-        pp_instance(), 0);
+    HostGlobals::Get()->GetInstance(pp_instance())->BindGraphics(pp_instance(),
+                                                                 0);
   }
 
   // Send context lost to plugin. This may have been caused by a PPAPI call, so
@@ -327,10 +348,8 @@ void PPB_Graphics3D_Impl::SendContextLost() {
   // send the Graphics3DContextLost to the plugin; the instance may care about
   // that event even though this context has been destroyed.
   PP_Instance this_pp_instance = pp_instance();
-  const PPP_Graphics3D* ppp_graphics_3d =
-      static_cast<const PPP_Graphics3D*>(
-          instance->module()->GetPluginInterface(
-              PPP_GRAPHICS_3D_INTERFACE));
+  const PPP_Graphics3D* ppp_graphics_3d = static_cast<const PPP_Graphics3D*>(
+      instance->module()->GetPluginInterface(PPP_GRAPHICS_3D_INTERFACE));
   // We have to check *again* that the instance exists, because it could have
   // been deleted during GetPluginInterface(). Even the PluginModule could be
   // deleted, but in that case, the instance should also be gone, so the