diff options
-rw-r--r-- | chrome/renderer/ggl/ggl.cc | 10 | ||||
-rw-r--r-- | chrome/renderer/ggl/ggl.h | 3 | ||||
-rw-r--r-- | chrome/renderer/pepper_platform_context_3d_impl.cc | 81 | ||||
-rw-r--r-- | chrome/renderer/pepper_platform_context_3d_impl.h | 19 | ||||
-rw-r--r-- | webkit/plugins/ppapi/plugin_delegate.h | 18 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_context_3d_impl.cc | 60 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_context_3d_impl.h | 12 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_surface_3d_impl.cc | 15 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_surface_3d_impl.h | 6 |
9 files changed, 152 insertions, 72 deletions
diff --git a/chrome/renderer/ggl/ggl.cc b/chrome/renderer/ggl/ggl.cc index 43b6f67..16260f1 100644 --- a/chrome/renderer/ggl/ggl.cc +++ b/chrome/renderer/ggl/ggl.cc @@ -123,6 +123,11 @@ class Context : public base::SupportsWeakPtr<Context> { gpu::gles2::GLES2Implementation* gles2_implementation() const { return gles2_implementation_; } + + CommandBufferProxy* command_buffer() const { + return command_buffer_; + } + private: void OnSwapBuffers(); @@ -575,4 +580,9 @@ gpu::gles2::GLES2Implementation* GetImplementation(Context* context) { return context->gles2_implementation(); } +CommandBufferProxy* GetCommandBufferProxy(Context* context) { + DCHECK(context); + return context->command_buffer(); +} + } // namespace ggl diff --git a/chrome/renderer/ggl/ggl.h b/chrome/renderer/ggl/ggl.h index c7402a0..04ac19e 100644 --- a/chrome/renderer/ggl/ggl.h +++ b/chrome/renderer/ggl/ggl.h @@ -17,6 +17,7 @@ class GpuChannelHost; class MessageLoop; +class CommandBufferProxy; namespace gpu { namespace gles2 { @@ -165,6 +166,8 @@ Error GetError(Context* context); // communicating with the GPU process. bool IsCommandBufferContextLost(Context* context); +CommandBufferProxy* GetCommandBufferProxy(Context* context); + } // namespace ggl #endif // CHROME_RENDERER_GGL_GGL_H_ diff --git a/chrome/renderer/pepper_platform_context_3d_impl.cc b/chrome/renderer/pepper_platform_context_3d_impl.cc index 57b849a..3d4ab7c 100644 --- a/chrome/renderer/pepper_platform_context_3d_impl.cc +++ b/chrome/renderer/pepper_platform_context_3d_impl.cc @@ -4,40 +4,58 @@ #include "chrome/renderer/pepper_platform_context_3d_impl.h" +#include "chrome/renderer/command_buffer_proxy.h" #include "chrome/renderer/ggl/ggl.h" #include "chrome/renderer/gpu_channel_host.h" #include "chrome/renderer/render_thread.h" +#include "gpu/command_buffer/client/gles2_cmd_helper.h" +#include "gpu/command_buffer/client/gles2_implementation.h" #ifdef ENABLE_GPU PlatformContext3DImpl::PlatformContext3DImpl(ggl::Context* parent_context) : parent_context_(parent_context), - context_(NULL) { + command_buffer_(NULL) { } PlatformContext3DImpl::~PlatformContext3DImpl() { - if (context_) { - ggl::DestroyContext(context_); - context_ = NULL; + if (command_buffer_) { + DCHECK(channel_.get()); + channel_->DestroyCommandBuffer(command_buffer_); + command_buffer_ = NULL; } + + channel_ = NULL; + + if (parent_context_ && parent_texture_id_ != 0) { + ggl::GetImplementation(parent_context_)->FreeTextureId(parent_texture_id_); + } + } bool PlatformContext3DImpl::Init() { // Ignore initializing more than once. - if (context_) + if (command_buffer_) return true; RenderThread* render_thread = RenderThread::current(); if (!render_thread) return false; - GpuChannelHost* host = render_thread->GetGpuChannel(); - if (!host) + channel_ = render_thread->GetGpuChannel(); + if (!channel_.get()) return false; - DCHECK(host->state() == GpuChannelHost::kConnected); + DCHECK(channel_->state() == GpuChannelHost::kConnected); + + // Flush any remaining commands in the parent context to make sure the + // texture id accounting stays consistent. + gpu::gles2::GLES2Implementation* parent_gles2 = + ggl::GetImplementation(parent_context_); + parent_gles2->helper()->CommandBufferHelper::Finish(); + parent_texture_id_ = parent_gles2->MakeTextureId(); // TODO(apatrick): Let Pepper plugins configure their back buffer surface. - static const int32 attribs[] = { + static const int32 kAttribs[] = { ggl::GGL_ALPHA_SIZE, 8, ggl::GGL_DEPTH_SIZE, 24, ggl::GGL_STENCIL_SIZE, 8, @@ -45,44 +63,35 @@ bool PlatformContext3DImpl::Init() { ggl::GGL_SAMPLE_BUFFERS, 0, ggl::GGL_NONE, }; - - // TODO(apatrick): Decide which extensions to expose to Pepper plugins. - // Currently they get only core GLES2. - context_ = ggl::CreateOffscreenContext(host, - parent_context_, - gfx::Size(1, 1), - "", - attribs); - if (!context_) + std::vector<int32> attribs(kAttribs, kAttribs + ARRAYSIZE_UNSAFE(kAttribs)); + CommandBufferProxy* parent_command_buffer = + ggl::GetCommandBufferProxy(parent_context_); + command_buffer_ = channel_->CreateOffscreenCommandBuffer( + parent_command_buffer, + gfx::Size(1, 1), + "", + attribs, + parent_texture_id_); + + if (!command_buffer_) return false; return true; } -bool PlatformContext3DImpl::SwapBuffers() { - DCHECK(context_); - return ggl::SwapBuffers(context_); -} - -unsigned PlatformContext3DImpl::GetError() { - DCHECK(context_); - return ggl::GetError(context_); -} - void PlatformContext3DImpl::SetSwapBuffersCallback(Callback0::Type* callback) { - DCHECK(context_); - ggl::SetSwapBuffersCallback(context_, callback); + DCHECK(command_buffer_); + command_buffer_->SetSwapBuffersCallback(callback); } unsigned PlatformContext3DImpl::GetBackingTextureId() { - DCHECK(context_); - return ggl::GetParentTextureId(context_); + DCHECK(command_buffer_); + return parent_texture_id_; } -gpu::gles2::GLES2Implementation* - PlatformContext3DImpl::GetGLES2Implementation() { - DCHECK(context_); - return ggl::GetImplementation(context_); +gpu::CommandBuffer* + PlatformContext3DImpl::GetCommandBuffer() { + return command_buffer_; } #endif // ENABLE_GPU diff --git a/chrome/renderer/pepper_platform_context_3d_impl.h b/chrome/renderer/pepper_platform_context_3d_impl.h index 1a34f98..463355a 100644 --- a/chrome/renderer/pepper_platform_context_3d_impl.h +++ b/chrome/renderer/pepper_platform_context_3d_impl.h @@ -8,12 +8,21 @@ #ifdef ENABLE_GPU +namespace gpu { + +class CommandBuffer; + +} // namespace gpu + namespace ggl { class Context; } // namespace ggl; +class GpuChannelHost; +class CommandBufferProxy; + class PlatformContext3DImpl : public webkit::ppapi::PluginDelegate::PlatformContext3D { public: @@ -21,15 +30,17 @@ class PlatformContext3DImpl virtual ~PlatformContext3DImpl(); virtual bool Init(); - virtual bool SwapBuffers(); - virtual unsigned GetError(); virtual void SetSwapBuffersCallback(Callback0::Type* callback); virtual unsigned GetBackingTextureId(); - virtual gpu::gles2::GLES2Implementation* GetGLES2Implementation(); + virtual gpu::CommandBuffer* GetCommandBuffer(); private: + bool InitRaw(); + ggl::Context* parent_context_; - ggl::Context* context_; + scoped_refptr<GpuChannelHost> channel_; + unsigned int parent_texture_id_; + CommandBufferProxy* command_buffer_; }; #endif // ENABLE_GPU diff --git a/webkit/plugins/ppapi/plugin_delegate.h b/webkit/plugins/ppapi/plugin_delegate.h index 869189b..94ffa61 100644 --- a/webkit/plugins/ppapi/plugin_delegate.h +++ b/webkit/plugins/ppapi/plugin_delegate.h @@ -38,9 +38,7 @@ class Rect; } namespace gpu { -namespace gles2 { -class GLES2Implementation; -} +class CommandBuffer; } namespace skia { @@ -145,12 +143,6 @@ class PluginDelegate { // Initialize the context. virtual bool Init() = 0; - // Present the rendered frame to the compositor. - virtual bool SwapBuffers() = 0; - - // Get the last EGL error. - virtual unsigned GetError() = 0; - // Set an optional callback that will be invoked when the side effects of // a SwapBuffers call become visible to the compositor. Takes ownership // of the callback. @@ -160,10 +152,10 @@ class PluginDelegate { // compositors namespace. Otherwise return 0. Returns 0 by default. virtual unsigned GetBackingTextureId() = 0; - // This call will return the address of the GLES2 implementation for this - // context that is constructed in Initialize() and is valid until this - // context is destroyed. - virtual gpu::gles2::GLES2Implementation* GetGLES2Implementation() = 0; + // This call will return the address of the command buffer for this context + // that is constructed in Initialize() and is valid until this context is + // destroyed. + virtual gpu::CommandBuffer* GetCommandBuffer() = 0; }; class PlatformAudio { diff --git a/webkit/plugins/ppapi/ppb_context_3d_impl.cc b/webkit/plugins/ppapi/ppb_context_3d_impl.cc index 034b3a9..ea2b127 100644 --- a/webkit/plugins/ppapi/ppb_context_3d_impl.cc +++ b/webkit/plugins/ppapi/ppb_context_3d_impl.cc @@ -6,6 +6,8 @@ #include "base/logging.h" #include "gpu/command_buffer/common/command_buffer.h" +#include "gpu/command_buffer/client/gles2_cmd_helper.h" +#include "gpu/command_buffer/client/gles2_implementation.h" #include "webkit/plugins/ppapi/common.h" #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" #include "webkit/plugins/ppapi/ppb_surface_3d_impl.h" @@ -16,7 +18,8 @@ namespace ppapi { namespace { // Size of the transfer buffer. -enum { kTransferBufferSize = 512 * 1024 }; +const int32 kCommandBufferSize = 1024 * 1024; +const int32 kTransferBufferSize = 1024 * 1024; PP_Resource Create(PP_Instance instance_id, PP_Config3D_Dev config, @@ -91,7 +94,7 @@ const PPB_Context3D_Dev ppb_context3d = { PPB_Context3D_Impl::PPB_Context3D_Impl(PluginInstance* instance) : Resource(instance), instance_(instance), - gles2_impl_(NULL), + transfer_buffer_id_(0), draw_surface_(NULL), read_surface_(NULL) { } @@ -122,8 +125,45 @@ bool PPB_Context3D_Impl::Init(PP_Config3D_Dev config, return false; } - gles2_impl_ = platform_context_->GetGLES2Implementation(); - DCHECK(gles2_impl_); + gpu::CommandBuffer* command_buffer = platform_context_->GetCommandBuffer(); + DCHECK(command_buffer); + + if (!command_buffer->Initialize(kCommandBufferSize)) { + Destroy(); + return false; + } + + // Create the GLES2 helper, which writes the command buffer protocol. + helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer)); + if (!helper_->Initialize(kCommandBufferSize)) { + Destroy(); + return false; + } + + // Create a transfer buffer used to copy resources between the renderer + // process and the GPU process. + transfer_buffer_id_ = + command_buffer->CreateTransferBuffer(kTransferBufferSize); + if (transfer_buffer_id_ < 0) { + Destroy(); + return false; + } + + // Map the buffer into the renderer process's address space. + gpu::Buffer transfer_buffer = + command_buffer->GetTransferBuffer(transfer_buffer_id_); + if (!transfer_buffer.ptr) { + Destroy(); + return false; + } + + // Create the object exposing the OpenGL API. + gles2_impl_.reset(new gpu::gles2::GLES2Implementation( + helper_.get(), + transfer_buffer.size, + transfer_buffer.ptr, + transfer_buffer_id_, + false)); return true; } @@ -143,7 +183,7 @@ int32_t PPB_Context3D_Impl::BindSurfaces(PPB_Surface3D_Impl* draw, if (draw_surface_) draw_surface_->BindToContext(NULL); - if (draw && !draw->BindToContext(platform_context_.get())) + if (draw && !draw->BindToContext(this)) return PP_ERROR_NOMEMORY; draw_surface_ = draw; @@ -155,7 +195,15 @@ void PPB_Context3D_Impl::Destroy() { if (draw_surface_) draw_surface_->BindToContext(NULL); - gles2_impl_ = NULL; + gles2_impl_.reset(); + + if (platform_context_.get() && transfer_buffer_id_ != 0) { + gpu::CommandBuffer* command_buffer = platform_context_->GetCommandBuffer(); + command_buffer->DestroyTransferBuffer(transfer_buffer_id_); + transfer_buffer_id_ = 0; + } + + helper_.reset(); platform_context_.reset(); } diff --git a/webkit/plugins/ppapi/ppb_context_3d_impl.h b/webkit/plugins/ppapi/ppb_context_3d_impl.h index 9046368..e0fe036 100644 --- a/webkit/plugins/ppapi/ppb_context_3d_impl.h +++ b/webkit/plugins/ppapi/ppb_context_3d_impl.h @@ -12,6 +12,7 @@ namespace gpu { namespace gles2 { +class GLES2CmdHelper; class GLES2Implementation; } // namespace gles2 } // namespace gpu @@ -39,8 +40,12 @@ class PPB_Context3D_Impl : public Resource { return instance_; } + PluginDelegate::PlatformContext3D* platform_context() { + return platform_context_.get(); + } + gpu::gles2::GLES2Implementation* gles2_impl() { - return gles2_impl_; + return gles2_impl_.get(); } int32_t BindSurfaces(PPB_Surface3D_Impl* draw, @@ -55,8 +60,9 @@ class PPB_Context3D_Impl : public Resource { // PluginDelegate's 3D Context. Responsible for providing the command buffer. scoped_ptr<PluginDelegate::PlatformContext3D> platform_context_; - // GLES2 Implementation instance. Owned by the platform context's GGL context. - gpu::gles2::GLES2Implementation* gles2_impl_; + scoped_ptr<gpu::gles2::GLES2CmdHelper> helper_; + int32 transfer_buffer_id_; + scoped_ptr<gpu::gles2::GLES2Implementation> gles2_impl_; PPB_Surface3D_Impl* draw_surface_; PPB_Surface3D_Impl* read_surface_; diff --git a/webkit/plugins/ppapi/ppb_surface_3d_impl.cc b/webkit/plugins/ppapi/ppb_surface_3d_impl.cc index 6603abf..d0c3a60 100644 --- a/webkit/plugins/ppapi/ppb_surface_3d_impl.cc +++ b/webkit/plugins/ppapi/ppb_surface_3d_impl.cc @@ -9,6 +9,7 @@ #include "ppapi/c/dev/ppb_graphics_3d_dev.h" #include "webkit/plugins/ppapi/common.h" #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" +#include "webkit/plugins/ppapi/ppb_context_3d_impl.h" namespace webkit { namespace ppapi { @@ -95,22 +96,21 @@ bool PPB_Surface3D_Impl::BindToInstance(bool bind) { } bool PPB_Surface3D_Impl::BindToContext( - PluginDelegate::PlatformContext3D* context) { + PPB_Context3D_Impl* context) { if (context == context_) return true; // Unbind from the current context. if (context_) { - context_->SetSwapBuffersCallback(NULL); + context_->platform_context()->SetSwapBuffersCallback(NULL); } if (context) { // Resize the backing texture to the size of the instance when it is bound. // TODO(alokp): This should be the responsibility of plugins. const gfx::Size& size = instance()->position().size(); - context->GetGLES2Implementation()->ResizeCHROMIUM( - size.width(), size.height()); + context->gles2_impl()->ResizeCHROMIUM(size.width(), size.height()); - context->SetSwapBuffersCallback( + context->platform_context()->SetSwapBuffersCallback( NewCallback(this, &PPB_Surface3D_Impl::OnSwapBuffers)); } context_ = context; @@ -127,7 +127,8 @@ bool PPB_Surface3D_Impl::SwapBuffers(PP_CompletionCallback callback) { } swap_callback_ = callback; - return context_->SwapBuffers(); + context_->gles2_impl()->SwapBuffers(); + return true; } void PPB_Surface3D_Impl::ViewInitiatedPaint() { @@ -149,7 +150,7 @@ void PPB_Surface3D_Impl::ViewFlushedPaint() { } unsigned int PPB_Surface3D_Impl::GetBackingTextureId() { - return context_ ? context_->GetBackingTextureId() : 0; + return context_ ? context_->platform_context()->GetBackingTextureId() : 0; } void PPB_Surface3D_Impl::OnSwapBuffers() { diff --git a/webkit/plugins/ppapi/ppb_surface_3d_impl.h b/webkit/plugins/ppapi/ppb_surface_3d_impl.h index e3d4173..1576673 100644 --- a/webkit/plugins/ppapi/ppb_surface_3d_impl.h +++ b/webkit/plugins/ppapi/ppb_surface_3d_impl.h @@ -30,7 +30,7 @@ class PPB_Surface3D_Impl : public Resource { bool Init(PP_Config3D_Dev config, const int32_t* attrib_list); - PluginDelegate::PlatformContext3D* context() const { + PPB_Context3D_Impl* context() const { return context_; } @@ -42,7 +42,7 @@ class PPB_Surface3D_Impl : public Resource { // Binds the context such that all draw calls to context // affect this surface. To unbind call this function will NULL context. // Returns true if successful. - bool BindToContext(PluginDelegate::PlatformContext3D* context); + bool BindToContext(PPB_Context3D_Impl* context); unsigned int GetBackingTextureId(); @@ -62,7 +62,7 @@ class PPB_Surface3D_Impl : public Resource { PP_CompletionCallback swap_callback_; // The context this surface is currently bound to. - PluginDelegate::PlatformContext3D* context_; + PPB_Context3D_Impl* context_; DISALLOW_COPY_AND_ASSIGN(PPB_Surface3D_Impl); }; |