summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ppapi/c/dev/ppb_context_3d_trusted_dev.h15
-rw-r--r--webkit/plugins/ppapi/plugin_module.cc3
-rw-r--r--webkit/plugins/ppapi/ppb_context_3d_impl.cc201
-rw-r--r--webkit/plugins/ppapi/ppb_context_3d_impl.h10
-rw-r--r--webkit/plugins/ppapi/ppb_surface_3d_impl.cc12
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;
}