diff options
-rw-r--r-- | ppapi/c/dev/ppb_context_3d_trusted_dev.h | 15 | ||||
-rw-r--r-- | webkit/plugins/ppapi/plugin_module.cc | 3 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_context_3d_impl.cc | 201 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_context_3d_impl.h | 10 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_surface_3d_impl.cc | 12 |
5 files changed, 219 insertions, 22 deletions
diff --git a/ppapi/c/dev/ppb_context_3d_trusted_dev.h b/ppapi/c/dev/ppb_context_3d_trusted_dev.h index 98fe25b..3a8757d 100644 --- a/ppapi/c/dev/ppb_context_3d_trusted_dev.h +++ b/ppapi/c/dev/ppb_context_3d_trusted_dev.h @@ -9,7 +9,7 @@ #include "ppapi/c/pp_resource.h" #include "ppapi/c/pp_stdint.h" -#define PPB_CONTEXT_3D_TRUSTED_DEV_INTERFACE "PPB_Context3DTrusted(Dev);0.1" +#define PPB_CONTEXT_3D_TRUSTED_DEV_INTERFACE "PPB_Context3DTrusted(Dev);0.2" enum PPB_Context3DTrustedError { kNoError, @@ -43,6 +43,19 @@ struct PP_Context3DTrustedState { }; struct PPB_Context3DTrusted_Dev { + // Creates a raw Context3D resource. A raw Context3D is intended to be used + // with the trusted interface, through the command buffer (for proxying). In + // particular, when a Surface3D is bound to a raw context, SwapBuffers has no + // effect. + PP_Resource (*CreateRaw)(PP_Instance instance_id, + PP_Config3D_Dev config, + PP_Resource share_context, + const int32_t* attrib_list); + + // Initializes the command buffer with the given size. + PP_Bool (*Initialize)(PP_Resource context_id, int32_t size); + + // Gets the ring buffer for the command buffer. PP_Bool (*GetRingBuffer)(PP_Resource context_id, int* shm_handle, uint32_t* shm_size); diff --git a/webkit/plugins/ppapi/plugin_module.cc b/webkit/plugins/ppapi/plugin_module.cc index fdd9448..cec7e79 100644 --- a/webkit/plugins/ppapi/plugin_module.cc +++ b/webkit/plugins/ppapi/plugin_module.cc @@ -15,6 +15,7 @@ #include "ppapi/c/dev/ppb_buffer_dev.h" #include "ppapi/c/dev/ppb_char_set_dev.h" #include "ppapi/c/dev/ppb_context_3d_dev.h" +#include "ppapi/c/dev/ppb_context_3d_trusted_dev.h" #include "ppapi/c/dev/ppb_cursor_control_dev.h" #include "ppapi/c/dev/ppb_directory_reader_dev.h" #include "ppapi/c/dev/ppb_file_io_dev.h" @@ -287,6 +288,8 @@ const void* GetInterface(const char* name) { return PPB_Graphics3D_Impl::GetInterface(); if (strcmp(name, PPB_CONTEXT_3D_DEV_INTERFACE) == 0) return PPB_Context3D_Impl::GetInterface(); + if (strcmp(name, PPB_CONTEXT_3D_TRUSTED_DEV_INTERFACE) == 0) + return PPB_Context3D_Impl::GetTrustedInterface(); if (strcmp(name, PPB_GLES_CHROMIUM_TEXTURE_MAPPING_DEV_INTERFACE) == 0) return PPB_GLESChromiumTextureMapping_Impl::GetInterface(); if (strcmp(name, PPB_OPENGLES2_DEV_INTERFACE) == 0) diff --git a/webkit/plugins/ppapi/ppb_context_3d_impl.cc b/webkit/plugins/ppapi/ppb_context_3d_impl.cc index ea2b127..df6bedc 100644 --- a/webkit/plugins/ppapi/ppb_context_3d_impl.cc +++ b/webkit/plugins/ppapi/ppb_context_3d_impl.cc @@ -5,9 +5,11 @@ #include "webkit/plugins/ppapi/ppb_context_3d_impl.h" #include "base/logging.h" -#include "gpu/command_buffer/common/command_buffer.h" +#include "base/shared_memory.h" #include "gpu/command_buffer/client/gles2_cmd_helper.h" #include "gpu/command_buffer/client/gles2_implementation.h" +#include "gpu/command_buffer/common/command_buffer.h" +#include "ppapi/c/dev/ppb_context_3d_trusted_dev.h" #include "webkit/plugins/ppapi/common.h" #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" #include "webkit/plugins/ppapi/ppb_surface_3d_impl.h" @@ -21,6 +23,34 @@ namespace { const int32 kCommandBufferSize = 1024 * 1024; const int32 kTransferBufferSize = 1024 * 1024; +bool ShmToHandle(base::SharedMemory* shm, + size_t size, + int* shm_handle, + uint32_t* shm_size) { + if (!shm || !shm_handle || !shm_size) + return 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 true; +} + +PP_Context3DTrustedState PPStateFromGPUState(gpu::CommandBuffer::State s) { + PP_Context3DTrustedState state = { + s.num_entries, + s.get_offset, + s.put_offset, + s.token, + static_cast<PPB_Context3DTrustedError>(s.error) + }; + return state; +} + PP_Resource Create(PP_Instance instance_id, PP_Config3D_Dev config, PP_Resource share_context, @@ -89,6 +119,114 @@ const PPB_Context3D_Dev ppb_context3d = { &GetBoundSurfaces, }; + +PP_Resource CreateRaw(PP_Instance instance_id, + PP_Config3D_Dev config, + PP_Resource share_context, + const int32_t* attrib_list) { + // TODO(alokp): Support shared context. + DCHECK_EQ(0, share_context); + if (share_context != 0) + return 0; + + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); + if (!instance) + return 0; + + scoped_refptr<PPB_Context3D_Impl> context( + new PPB_Context3D_Impl(instance)); + if (!context->InitRaw(config, share_context, attrib_list)) + return 0; + + return context->GetReference(); +} + +PP_Bool Initialize(PP_Resource context_id, int32_t size) { + scoped_refptr<PPB_Context3D_Impl> context( + Resource::GetAs<PPB_Context3D_Impl>(context_id)); + if (!context.get()) + return PP_FALSE; + return context->command_buffer()->Initialize(size) ? PP_TRUE : PP_FALSE; +} + +PP_Bool GetRingBuffer(PP_Resource context_id, + int* shm_handle, + uint32_t* shm_size) { + scoped_refptr<PPB_Context3D_Impl> context( + Resource::GetAs<PPB_Context3D_Impl>(context_id)); + if (!context.get()) + return PP_FALSE; + + gpu::Buffer buffer = context->command_buffer()->GetRingBuffer(); + + return ShmToHandle(buffer.shared_memory, buffer.size, shm_handle, shm_size) + ? PP_TRUE : PP_FALSE; +} + +PP_Context3DTrustedState GetState(PP_Resource context_id) { + scoped_refptr<PPB_Context3D_Impl> context( + Resource::GetAs<PPB_Context3D_Impl>(context_id)); + if (!context.get()) { + PP_Context3DTrustedState error_state = { 0 }; + return error_state; + } + + return PPStateFromGPUState(context->command_buffer()->GetState()); +} + +PP_Bool Flush(PP_Resource context_id, int32_t put_offset) { + scoped_refptr<PPB_Context3D_Impl> context( + Resource::GetAs<PPB_Context3D_Impl>(context_id)); + if (!context.get()) + return PP_FALSE; + + context->command_buffer()->Flush(put_offset); + return PP_TRUE; +} + +PP_Context3DTrustedState FlushSync(PP_Resource context_id, int32_t put_offset) { + scoped_refptr<PPB_Context3D_Impl> context( + Resource::GetAs<PPB_Context3D_Impl>(context_id)); + if (!context.get()) { + PP_Context3DTrustedState error_state = { 0 }; + return error_state; + } + + return PPStateFromGPUState(context->command_buffer()->FlushSync(put_offset)); +} + +int32_t CreateTransferBuffer(PP_Resource context_id, size_t size) { + scoped_refptr<PPB_Context3D_Impl> context( + Resource::GetAs<PPB_Context3D_Impl>(context_id)); + if (!context.get()) + return 0; + return context->command_buffer()->CreateTransferBuffer(size); +} + +PP_Bool DestroyTransferBuffer(PP_Resource context_id, int32_t id) { + scoped_refptr<PPB_Context3D_Impl> context( + Resource::GetAs<PPB_Context3D_Impl>(context_id)); + if (!context.get()) + return PP_FALSE; + context->command_buffer()->DestroyTransferBuffer(id); + return PP_TRUE; +} + +PP_Bool GetTransferBuffer(PP_Resource context_id, + int32_t id, + int* shm_handle, + uint32_t* shm_size) { + scoped_refptr<PPB_Context3D_Impl> context( + Resource::GetAs<PPB_Context3D_Impl>(context_id)); + if (!context.get()) + return PP_FALSE; + gpu::Buffer buffer = context->command_buffer()->GetTransferBuffer(id); + + return ShmToHandle(buffer.shared_memory, buffer.size, shm_handle, shm_size) + ? PP_TRUE : PP_FALSE; +} + + } // namespace PPB_Context3D_Impl::PPB_Context3D_Impl(PluginInstance* instance) @@ -107,13 +245,28 @@ const PPB_Context3D_Dev* PPB_Context3D_Impl::GetInterface() { return &ppb_context3d; } +const PPB_Context3DTrusted_Dev* PPB_Context3D_Impl::GetTrustedInterface() { + static const PPB_Context3DTrusted_Dev iface = { + &CreateRaw, + &Initialize, + &GetRingBuffer, + &GetState, + &Flush, + &FlushSync, + &CreateTransferBuffer, + &DestroyTransferBuffer, + &GetTransferBuffer + }; + return &iface; +} + PPB_Context3D_Impl* PPB_Context3D_Impl::AsPPB_Context3D_Impl() { return this; } -bool PPB_Context3D_Impl::Init(PP_Config3D_Dev config, - PP_Resource share_context, - const int32_t* attrib_list) { +bool PPB_Context3D_Impl::InitRaw(PP_Config3D_Dev config, + PP_Resource share_context, + const int32_t* attrib_list) { // Create and initialize the objects required to issue GLES2 calls. platform_context_.reset(instance()->CreateContext3D()); if (!platform_context_.get()) { @@ -124,38 +277,47 @@ bool PPB_Context3D_Impl::Init(PP_Config3D_Dev config, Destroy(); return false; } + return true; +} - gpu::CommandBuffer* command_buffer = platform_context_->GetCommandBuffer(); - DCHECK(command_buffer); +bool PPB_Context3D_Impl::Init(PP_Config3D_Dev config, + PP_Resource share_context, + const int32_t* attrib_list) { + if (!InitRaw(config, share_context, attrib_list)) + return false; - if (!command_buffer->Initialize(kCommandBufferSize)) { + if (!CreateImplementation()) { Destroy(); return false; } + return true; +} + +bool PPB_Context3D_Impl::CreateImplementation() { + gpu::CommandBuffer* command_buffer = platform_context_->GetCommandBuffer(); + DCHECK(command_buffer); + + if (!command_buffer->Initialize(kCommandBufferSize)) + 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(); + if (!helper_->Initialize(kCommandBufferSize)) 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(); + if (transfer_buffer_id_ < 0) 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(); + if (!transfer_buffer.ptr) return false; - } // Create the object exposing the OpenGL API. gles2_impl_.reset(new gpu::gles2::GLES2Implementation( @@ -198,8 +360,7 @@ void PPB_Context3D_Impl::Destroy() { gles2_impl_.reset(); if (platform_context_.get() && transfer_buffer_id_ != 0) { - gpu::CommandBuffer* command_buffer = platform_context_->GetCommandBuffer(); - command_buffer->DestroyTransferBuffer(transfer_buffer_id_); + command_buffer()->DestroyTransferBuffer(transfer_buffer_id_); transfer_buffer_id_ = 0; } @@ -207,6 +368,10 @@ void PPB_Context3D_Impl::Destroy() { platform_context_.reset(); } +gpu::CommandBuffer *PPB_Context3D_Impl::command_buffer() { + return platform_context_->GetCommandBuffer(); +} + } // namespace ppapi } // namespace webkit diff --git a/webkit/plugins/ppapi/ppb_context_3d_impl.h b/webkit/plugins/ppapi/ppb_context_3d_impl.h index e0fe036..0021984 100644 --- a/webkit/plugins/ppapi/ppb_context_3d_impl.h +++ b/webkit/plugins/ppapi/ppb_context_3d_impl.h @@ -10,7 +10,10 @@ #include "webkit/plugins/ppapi/plugin_delegate.h" #include "webkit/plugins/ppapi/resource.h" +struct PPB_Context3DTrusted_Dev; + namespace gpu { +class CommandBuffer; namespace gles2 { class GLES2CmdHelper; class GLES2Implementation; @@ -28,6 +31,7 @@ class PPB_Context3D_Impl : public Resource { virtual ~PPB_Context3D_Impl(); static const PPB_Context3D_Dev* GetInterface(); + static const PPB_Context3DTrusted_Dev* GetTrustedInterface(); // Resource override. virtual PPB_Context3D_Impl* AsPPB_Context3D_Impl(); @@ -35,6 +39,9 @@ class PPB_Context3D_Impl : public Resource { bool Init(PP_Config3D_Dev config, PP_Resource share_context, const int32_t* attrib_list); + bool InitRaw(PP_Config3D_Dev config, + PP_Resource share_context, + const int32_t* attrib_list); PluginInstance* instance() { return instance_; @@ -48,11 +55,14 @@ class PPB_Context3D_Impl : public Resource { return gles2_impl_.get(); } + gpu::CommandBuffer* command_buffer(); + int32_t BindSurfaces(PPB_Surface3D_Impl* draw, PPB_Surface3D_Impl* read); private: void Destroy(); + bool CreateImplementation(); // Plugin instance this context is associated with. PluginInstance* instance_; diff --git a/webkit/plugins/ppapi/ppb_surface_3d_impl.cc b/webkit/plugins/ppapi/ppb_surface_3d_impl.cc index d0c3a60..baa03ea 100644 --- a/webkit/plugins/ppapi/ppb_surface_3d_impl.cc +++ b/webkit/plugins/ppapi/ppb_surface_3d_impl.cc @@ -107,8 +107,11 @@ bool PPB_Surface3D_Impl::BindToContext( 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->gles2_impl()->ResizeCHROMIUM(size.width(), size.height()); + gpu::gles2::GLES2Implementation* impl = context->gles2_impl(); + if (impl) { + const gfx::Size& size = instance()->position().size(); + impl->ResizeCHROMIUM(size.width(), size.height()); + } context->platform_context()->SetSwapBuffersCallback( NewCallback(this, &PPB_Surface3D_Impl::OnSwapBuffers)); @@ -127,7 +130,10 @@ bool PPB_Surface3D_Impl::SwapBuffers(PP_CompletionCallback callback) { } swap_callback_ = callback; - context_->gles2_impl()->SwapBuffers(); + gpu::gles2::GLES2Implementation* impl = context_->gles2_impl(); + if (impl) { + context_->gles2_impl()->SwapBuffers(); + } return true; } |