summaryrefslogtreecommitdiffstats
path: root/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc')
-rw-r--r--chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc214
1 files changed, 113 insertions, 101 deletions
diff --git a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc
index 989b9994395..d40f2202ebb 100644
--- a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc
+++ b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc
@@ -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"
@@ -21,14 +23,14 @@
#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,42 +40,26 @@ namespace {
const int32 kCommandBufferSize = 1024 * 1024;
const int32 kTransferBufferSize = 1024 * 1024;
-PP_Bool ShmToHandle(base::SharedMemory* shm,
- size_t size,
- int* shm_handle,
- uint32_t* shm_size) {
- if (!shm || !shm_handle || !shm_size)
- return PP_FALSE;
-#if defined(OS_POSIX)
- *shm_handle = shm->handle().fd;
-#elif defined(OS_WIN)
- *shm_handle = reinterpret_cast<int>(shm->handle());
-#else
- #error "Platform not supported."
-#endif
- *shm_size = 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;
+ }
-// static
-PP_Bool PPB_Graphics3D_Impl::IsGpuBlacklisted() {
- CommandLine* command_line = CommandLine::ForCurrentProcess();
- if (command_line)
- return PP_FromBool(command_line->HasSwitch(switches::kDisablePepper3d));
- return PP_TRUE;
+ channel_ = NULL;
}
// static
@@ -81,8 +67,6 @@ PP_Resource PPB_Graphics3D_Impl::Create(PP_Instance instance,
PP_Resource share_context,
const int32_t* attrib_list) {
PPB_Graphics3D_API* share_api = NULL;
- if (IsGpuBlacklisted())
- return 0;
if (share_context) {
EnterResourceNoLock<PPB_Graphics3D_API> enter(share_context, true);
if (enter.failed())
@@ -101,8 +85,6 @@ PP_Resource PPB_Graphics3D_Impl::CreateRaw(PP_Instance instance,
PP_Resource share_context,
const int32_t* attrib_list) {
PPB_Graphics3D_API* share_api = NULL;
- if (IsGpuBlacklisted())
- return 0;
if (share_context) {
EnterResourceNoLock<PPB_Graphics3D_API> enter(share_context, true);
if (enter.failed())
@@ -121,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) {
@@ -136,31 +114,27 @@ 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) {
- gpu::Buffer buffer = GetCommandBuffer()->GetTransferBuffer(id);
- return ShmToHandle(buffer.shared_memory, buffer.size, shm_handle, shm_size);
-}
-
PP_Bool PPB_Graphics3D_Impl::Flush(int32_t put_offset) {
GetCommandBuffer()->Flush(put_offset);
return PP_TRUE;
}
-gpu::CommandBuffer::State PPB_Graphics3D_Impl::FlushSync(int32_t put_offset) {
- gpu::CommandBuffer::State state = GetCommandBuffer()->GetState();
- return GetCommandBuffer()->FlushSync(put_offset, state.get_offset);
+gpu::CommandBuffer::State PPB_Graphics3D_Impl::WaitForTokenInRange(
+ int32_t start,
+ int32_t end) {
+ GetCommandBuffer()->WaitForTokenInRange(start, end);
+ return GetCommandBuffer()->GetLastState();
}
-gpu::CommandBuffer::State PPB_Graphics3D_Impl::FlushSyncFast(
- int32_t put_offset,
- int32_t last_known_get) {
- return GetCommandBuffer()->FlushSync(put_offset, last_known_get);
+gpu::CommandBuffer::State PPB_Graphics3D_Impl::WaitForGetOffsetInRange(
+ int32_t start,
+ int32_t end) {
+ GetCommandBuffer()->WaitForGetOffsetInRange(start, end);
+ return GetCommandBuffer()->GetLastState();
}
uint32_t PPB_Graphics3D_Impl::InsertSyncPoint() {
- return platform_context_->GetGpuControl()->InsertSyncPoint();
+ return command_buffer_->InsertSyncPoint();
}
bool PPB_Graphics3D_Impl::BindToInstance(bool bind) {
@@ -168,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;
@@ -179,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.
@@ -199,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
@@ -213,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;
}
@@ -226,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,
@@ -247,51 +218,94 @@ bool PPB_Graphics3D_Impl::InitRaw(PPB_Graphics3D_API* share_context,
if (!plugin_instance)
return false;
- PlatformContext3D* share_platform_context = NULL;
+ 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;
+
+ RenderThreadImpl* render_thread = RenderThreadImpl::current();
+ if (!render_thread)
+ return false;
+
+ channel_ = render_thread->EstablishGpuChannelSync(
+ CAUSE_FOR_GPU_LAUNCH_PEPPERPLATFORMCONTEXT3DIMPL_INITIALIZE);
+ if (!channel_.get())
+ return false;
+
+ 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 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.
- const WebPreferences& prefs = static_cast<RenderViewImpl*>(plugin_instance->
- GetRenderView())->webkit_preferences();
- if (!prefs.accelerated_compositing_for_plugins_enabled)
+ command_buffer_ = channel_->CreateOffscreenCommandBuffer(
+ surface_size, share_buffer, attribs, GURL::EmptyGURL(), gpu_preference);
+ if (!command_buffer_)
return false;
-
- platform_context_.reset(new PlatformContext3D);
- if (!platform_context_)
+ if (!command_buffer_->Initialize())
return false;
-
- if (!platform_context_->Init(attrib_list, share_platform_context))
+ 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(
- WebConsoleMessage::LevelError, WebString(UTF8ToUTF16(message)));
+ WebConsoleMessage::LevelError, WebString(base::UTF8ToUTF16(message)));
frame->addMessageToConsole(console_message);
}
@@ -308,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
@@ -334,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