diff options
39 files changed, 1257 insertions, 535 deletions
diff --git a/ppapi/ppapi_shared_proxy.gypi b/ppapi/ppapi_shared_proxy.gypi index c02ba86..5cfcdc5 100644 --- a/ppapi/ppapi_shared_proxy.gypi +++ b/ppapi/ppapi_shared_proxy.gypi @@ -30,8 +30,17 @@ 'shared_impl/crypto_impl.h', 'shared_impl/image_data_impl.cc', 'shared_impl/image_data_impl.h', + 'shared_impl/tracker_base.cc', + 'shared_impl/tracker_base.h', 'shared_impl/url_util_impl.cc', 'shared_impl/url_util_impl.h', + + 'thunk/enter.h', + 'thunk/ppb_graphics_2d_api.h', + 'thunk/ppb_graphics_2d_thunk.cc', + 'thunk/ppb_image_data_api.h', + 'thunk/ppb_image_data_thunk.cc', + 'thunk/thunk.h', ], 'conditions': [ ['OS=="win"', { @@ -163,6 +172,8 @@ 'proxy/proxy_channel.h', 'proxy/proxy_module.cc', 'proxy/proxy_module.h', + 'proxy/resource_creation_proxy.cc', + 'proxy/resource_creation_proxy.h', 'proxy/serialized_flash_menu.cc', 'proxy/serialized_flash_menu.h', 'proxy/serialized_structs.cc', diff --git a/ppapi/proxy/host_dispatcher.cc b/ppapi/proxy/host_dispatcher.cc index 1482096..00c1c26 100644 --- a/ppapi/proxy/host_dispatcher.cc +++ b/ppapi/proxy/host_dispatcher.cc @@ -12,6 +12,7 @@ #include "ppapi/c/dev/ppb_var_deprecated.h" #include "ppapi/proxy/host_var_serialization_rules.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/resource_creation_proxy.h" namespace pp { namespace proxy { @@ -165,6 +166,15 @@ bool HostDispatcher::OnMessageReceived(const IPC::Message& msg) { return true; } + // New-style function proxies. + // TODO(brettw) this is hacked in for the routing for the types we've + // implemented in this style so far. When everything is implemented in this + // style, this function should be cleaned up. + if (msg.routing_id() == INTERFACE_ID_RESOURCE_CREATION) { + ResourceCreationProxy proxy(this); + return proxy.OnMessageReceived(msg); + } + InterfaceProxy* proxy = target_proxies_[msg.routing_id()].get(); if (!proxy) { // Autocreate any proxy objects to handle requests from the plugin. Since diff --git a/ppapi/proxy/host_dispatcher.h b/ppapi/proxy/host_dispatcher.h index 2391308..9547c46 100644 --- a/ppapi/proxy/host_dispatcher.h +++ b/ppapi/proxy/host_dispatcher.h @@ -14,6 +14,7 @@ #include "ppapi/c/pp_instance.h" #include "ppapi/proxy/dispatcher.h" #include "ppapi/proxy/plugin_var_tracker.h" +#include "ppapi/shared_impl/function_group_base.h" struct PPB_Proxy_Private; struct PPB_Var_Deprecated; @@ -115,6 +116,12 @@ class HostDispatcher : public Dispatcher { // messages. They are created on demand when we receive messages. scoped_ptr<InterfaceProxy> target_proxies_[INTERFACE_ID_COUNT]; + // Function proxies created for "new-style" FunctionGroups. + // TODO(brettw) this is in progress. It should be merged with the target + // proxies so there is one list to consult. + scoped_ptr< ::ppapi::shared_impl::FunctionGroupBase > + function_proxies_[INTERFACE_ID_COUNT]; + // Guaranteed non-NULL. const PPB_Proxy_Private* ppb_proxy_; diff --git a/ppapi/proxy/interface_id.h b/ppapi/proxy/interface_id.h index c7346b5..eef19cb 100644 --- a/ppapi/proxy/interface_id.h +++ b/ppapi/proxy/interface_id.h @@ -56,6 +56,8 @@ enum InterfaceID { INTERFACE_ID_PPP_INSTANCE, INTERFACE_ID_PPP_VIDEO_DECODER_DEV, + INTERFACE_ID_RESOURCE_CREATION, + // Must be last to indicate the number of interface IDs. INTERFACE_ID_COUNT }; diff --git a/ppapi/proxy/plugin_dispatcher.cc b/ppapi/proxy/plugin_dispatcher.cc index 26a35e3..e3bf9cd 100644 --- a/ppapi/proxy/plugin_dispatcher.cc +++ b/ppapi/proxy/plugin_dispatcher.cc @@ -14,9 +14,12 @@ #include "ppapi/c/pp_errors.h" #include "ppapi/proxy/interface_proxy.h" #include "ppapi/proxy/plugin_message_filter.h" +#include "ppapi/proxy/plugin_resource_tracker.h" #include "ppapi/proxy/plugin_var_serialization_rules.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppp_class_proxy.h" +#include "ppapi/proxy/resource_creation_proxy.h" +#include "ppapi/shared_impl/tracker_base.h" #if defined(OS_POSIX) #include "base/eintr_wrapper.h" @@ -41,6 +44,9 @@ PluginDispatcher::PluginDispatcher(base::ProcessHandle remote_process_handle, // As a plugin, we always support the PPP_Class interface. There's no // GetInterface call or name for it, so we insert it into our table now. target_proxies_[INTERFACE_ID_PPP_CLASS].reset(new PPP_Class_Proxy(this)); + + ::ppapi::shared_impl::TrackerBase::Init( + &PluginResourceTracker::GetTrackerBaseInstance); } PluginDispatcher::~PluginDispatcher() { @@ -195,6 +201,17 @@ InstanceData* PluginDispatcher::GetInstanceData(PP_Instance instance) { return (it == instance_map_.end()) ? NULL : &it->second; } +::ppapi::shared_impl::FunctionGroupBase* PluginDispatcher::GetFunctionAPI( + pp::proxy::InterfaceID id) { + if (function_proxies_[id].get()) + return function_proxies_[id].get(); + + if (id == INTERFACE_ID_RESOURCE_CREATION) + function_proxies_[id].reset(new ResourceCreationProxy(this)); + + return function_proxies_[id].get(); +} + void PluginDispatcher::ForceFreeAllInstances() { if (!g_instance_to_dispatcher) return; diff --git a/ppapi/proxy/plugin_dispatcher.h b/ppapi/proxy/plugin_dispatcher.h index c3df7ae..ca260fd 100644 --- a/ppapi/proxy/plugin_dispatcher.h +++ b/ppapi/proxy/plugin_dispatcher.h @@ -14,6 +14,7 @@ #include "ppapi/c/pp_rect.h" #include "ppapi/c/pp_instance.h" #include "ppapi/proxy/dispatcher.h" +#include "ppapi/shared_impl/function_group_base.h" class MessageLoop; @@ -71,9 +72,16 @@ class PluginDispatcher : public Dispatcher { void DidDestroyInstance(PP_Instance instance); // Gets the data for an existing instance, or NULL if the instance id doesn't - // correspond to a known instance. + // correspond to a known instance. InstanceData* GetInstanceData(PP_Instance instance); + // Returns the "new-style" function API for the given interface ID, creating + // it if necessary. + // TODO(brettw) this is in progress. It should be merged with the target + // proxies so there is one list to consult. + ::ppapi::shared_impl::FunctionGroupBase* GetFunctionAPI( + pp::proxy::InterfaceID id); + private: friend class PluginDispatcherTest; @@ -88,6 +96,12 @@ class PluginDispatcher : public Dispatcher { // messages. scoped_ptr<InterfaceProxy> target_proxies_[INTERFACE_ID_COUNT]; + // Function proxies created for "new-style" FunctionGroups. + // TODO(brettw) this is in progress. It should be merged with the target + // proxies so there is one list to consult. + scoped_ptr< ::ppapi::shared_impl::FunctionGroupBase > + function_proxies_[INTERFACE_ID_COUNT]; + typedef base::hash_map<PP_Instance, InstanceData> InstanceDataMap; InstanceDataMap instance_map_; diff --git a/ppapi/proxy/plugin_resource.cc b/ppapi/proxy/plugin_resource.cc index 83dadc6..d25dde1 100644 --- a/ppapi/proxy/plugin_resource.cc +++ b/ppapi/proxy/plugin_resource.cc @@ -19,5 +19,11 @@ PluginResource::~PluginResource() { FOR_ALL_PLUGIN_RESOURCES(DEFINE_TYPE_GETTER) #undef DEFINE_TYPE_GETTER +PluginDispatcher* PluginResource::GetDispatcher() { + PluginDispatcher* disp = PluginDispatcher::GetForInstance(instance()); + CHECK(disp); + return disp; +} + } // namespace proxy } // namespace pp diff --git a/ppapi/proxy/plugin_resource.h b/ppapi/proxy/plugin_resource.h index 57fd4ac..5009af8 100644 --- a/ppapi/proxy/plugin_resource.h +++ b/ppapi/proxy/plugin_resource.h @@ -10,6 +10,7 @@ #include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_resource_tracker.h" +#include "ppapi/shared_impl/resource_object_base.h" // If you inherit from resource, make sure you add the class name here. #define FOR_ALL_PLUGIN_RESOURCES(F) \ @@ -41,7 +42,7 @@ namespace proxy { FOR_ALL_PLUGIN_RESOURCES(DECLARE_RESOURCE_CLASS) #undef DECLARE_RESOURCE_CLASS -class PluginResource { +class PluginResource : public ::ppapi::shared_impl::ResourceObjectBase { public: PluginResource(const HostResource& resource); virtual ~PluginResource(); @@ -62,6 +63,8 @@ class PluginResource { return host_resource_; } + PluginDispatcher* GetDispatcher(); + private: // Type-specific getters for individual resource types. These will return // NULL if the resource does not match the specified type. Used by the Cast() diff --git a/ppapi/proxy/plugin_resource_tracker.cc b/ppapi/proxy/plugin_resource_tracker.cc index 2e9e32a..202fef3 100644 --- a/ppapi/proxy/plugin_resource_tracker.cc +++ b/ppapi/proxy/plugin_resource_tracker.cc @@ -10,6 +10,7 @@ #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/plugin_resource.h" #include "ppapi/proxy/serialized_var.h" +#include "ppapi/shared_impl/tracker_base.h" namespace pp { namespace proxy { @@ -19,6 +20,10 @@ namespace { // When non-NULL, this object overrides the ResourceTrackerSingleton. PluginResourceTracker* g_resource_tracker_override = NULL; +::ppapi::shared_impl::TrackerBase* GetTrackerBase() { + return PluginResourceTracker::GetInstance(); +} + } // namespace PluginResourceTracker::ResourceInfo::ResourceInfo() : ref_count(0) { @@ -33,6 +38,8 @@ PluginResourceTracker::ResourceInfo::ResourceInfo(int rc, PluginResourceTracker::ResourceInfo::ResourceInfo(const ResourceInfo& other) : ref_count(other.ref_count), resource(other.resource) { + // Wire up the new shared resource tracker base to use our implementation. + ::ppapi::shared_impl::TrackerBase::Init(&GetTrackerBase); } PluginResourceTracker::ResourceInfo::~ResourceInfo() { @@ -67,6 +74,12 @@ PluginResourceTracker* PluginResourceTracker::GetInstance() { return Singleton<PluginResourceTracker>::get(); } +// static +::ppapi::shared_impl::TrackerBase* +PluginResourceTracker::GetTrackerBaseInstance() { + return GetInstance(); +} + PluginResource* PluginResourceTracker::GetResourceObject( PP_Resource pp_resource) { ResourceMap::iterator found = resource_map_.find(pp_resource); @@ -112,6 +125,23 @@ PP_Resource PluginResourceTracker::PluginResourceForHostResource( return found->second; } +::ppapi::shared_impl::ResourceObjectBase* PluginResourceTracker::GetResourceAPI( + PP_Resource res) { + ResourceMap::iterator found = resource_map_.find(res); + if (found == resource_map_.end()) + return NULL; + return found->second.resource.get(); +} + +::ppapi::shared_impl::FunctionGroupBase* PluginResourceTracker::GetFunctionAPI( + PP_Instance inst, + pp::proxy::InterfaceID id) { + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(inst); + if (dispatcher) + return dispatcher->GetFunctionAPI(id); + return NULL; +} + void PluginResourceTracker::ReleasePluginResourceRef( const PP_Resource& resource, bool notify_browser_on_release) { diff --git a/ppapi/proxy/plugin_resource_tracker.h b/ppapi/proxy/plugin_resource_tracker.h index f0d25f23..268709f 100644 --- a/ppapi/proxy/plugin_resource_tracker.h +++ b/ppapi/proxy/plugin_resource_tracker.h @@ -15,6 +15,7 @@ #include "ppapi/c/pp_resource.h" #include "ppapi/c/pp_var.h" #include "ppapi/proxy/host_resource.h" +#include "ppapi/shared_impl/tracker_base.h" template<typename T> struct DefaultSingletonTraits; @@ -24,7 +25,7 @@ namespace proxy { class PluginDispatcher; class PluginResource; -class PluginResourceTracker { +class PluginResourceTracker : public ::ppapi::shared_impl::TrackerBase { public: // Called by tests that want to specify a specific ResourceTracker. This // allows them to use a unique one each time and avoids singletons sticking @@ -33,6 +34,7 @@ class PluginResourceTracker { // Returns the global singleton resource tracker for the plugin. static PluginResourceTracker* GetInstance(); + static ::ppapi::shared_impl::TrackerBase* GetTrackerBaseInstance(); // Returns the object associated with the given resource ID, or NULL if // there isn't one. @@ -52,6 +54,13 @@ class PluginResourceTracker { PP_Resource PluginResourceForHostResource( const HostResource& resource) const; + // TrackerBase. + virtual ::ppapi::shared_impl::ResourceObjectBase* GetResourceAPI( + PP_Resource res); + virtual ::ppapi::shared_impl::FunctionGroupBase* GetFunctionAPI( + PP_Instance inst, + pp::proxy::InterfaceID id); + private: friend struct DefaultSingletonTraits<PluginResourceTracker>; friend class PluginResourceTrackerTest; diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index 916f508..f5bbe65 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -573,11 +573,6 @@ IPC_SYNC_MESSAGE_ROUTED1_2(PpapiHostMsg_PPBFullscreen_GetScreenSize, PP_Size /* size */) // PPB_Graphics2D. -IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBGraphics2D_Create, - PP_Instance /* instance */, - PP_Size /* size */, - PP_Bool /* is_always_opaque */, - pp::proxy::HostResource /* result */) IPC_MESSAGE_ROUTED5(PpapiHostMsg_PPBGraphics2D_PaintImageData, pp::proxy::HostResource /* graphics_2d */, pp::proxy::HostResource /* image_data */, @@ -595,16 +590,6 @@ IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBGraphics2D_ReplaceContents, IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBGraphics2D_Flush, pp::proxy::HostResource /* graphics_2d */) -// PPB_ImageData. -IPC_SYNC_MESSAGE_ROUTED4_3(PpapiHostMsg_PPBImageData_Create, - PP_Instance /* instance */, - int32 /* format */, - PP_Size /* size */, - PP_Bool /* init_to_zero */, - pp::proxy::HostResource /* result_resource */, - std::string /* image_data_desc */, - pp::proxy::ImageHandle /* result */) - // PPB_Instance. IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBInstance_GetWindowObject, PP_Instance /* instance */, @@ -798,3 +783,18 @@ IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBVar_CreateObjectDeprecated, int64 /* object_class */, int64 /* object_data */, pp::proxy::SerializedVar /* result */) + +IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_ResourceCreation_Graphics2D, + PP_Instance /* instance */, + PP_Size /* size */, + PP_Bool /* is_always_opaque */, + pp::proxy::HostResource /* result */) +IPC_SYNC_MESSAGE_ROUTED4_3(PpapiHostMsg_ResourceCreation_ImageData, + PP_Instance /* instance */, + int32 /* format */, + PP_Size /* size */, + PP_Bool /* init_to_zero */, + pp::proxy::HostResource /* result_resource */, + std::string /* image_data_desc */, + pp::proxy::ImageHandle /* result */) + diff --git a/ppapi/proxy/ppb_graphics_2d_proxy.cc b/ppapi/proxy/ppb_graphics_2d_proxy.cc index 3f1c8ef..38777b7 100644 --- a/ppapi/proxy/ppb_graphics_2d_proxy.cc +++ b/ppapi/proxy/ppb_graphics_2d_proxy.cc @@ -15,197 +15,85 @@ #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_resource.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/thunk.h" + +using ::ppapi::thunk::PPB_Graphics2D_API; +using ::ppapi::thunk::EnterResource; namespace pp { namespace proxy { -class Graphics2D : public PluginResource { - public: - Graphics2D(const HostResource& host_resource, - const PP_Size& size, - PP_Bool is_always_opaque) - : PluginResource(host_resource), - size_(size), - is_always_opaque_(is_always_opaque), - current_flush_callback_(PP_BlockUntilComplete()) { - } - virtual ~Graphics2D() { - } - - // Resource overrides. - virtual Graphics2D* AsGraphics2D() { return this; } - - const PP_Size& size() const { return size_; } - PP_Bool is_always_opaque() const { return is_always_opaque_; } - - bool is_flush_pending() const { return !!current_flush_callback_.func; } - - PP_CompletionCallback current_flush_callback() const { - return current_flush_callback_; - } - void set_current_flush_callback(PP_CompletionCallback cb) { - current_flush_callback_ = cb; - } - - private: - PP_Size size_; - PP_Bool is_always_opaque_; - - // In the plugin, this is the current callback set for Flushes. When the - // callback function pointer is non-NULL, we're waiting for a flush ACK. - PP_CompletionCallback current_flush_callback_; - - DISALLOW_COPY_AND_ASSIGN(Graphics2D); -}; - namespace { -PP_Resource Create(PP_Instance instance, - const PP_Size* size, - PP_Bool is_always_opaque) { - PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); - if (!dispatcher) - return PP_ERROR_BADARGUMENT; - - HostResource result; - dispatcher->Send(new PpapiHostMsg_PPBGraphics2D_Create( - INTERFACE_ID_PPB_GRAPHICS_2D, instance, *size, is_always_opaque, - &result)); - if (result.is_null()) - return 0; - linked_ptr<Graphics2D> graphics_2d(new Graphics2D(result, *size, - is_always_opaque)); - return PluginResourceTracker::GetInstance()->AddResource(graphics_2d); +InterfaceProxy* CreateGraphics2DProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_Graphics2D_Proxy(dispatcher, target_interface); } -PP_Bool IsGraphics2D(PP_Resource resource) { - Graphics2D* object = PluginResource::GetAs<Graphics2D>(resource); - return BoolToPPBool(!!object); -} +} // namespace -PP_Bool Describe(PP_Resource graphics_2d, - PP_Size* size, - PP_Bool* is_always_opaque) { - Graphics2D* object = PluginResource::GetAs<Graphics2D>(graphics_2d); - if (!object) { - size->width = 0; - size->height = 0; - *is_always_opaque = PP_FALSE; - return PP_FALSE; - } +PPB_Graphics2D_API* Graphics2D::AsGraphics2D_API() { + return this; +} - *size = object->size(); - *is_always_opaque = object->is_always_opaque(); +PP_Bool Graphics2D::Describe(PP_Size* size, PP_Bool* is_always_opaque) { + *size = size_; + *is_always_opaque = is_always_opaque_; return PP_TRUE; } -void PaintImageData(PP_Resource graphics_2d, - PP_Resource image_data, - const PP_Point* top_left, - const PP_Rect* src_rect) { - Graphics2D* graphics_object = PluginResource::GetAs<Graphics2D>(graphics_2d); - if (!graphics_object) - return; +void Graphics2D::PaintImageData(PP_Resource image_data, + const PP_Point* top_left, + const PP_Rect* src_rect) { PluginResource* image_object = PluginResourceTracker::GetInstance()-> GetResourceObject(image_data); - if (!image_object) - return; - if (graphics_object->instance() != image_object->instance()) - return; - - PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance( - graphics_object->instance()); - if (!dispatcher) - return; + //if (!image_object || instance() != image_object->instance()) + // return; PP_Rect dummy; memset(&dummy, 0, sizeof(PP_Rect)); - dispatcher->Send(new PpapiHostMsg_PPBGraphics2D_PaintImageData( - INTERFACE_ID_PPB_GRAPHICS_2D, graphics_object->host_resource(), + GetDispatcher()->Send(new PpapiHostMsg_PPBGraphics2D_PaintImageData( + INTERFACE_ID_PPB_GRAPHICS_2D, host_resource(), image_object->host_resource(), *top_left, !!src_rect, src_rect ? *src_rect : dummy)); } -void Scroll(PP_Resource graphics_2d, - const PP_Rect* clip_rect, - const PP_Point* amount) { - Graphics2D* object = PluginResource::GetAs<Graphics2D>(graphics_2d); - if (!object) - return; - PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance( - object->instance()); - if (!dispatcher) - return; - +void Graphics2D::Scroll(const PP_Rect* clip_rect, + const PP_Point* amount) { PP_Rect dummy; memset(&dummy, 0, sizeof(PP_Rect)); - dispatcher->Send(new PpapiHostMsg_PPBGraphics2D_Scroll( - INTERFACE_ID_PPB_GRAPHICS_2D, object->host_resource(), + GetDispatcher()->Send(new PpapiHostMsg_PPBGraphics2D_Scroll( + INTERFACE_ID_PPB_GRAPHICS_2D, host_resource(), !!clip_rect, clip_rect ? *clip_rect : dummy, *amount)); } -void ReplaceContents(PP_Resource graphics_2d, PP_Resource image_data) { - Graphics2D* graphics_object = PluginResource::GetAs<Graphics2D>(graphics_2d); - if (!graphics_object) - return; +void Graphics2D::ReplaceContents(PP_Resource image_data) { PluginResource* image_object = PluginResourceTracker::GetInstance()-> GetResourceObject(image_data); - if (!image_object) - return; - if (graphics_object->instance() != image_object->instance()) - return; - - PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance( - graphics_object->instance()); - if (!dispatcher) + if (!image_object || instance() != image_object->instance()) return; - dispatcher->Send(new PpapiHostMsg_PPBGraphics2D_ReplaceContents( - INTERFACE_ID_PPB_GRAPHICS_2D, graphics_object->host_resource(), + GetDispatcher()->Send(new PpapiHostMsg_PPBGraphics2D_ReplaceContents( + INTERFACE_ID_PPB_GRAPHICS_2D, host_resource(), image_object->host_resource())); } -int32_t Flush(PP_Resource graphics_2d, - PP_CompletionCallback callback) { - Graphics2D* object = PluginResource::GetAs<Graphics2D>(graphics_2d); - if (!object) - return PP_ERROR_BADRESOURCE; - PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance( - object->instance()); - if (!dispatcher) - return PP_ERROR_FAILED; - +int32_t Graphics2D::Flush(PP_CompletionCallback callback) { // For now, disallow blocking calls. We'll need to add support for other // threads to this later. if (!callback.func) return PP_ERROR_BADARGUMENT; - if (object->is_flush_pending()) + if (is_flush_pending()) return PP_ERROR_INPROGRESS; // Can't have >1 flush pending. - object->set_current_flush_callback(callback); + set_current_flush_callback(callback); - dispatcher->Send(new PpapiHostMsg_PPBGraphics2D_Flush( - INTERFACE_ID_PPB_GRAPHICS_2D, object->host_resource())); + GetDispatcher()->Send(new PpapiHostMsg_PPBGraphics2D_Flush( + INTERFACE_ID_PPB_GRAPHICS_2D, host_resource())); return PP_OK_COMPLETIONPENDING; } -const PPB_Graphics2D graphics_2d_interface = { - &Create, - &IsGraphics2D, - &Describe, - &PaintImageData, - &Scroll, - &ReplaceContents, - &Flush -}; - -InterfaceProxy* CreateGraphics2DProxy(Dispatcher* dispatcher, - const void* target_interface) { - return new PPB_Graphics2D_Proxy(dispatcher, target_interface); -} - -} // namespace - PPB_Graphics2D_Proxy::PPB_Graphics2D_Proxy(Dispatcher* dispatcher, const void* target_interface) : InterfaceProxy(dispatcher, target_interface), @@ -218,7 +106,7 @@ PPB_Graphics2D_Proxy::~PPB_Graphics2D_Proxy() { // static const InterfaceProxy::Info* PPB_Graphics2D_Proxy::GetInfo() { static const Info info = { - &graphics_2d_interface, + ::ppapi::thunk::GetPPB_Graphics2D_Thunk(), PPB_GRAPHICS_2D_INTERFACE, INTERFACE_ID_PPB_GRAPHICS_2D, false, @@ -230,8 +118,6 @@ const InterfaceProxy::Info* PPB_Graphics2D_Proxy::GetInfo() { bool PPB_Graphics2D_Proxy::OnMessageReceived(const IPC::Message& msg) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(PPB_Graphics2D_Proxy, msg) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics2D_Create, - OnMsgCreate) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics2D_PaintImageData, OnMsgPaintImageData) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics2D_Scroll, @@ -249,22 +135,16 @@ bool PPB_Graphics2D_Proxy::OnMessageReceived(const IPC::Message& msg) { return handled; } -void PPB_Graphics2D_Proxy::OnMsgCreate(PP_Instance instance, - const PP_Size& size, - PP_Bool is_always_opaque, - HostResource* result) { - result->SetHostResource(instance, ppb_graphics_2d_target()->Create( - instance, &size, is_always_opaque)); -} - void PPB_Graphics2D_Proxy::OnMsgPaintImageData( const HostResource& graphics_2d, const HostResource& image_data, const PP_Point& top_left, bool src_rect_specified, const PP_Rect& src_rect) { - ppb_graphics_2d_target()->PaintImageData( - graphics_2d.host_resource(), image_data.host_resource(), &top_left, + EnterResource<PPB_Graphics2D_API> enter(graphics_2d.host_resource(), false); + if (enter.failed()) + return; + enter.object()->PaintImageData(image_data.host_resource(), &top_left, src_rect_specified ? &src_rect : NULL); } @@ -272,15 +152,19 @@ void PPB_Graphics2D_Proxy::OnMsgScroll(const HostResource& graphics_2d, bool clip_specified, const PP_Rect& clip, const PP_Point& amount) { - ppb_graphics_2d_target()->Scroll(graphics_2d.host_resource(), - clip_specified ? &clip : NULL, &amount); + EnterResource<PPB_Graphics2D_API> enter(graphics_2d.host_resource(), false); + if (enter.failed()) + return; + enter.object()->Scroll(clip_specified ? &clip : NULL, &amount); } void PPB_Graphics2D_Proxy::OnMsgReplaceContents( const HostResource& graphics_2d, const HostResource& image_data) { - ppb_graphics_2d_target()->ReplaceContents(graphics_2d.host_resource(), - image_data.host_resource()); + EnterResource<PPB_Graphics2D_API> enter(graphics_2d.host_resource(), false); + if (enter.failed()) + return; + enter.object()->ReplaceContents(image_data.host_resource()); } void PPB_Graphics2D_Proxy::OnMsgFlush(const HostResource& graphics_2d) { diff --git a/ppapi/proxy/ppb_graphics_2d_proxy.h b/ppapi/proxy/ppb_graphics_2d_proxy.h index c98065d..b799950 100644 --- a/ppapi/proxy/ppb_graphics_2d_proxy.h +++ b/ppapi/proxy/ppb_graphics_2d_proxy.h @@ -15,7 +15,9 @@ #include "ppapi/cpp/completion_callback.h" #include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/interface_proxy.h" +#include "ppapi/proxy/plugin_resource.h" #include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" +#include "ppapi/thunk/ppb_graphics_2d_api.h" struct PPB_Graphics2D; struct PP_Point; @@ -40,10 +42,6 @@ class PPB_Graphics2D_Proxy : public InterfaceProxy { private: // Plugin->renderer message handlers. - void OnMsgCreate(PP_Module module, - const PP_Size& size, - PP_Bool is_always_opaque, - HostResource* result); void OnMsgPaintImageData(const HostResource& graphics_2d, const HostResource& image_data, const PP_Point& top_left, @@ -69,6 +67,60 @@ class PPB_Graphics2D_Proxy : public InterfaceProxy { ProxyNonThreadSafeRefCount> callback_factory_; }; +class Graphics2D : public PluginResource, + public ::ppapi::thunk::PPB_Graphics2D_API { + public: + Graphics2D(const HostResource& host_resource, + const PP_Size& size, + PP_Bool is_always_opaque) + : PluginResource(host_resource), + size_(size), + is_always_opaque_(is_always_opaque), + current_flush_callback_(PP_BlockUntilComplete()) { + } + virtual ~Graphics2D() { + } + + // Resource overrides. + virtual Graphics2D* AsGraphics2D() { return this; } + + const PP_Size& size() const { return size_; } + PP_Bool is_always_opaque() const { return is_always_opaque_; } + + bool is_flush_pending() const { return !!current_flush_callback_.func; } + + PP_CompletionCallback current_flush_callback() const { + return current_flush_callback_; + } + void set_current_flush_callback(PP_CompletionCallback cb) { + current_flush_callback_ = cb; + } + + // ResourceObjectBase. + virtual PPB_Graphics2D_API* AsGraphics2D_API(); + + // PPB_Graphics_2D_API. + PP_Bool Describe(PP_Size* size, PP_Bool* is_always_opaque); + void PaintImageData(PP_Resource image_data, + const PP_Point* top_left, + const PP_Rect* src_rect); + void Scroll(const PP_Rect* clip_rect, + const PP_Point* amount); + void ReplaceContents(PP_Resource image_data); + int32_t Flush(PP_CompletionCallback callback); + + private: + PP_Size size_; + PP_Bool is_always_opaque_; + + // In the plugin, this is the current callback set for Flushes. When the + // callback function pointer is non-NULL, we're waiting for a flush ACK. + PP_CompletionCallback current_flush_callback_; + + DISALLOW_COPY_AND_ASSIGN(Graphics2D); +}; + + } // namespace proxy } // namespace pp diff --git a/ppapi/proxy/ppb_image_data_proxy.cc b/ppapi/proxy/ppb_image_data_proxy.cc index 0154a04..ebb1d19 100644 --- a/ppapi/proxy/ppb_image_data_proxy.cc +++ b/ppapi/proxy/ppb_image_data_proxy.cc @@ -13,13 +13,11 @@ #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_resource.h" -#include "ppapi/c/trusted/ppb_image_data_trusted.h" #include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/plugin_dispatcher.h" -#include "ppapi/proxy/plugin_resource.h" #include "ppapi/proxy/plugin_resource_tracker.h" #include "ppapi/proxy/ppapi_messages.h" -#include "ppapi/shared_impl/image_data_impl.h" +#include "ppapi/thunk/thunk.h" #if defined(OS_LINUX) #include <sys/shm.h> @@ -33,33 +31,42 @@ namespace pp { namespace proxy { -class ImageData : public PluginResource, - public pp::shared_impl::ImageDataImpl { - public: - ImageData(const HostResource& resource, - const PP_ImageDataDesc& desc, - ImageHandle handle); - virtual ~ImageData(); +namespace { - // Resource overrides. - virtual ImageData* AsImageData(); +InterfaceProxy* CreateImageDataProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_ImageData_Proxy(dispatcher, target_interface); +} - void* Map(); - void Unmap(); +} // namespace - const PP_ImageDataDesc& desc() const { return desc_; } +// PPB_ImageData_Proxy --------------------------------------------------------- - static const ImageHandle NullHandle; - static ImageHandle HandleFromInt(int32_t i); +PPB_ImageData_Proxy::PPB_ImageData_Proxy(Dispatcher* dispatcher, + const void* target_interface) + : InterfaceProxy(dispatcher, target_interface) { +} - private: - PP_ImageDataDesc desc_; - ImageHandle handle_; +PPB_ImageData_Proxy::~PPB_ImageData_Proxy() { +} + +// static +const InterfaceProxy::Info* PPB_ImageData_Proxy::GetInfo() { + static const Info info = { + ::ppapi::thunk::GetPPB_ImageData_Thunk(), + PPB_IMAGEDATA_INTERFACE, + INTERFACE_ID_PPB_IMAGE_DATA, + false, + &CreateImageDataProxy, + }; + return &info; +} - void* mapped_data_; +bool PPB_ImageData_Proxy::OnMessageReceived(const IPC::Message& msg) { + return false; +} - DISALLOW_COPY_AND_ASSIGN(ImageData); -}; +// ImageData ------------------------------------------------------------------- ImageData::ImageData(const HostResource& resource, const PP_ImageDataDesc& desc, @@ -74,10 +81,19 @@ ImageData::~ImageData() { Unmap(); } +::ppapi::thunk::PPB_ImageData_API* ImageData::AsImageData_API() { + return this; +} + ImageData* ImageData::AsImageData() { return this; } +PP_Bool ImageData::Describe(PP_ImageDataDesc* desc) { + memcpy(desc, &desc_, sizeof(PP_ImageDataDesc)); + return PP_TRUE; +} + void* ImageData::Map() { #if defined(OS_WIN) mapped_data_ = ::MapViewOfFile(handle_, FILE_MAP_READ | FILE_MAP_WRITE, @@ -140,154 +156,5 @@ ImageHandle ImageData::HandleFromInt(int32_t i) { #endif } -namespace { - -PP_ImageDataFormat GetNativeImageDataFormat() { - return ImageData::GetNativeImageDataFormat(); -} - -PP_Bool IsImageDataFormatSupported(PP_ImageDataFormat format) { - return BoolToPPBool(ImageData::IsImageDataFormatSupported(format)); -} - -PP_Resource Create(PP_Instance instance, - PP_ImageDataFormat format, - const PP_Size* size, - PP_Bool init_to_zero) { - PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); - if (!dispatcher) - return 0; - - HostResource result; - std::string image_data_desc; - ImageHandle image_handle = ImageData::NullHandle; - dispatcher->Send(new PpapiHostMsg_PPBImageData_Create( - INTERFACE_ID_PPB_IMAGE_DATA, instance, format, *size, init_to_zero, - &result, &image_data_desc, &image_handle)); - - if (result.is_null() || image_data_desc.size() != sizeof(PP_ImageDataDesc)) - return 0; - - // We serialize the PP_ImageDataDesc just by copying to a string. - PP_ImageDataDesc desc; - memcpy(&desc, image_data_desc.data(), sizeof(PP_ImageDataDesc)); - - linked_ptr<ImageData> object(new ImageData(result, desc, image_handle)); - return PluginResourceTracker::GetInstance()->AddResource(object); -} - -PP_Bool IsImageData(PP_Resource resource) { - ImageData* object = PluginResource::GetAs<ImageData>(resource); - return BoolToPPBool(!!object); -} - -PP_Bool Describe(PP_Resource resource, PP_ImageDataDesc* desc) { - ImageData* object = PluginResource::GetAs<ImageData>(resource); - if (!object) - return PP_FALSE; - memcpy(desc, &object->desc(), sizeof(PP_ImageDataDesc)); - return PP_TRUE; -} - -void* Map(PP_Resource resource) { - ImageData* object = PluginResource::GetAs<ImageData>(resource); - if (!object) - return NULL; - return object->Map(); -} - -void Unmap(PP_Resource resource) { - ImageData* object = PluginResource::GetAs<ImageData>(resource); - if (object) - object->Unmap(); -} - -const PPB_ImageData image_data_interface = { - &GetNativeImageDataFormat, - &IsImageDataFormatSupported, - &Create, - &IsImageData, - &Describe, - &Map, - &Unmap, -}; - -InterfaceProxy* CreateImageDataProxy(Dispatcher* dispatcher, - const void* target_interface) { - return new PPB_ImageData_Proxy(dispatcher, target_interface); -} - -} // namespace - -PPB_ImageData_Proxy::PPB_ImageData_Proxy(Dispatcher* dispatcher, - const void* target_interface) - : InterfaceProxy(dispatcher, target_interface) { -} - -PPB_ImageData_Proxy::~PPB_ImageData_Proxy() { -} - -// static -const InterfaceProxy::Info* PPB_ImageData_Proxy::GetInfo() { - static const Info info = { - &image_data_interface, - PPB_IMAGEDATA_INTERFACE, - INTERFACE_ID_PPB_IMAGE_DATA, - false, - &CreateImageDataProxy, - }; - return &info; -} - -bool PPB_ImageData_Proxy::OnMessageReceived(const IPC::Message& msg) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(PPB_ImageData_Proxy, msg) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_Create, OnMsgCreate) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - // FIXME(brettw) handle bad messages! - return handled; -} - -void PPB_ImageData_Proxy::OnMsgCreate(PP_Instance instance, - int32_t format, - const PP_Size& size, - PP_Bool init_to_zero, - HostResource* result, - std::string* image_data_desc, - ImageHandle* result_image_handle) { - PP_Resource resource = ppb_image_data_target()->Create( - instance, static_cast<PP_ImageDataFormat>(format), &size, init_to_zero); - *result_image_handle = ImageData::NullHandle; - if (resource) { - // The ImageDesc is just serialized as a string. - PP_ImageDataDesc desc; - if (ppb_image_data_target()->Describe(resource, &desc)) { - image_data_desc->resize(sizeof(PP_ImageDataDesc)); - memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc)); - } - - // Get the shared memory handle. - const PPB_ImageDataTrusted* trusted = - reinterpret_cast<const PPB_ImageDataTrusted*>( - dispatcher()->GetLocalInterface(PPB_IMAGEDATA_TRUSTED_INTERFACE)); - uint32_t byte_count = 0; - if (trusted) { - int32_t handle; - if (trusted->GetSharedMemory(resource, &handle, &byte_count) == PP_OK) { -#if defined(OS_WIN) - pp::proxy::ImageHandle ih = ImageData::HandleFromInt(handle); - *result_image_handle = dispatcher()->ShareHandleWithRemote(ih, false); -#else - // TODO: This memory sharing is probaly broken on Mac. - *result_image_handle = ImageData::HandleFromInt(handle); -#endif - } - } - - result->SetHostResource(instance, resource); - } -} - } // namespace proxy } // namespace pp diff --git a/ppapi/proxy/ppb_image_data_proxy.h b/ppapi/proxy/ppb_image_data_proxy.h index 70632cb..8a3bce2 100644 --- a/ppapi/proxy/ppb_image_data_proxy.h +++ b/ppapi/proxy/ppb_image_data_proxy.h @@ -13,7 +13,10 @@ #include "ppapi/c/pp_size.h" #include "ppapi/c/pp_var.h" #include "ppapi/proxy/interface_proxy.h" +#include "ppapi/proxy/plugin_resource.h" #include "ppapi/proxy/serialized_structs.h" +#include "ppapi/shared_impl/image_data_impl.h" +#include "ppapi/thunk/ppb_image_data_api.h" struct PPB_ImageData; @@ -35,18 +38,40 @@ class PPB_ImageData_Proxy : public InterfaceProxy { // InterfaceProxy implementation. virtual bool OnMessageReceived(const IPC::Message& msg); +}; + +class ImageData : public PluginResource, + public ::ppapi::thunk::PPB_ImageData_API, + public pp::shared_impl::ImageDataImpl { + public: + ImageData(const HostResource& resource, + const PP_ImageDataDesc& desc, + ImageHandle handle); + virtual ~ImageData(); + + // ResourceObjectBase overrides. + virtual ::ppapi::thunk::PPB_ImageData_API* AsImageData_API(); + + // Resource overrides. + virtual ImageData* AsImageData(); + + // PPB_ImageData API. + virtual PP_Bool Describe(PP_ImageDataDesc* desc); + virtual void* Map(); + virtual void Unmap(); + + const PP_ImageDataDesc& desc() const { return desc_; } + + static const ImageHandle NullHandle; + static ImageHandle HandleFromInt(int32_t i); private: - // Message handlers. - void OnMsgGetNativeImageDataFormat(int32* result); - void OnMsgIsImageDataFormatSupported(int32 format, PP_Bool* result); - void OnMsgCreate(PP_Instance instance, - int32_t format, - const PP_Size& size, - PP_Bool init_to_zero, - HostResource* result, - std::string* image_data_desc, - ImageHandle* result_image_handle); + PP_ImageDataDesc desc_; + ImageHandle handle_; + + void* mapped_data_; + + DISALLOW_COPY_AND_ASSIGN(ImageData); }; } // namespace proxy diff --git a/ppapi/proxy/resource_creation_proxy.cc b/ppapi/proxy/resource_creation_proxy.cc new file mode 100644 index 0000000..f24123c --- /dev/null +++ b/ppapi/proxy/resource_creation_proxy.cc @@ -0,0 +1,155 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/proxy/resource_creation_proxy.h" + +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_size.h" +#include "ppapi/proxy/host_resource.h" +#include "ppapi/proxy/interface_id.h" +#include "ppapi/proxy/plugin_dispatcher.h" +#include "ppapi/proxy/plugin_resource_tracker.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/ppb_graphics_2d_proxy.h" +#include "ppapi/proxy/ppb_image_data_proxy.h" +#include "ppapi/c/trusted/ppb_image_data_trusted.h" +#include "ppapi/shared_impl/function_group_base.h" +#include "ppapi/thunk/enter.h" + +using ::ppapi::thunk::ResourceCreationAPI; + +namespace pp { +namespace proxy { + +ResourceCreationProxy::ResourceCreationProxy(Dispatcher* dispatcher) + : dispatcher_(dispatcher) { +} + +ResourceCreationProxy::~ResourceCreationProxy() { +} + +::ppapi::thunk::ResourceCreationAPI* +ResourceCreationProxy::AsResourceCreation() { + return this; +} + +PP_Resource ResourceCreationProxy::CreateGraphics2D(PP_Instance pp_instance, + const PP_Size& size, + PP_Bool is_always_opaque) { + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(pp_instance); + if (!dispatcher) + return PP_ERROR_BADARGUMENT; + + HostResource result; + dispatcher->Send(new PpapiHostMsg_ResourceCreation_Graphics2D( + INTERFACE_ID_RESOURCE_CREATION, pp_instance, size, is_always_opaque, + &result)); + if (result.is_null()) + return 0; + linked_ptr<Graphics2D> graphics_2d(new Graphics2D(result, size, + is_always_opaque)); + return PluginResourceTracker::GetInstance()->AddResource(graphics_2d); +} + +PP_Resource ResourceCreationProxy::CreateImageData(PP_Instance instance, + PP_ImageDataFormat format, + const PP_Size& size, + PP_Bool init_to_zero) { + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); + if (!dispatcher) + return 0; + + HostResource result; + std::string image_data_desc; + ImageHandle image_handle = ImageData::NullHandle; + dispatcher->Send(new PpapiHostMsg_ResourceCreation_ImageData( + INTERFACE_ID_RESOURCE_CREATION, instance, format, size, init_to_zero, + &result, &image_data_desc, &image_handle)); + + if (result.is_null() || image_data_desc.size() != sizeof(PP_ImageDataDesc)) + return 0; + + // We serialize the PP_ImageDataDesc just by copying to a string. + PP_ImageDataDesc desc; + memcpy(&desc, image_data_desc.data(), sizeof(PP_ImageDataDesc)); + + linked_ptr<ImageData> object(new ImageData(result, desc, image_handle)); + return PluginResourceTracker::GetInstance()->AddResource(object); +} + +bool ResourceCreationProxy::Send(IPC::Message* msg) { + return dispatcher_->Send(msg); +} + +bool ResourceCreationProxy::OnMessageReceived(const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(ResourceCreationProxy, msg) + IPC_MESSAGE_HANDLER(PpapiHostMsg_ResourceCreation_Graphics2D, + OnMsgCreateGraphics2D) + IPC_MESSAGE_HANDLER(PpapiHostMsg_ResourceCreation_ImageData, + OnMsgCreateImageData) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void ResourceCreationProxy::OnMsgCreateGraphics2D(PP_Instance instance, + const PP_Size& size, + PP_Bool is_always_opaque, + HostResource* result) { + ppapi::thunk::EnterFunction<ResourceCreationAPI> enter(instance, false); + if (enter.succeeded()) { + result->SetHostResource(instance, enter.functions()->CreateGraphics2D( + instance, size, is_always_opaque)); + } +} + +void ResourceCreationProxy::OnMsgCreateImageData( + PP_Instance instance, + int32_t format, + const PP_Size& size, + PP_Bool init_to_zero, + HostResource* result, + std::string* image_data_desc, + ImageHandle* result_image_handle) { + *result_image_handle = ImageData::NullHandle; + + ppapi::thunk::EnterFunction<ResourceCreationAPI> enter(instance, false); + if (enter.failed()) + return; + + PP_Resource resource = enter.functions()->CreateImageData( + instance, static_cast<PP_ImageDataFormat>(format), size, init_to_zero); + if (!resource) + return; + result->SetHostResource(instance, resource); + + // Get the description, it's just serialized as a string. + ppapi::thunk::EnterResource<PPB_ImageData> enter_resource(resource, false); + PP_ImageDataDesc desc; + if (enter_resource.object()->Describe(resource, &desc)) { + image_data_desc->resize(sizeof(PP_ImageDataDesc)); + memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc)); + } + + // Get the shared memory handle. + const PPB_ImageDataTrusted* trusted = + reinterpret_cast<const PPB_ImageDataTrusted*>( + dispatcher_->GetLocalInterface(PPB_IMAGEDATA_TRUSTED_INTERFACE)); + uint32_t byte_count = 0; + if (trusted) { + int32_t handle; + if (trusted->GetSharedMemory(resource, &handle, &byte_count) == PP_OK) { +#if defined(OS_WIN) + pp::proxy::ImageHandle ih = ImageData::HandleFromInt(handle); + *result_image_handle = dispatcher_->ShareHandleWithRemote(ih, false); +#else + *result_image_handle = ImageData::HandleFromInt(handle); +#endif + } + } +} + +} // namespace proxy +} // namespace pp diff --git a/ppapi/proxy/resource_creation_proxy.h b/ppapi/proxy/resource_creation_proxy.h new file mode 100644 index 0000000..898c16e --- /dev/null +++ b/ppapi/proxy/resource_creation_proxy.h @@ -0,0 +1,68 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_PROXY_RESOURCE_CREATION_PROXY_H_ +#define PPAPI_PROXY_RESOURCE_CREATION_PROXY_H_ + +#include "base/basictypes.h" +#include "ipc/ipc_channel.h" +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/proxy/serialized_structs.h" +#include "ppapi/shared_impl/function_group_base.h" +#include "ppapi/thunk/resource_creation_api.h" + +struct PP_Size; + +namespace pp { +namespace proxy { + +class HostResource; +class Dispatcher; + +class ResourceCreationProxy : public ::ppapi::shared_impl::FunctionGroupBase, + public ::ppapi::thunk::ResourceCreationAPI, + public ::IPC::Channel::Listener, + public IPC::Message::Sender { + public: + ResourceCreationProxy(Dispatcher* dispatcher); + virtual ~ResourceCreationProxy(); + + virtual ::ppapi::thunk::ResourceCreationAPI* AsResourceCreation(); + + // ResourceCreationAPI (called in plugin). + virtual PP_Resource CreateGraphics2D(PP_Instance pp_instance, + const PP_Size& size, + PP_Bool is_always_opaque); + virtual PP_Resource CreateImageData(PP_Instance instance, + PP_ImageDataFormat format, + const PP_Size& size, + PP_Bool init_to_zero); + + virtual bool Send(IPC::Message* msg); + virtual bool OnMessageReceived(const IPC::Message& msg); + + private: + // IPC message handlers (called in browser). + void OnMsgCreateGraphics2D(PP_Instance instance, + const PP_Size& size, + PP_Bool is_always_opaque, + HostResource* result); + void OnMsgCreateImageData(PP_Instance instance, + int32_t format, + const PP_Size& size, + PP_Bool init_to_zero, + HostResource* result, + std::string* image_data_desc, + ImageHandle* result_image_handle); + + Dispatcher* dispatcher_; + + DISALLOW_COPY_AND_ASSIGN(ResourceCreationProxy); +}; + +} // namespace proxy +} // namespace pp + +#endif // PPAPI_PROXY_RESOURCE_CREATION_PROXY_H_ diff --git a/ppapi/shared_impl/function_group_base.h b/ppapi/shared_impl/function_group_base.h new file mode 100644 index 0000000..9b3f728 --- /dev/null +++ b/ppapi/shared_impl/function_group_base.h @@ -0,0 +1,33 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_SHARED_IMPL_FUNCTION_GROUP_BASE_H_ +#define PPAPI_SHARED_IMPL_FUNCTION_GROUP_BASE_H_ + +namespace ppapi { + +namespace thunk { +class ResourceCreationAPI; +} + +namespace shared_impl { + +class FunctionGroupBase { + public: + // Dynamic casting for this object. Returns the pointer to the given type if + // it's supported. + virtual thunk::ResourceCreationAPI* AsResourceCreation() { return NULL; } + + template <typename T> T* GetAs() { return NULL; } +}; + +template<> +inline thunk::ResourceCreationAPI* FunctionGroupBase::GetAs() { + return AsResourceCreation(); +} + +} // namespace shared_impl +} // namespace ppapi + +#endif // PPAPI_SHARED_IMPL_FUNCTION_GROUP_BASE_H_ diff --git a/ppapi/shared_impl/resource_object_base.h b/ppapi/shared_impl/resource_object_base.h new file mode 100644 index 0000000..50ba30d --- /dev/null +++ b/ppapi/shared_impl/resource_object_base.h @@ -0,0 +1,38 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_SHARED_IMPL_RESOURCE_OBJECT_BASE_H_ +#define PPAPI_SHARED_IMPL_RESOURCE_OBJECT_BASE_H_ + +namespace ppapi { + +namespace thunk { +class PPB_Graphics2D_API; +class PPB_ImageData_API; +} + +namespace shared_impl { + +class ResourceObjectBase { + public: + + virtual thunk::PPB_Graphics2D_API* AsGraphics2D_API() { return NULL; } + virtual thunk::PPB_ImageData_API* AsImageData_API() { return NULL; } + + template <typename T> T* GetAs() { return NULL; } +}; + +template<> +inline thunk::PPB_Graphics2D_API* ResourceObjectBase::GetAs() { + return AsGraphics2D_API(); +} +template<> +inline thunk::PPB_ImageData_API* ResourceObjectBase::GetAs() { + return AsImageData_API(); +} + +} // namespace shared_impl +} // namespace ppapi + +#endif // PPAPI_SHARED_IMPL_RESOURCE_OBJECT_BASE_H_ diff --git a/ppapi/shared_impl/tracker_base.cc b/ppapi/shared_impl/tracker_base.cc new file mode 100644 index 0000000..79c4b4e --- /dev/null +++ b/ppapi/shared_impl/tracker_base.cc @@ -0,0 +1,25 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/shared_impl/tracker_base.h" + +#include "base/logging.h" + +namespace ppapi { +namespace shared_impl { + +static TrackerBase* (*g_global_getter)() = NULL; + +// static +void TrackerBase::Init(TrackerBase* (*getter)()) { + g_global_getter = getter; +} + +// static +TrackerBase* TrackerBase::Get() { + return g_global_getter(); +} + +} // namespace shared_impl +} // namespace ppapi diff --git a/ppapi/shared_impl/tracker_base.h b/ppapi/shared_impl/tracker_base.h new file mode 100644 index 0000000..c44ee2b --- /dev/null +++ b/ppapi/shared_impl/tracker_base.h @@ -0,0 +1,49 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_SHARED_IMPL_TRACKER_BASE_H_ +#define PPAPI_SHARED_IMPL_TRACKER_BASE_H_ + +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/proxy/interface_id.h" + +namespace ppapi { +namespace shared_impl { + +class FunctionGroupBase; +class ResourceObjectBase; + +// Tracks resource and function APIs, providing a mapping between ID and +// object. +// TODO(brettw) Eventually this should be one object with global tracking and +// called "Tracker", and this would be used in both the plugin side of the +// proxy as well as the implementation in the renderer. Currently, all this +// does is forward to the process-type-specific tracker to get the information. +class TrackerBase { + public: + // Must be called before any other function that uses the TrackerBase. + // This sets the getter that returns the global implmenetation of + // TrackerBase. It will be different for in the renderer and in the plugin + // process. + static void Init(TrackerBase*(*getter)()); + + // Retrieves the global tracker. This will be NULL if you haven't called + // Init() first (it should be unnecessary to NULL-check this). + static TrackerBase* Get(); + + // Returns the resource object corresponding to the given ID, or NULL if + // there isn't one. + virtual ResourceObjectBase* GetResourceAPI(PP_Resource res) = 0; + + // Returns the function object corresponding to the given ID, or NULL if + // there isn't one. + virtual FunctionGroupBase* GetFunctionAPI(PP_Instance inst, + pp::proxy::InterfaceID id) = 0; +}; + +} // namespace shared_impl +} // namespace ppapi + +#endif // PPAPI_SHARED_IMPL_TRACKER_BASE_H_ diff --git a/ppapi/thunk/enter.h b/ppapi/thunk/enter.h new file mode 100644 index 0000000..1a18cf6 --- /dev/null +++ b/ppapi/thunk/enter.h @@ -0,0 +1,91 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_THUNK_ENTER_H_ +#define PPAPI_THUNK_ENTER_H_ + +#include "base/basictypes.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/proxy/interface_id.h" +#include "ppapi/shared_impl/function_group_base.h" +#include "ppapi/shared_impl/resource_object_base.h" +#include "ppapi/shared_impl/tracker_base.h" + +namespace ppapi { +namespace thunk { + +// EnterHost* helper objects: These objects wrap a call from the C PPAPI into +// the internal implementation. They make sure the lock is acquired and will +// automatically set up some stuff for you. +// +// You should always check whether the enter succeeded before using the object. +// If this fails, then the instance or resource ID supplied was invalid. +// +// The |report_error| arguments to the constructor should indicate if errors +// should be logged to the console. If the calling function expects that the +// input values are correct (the normal case), this should be set to true. In +// some case like |IsFoo(PP_Resource)| the caller is quersioning whether their +// handle is this type, and we don't want to report an error if it's not. +// +// Standalone functions: EnterHostFunction +// Automatically gets the implementation for the function API for the +// supplied PP_Instance. +// +// Resource member functions: EnterHostResource +// Automatically interprets the given PP_Resource as a resource ID and sets +// up the resource object for you. + +template<typename FunctionsT> +class EnterFunction { + public: + EnterFunction(PP_Instance instance, bool report_error) + : functions_(NULL) { + shared_impl::FunctionGroupBase* base = + shared_impl::TrackerBase::Get()->GetFunctionAPI( + instance, FunctionsT::interface_id); + if (base) + functions_ = base->GetAs<FunctionsT>(); + // TODO(brettw) check error and if report_error is set, do something. + } + ~EnterFunction() {} + + bool succeeded() const { return !!functions_; } + bool failed() const { return !functions_; } + + FunctionsT* functions() { return functions_; } + + private: + FunctionsT* functions_; + + DISALLOW_COPY_AND_ASSIGN(EnterFunction); +}; + +template<typename ResourceT> +class EnterResource { + public: + EnterResource(PP_Resource resource, bool report_error) + : object_(NULL) { + shared_impl::ResourceObjectBase* base = + shared_impl::TrackerBase::Get()->GetResourceAPI(resource); + if (base) + object_ = base->GetAs<ResourceT>(); + // TODO(brettw) check error and if report_error is set, do something. + } + ~EnterResource() {} + + bool succeeded() const { return !!object_; } + bool failed() const { return !object_; } + + ResourceT* object() { return object_; } + + private: + ResourceT* object_; + + DISALLOW_COPY_AND_ASSIGN(EnterResource); +}; + +} // namespace thunk +} // namespace ppapi + +#endif // PPAPI_THUNK_ENTER_H_ diff --git a/ppapi/thunk/ppb_graphics_2d_api.h b/ppapi/thunk/ppb_graphics_2d_api.h new file mode 100644 index 0000000..ae6dc45 --- /dev/null +++ b/ppapi/thunk/ppb_graphics_2d_api.h @@ -0,0 +1,28 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_point.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_size.h" + +namespace ppapi { +namespace thunk { + +class PPB_Graphics2D_API { + public: + virtual PP_Bool Describe(PP_Size* size, PP_Bool* is_always_opaque) = 0; + virtual void PaintImageData(PP_Resource image_data, + const PP_Point* top_left, + const PP_Rect* src_rect) = 0; + virtual void Scroll(const PP_Rect* clip_rect, + const PP_Point* amount) = 0; + virtual void ReplaceContents(PP_Resource image_data) = 0; + virtual int32_t Flush(PP_CompletionCallback callback) = 0; +}; + +} // namespace thunk +} // namespace ppapi diff --git a/ppapi/thunk/ppb_graphics_2d_thunk.cc b/ppapi/thunk/ppb_graphics_2d_thunk.cc new file mode 100644 index 0000000..f3ef473 --- /dev/null +++ b/ppapi/thunk/ppb_graphics_2d_thunk.cc @@ -0,0 +1,95 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_graphics_2d.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_graphics_2d_api.h" +#include "ppapi/thunk/resource_creation_api.h" + +namespace ppapi { +namespace thunk { + +namespace { + +PP_Resource Create(PP_Instance instance, + const PP_Size* size, + PP_Bool is_always_opaque) { + EnterFunction<ResourceCreationAPI> enter(instance, true); + if (enter.failed()) + return 0; + return enter.functions()->CreateGraphics2D(instance, *size, is_always_opaque); +} + +PP_Bool IsGraphics2D(PP_Resource resource) { + EnterResource<PPB_Graphics2D_API> enter(resource, false); + return enter.succeeded() ? PP_TRUE : PP_FALSE; +} + +PP_Bool Describe(PP_Resource graphics_2d, + PP_Size* size, + PP_Bool* is_always_opaque) { + EnterResource<PPB_Graphics2D_API> enter(graphics_2d, true); + if (enter.failed()) { + size->width = 0; + size->height = 0; + *is_always_opaque = PP_FALSE; + return PP_FALSE; + } + return enter.object()->Describe(size, is_always_opaque); +} + +void PaintImageData(PP_Resource graphics_2d, + PP_Resource image_data, + const PP_Point* top_left, + const PP_Rect* src_rect) { + EnterResource<PPB_Graphics2D_API> enter(graphics_2d, true); + if (enter.failed()) + return; + enter.object()->PaintImageData(image_data, top_left, src_rect); +} + +void Scroll(PP_Resource graphics_2d, + const PP_Rect* clip_rect, + const PP_Point* amount) { + EnterResource<PPB_Graphics2D_API> enter(graphics_2d, true); + if (enter.failed()) + return; + enter.object()->Scroll(clip_rect, amount); +} + +void ReplaceContents(PP_Resource graphics_2d, PP_Resource image_data) { + EnterResource<PPB_Graphics2D_API> enter(graphics_2d, true); + if (enter.failed()) + return; + enter.object()->ReplaceContents(image_data); +} + +int32_t Flush(PP_Resource graphics_2d, + PP_CompletionCallback callback) { + EnterResource<PPB_Graphics2D_API> enter(graphics_2d, true); + if (enter.failed()) + return PP_ERROR_BADARGUMENT; + return enter.object()->Flush(callback); +} + +const PPB_Graphics2D g_ppb_graphics_2d_thunk = { + &Create, + &IsGraphics2D, + &Describe, + &PaintImageData, + &Scroll, + &ReplaceContents, + &Flush +}; + +} // namespace + +const PPB_Graphics2D* GetPPB_Graphics2D_Thunk() { + return &g_ppb_graphics_2d_thunk; +} + +} // namespace thunk +} // namespace ppapi diff --git a/ppapi/thunk/ppb_image_data_api.h b/ppapi/thunk/ppb_image_data_api.h new file mode 100644 index 0000000..a76a331 --- /dev/null +++ b/ppapi/thunk/ppb_image_data_api.h @@ -0,0 +1,21 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/ppb_image_data.h" +#include "ppapi/c/pp_point.h" +#include "ppapi/c/pp_resource.h" + +namespace ppapi { +namespace thunk { + +class PPB_ImageData_API { + public: + virtual PP_Bool Describe(PP_ImageDataDesc* desc) = 0; + virtual void* Map() = 0; + virtual void Unmap() = 0; +}; + +} // namespace thunk +} // namespace ppapi diff --git a/ppapi/thunk/ppb_image_data_thunk.cc b/ppapi/thunk/ppb_image_data_thunk.cc new file mode 100644 index 0000000..6f75d79 --- /dev/null +++ b/ppapi/thunk/ppb_image_data_thunk.cc @@ -0,0 +1,83 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_image_data.h" +#include "ppapi/shared_impl/image_data_impl.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_image_data_api.h" +#include "ppapi/thunk/resource_creation_api.h" + +namespace ppapi { +namespace thunk { + +namespace { + +PP_ImageDataFormat GetNativeImageDataFormat() { + return pp::shared_impl::ImageDataImpl::GetNativeImageDataFormat(); +} + +PP_Bool IsImageDataFormatSupported(PP_ImageDataFormat format) { + return pp::shared_impl::ImageDataImpl::IsImageDataFormatSupported(format) + ? PP_TRUE : PP_FALSE; +} + +PP_Resource Create(PP_Instance instance, + PP_ImageDataFormat format, + const PP_Size* size, + PP_Bool init_to_zero) { + EnterFunction<ResourceCreationAPI> enter(instance, true); + if (enter.failed()) + return 0; + return enter.functions()->CreateImageData(instance, format, + *size, init_to_zero); +} + +PP_Bool IsImageData(PP_Resource resource) { + EnterResource<PPB_ImageData_API> enter(resource, false); + return enter.succeeded() ? PP_TRUE : PP_FALSE; +} + +PP_Bool Describe(PP_Resource resource, PP_ImageDataDesc* desc) { + // Give predictable values on failure. + memset(desc, 0, sizeof(PP_ImageDataDesc)); + + EnterResource<PPB_ImageData_API> enter(resource, true); + if (enter.failed()) + return PP_FALSE; + return enter.object()->Describe(desc); +} + +void* Map(PP_Resource resource) { + EnterResource<PPB_ImageData_API> enter(resource, true); + if (enter.failed()) + return NULL; + return enter.object()->Map(); +} + +void Unmap(PP_Resource resource) { + EnterResource<PPB_ImageData_API> enter(resource, true); + if (enter.failed()) + return; + enter.object()->Unmap(); +} + +const PPB_ImageData g_ppb_image_data_thunk = { + &GetNativeImageDataFormat, + &IsImageDataFormatSupported, + &Create, + &IsImageData, + &Describe, + &Map, + &Unmap, +}; + +} // namespace + +const PPB_ImageData* GetPPB_ImageData_Thunk() { + return &g_ppb_image_data_thunk; +} + +} // namespace thunk +} // namespace ppapi diff --git a/ppapi/thunk/resource_creation_api.h b/ppapi/thunk/resource_creation_api.h new file mode 100644 index 0000000..bb81776 --- /dev/null +++ b/ppapi/thunk/resource_creation_api.h @@ -0,0 +1,41 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_THUNK_RESOURCE_CREATION_API_H_ +#define PPAPI_THUNK_RESOURCE_CREATION_API_H_ + +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/ppb_image_data.h" +#include "ppapi/proxy/interface_id.h" + +struct PP_Size; + +namespace ppapi { +namespace thunk { + +// A functional API for creating resource types. Separating out the creation +// functions here allows us to implement most resources as a pure "resource +// API", meaning all calls are routed on a per-resource-object basis. The +// creationg functions are not per-object (since there's no object during +// creation) so need functional routing based on the instance ID. +class ResourceCreationAPI { + public: + static const ::pp::proxy::InterfaceID interface_id = + ::pp::proxy::INTERFACE_ID_RESOURCE_CREATION; + + virtual PP_Resource CreateGraphics2D(PP_Instance instance, + const PP_Size& size, + PP_Bool is_always_opaque) = 0; + virtual PP_Resource CreateImageData(PP_Instance instance, + PP_ImageDataFormat format, + const PP_Size& size, + PP_Bool init_to_zero) = 0; +}; + +} // namespace thunk +} // namespace ppapi + +#endif // PPAPI_THUNK_RESOURCE_CREATION_API_H_ diff --git a/ppapi/thunk/thunk.h b/ppapi/thunk/thunk.h new file mode 100644 index 0000000..39ae8f9 --- /dev/null +++ b/ppapi/thunk/thunk.h @@ -0,0 +1,24 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_THUNK_THUNK_H_ +#define PPAPI_THUNK_THUNK_H_ + +#include "base/synchronization/lock.h" + +struct PPB_Graphics2D; +struct PPB_ImageData; + +namespace ppapi { +namespace thunk { + +const PPB_Graphics2D* GetPPB_Graphics2D_Thunk(); +const PPB_ImageData* GetPPB_ImageData_Thunk(); + +} // namespace thunk +} // namespace ppapi + +#endif // PPAPI_THUNK_THUNK_H_ + + diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi index 1e1bfec..74772cc 100644 --- a/webkit/glue/webkit_glue.gypi +++ b/webkit/glue/webkit_glue.gypi @@ -307,6 +307,8 @@ '../plugins/ppapi/ppb_widget_impl.h', '../plugins/ppapi/resource.cc', '../plugins/ppapi/resource.h', + '../plugins/ppapi/resource_creation_impl.cc', + '../plugins/ppapi/resource_creation_impl.h', '../plugins/ppapi/resource_tracker.cc', '../plugins/ppapi/resource_tracker.h', '../plugins/ppapi/string.cc', diff --git a/webkit/plugins/ppapi/DEPS b/webkit/plugins/ppapi/DEPS index baf1b82..4b47d9c 100644 --- a/webkit/plugins/ppapi/DEPS +++ b/webkit/plugins/ppapi/DEPS @@ -2,8 +2,13 @@ include_rules = [ "+gpu/command_buffer", "+ppapi/c", "+ppapi/shared_impl", + "+ppapi/thunk", "+printing", "+media/video", "+skia", "+ui/base", + + # This should technically not be allowed. Brett is refactoring this and will + # move this file to a more proper shared location in a future iteration. + "+ppapi/proxy/interface_id.h", ] diff --git a/webkit/plugins/ppapi/ppb_graphics_2d_impl.cc b/webkit/plugins/ppapi/ppb_graphics_2d_impl.cc index c1b6ab9..a3f1c0d 100644 --- a/webkit/plugins/ppapi/ppb_graphics_2d_impl.cc +++ b/webkit/plugins/ppapi/ppb_graphics_2d_impl.cc @@ -15,6 +15,7 @@ #include "ppapi/c/pp_resource.h" #include "ppapi/c/ppb_graphics_2d.h" #include "ppapi/cpp/common.h" +#include "ppapi/thunk/thunk.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/blit.h" #include "ui/gfx/point.h" @@ -114,82 +115,6 @@ void ConvertImageData(PPB_ImageData_Impl* src_image, const SkIRect& src_rect, } } -PP_Resource Create(PP_Instance instance_id, - const PP_Size* size, - PP_Bool is_always_opaque) { - PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); - if (!instance) - return 0; - - scoped_refptr<PPB_Graphics2D_Impl> context( - new PPB_Graphics2D_Impl(instance)); - if (!context->Init(size->width, size->height, PPBoolToBool(is_always_opaque))) - return 0; - return context->GetReference(); -} - -PP_Bool IsGraphics2D(PP_Resource resource) { - return BoolToPPBool(!!Resource::GetAs<PPB_Graphics2D_Impl>(resource)); -} - -PP_Bool Describe(PP_Resource graphics_2d, - PP_Size* size, - PP_Bool* is_always_opaque) { - scoped_refptr<PPB_Graphics2D_Impl> context( - Resource::GetAs<PPB_Graphics2D_Impl>(graphics_2d)); - if (!context) { - *size = PP_MakeSize(0, 0); - *is_always_opaque = PP_FALSE; - return PP_FALSE; - } - return context->Describe(size, is_always_opaque); -} - -void PaintImageData(PP_Resource graphics_2d, - PP_Resource image_data, - const PP_Point* top_left, - const PP_Rect* src_rect) { - scoped_refptr<PPB_Graphics2D_Impl> context( - Resource::GetAs<PPB_Graphics2D_Impl>(graphics_2d)); - if (context) - context->PaintImageData(image_data, top_left, src_rect); -} - -void Scroll(PP_Resource graphics_2d, - const PP_Rect* clip_rect, - const PP_Point* amount) { - scoped_refptr<PPB_Graphics2D_Impl> context( - Resource::GetAs<PPB_Graphics2D_Impl>(graphics_2d)); - if (context) - context->Scroll(clip_rect, amount); -} - -void ReplaceContents(PP_Resource graphics_2d, PP_Resource image_data) { - scoped_refptr<PPB_Graphics2D_Impl> context( - Resource::GetAs<PPB_Graphics2D_Impl>(graphics_2d)); - if (context) - context->ReplaceContents(image_data); -} - -int32_t Flush(PP_Resource graphics_2d, - PP_CompletionCallback callback) { - scoped_refptr<PPB_Graphics2D_Impl> context( - Resource::GetAs<PPB_Graphics2D_Impl>(graphics_2d)); - if (!context) - return PP_ERROR_BADRESOURCE; - return context->Flush(callback); -} - -const PPB_Graphics2D ppb_graphics_2d = { - &Create, - &IsGraphics2D, - &Describe, - &PaintImageData, - &Scroll, - &ReplaceContents, - &Flush -}; - } // namespace struct PPB_Graphics2D_Impl::QueuedOperation { @@ -235,7 +160,7 @@ PPB_Graphics2D_Impl::~PPB_Graphics2D_Impl() { // static const PPB_Graphics2D* PPB_Graphics2D_Impl::GetInterface() { - return &ppb_graphics_2d; + return ::ppapi::thunk::GetPPB_Graphics2D_Thunk(); } bool PPB_Graphics2D_Impl::Init(int width, int height, bool is_always_opaque) { @@ -251,6 +176,10 @@ bool PPB_Graphics2D_Impl::Init(int width, int height, bool is_always_opaque) { return true; } +::ppapi::thunk::PPB_Graphics2D_API* PPB_Graphics2D_Impl::AsGraphics2D_API() { + return this; +} + PPB_Graphics2D_Impl* PPB_Graphics2D_Impl::AsPPB_Graphics2D_Impl() { return this; } @@ -340,7 +269,7 @@ void PPB_Graphics2D_Impl::ReplaceContents(PP_Resource image_data) { queued_operations_.push_back(operation); } -int32_t PPB_Graphics2D_Impl::Flush(const PP_CompletionCallback& callback) { +int32_t PPB_Graphics2D_Impl::Flush(PP_CompletionCallback callback) { // Don't allow more than one pending flush at a time. if (HasPendingFlush()) return PP_ERROR_INPROGRESS; diff --git a/webkit/plugins/ppapi/ppb_graphics_2d_impl.h b/webkit/plugins/ppapi/ppb_graphics_2d_impl.h index 9c1bbfd..66e3032 100644 --- a/webkit/plugins/ppapi/ppb_graphics_2d_impl.h +++ b/webkit/plugins/ppapi/ppb_graphics_2d_impl.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -10,6 +10,7 @@ #include "base/basictypes.h" #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/ppb_graphics_2d.h" +#include "ppapi/thunk/ppb_graphics_2d_api.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebCanvas.h" #include "webkit/plugins/ppapi/resource.h" @@ -26,7 +27,9 @@ class PPB_ImageData_Impl; class PluginInstance; class PluginModule; -class PPB_Graphics2D_Impl : public Resource { +class PPB_Graphics2D_Impl + : public Resource, + public ::ppapi::thunk::PPB_Graphics2D_API { public: PPB_Graphics2D_Impl(PluginInstance* instance); virtual ~PPB_Graphics2D_Impl(); @@ -39,17 +42,19 @@ class PPB_Graphics2D_Impl : public Resource { bool is_always_opaque() const { return is_always_opaque_; } + virtual ::ppapi::thunk::PPB_Graphics2D_API* AsGraphics2D_API(); + // Resource override. virtual PPB_Graphics2D_Impl* AsPPB_Graphics2D_Impl(); // PPB_Graphics2D functions. - PP_Bool Describe(PP_Size* size, PP_Bool* is_always_opaque); - void PaintImageData(PP_Resource image_data, - const PP_Point* top_left, - const PP_Rect* src_rect); - void Scroll(const PP_Rect* clip_rect, const PP_Point* amount); - void ReplaceContents(PP_Resource image_data); - int32_t Flush(const PP_CompletionCallback& callback); + virtual PP_Bool Describe(PP_Size* size, PP_Bool* is_always_opaque); + virtual void PaintImageData(PP_Resource image_data, + const PP_Point* top_left, + const PP_Rect* src_rect); + virtual void Scroll(const PP_Rect* clip_rect, const PP_Point* amount); + virtual void ReplaceContents(PP_Resource image_data); + virtual int32_t Flush(PP_CompletionCallback callback); bool ReadImageData(PP_Resource image, const PP_Point* top_left); diff --git a/webkit/plugins/ppapi/ppb_image_data_impl.cc b/webkit/plugins/ppapi/ppb_image_data_impl.cc index 967a978..9f5c15c 100644 --- a/webkit/plugins/ppapi/ppb_image_data_impl.cc +++ b/webkit/plugins/ppapi/ppb_image_data_impl.cc @@ -14,6 +14,7 @@ #include "ppapi/c/pp_resource.h" #include "ppapi/c/ppb_image_data.h" #include "ppapi/c/trusted/ppb_image_data_trusted.h" +#include "ppapi/thunk/thunk.h" #include "third_party/skia/include/core/SkColorPriv.h" #include "webkit/plugins/ppapi/common.h" #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" @@ -23,64 +24,6 @@ namespace ppapi { namespace { -PP_ImageDataFormat GetNativeImageDataFormat() { - return PPB_ImageData_Impl::GetNativeImageDataFormat(); -} - -PP_Bool IsImageDataFormatSupported(PP_ImageDataFormat format) { - return BoolToPPBool(PPB_ImageData_Impl::IsImageDataFormatSupported(format)); -} - -PP_Resource Create(PP_Instance instance_id, - PP_ImageDataFormat format, - const PP_Size* size, - PP_Bool init_to_zero) { - PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); - if (!instance) - return 0; - - scoped_refptr<PPB_ImageData_Impl> data(new PPB_ImageData_Impl(instance)); - if (!data->Init(format, - size->width, - size->height, - PPBoolToBool(init_to_zero))) { - return 0; - } - - return data->GetReference(); -} - -PP_Bool IsImageData(PP_Resource resource) { - return BoolToPPBool(!!Resource::GetAs<PPB_ImageData_Impl>(resource)); -} - -PP_Bool Describe(PP_Resource resource, PP_ImageDataDesc* desc) { - // Give predictable values on failure. - memset(desc, 0, sizeof(PP_ImageDataDesc)); - - scoped_refptr<PPB_ImageData_Impl> image_data( - Resource::GetAs<PPB_ImageData_Impl>(resource)); - if (!image_data) - return PP_FALSE; - image_data->Describe(desc); - return PP_TRUE; -} - -void* Map(PP_Resource resource) { - scoped_refptr<PPB_ImageData_Impl> image_data( - Resource::GetAs<PPB_ImageData_Impl>(resource)); - if (!image_data) - return NULL; - return image_data->Map(); -} - -void Unmap(PP_Resource resource) { - scoped_refptr<PPB_ImageData_Impl> image_data( - Resource::GetAs<PPB_ImageData_Impl>(resource)); - if (image_data) - image_data->Unmap(); -} - int32_t GetSharedMemory(PP_Resource resource, int* handle, uint32_t* byte_count) { @@ -93,16 +36,6 @@ int32_t GetSharedMemory(PP_Resource resource, return PP_ERROR_BADRESOURCE; } -const PPB_ImageData ppb_imagedata = { - &GetNativeImageDataFormat, - &IsImageDataFormatSupported, - &Create, - &IsImageData, - &Describe, - &Map, - &Unmap, -}; - const PPB_ImageDataTrusted ppb_imagedata_trusted = { &GetSharedMemory, }; @@ -121,7 +54,7 @@ PPB_ImageData_Impl::~PPB_ImageData_Impl() { // static const PPB_ImageData* PPB_ImageData_Impl::GetInterface() { - return &ppb_imagedata; + return ::ppapi::thunk::GetPPB_ImageData_Thunk(); } // static @@ -129,6 +62,10 @@ const PPB_ImageDataTrusted* PPB_ImageData_Impl::GetTrustedInterface() { return &ppb_imagedata_trusted; } +::ppapi::thunk::PPB_ImageData_API* PPB_ImageData_Impl::AsImageData_API() { + return this; +} + PPB_ImageData_Impl* PPB_ImageData_Impl::AsPPB_ImageData_Impl() { return this; } @@ -154,11 +91,12 @@ bool PPB_ImageData_Impl::Init(PP_ImageDataFormat format, return !!platform_image_.get(); } -void PPB_ImageData_Impl::Describe(PP_ImageDataDesc* desc) const { +PP_Bool PPB_ImageData_Impl::Describe(PP_ImageDataDesc* desc) { desc->format = format_; desc->size.width = width_; desc->size.height = height_; desc->stride = width_ * 4; + return PP_TRUE; } void* PPB_ImageData_Impl::Map() { diff --git a/webkit/plugins/ppapi/ppb_image_data_impl.h b/webkit/plugins/ppapi/ppb_image_data_impl.h index 759da1a..69a7a65 100644 --- a/webkit/plugins/ppapi/ppb_image_data_impl.h +++ b/webkit/plugins/ppapi/ppb_image_data_impl.h @@ -9,6 +9,7 @@ #include "base/memory/scoped_ptr.h" #include "ppapi/c/ppb_image_data.h" #include "ppapi/shared_impl/image_data_impl.h" +#include "ppapi/thunk/ppb_image_data_api.h" #include "webkit/plugins/ppapi/plugin_delegate.h" #include "webkit/plugins/ppapi/resource.h" @@ -23,11 +24,16 @@ namespace webkit { namespace ppapi { class PPB_ImageData_Impl : public Resource, - public pp::shared_impl::ImageDataImpl { + public pp::shared_impl::ImageDataImpl, + public ::ppapi::thunk::PPB_ImageData_API { public: explicit PPB_ImageData_Impl(PluginInstance* instance); virtual ~PPB_ImageData_Impl(); + bool Init(PP_ImageDataFormat format, + int width, int height, + bool init_to_zero); + int width() const { return width_; } int height() const { return height_; } @@ -47,16 +53,15 @@ class PPB_ImageData_Impl : public Resource, static const PPB_ImageData* GetInterface(); static const PPB_ImageDataTrusted* GetTrustedInterface(); + virtual ::ppapi::thunk::PPB_ImageData_API* AsImageData_API(); + // Resource overrides. virtual PPB_ImageData_Impl* AsPPB_ImageData_Impl(); - // PPB_ImageData implementation. - bool Init(PP_ImageDataFormat format, - int width, int height, - bool init_to_zero); - void Describe(PP_ImageDataDesc* desc) const; - void* Map(); - void Unmap(); + // PPB_ImageData_API implementation. + virtual PP_Bool Describe(PP_ImageDataDesc* desc); + virtual void* Map(); + virtual void Unmap(); // PPB_ImageDataTrusted implementation. int GetSharedMemoryHandle(uint32* byte_count) const; diff --git a/webkit/plugins/ppapi/resource.h b/webkit/plugins/ppapi/resource.h index 8b08805..a263231 100644 --- a/webkit/plugins/ppapi/resource.h +++ b/webkit/plugins/ppapi/resource.h @@ -8,6 +8,7 @@ #include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "ppapi/c/pp_resource.h" +#include "ppapi/shared_impl/resource_object_base.h" #include "webkit/plugins/ppapi/resource_tracker.h" namespace webkit { @@ -49,7 +50,8 @@ namespace ppapi { FOR_ALL_RESOURCES(DECLARE_RESOURCE_CLASS) #undef DECLARE_RESOURCE_CLASS -class Resource : public base::RefCountedThreadSafe<Resource> { +class Resource : public base::RefCountedThreadSafe<Resource>, + public ::ppapi::shared_impl::ResourceObjectBase { public: explicit Resource(PluginInstance* instance); virtual ~Resource(); diff --git a/webkit/plugins/ppapi/resource_creation_impl.cc b/webkit/plugins/ppapi/resource_creation_impl.cc new file mode 100644 index 0000000..674aee1 --- /dev/null +++ b/webkit/plugins/ppapi/resource_creation_impl.cc @@ -0,0 +1,58 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/plugins/ppapi/resource_creation_impl.h" + +#include "ppapi/c/pp_size.h" +#include "webkit/plugins/ppapi/common.h" +#include "webkit/plugins/ppapi/ppb_graphics_2d_impl.h" +#include "webkit/plugins/ppapi/ppb_image_data_impl.h" + +namespace webkit { +namespace ppapi { + +ResourceCreationImpl::ResourceCreationImpl() { +} + +ResourceCreationImpl::~ResourceCreationImpl() { +} + +::ppapi::thunk::ResourceCreationAPI* +ResourceCreationImpl::AsResourceCreation() { + return this; +} + +PP_Resource ResourceCreationImpl::CreateGraphics2D( + PP_Instance pp_instance, + const PP_Size& size, + PP_Bool is_always_opaque) { + PluginInstance* instance = ResourceTracker::Get()->GetInstance(pp_instance); + if (!instance) + return 0; + + scoped_refptr<PPB_Graphics2D_Impl> graphics_2d( + new PPB_Graphics2D_Impl(instance)); + if (!graphics_2d->Init(size.width, size.height, + PPBoolToBool(is_always_opaque))) { + return 0; + } + return graphics_2d->GetReference(); +} + +PP_Resource ResourceCreationImpl::CreateImageData(PP_Instance pp_instance, + PP_ImageDataFormat format, + const PP_Size& size, + PP_Bool init_to_zero) { + PluginInstance* instance = ResourceTracker::Get()->GetInstance(pp_instance); + if (!instance) + return 0; + + scoped_refptr<PPB_ImageData_Impl> data(new PPB_ImageData_Impl(instance)); + if (!data->Init(format, size.width, size.height, !!init_to_zero)) + return 0; + return data->GetReference(); +} + +} // namespace ppapi +} // namespace webkit diff --git a/webkit/plugins/ppapi/resource_creation_impl.h b/webkit/plugins/ppapi/resource_creation_impl.h new file mode 100644 index 0000000..4d89715 --- /dev/null +++ b/webkit/plugins/ppapi/resource_creation_impl.h @@ -0,0 +1,40 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_PLUGINS_PPAPI_RESOURCE_CREATION_IMPL_H_ +#define WEBKIT_PLUGINS_PPAPI_RESOURCE_CREATION_IMPL_H_ + +#include "base/basictypes.h" +#include "ppapi/shared_impl/function_group_base.h" +#include "ppapi/thunk/resource_creation_api.h" + +namespace webkit { +namespace ppapi { + +class ResourceCreationImpl : public ::ppapi::shared_impl::FunctionGroupBase, + public ::ppapi::thunk::ResourceCreationAPI { + public: + ResourceCreationImpl(); + virtual ~ResourceCreationImpl(); + + // FunctionGroupBase implementation. + virtual ::ppapi::thunk::ResourceCreationAPI* AsResourceCreation(); + + // ResourceCreationAPI implementation. + virtual PP_Resource CreateGraphics2D(PP_Instance pp_instance, + const PP_Size& size, + PP_Bool is_always_opaque); + virtual PP_Resource CreateImageData(PP_Instance instance, + PP_ImageDataFormat format, + const PP_Size& size, + PP_Bool init_to_zero); + + private: + DISALLOW_COPY_AND_ASSIGN(ResourceCreationImpl); +}; + +} // namespace ppapi +} // namespace webkit + +#endif // WEBKIT_PLUGINS_PPAPI_RESOURCE_CREATION_IMPL_H_ diff --git a/webkit/plugins/ppapi/resource_tracker.cc b/webkit/plugins/ppapi/resource_tracker.cc index 4642b63..1c4b3a1 100644 --- a/webkit/plugins/ppapi/resource_tracker.cc +++ b/webkit/plugins/ppapi/resource_tracker.cc @@ -11,9 +11,11 @@ #include "base/rand_util.h" #include "ppapi/c/pp_resource.h" #include "ppapi/c/pp_var.h" +#include "ppapi/shared_impl/tracker_base.h" #include "webkit/plugins/ppapi/plugin_module.h" #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" #include "webkit/plugins/ppapi/resource.h" +#include "webkit/plugins/ppapi/resource_creation_impl.h" #include "webkit/plugins/ppapi/var.h" enum PPIdType { @@ -40,9 +42,19 @@ template <typename T> static inline bool CheckIdType(T id, PPIdType type) { return (id & mask) == type; } +namespace shared_impl = ::ppapi::shared_impl; + namespace webkit { namespace ppapi { +namespace { + +shared_impl::TrackerBase* GetTrackerBase() { + return ResourceTracker::Get(); +} + +} // namespace + struct ResourceTracker::InstanceData { InstanceData() : instance(0) {} @@ -72,6 +84,8 @@ ResourceTracker* ResourceTracker::singleton_override_ = NULL; ResourceTracker::ResourceTracker() : last_resource_id_(0), last_var_id_(0) { + // Wire up the new shared resource tracker base to use our implementation. + shared_impl::TrackerBase::Init(&GetTrackerBase); } ResourceTracker::~ResourceTracker() { @@ -226,6 +240,28 @@ uint32 ResourceTracker::GetLiveObjectsForInstance( found->second.object_vars.size()); } +shared_impl::ResourceObjectBase* ResourceTracker::GetResourceAPI( + PP_Resource res) { + DLOG_IF(ERROR, !CheckIdType(res, PP_ID_TYPE_RESOURCE)) + << res << " is not a PP_Resource."; + ResourceMap::const_iterator result = live_resources_.find(res); + if (result == live_resources_.end()) + return NULL; + return result->second.first.get(); +} + +shared_impl::FunctionGroupBase* ResourceTracker::GetFunctionAPI( + PP_Instance inst, + pp::proxy::InterfaceID id) { + if (function_proxies_[id].get()) + return function_proxies_[id].get(); + + if (id == ::pp::proxy::INTERFACE_ID_RESOURCE_CREATION) + function_proxies_[id].reset(new ResourceCreationImpl()); + + return function_proxies_[id].get(); +} + scoped_refptr<Var> ResourceTracker::GetVar(int32 var_id) const { DLOG_IF(ERROR, !CheckIdType(var_id, PP_ID_TYPE_VAR)) << var_id << " is not a PP_Var ID."; diff --git a/webkit/plugins/ppapi/resource_tracker.h b/webkit/plugins/ppapi/resource_tracker.h index a5cd70d..744d90c 100644 --- a/webkit/plugins/ppapi/resource_tracker.h +++ b/webkit/plugins/ppapi/resource_tracker.h @@ -13,9 +13,13 @@ #include "base/gtest_prod_util.h" #include "base/hash_tables.h" #include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_module.h" #include "ppapi/c/pp_resource.h" +#include "ppapi/proxy/interface_id.h" +#include "ppapi/shared_impl/function_group_base.h" +#include "ppapi/shared_impl/tracker_base.h" namespace webkit { namespace ppapi { @@ -30,7 +34,7 @@ class Var; // us to check resource ID validity and to map them to a specific module. // // This object is NOT threadsafe. -class ResourceTracker { +class ResourceTracker : public ::ppapi::shared_impl::TrackerBase { public: // Returns the pointer to the singleton object. static ResourceTracker* Get(); @@ -52,6 +56,13 @@ class ResourceTracker { // Returns the number of resources associated with this module. uint32 GetLiveObjectsForInstance(PP_Instance instance) const; + // ResourceTrackerBase. + virtual ::ppapi::shared_impl::ResourceObjectBase* GetResourceAPI( + PP_Resource res); + virtual ::ppapi::shared_impl::FunctionGroupBase* GetFunctionAPI( + PP_Instance inst, + pp::proxy::InterfaceID id); + // PP_Vars ------------------------------------------------------------------- scoped_refptr<Var> GetVar(int32 var_id) const; @@ -177,6 +188,9 @@ class ResourceTracker { typedef std::map<PP_Module, PluginModule*> ModuleMap; ModuleMap module_map_; + scoped_ptr< ::ppapi::shared_impl::FunctionGroupBase > + function_proxies_[::pp::proxy::INTERFACE_ID_COUNT]; + DISALLOW_COPY_AND_ASSIGN(ResourceTracker); }; |