diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-06 22:55:47 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-06 22:55:47 +0000 |
commit | 6239d34076222cbfe1d42770c604822b0ba894f4 (patch) | |
tree | d873cdf138b002bb2d2d4a554ba4fcd210251760 /ppapi/proxy | |
parent | c50a948dd9c07a71524949a28a5347e11d80da47 (diff) | |
download | chromium_src-6239d34076222cbfe1d42770c604822b0ba894f4.zip chromium_src-6239d34076222cbfe1d42770c604822b0ba894f4.tar.gz chromium_src-6239d34076222cbfe1d42770c604822b0ba894f4.tar.bz2 |
This implements the new system for Graphics2D only.
This works by adding a new thunk layer that will forward to an "API" that's either per-instance (function APIs) or per-resource (resource APIs). The proxying and such is then implemented in terms of this C++ API.
Ideally the trackers of the PP_Resource/PP_Instance -> object mapping would be shared between the plugin and renderer processes. To keep this patch under control, I did this as a virtual base class which is implemented by ppapi::proxy::PluginResourceTracker and webkit::ppapi::ResourceTracker. Later, the functionality of these objects should be shared in a common tracker class.
Still to do it a lot of cleanup and merging of things. Also, the namespaces are a bit out of control.
Review URL: http://codereview.chromium.org/6905088
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@84519 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/proxy')
-rw-r--r-- | ppapi/proxy/host_dispatcher.cc | 10 | ||||
-rw-r--r-- | ppapi/proxy/host_dispatcher.h | 7 | ||||
-rw-r--r-- | ppapi/proxy/interface_id.h | 2 | ||||
-rw-r--r-- | ppapi/proxy/plugin_dispatcher.cc | 17 | ||||
-rw-r--r-- | ppapi/proxy/plugin_dispatcher.h | 16 | ||||
-rw-r--r-- | ppapi/proxy/plugin_resource.cc | 6 | ||||
-rw-r--r-- | ppapi/proxy/plugin_resource.h | 5 | ||||
-rw-r--r-- | ppapi/proxy/plugin_resource_tracker.cc | 30 | ||||
-rw-r--r-- | ppapi/proxy/plugin_resource_tracker.h | 11 | ||||
-rw-r--r-- | ppapi/proxy/ppapi_messages.h | 30 | ||||
-rw-r--r-- | ppapi/proxy/ppb_graphics_2d_proxy.cc | 212 | ||||
-rw-r--r-- | ppapi/proxy/ppb_graphics_2d_proxy.h | 60 | ||||
-rw-r--r-- | ppapi/proxy/ppb_image_data_proxy.cc | 211 | ||||
-rw-r--r-- | ppapi/proxy/ppb_image_data_proxy.h | 45 | ||||
-rw-r--r-- | ppapi/proxy/resource_creation_proxy.cc | 155 | ||||
-rw-r--r-- | ppapi/proxy/resource_creation_proxy.h | 68 |
16 files changed, 517 insertions, 368 deletions
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_ |