| Index: ppapi/proxy/ppb_context_3d_proxy.cc
|
| ===================================================================
|
| --- ppapi/proxy/ppb_context_3d_proxy.cc (revision 89672)
|
| +++ ppapi/proxy/ppb_context_3d_proxy.cc (working copy)
|
| @@ -11,126 +11,26 @@
|
| #include "ppapi/c/pp_resource.h"
|
| #include "ppapi/c/dev/ppb_context_3d_dev.h"
|
| #include "ppapi/c/dev/ppb_context_3d_trusted_dev.h"
|
| +#include "ppapi/proxy/enter_proxy.h"
|
| #include "ppapi/proxy/plugin_dispatcher.h"
|
| #include "ppapi/proxy/plugin_resource.h"
|
| #include "ppapi/proxy/ppapi_messages.h"
|
| #include "ppapi/proxy/ppb_surface_3d_proxy.h"
|
| +#include "ppapi/thunk/enter.h"
|
| +#include "ppapi/thunk/resource_creation_api.h"
|
| +#include "ppapi/thunk/thunk.h"
|
|
|
| +using ppapi::thunk::EnterFunctionNoLock;
|
| +using ppapi::thunk::EnterResourceNoLock;
|
| +using ppapi::thunk::PPB_Context3D_API;
|
| +using ppapi::thunk::PPB_Surface3D_API;
|
| +using ppapi::thunk::ResourceCreationAPI;
|
| +
|
| namespace pp {
|
| namespace proxy {
|
|
|
| namespace {
|
|
|
| -PP_Resource Create(PP_Instance instance,
|
| - PP_Config3D_Dev config,
|
| - PP_Resource share_context,
|
| - const int32_t* attrib_list) {
|
| - PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
|
| - if (!dispatcher)
|
| - return PP_ERROR_BADARGUMENT;
|
| -
|
| - // TODO(alokp): Support shared context.
|
| - DCHECK_EQ(0, share_context);
|
| - if (share_context != 0)
|
| - return 0;
|
| -
|
| - std::vector<int32_t> attribs;
|
| - if (attrib_list) {
|
| - for (const int32_t* attr = attrib_list; attr; ++attr)
|
| - attribs.push_back(*attr);
|
| - } else {
|
| - attribs.push_back(0);
|
| - }
|
| -
|
| - HostResource result;
|
| - dispatcher->Send(new PpapiHostMsg_PPBContext3D_Create(
|
| - INTERFACE_ID_PPB_CONTEXT_3D, instance, config, attribs, &result));
|
| -
|
| - if (result.is_null())
|
| - return 0;
|
| - linked_ptr<Context3D> context_3d(new Context3D(result));
|
| - if (!context_3d->CreateImplementation())
|
| - return 0;
|
| - return PluginResourceTracker::GetInstance()->AddResource(context_3d);
|
| -}
|
| -
|
| -PP_Bool IsContext3D(PP_Resource resource) {
|
| - Context3D* object = PluginResource::GetAs<Context3D>(resource);
|
| - return BoolToPPBool(!!object);
|
| -}
|
| -
|
| -int32_t GetAttrib(PP_Resource context,
|
| - int32_t attribute,
|
| - int32_t* value) {
|
| - // TODO(alokp): Implement me.
|
| - return 0;
|
| -}
|
| -
|
| -int32_t BindSurfaces(PP_Resource context_id,
|
| - PP_Resource draw,
|
| - PP_Resource read) {
|
| - Context3D* object = PluginResource::GetAs<Context3D>(context_id);
|
| - if (!object)
|
| - return PP_ERROR_BADRESOURCE;
|
| - PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(
|
| - object->instance());
|
| - if (!dispatcher)
|
| - return PP_ERROR_FAILED;
|
| -
|
| - // TODO(alokp): Support separate draw-read surfaces.
|
| - DCHECK_EQ(draw, read);
|
| - if (draw != read)
|
| - return PP_GRAPHICS3DERROR_BAD_MATCH;
|
| -
|
| - Surface3D* draw_surface = PluginResource::GetAs<Surface3D>(draw);
|
| - Surface3D* read_surface = PluginResource::GetAs<Surface3D>(read);
|
| - if (draw && !draw_surface)
|
| - return PP_ERROR_BADRESOURCE;
|
| - if (read && !read_surface)
|
| - return PP_ERROR_BADRESOURCE;
|
| - HostResource host_draw =
|
| - draw_surface ? draw_surface->host_resource() : HostResource();
|
| - HostResource host_read =
|
| - read_surface ? read_surface->host_resource() : HostResource();
|
| -
|
| - int32_t result;
|
| - dispatcher->Send(new PpapiHostMsg_PPBContext3D_BindSurfaces(
|
| - INTERFACE_ID_PPB_CONTEXT_3D,
|
| - object->host_resource(),
|
| - host_draw,
|
| - host_read,
|
| - &result));
|
| -
|
| - if (result == PP_OK)
|
| - object->BindSurfaces(draw_surface, read_surface);
|
| -
|
| - return result;
|
| -}
|
| -
|
| -int32_t GetBoundSurfaces(PP_Resource context,
|
| - PP_Resource* draw,
|
| - PP_Resource* read) {
|
| - Context3D* object = PluginResource::GetAs<Context3D>(context);
|
| - if (!object)
|
| - return PP_ERROR_BADRESOURCE;
|
| -
|
| - Surface3D* draw_surface = object->get_draw_surface();
|
| - Surface3D* read_surface = object->get_read_surface();
|
| -
|
| - *draw = draw_surface ? draw_surface->resource() : 0;
|
| - *read = read_surface ? read_surface->resource() : 0;
|
| - return PP_OK;
|
| -}
|
| -
|
| -
|
| -const PPB_Context3D_Dev context_3d_interface = {
|
| - &Create,
|
| - &IsContext3D,
|
| - &GetAttrib,
|
| - &BindSurfaces,
|
| - &GetBoundSurfaces,
|
| -};
|
| -
|
| base::SharedMemoryHandle TransportSHMHandleFromInt(Dispatcher* dispatcher,
|
| int shm_handle) {
|
| // TODO(piman): Change trusted interface to return a PP_FileHandle, those
|
| @@ -147,6 +47,12 @@
|
| return dispatcher->ShareHandleWithRemote(source, false);
|
| }
|
|
|
| +PP_Context3DTrustedState GetErrorState() {
|
| + PP_Context3DTrustedState error_state = { 0 };
|
| + error_state.error = kGenericError;
|
| + return error_state;
|
| +}
|
| +
|
| gpu::CommandBuffer::State GPUStateFromPPState(
|
| const PP_Context3DTrustedState& s) {
|
| gpu::CommandBuffer::State state;
|
| @@ -419,6 +325,8 @@
|
| last_state_ = state;
|
| }
|
|
|
| +// Context3D -------------------------------------------------------------------
|
| +
|
| Context3D::Context3D(const HostResource& resource)
|
| : PluginResource(resource),
|
| draw_(NULL),
|
| @@ -431,6 +339,10 @@
|
| draw_->set_context(NULL);
|
| }
|
|
|
| +PPB_Context3D_API* Context3D::AsPPB_Context3D_API() {
|
| + return this;
|
| +}
|
| +
|
| bool Context3D::CreateImplementation() {
|
| PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance());
|
| if (!dispatcher)
|
| @@ -465,28 +377,132 @@
|
| return true;
|
| }
|
|
|
| -void Context3D::BindSurfaces(Surface3D* draw, Surface3D* read) {
|
| - if (draw != draw_) {
|
| +int32_t Context3D::GetAttrib(int32_t attribute, int32_t* value) {
|
| + // TODO(alokp): Implement me.
|
| + return 0;
|
| +}
|
| +
|
| +int32_t Context3D::BindSurfaces(PP_Resource pp_draw, PP_Resource pp_read) {
|
| + // TODO(alokp): Support separate draw-read surfaces.
|
| + DCHECK_EQ(pp_draw, pp_read);
|
| + if (pp_draw != pp_read)
|
| + return PP_GRAPHICS3DERROR_BAD_MATCH;
|
| +
|
| + EnterResourceNoLock<PPB_Surface3D_API> enter_draw(pp_draw, false);
|
| + EnterResourceNoLock<PPB_Surface3D_API> enter_read(pp_read, false);
|
| + Surface3D* draw_surface = enter_draw.succeeded() ?
|
| + static_cast<Surface3D*>(enter_draw.object()) : NULL;
|
| + Surface3D* read_surface = enter_read.succeeded() ?
|
| + static_cast<Surface3D*>(enter_read.object()) : NULL;
|
| +
|
| + if (pp_draw && !draw_surface)
|
| + return PP_ERROR_BADRESOURCE;
|
| + if (pp_read && !read_surface)
|
| + return PP_ERROR_BADRESOURCE;
|
| + HostResource host_draw =
|
| + draw_surface ? draw_surface->host_resource() : HostResource();
|
| + HostResource host_read =
|
| + read_surface ? read_surface->host_resource() : HostResource();
|
| +
|
| + int32_t result;
|
| + GetDispatcher()->Send(new PpapiHostMsg_PPBContext3D_BindSurfaces(
|
| + INTERFACE_ID_PPB_CONTEXT_3D,
|
| + host_resource(), host_draw, host_read, &result));
|
| + if (result != PP_OK)
|
| + return result;
|
| +
|
| + if (draw_surface != draw_) {
|
| if (draw_)
|
| draw_->set_context(NULL);
|
| - if (draw) {
|
| - draw->set_context(this);
|
| + if (draw_surface) {
|
| + draw_surface->set_context(this);
|
| // Resize the backing texture to the size of the instance when it is
|
| // bound.
|
| // TODO(alokp): This should be the responsibility of plugins.
|
| - PluginDispatcher* dispatcher =
|
| - PluginDispatcher::GetForInstance(instance());
|
| - DCHECK(dispatcher);
|
| - InstanceData* data = dispatcher->GetInstanceData(instance());
|
| - DCHECK(data);
|
| + InstanceData* data = GetDispatcher()->GetInstanceData(instance());
|
| gles2_impl()->ResizeCHROMIUM(data->position.size.width,
|
| data->position.size.height);
|
| }
|
| - draw_ = draw;
|
| + draw_ = draw_surface;
|
| }
|
| - read_ = read;
|
| + read_ = read_surface;
|
| + return PP_OK;
|
| }
|
|
|
| +int32_t Context3D::GetBoundSurfaces(PP_Resource* draw, PP_Resource* read) {
|
| + *draw = draw_ ? draw_->resource() : 0;
|
| + *read = read_ ? read_->resource() : 0;
|
| + return PP_OK;
|
| +}
|
| +
|
| +PP_Bool Context3D::InitializeTrusted(int32_t size) {
|
| + // Trusted interface not implemented in the proxy.
|
| + return PP_FALSE;
|
| +}
|
| +
|
| +PP_Bool Context3D::GetRingBuffer(int* shm_handle,
|
| + uint32_t* shm_size) {
|
| + // Trusted interface not implemented in the proxy.
|
| + return PP_FALSE;
|
| +}
|
| +
|
| +PP_Context3DTrustedState Context3D::GetState() {
|
| + // Trusted interface not implemented in the proxy.
|
| + return GetErrorState();
|
| +}
|
| +
|
| +PP_Bool Context3D::Flush(int32_t put_offset) {
|
| + // Trusted interface not implemented in the proxy.
|
| + return PP_FALSE;
|
| +}
|
| +
|
| +PP_Context3DTrustedState Context3D::FlushSync(int32_t put_offset) {
|
| + // Trusted interface not implemented in the proxy.
|
| + return GetErrorState();
|
| +}
|
| +
|
| +int32_t Context3D::CreateTransferBuffer(uint32_t size) {
|
| + // Trusted interface not implemented in the proxy.
|
| + return 0;
|
| +}
|
| +
|
| +PP_Bool Context3D::DestroyTransferBuffer(int32_t id) {
|
| + // Trusted interface not implemented in the proxy.
|
| + return PP_FALSE;
|
| +}
|
| +
|
| +PP_Bool Context3D::GetTransferBuffer(int32_t id,
|
| + int* shm_handle,
|
| + uint32_t* shm_size) {
|
| + // Trusted interface not implemented in the proxy.
|
| + return PP_FALSE;
|
| +}
|
| +
|
| +PP_Context3DTrustedState Context3D::FlushSyncFast(int32_t put_offset,
|
| + int32_t last_known_get) {
|
| + // Trusted interface not implemented in the proxy.
|
| + return GetErrorState();
|
| +}
|
| +
|
| +void* Context3D::MapTexSubImage2DCHROMIUM(GLenum target,
|
| + GLint level,
|
| + GLint xoffset,
|
| + GLint yoffset,
|
| + GLsizei width,
|
| + GLsizei height,
|
| + GLenum format,
|
| + GLenum type,
|
| + GLenum access) {
|
| + return gles2_impl_->MapTexSubImage2DCHROMIUM(
|
| + target, level, xoffset, yoffset, width, height, format, type, access);
|
| +}
|
| +
|
| +void Context3D::UnmapTexSubImage2DCHROMIUM(const void* mem) {
|
| + gles2_impl_->UnmapTexSubImage2DCHROMIUM(mem);
|
| +}
|
| +
|
| +// PPB_Context3D_Proxy ---------------------------------------------------------
|
| +
|
| PPB_Context3D_Proxy::PPB_Context3D_Proxy(Dispatcher* dispatcher,
|
| const void* target_interface)
|
| : InterfaceProxy(dispatcher, target_interface) {
|
| @@ -498,7 +514,7 @@
|
| // static
|
| const InterfaceProxy::Info* PPB_Context3D_Proxy::GetInfo() {
|
| static const Info info = {
|
| - &context_3d_interface,
|
| + ::ppapi::thunk::GetPPB_Context3D_Thunk(),
|
| PPB_CONTEXT_3D_DEV_INTERFACE,
|
| INTERFACE_ID_PPB_CONTEXT_3D,
|
| false,
|
| @@ -507,13 +523,52 @@
|
| return &info;
|
| }
|
|
|
| -const PPB_Context3DTrusted_Dev*
|
| -PPB_Context3D_Proxy::ppb_context_3d_trusted() const {
|
| - return static_cast<const PPB_Context3DTrusted_Dev*>(
|
| - dispatcher()->GetLocalInterface(
|
| - PPB_CONTEXT_3D_TRUSTED_DEV_INTERFACE));
|
| +// static
|
| +const InterfaceProxy::Info* PPB_Context3D_Proxy::GetTextureMappingInfo() {
|
| + static const Info info = {
|
| + ::ppapi::thunk::GetPPB_GLESChromiumTextureMapping_Thunk(),
|
| + PPB_GLES_CHROMIUM_TEXTURE_MAPPING_DEV_INTERFACE,
|
| + INTERFACE_ID_NONE, // CONTEXT_3D is the canonical one.
|
| + false,
|
| + &CreateContext3DProxy,
|
| + };
|
| + return &info;
|
| }
|
|
|
| +// static
|
| +PP_Resource PPB_Context3D_Proxy::Create(PP_Instance instance,
|
| + PP_Config3D_Dev config,
|
| + PP_Resource share_context,
|
| + const int32_t* attrib_list) {
|
| + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
|
| + if (!dispatcher)
|
| + return PP_ERROR_BADARGUMENT;
|
| +
|
| + // TODO(alokp): Support shared context.
|
| + DCHECK_EQ(0, share_context);
|
| + if (share_context != 0)
|
| + return 0;
|
| +
|
| + std::vector<int32_t> attribs;
|
| + if (attrib_list) {
|
| + for (const int32_t* attr = attrib_list; attr; ++attr)
|
| + attribs.push_back(*attr);
|
| + } else {
|
| + attribs.push_back(0);
|
| + }
|
| +
|
| + HostResource result;
|
| + dispatcher->Send(new PpapiHostMsg_PPBContext3D_Create(
|
| + INTERFACE_ID_PPB_CONTEXT_3D, instance, config, attribs, &result));
|
| +
|
| + if (result.is_null())
|
| + return 0;
|
| + linked_ptr<Context3D> context_3d(new Context3D(result));
|
| + if (!context_3d->CreateImplementation())
|
| + return 0;
|
| + return PluginResourceTracker::GetInstance()->AddResource(context_3d);
|
| +}
|
| +
|
| bool PPB_Context3D_Proxy::OnMessageReceived(const IPC::Message& msg) {
|
| bool handled = true;
|
| IPC_BEGIN_MESSAGE_MAP(PPB_Context3D_Proxy, msg)
|
| @@ -545,46 +600,56 @@
|
| void PPB_Context3D_Proxy::OnMsgCreate(PP_Instance instance,
|
| PP_Config3D_Dev config,
|
| std::vector<int32_t> attribs,
|
| - HostResource* result) {
|
| - DCHECK(attribs.back() == 0);
|
| - PP_Resource resource = ppb_context_3d_trusted()->CreateRaw(
|
| - instance, config, 0, &attribs.front());
|
| - result->SetHostResource(instance, resource);
|
| + HostResource* result) {
|
| + if (attribs.empty() || attribs.back() != 0)
|
| + return; // Bad message.
|
| + EnterFunctionNoLock<ResourceCreationAPI> enter(instance, true);
|
| + if (enter.succeeded()) {
|
| + result->SetHostResource(
|
| + instance,
|
| + enter.functions()->CreateContext3DRaw(instance, config, 0,
|
| + &attribs.front()));
|
| + }
|
| }
|
|
|
| void PPB_Context3D_Proxy::OnMsgBindSurfaces(const HostResource& context,
|
| const HostResource& draw,
|
| const HostResource& read,
|
| int32_t* result) {
|
| - *result = ppb_context_3d_target()->BindSurfaces(context.host_resource(),
|
| - draw.host_resource(),
|
| - read.host_resource());
|
| + EnterHostFromHostResource<PPB_Context3D_API> enter(context);
|
| + if (enter.succeeded()) {
|
| + *result = enter.object()->BindSurfaces(draw.host_resource(),
|
| + read.host_resource());
|
| + } else {
|
| + *result = PP_ERROR_BADRESOURCE;
|
| + }
|
| }
|
|
|
| void PPB_Context3D_Proxy::OnMsgInitialize(
|
| const HostResource& context,
|
| int32 size,
|
| base::SharedMemoryHandle* ring_buffer) {
|
| - const PPB_Context3DTrusted_Dev* context_3d_trusted = ppb_context_3d_trusted();
|
| *ring_buffer = base::SharedMemory::NULLHandle();
|
| - if (!context_3d_trusted->Initialize(context.host_resource(), size))
|
| + EnterHostFromHostResource<PPB_Context3D_API> enter(context);
|
| + if (enter.failed())
|
| return;
|
|
|
| + if (!enter.object()->InitializeTrusted(size))
|
| + return;
|
| +
|
| int shm_handle;
|
| uint32_t shm_size;
|
| - if (!context_3d_trusted->GetRingBuffer(context.host_resource(),
|
| - &shm_handle,
|
| - &shm_size)) {
|
| + if (!enter.object()->GetRingBuffer(&shm_handle, &shm_size))
|
| return;
|
| - }
|
| -
|
| *ring_buffer = TransportSHMHandleFromInt(dispatcher(), shm_handle);
|
| }
|
|
|
| void PPB_Context3D_Proxy::OnMsgGetState(const HostResource& context,
|
| gpu::CommandBuffer::State* state) {
|
| - PP_Context3DTrustedState pp_state =
|
| - ppb_context_3d_trusted()->GetState(context.host_resource());
|
| + EnterHostFromHostResource<PPB_Context3D_API> enter(context);
|
| + if (enter.failed())
|
| + return;
|
| + PP_Context3DTrustedState pp_state = enter.object()->GetState();
|
| *state = GPUStateFromPPState(pp_state);
|
| }
|
|
|
| @@ -592,28 +657,38 @@
|
| int32 put_offset,
|
| int32 last_known_get,
|
| gpu::CommandBuffer::State* state) {
|
| - PP_Context3DTrustedState pp_state = ppb_context_3d_trusted()->FlushSyncFast(
|
| - context.host_resource(), put_offset, last_known_get);
|
| + EnterHostFromHostResource<PPB_Context3D_API> enter(context);
|
| + if (enter.failed())
|
| + return;
|
| + PP_Context3DTrustedState pp_state = enter.object()->FlushSyncFast(
|
| + put_offset, last_known_get);
|
| *state = GPUStateFromPPState(pp_state);
|
| }
|
|
|
| void PPB_Context3D_Proxy::OnMsgAsyncFlush(const HostResource& context,
|
| int32 put_offset) {
|
| - ppb_context_3d_trusted()->Flush(context.host_resource(), put_offset);
|
| + EnterHostFromHostResource<PPB_Context3D_API> enter(context);
|
| + if (enter.succeeded())
|
| + enter.object()->Flush(put_offset);
|
| }
|
|
|
| void PPB_Context3D_Proxy::OnMsgCreateTransferBuffer(
|
| const HostResource& context,
|
| int32 size,
|
| int32* id) {
|
| - *id = ppb_context_3d_trusted()->CreateTransferBuffer(
|
| - context.host_resource(), size);
|
| + EnterHostFromHostResource<PPB_Context3D_API> enter(context);
|
| + if (enter.succeeded())
|
| + *id = enter.object()->CreateTransferBuffer(size);
|
| + else
|
| + *id = 0;
|
| }
|
|
|
| void PPB_Context3D_Proxy::OnMsgDestroyTransferBuffer(
|
| const HostResource& context,
|
| int32 id) {
|
| - ppb_context_3d_trusted()->DestroyTransferBuffer(context.host_resource(), id);
|
| + EnterHostFromHostResource<PPB_Context3D_API> enter(context);
|
| + if (enter.succeeded())
|
| + enter.object()->DestroyTransferBuffer(id);
|
| }
|
|
|
| void PPB_Context3D_Proxy::OnMsgGetTransferBuffer(
|
| @@ -622,16 +697,16 @@
|
| base::SharedMemoryHandle* transfer_buffer,
|
| uint32* size) {
|
| *transfer_buffer = base::SharedMemory::NULLHandle();
|
| - int shm_handle;
|
| - uint32_t shm_size;
|
| - if (!ppb_context_3d_trusted()->GetTransferBuffer(context.host_resource(),
|
| - id,
|
| - &shm_handle,
|
| - &shm_size)) {
|
| - return;
|
| + *size = 0;
|
| +
|
| + EnterHostFromHostResource<PPB_Context3D_API> enter(context);
|
| + int shm_handle = 0;
|
| + uint32_t shm_size = 0;
|
| + if (enter.succeeded() &&
|
| + enter.object()->GetTransferBuffer(id, &shm_handle, &shm_size)) {
|
| + *transfer_buffer = TransportSHMHandleFromInt(dispatcher(), shm_handle);
|
| + *size = shm_size;
|
| }
|
| - *transfer_buffer = TransportSHMHandleFromInt(dispatcher(), shm_handle);
|
| - *size = shm_size;
|
| }
|
|
|
| } // namespace proxy
|
|
|