| Index: webkit/plugins/ppapi/ppb_context_3d_impl.cc
|
| diff --git a/webkit/plugins/ppapi/ppb_context_3d_impl.cc b/webkit/plugins/ppapi/ppb_context_3d_impl.cc
|
| index ea2b127b330798f4de311f21a30eb6187c14fc8e..26b80e238037bacd2fbccd2f665a944efad1a751 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,116 @@ 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 +247,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 +279,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 +362,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 +370,10 @@ void PPB_Context3D_Impl::Destroy() {
|
| platform_context_.reset();
|
| }
|
|
|
| +gpu::CommandBuffer *PPB_Context3D_Impl::command_buffer() {
|
| + return platform_context_->GetCommandBuffer();
|
| +}
|
| +
|
| } // namespace ppapi
|
| } // namespace webkit
|
|
|
|
|