| OLD | NEW |
| 1 // Copyright (c) 2011 The Native Client Authors. All rights reserved. | 1 // Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_RESOURCE_H_ | 5 #ifndef NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_RESOURCE_H_ |
| 6 #define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_RESOURCE_H_ | 6 #define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_RESOURCE_H_ |
| 7 | 7 |
| 8 #include "native_client/src/include/nacl_base.h" | 8 #include "native_client/src/include/nacl_base.h" |
| 9 #include "native_client/src/include/ref_counted.h" | 9 #include "native_client/src/include/ref_counted.h" |
| 10 #include "native_client/src/shared/ppapi_proxy/plugin_resource_tracker.h" | 10 #include "native_client/src/shared/ppapi_proxy/plugin_resource_tracker.h" |
| 11 #include "native_client/src/third_party/ppapi/c/pp_resource.h" | 11 #include "native_client/src/third_party/ppapi/c/pp_resource.h" |
| 12 | 12 |
| 13 namespace ppapi_proxy { | 13 namespace ppapi_proxy { |
| 14 | 14 |
| 15 // If you inherit from resource, make sure you add the class name here. | 15 // If you inherit from resource, make sure you add the class name here. |
| 16 #define FOR_ALL_RESOURCES(F) \ | 16 #define FOR_ALL_RESOURCES(F) \ |
| 17 F(PluginAudio) \ | 17 F(PluginAudio) \ |
| 18 F(PluginAudioConfig) \ | 18 F(PluginAudioConfig) \ |
| 19 F(PluginBuffer) \ | 19 F(PluginBuffer) \ |
| 20 F(PluginContext3D) \ | 20 F(PluginContext3D) \ |
| 21 F(PluginFont) \ | 21 F(PluginFont) \ |
| 22 F(PluginGraphics2D) \ | 22 F(PluginGraphics2D) \ |
| 23 F(PluginImageData) \ | 23 F(PluginImageData) \ |
| 24 F(PluginInputEvent) \ |
| 24 F(PluginSurface3D) | 25 F(PluginSurface3D) |
| 25 | 26 |
| 26 // Forward declaration of PluginResource classes. | 27 // Forward declaration of PluginResource classes. |
| 27 #define DECLARE_RESOURCE_CLASS(RESOURCE) class RESOURCE; | 28 #define DECLARE_RESOURCE_CLASS(RESOURCE) class RESOURCE; |
| 28 FOR_ALL_RESOURCES(DECLARE_RESOURCE_CLASS) | 29 FOR_ALL_RESOURCES(DECLARE_RESOURCE_CLASS) |
| 29 #undef DECLARE_RESOURCE_CLASS | 30 #undef DECLARE_RESOURCE_CLASS |
| 30 | 31 |
| 31 class PluginResource : public nacl::RefCounted<PluginResource> { | 32 class PluginResource : public nacl::RefCounted<PluginResource> { |
| 32 public: | 33 public: |
| 33 PluginResource(); | 34 PluginResource(); |
| 34 virtual ~PluginResource(); | 35 virtual ~PluginResource(); |
| 35 | 36 |
| 36 // Returns NULL if the resource is invalid or is a different type. | 37 // Returns NULL if the resource is invalid or is a different type. |
| 37 template<typename T> | 38 template<typename T> |
| 38 static scoped_refptr<T> GetAs(PP_Resource res) { | 39 static scoped_refptr<T> GetAs(PP_Resource res) { |
| 39 // See if we have the resource cached. | 40 // See if we have the resource cached. |
| 40 scoped_refptr<PluginResource> resource = | 41 scoped_refptr<PluginResource> resource = |
| 41 PluginResourceTracker::Get()->GetExistingResource(res); | 42 PluginResourceTracker::Get()->GetExistingResource(res); |
| 42 | 43 |
| 43 return resource ? resource->Cast<T>() : NULL; | 44 return resource ? resource->Cast<T>() : NULL; |
| 44 } | 45 } |
| 45 | 46 |
| 47 // Adopt the given PP_Resource as type T. Use this function for resources that |
| 48 // the browser provides to the plugin with an incremented ref count (i.e., |
| 49 // calls AddRefResource); it initializes the browser refcount to 1 or |
| 50 // increments it if the resource already exists. |
| 46 // Returns NULL if the resource is invalid or is a different type. | 51 // Returns NULL if the resource is invalid or is a different type. |
| 47 template<typename T> | 52 template<typename T> |
| 48 static scoped_refptr<T> AdoptAs(PP_Resource res); | 53 static scoped_refptr<T> AdoptAs(PP_Resource res); |
| 49 | 54 |
| 55 // Adopt the given PP_Resource as type T. Use this function for resources |
| 56 // when the browser drops the refcount immediately. These resources are |
| 57 // typically meant to be cached on the plugin side, with little or no |
| 58 // interaction back to the browser. For an example, see PluginInputEvent. |
| 59 // This is like AdoptAs above, except it initializes the browser_refcount to |
| 60 // 0 for resources that are new to the plugin, and does not increment the |
| 61 // browser_refcount for resources that exist. |
| 62 // Returns NULL if the resource is invalid or is a different type. |
| 63 template<typename T> |
| 64 static scoped_refptr<T> AdoptAsWithNoBrowserCount(PP_Resource res); |
| 65 |
| 50 // Cast the resource into a specified type. This will return NULL if the | 66 // Cast the resource into a specified type. This will return NULL if the |
| 51 // resource does not match the specified type. Specializations of this | 67 // resource does not match the specified type. Specializations of this |
| 52 // template call into As* functions. | 68 // template call into As* functions. |
| 53 template <typename T> T* Cast() { return NULL; } | 69 template <typename T> T* Cast() { return NULL; } |
| 54 | 70 |
| 55 // Returns an resource id of this object. If the object doesn't have a | |
| 56 // resource id, new one is created with plugin refcount of 1. If it does, | |
| 57 // the refcount is incremented. Use this when you need to return a new | |
| 58 // reference to the plugin. | |
| 59 PP_Resource GetReference(); | |
| 60 | |
| 61 // When you need to ensure that a resource has a reference, but you do not | |
| 62 // want to increase the refcount (for example, if you need to call a plugin | |
| 63 // callback function with a reference), you can use this class. For example: | |
| 64 // | |
| 65 // plugin_callback(.., ScopedResourceId(resource).id, ...); | |
| 66 class ScopedResourceId { | |
| 67 public: | |
| 68 explicit ScopedResourceId(PluginResource* resource) | |
| 69 : id(resource->GetReference()) {} | |
| 70 ~ScopedResourceId() { | |
| 71 PluginResourceTracker::Get()->UnrefResource(id); | |
| 72 } | |
| 73 const PP_Resource id; | |
| 74 }; | |
| 75 | |
| 76 protected: | 71 protected: |
| 77 virtual bool InitFromBrowserResource(PP_Resource resource) = 0; | 72 virtual bool InitFromBrowserResource(PP_Resource resource) = 0; |
| 78 | 73 |
| 79 private: | 74 private: |
| 80 // Type-specific getters for individual resource types. These will return | 75 // Type-specific getters for individual resource types. These will return |
| 81 // NULL if the resource does not match the specified type. Used by the Cast() | 76 // NULL if the resource does not match the specified type. Used by the Cast() |
| 82 // function. | 77 // function. |
| 83 #define DEFINE_TYPE_GETTER(RESOURCE) \ | 78 #define DEFINE_TYPE_GETTER(RESOURCE) \ |
| 84 virtual RESOURCE* As##RESOURCE() { return NULL; } | 79 virtual RESOURCE* As##RESOURCE() { return NULL; } |
| 85 FOR_ALL_RESOURCES(DEFINE_TYPE_GETTER) | 80 FOR_ALL_RESOURCES(DEFINE_TYPE_GETTER) |
| 86 #undef DEFINE_TYPE_GETTER | 81 #undef DEFINE_TYPE_GETTER |
| 87 | 82 |
| 88 // Call this macro in the derived class declaration to actually implement the | 83 // Call this macro in the derived class declaration to actually implement the |
| 89 // type getter. | 84 // type getter. |
| 90 #define IMPLEMENT_RESOURCE(RESOURCE) \ | 85 #define IMPLEMENT_RESOURCE(RESOURCE) \ |
| 91 virtual RESOURCE* As##RESOURCE() { return this; } | 86 virtual RESOURCE* As##RESOURCE() { return this; } |
| 92 | 87 |
| 93 // If referenced by a plugin, holds the id of this resource object. Do not | |
| 94 // access this member directly, because it is possible that the plugin holds | |
| 95 // no references to the object, and therefore the resource_id_ is zero. Use | |
| 96 // either GetReference() to obtain a new resource_id and increase the | |
| 97 // refcount, or TemporaryReference when you do not want to increase the | |
| 98 // refcount. | |
| 99 PP_Resource resource_id_; | |
| 100 | |
| 101 // Called by the resource tracker when the last plugin reference has been | |
| 102 // dropped. You cannot use resource_id_ after this function is called! | |
| 103 friend class PluginResourceTracker; | |
| 104 void StoppedTracking(); | |
| 105 | |
| 106 DISALLOW_COPY_AND_ASSIGN(PluginResource); | 88 DISALLOW_COPY_AND_ASSIGN(PluginResource); |
| 107 }; | 89 }; |
| 108 | 90 |
| 109 // Cast() specializations. | 91 // Cast() specializations. |
| 110 #define DEFINE_RESOURCE_CAST(Type) \ | 92 #define DEFINE_RESOURCE_CAST(Type) \ |
| 111 template <> inline Type* PluginResource::Cast<Type>() { \ | 93 template <> inline Type* PluginResource::Cast<Type>() { \ |
| 112 return As##Type(); \ | 94 return As##Type(); \ |
| 113 } | 95 } |
| 114 | 96 |
| 115 FOR_ALL_RESOURCES(DEFINE_RESOURCE_CAST) | 97 FOR_ALL_RESOURCES(DEFINE_RESOURCE_CAST) |
| 116 #undef DEFINE_RESOURCE_CAST | 98 #undef DEFINE_RESOURCE_CAST |
| 117 | 99 |
| 118 #undef FOR_ALL_RESOURCES | 100 #undef FOR_ALL_RESOURCES |
| 119 | 101 |
| 120 template<typename T> scoped_refptr<T> | 102 template<typename T> scoped_refptr<T> |
| 121 PluginResourceTracker::AdoptBrowserResource(PP_Resource res) { | 103 PluginResourceTracker::AdoptBrowserResource(PP_Resource res, |
| 104 size_t browser_refcount) { |
| 122 ResourceMap::iterator result = live_resources_.find(res); | 105 ResourceMap::iterator result = live_resources_.find(res); |
| 123 // Do we have it already? | 106 // Do we have it already? |
| 124 if (result == live_resources_.end()) { | 107 if (result == live_resources_.end()) { |
| 125 // No - try to create a new one. | 108 // No - try to create a new one. |
| 126 scoped_refptr<T> new_resource = new T(); | 109 scoped_refptr<T> new_resource = new T(); |
| 127 if (new_resource->InitFromBrowserResource(res)) { | 110 if (new_resource->InitFromBrowserResource(res)) { |
| 128 AddResource(new_resource, res); | 111 AddResource(new_resource, res, browser_refcount); |
| 129 return new_resource; | 112 return new_resource; |
| 130 } else { | 113 } else { |
| 131 return scoped_refptr<T>(); | 114 return scoped_refptr<T>(); |
| 132 } | 115 } |
| 133 } else { | 116 } else { |
| 134 // Consume one more browser refcount. | 117 // Consume more browser refcounts (unless browser_refcount is 0). |
| 135 ++result->second.browser_refcount; | 118 result->second.browser_refcount += browser_refcount; |
| 136 return result->second.resource->Cast<T>(); | 119 return result->second.resource->Cast<T>(); |
| 137 } | 120 } |
| 138 } | 121 } |
| 139 | 122 |
| 140 template<typename T> | 123 template<typename T> |
| 141 scoped_refptr<T> PluginResource::AdoptAs(PP_Resource res) { | 124 scoped_refptr<T> PluginResource::AdoptAs(PP_Resource res) { |
| 142 // Short-circuit if null resource. | 125 // Short-circuit if null resource. |
| 143 if (!res) | 126 if (!res) |
| 144 return NULL; | 127 return NULL; |
| 145 | 128 |
| 146 // Adopt the resource. | 129 // Adopt the resource with 1 browser-side refcount. |
| 147 return PluginResourceTracker::Get()->AdoptBrowserResource<T>(res); | 130 const size_t browser_refcount = 1; |
| 131 return PluginResourceTracker::Get()->AdoptBrowserResource<T>( |
| 132 res, browser_refcount); |
| 133 } |
| 134 |
| 135 template<typename T> |
| 136 scoped_refptr<T> PluginResource::AdoptAsWithNoBrowserCount(PP_Resource res) { |
| 137 // Short-circuit if null resource. |
| 138 if (!res) |
| 139 return NULL; |
| 140 |
| 141 // Adopt the resource with 0 browser-side refcount. |
| 142 const size_t browser_refcount = 0; |
| 143 return PluginResourceTracker::Get()->AdoptBrowserResource<T>( |
| 144 res, browser_refcount); |
| 148 } | 145 } |
| 149 | 146 |
| 150 } // namespace ppapi_proxy | 147 } // namespace ppapi_proxy |
| 151 | 148 |
| 152 #endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_RESOURCE_H_ | 149 #endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_RESOURCE_H_ |
| 153 | 150 |
| OLD | NEW |