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 |