diff options
Diffstat (limited to 'chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc')
-rw-r--r-- | chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc | 214 |
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 |