| OLD | NEW |
| 1 // Copyright (c) 2010 The Native Client Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "ppapi/c/pp_resource.h" | 11 #include "ppapi/c/pp_resource.h" |
| 12 | 12 |
| 13 namespace ppapi_proxy { | 13 namespace ppapi_proxy { |
| 14 | 14 |
| 15 class PluginModule; | |
| 16 | |
| 17 // 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. |
| 18 #define FOR_ALL_RESOURCES(F) \ | 16 #define FOR_ALL_RESOURCES(F) \ |
| 19 F(Audio) \ | 17 F(PluginAudio) \ |
| 20 F(AudioConfig) \ | 18 F(PluginAudioConfig) \ |
| 21 F(Buffer) \ | 19 F(PluginBuffer) \ |
| 22 F(Graphics2D) \ | 20 F(PluginGraphics2D) \ |
| 23 F(Graphics3D) \ | 21 F(PluginGraphics3D) \ |
| 24 F(ImageData) | 22 F(PluginImageData) |
| 25 | 23 |
| 26 // Forward declaration of PluginResource classes. | 24 // Forward declaration of PluginResource classes. |
| 27 #define DECLARE_RESOURCE_CLASS(RESOURCE) class RESOURCE; | 25 #define DECLARE_RESOURCE_CLASS(RESOURCE) class RESOURCE; |
| 28 FOR_ALL_RESOURCES(DECLARE_RESOURCE_CLASS) | 26 FOR_ALL_RESOURCES(DECLARE_RESOURCE_CLASS) |
| 29 #undef DECLARE_RESOURCE_CLASS | 27 #undef DECLARE_RESOURCE_CLASS |
| 30 | 28 |
| 31 class PluginResource : public nacl::RefCounted<PluginResource> { | 29 class PluginResource : public nacl::RefCounted<PluginResource> { |
| 32 public: | 30 public: |
| 33 explicit PluginResource(PluginModule* module); | 31 PluginResource(); |
| 34 virtual ~PluginResource(); | 32 virtual ~PluginResource(); |
| 35 | 33 |
| 36 // Returns NULL if the resource is invalid or is a different type. | 34 // Returns NULL if the resource is invalid or is a different type. |
| 37 template<typename T> | 35 template<typename T> |
| 38 static scoped_refptr<T> GetAs(PP_Resource res) { | 36 static scoped_refptr<T> GetAs(PP_Resource res) { |
| 37 // See if we have the resource cached. |
| 39 scoped_refptr<PluginResource> resource = | 38 scoped_refptr<PluginResource> resource = |
| 40 PluginResourceTracker::Get()->GetResource(res); | 39 PluginResourceTracker::Get()->GetExistingResource(res); |
| 40 |
| 41 return resource ? resource->Cast<T>() : NULL; | 41 return resource ? resource->Cast<T>() : NULL; |
| 42 } | 42 } |
| 43 | 43 |
| 44 PluginModule* module() const { return module_; } | 44 // Returns NULL if the resource is invalid or is a different type. |
| 45 template<typename T> |
| 46 static scoped_refptr<T> AdoptAs(PP_Resource res); |
| 45 | 47 |
| 46 // Cast the resource into a specified type. This will return NULL if the | 48 // Cast the resource into a specified type. This will return NULL if the |
| 47 // resource does not match the specified type. Specializations of this | 49 // resource does not match the specified type. Specializations of this |
| 48 // template call into As* functions. | 50 // template call into As* functions. |
| 49 template <typename T> T* Cast() { return NULL; } | 51 template <typename T> T* Cast() { return NULL; } |
| 50 | 52 |
| 51 // Returns an resource id of this object. If the object doesn't have a | 53 // Returns an resource id of this object. If the object doesn't have a |
| 52 // resource id, new one is created with plugin refcount of 1. If it does, | 54 // resource id, new one is created with plugin refcount of 1. If it does, |
| 53 // the refcount is incremented. Use this when you need to return a new | 55 // the refcount is incremented. Use this when you need to return a new |
| 54 // reference to the plugin. | 56 // reference to the plugin. |
| 55 PP_Resource GetReference(); | 57 PP_Resource GetReference(); |
| 56 | 58 |
| 57 // When you need to ensure that a resource has a reference, but you do not | 59 // When you need to ensure that a resource has a reference, but you do not |
| 58 // want to increase the refcount (for example, if you need to call a plugin | 60 // want to increase the refcount (for example, if you need to call a plugin |
| 59 // callback function with a reference), you can use this class. For example: | 61 // callback function with a reference), you can use this class. For example: |
| 60 // | 62 // |
| 61 // plugin_callback(.., ScopedResourceId(resource).id, ...); | 63 // plugin_callback(.., ScopedResourceId(resource).id, ...); |
| 62 class ScopedResourceId { | 64 class ScopedResourceId { |
| 63 public: | 65 public: |
| 64 explicit ScopedResourceId(PluginResource* resource) | 66 explicit ScopedResourceId(PluginResource* resource) |
| 65 : id(resource->GetReference()) {} | 67 : id(resource->GetReference()) {} |
| 66 ~ScopedResourceId() { | 68 ~ScopedResourceId() { |
| 67 PluginResourceTracker::Get()->UnrefResource(id); | 69 PluginResourceTracker::Get()->UnrefResource(id); |
| 68 } | 70 } |
| 69 const PP_Resource id; | 71 const PP_Resource id; |
| 70 }; | 72 }; |
| 71 | 73 |
| 74 protected: |
| 75 virtual bool InitFromBrowserResource(PP_Resource resource) = 0; |
| 76 |
| 72 private: | 77 private: |
| 73 // Type-specific getters for individual resource types. These will return | 78 // Type-specific getters for individual resource types. These will return |
| 74 // NULL if the resource does not match the specified type. Used by the Cast() | 79 // NULL if the resource does not match the specified type. Used by the Cast() |
| 75 // function. | 80 // function. |
| 76 #define DEFINE_TYPE_GETTER(RESOURCE) \ | 81 #define DEFINE_TYPE_GETTER(RESOURCE) \ |
| 77 virtual RESOURCE* As##RESOURCE() { return NULL; } | 82 virtual RESOURCE* As##RESOURCE() { return NULL; } |
| 78 FOR_ALL_RESOURCES(DEFINE_TYPE_GETTER) | 83 FOR_ALL_RESOURCES(DEFINE_TYPE_GETTER) |
| 79 #undef DEFINE_TYPE_GETTER | 84 #undef DEFINE_TYPE_GETTER |
| 80 | 85 |
| 81 // Call this macro in the derived class declaration to actually implement the | 86 // Call this macro in the derived class declaration to actually implement the |
| 82 // type getter. | 87 // type getter. |
| 83 #define IMPLEMENT_RESOURCE(RESOURCE) \ | 88 #define IMPLEMENT_RESOURCE(RESOURCE) \ |
| 84 virtual RESOURCE* As##RESOURCE() { return this; } | 89 virtual RESOURCE* As##RESOURCE() { return this; } |
| 85 | 90 |
| 86 private: | |
| 87 // If referenced by a plugin, holds the id of this resource object. Do not | 91 // If referenced by a plugin, holds the id of this resource object. Do not |
| 88 // access this member directly, because it is possible that the plugin holds | 92 // access this member directly, because it is possible that the plugin holds |
| 89 // no references to the object, and therefore the resource_id_ is zero. Use | 93 // no references to the object, and therefore the resource_id_ is zero. Use |
| 90 // either GetReference() to obtain a new resource_id and increase the | 94 // either GetReference() to obtain a new resource_id and increase the |
| 91 // refcount, or TemporaryReference when you do not want to increase the | 95 // refcount, or TemporaryReference when you do not want to increase the |
| 92 // refcount. | 96 // refcount. |
| 93 PP_Resource resource_id_; | 97 PP_Resource resource_id_; |
| 94 | 98 |
| 95 // Non-owning pointer to our module. | |
| 96 PluginModule* module_; | |
| 97 | |
| 98 // Called by the resource tracker when the last plugin reference has been | 99 // Called by the resource tracker when the last plugin reference has been |
| 99 // dropped. | 100 // dropped. You cannot use resource_id_ after this function is called! |
| 100 friend class PluginResourceTracker; | 101 friend class PluginResourceTracker; |
| 101 void StoppedTracking(); | 102 void StoppedTracking(); |
| 102 | 103 |
| 103 DISALLOW_COPY_AND_ASSIGN(PluginResource); | 104 DISALLOW_COPY_AND_ASSIGN(PluginResource); |
| 104 }; | 105 }; |
| 105 | 106 |
| 106 // Cast() specializations. | 107 // Cast() specializations. |
| 107 #define DEFINE_RESOURCE_CAST(Type) \ | 108 #define DEFINE_RESOURCE_CAST(Type) \ |
| 108 template <> inline Type* PluginResource::Cast<Type>() { \ | 109 template <> inline Type* PluginResource::Cast<Type>() { \ |
| 109 return As##Type(); \ | 110 return As##Type(); \ |
| 110 } | 111 } |
| 111 | 112 |
| 112 FOR_ALL_RESOURCES(DEFINE_RESOURCE_CAST) | 113 FOR_ALL_RESOURCES(DEFINE_RESOURCE_CAST) |
| 113 #undef DEFINE_RESOURCE_CAST | 114 #undef DEFINE_RESOURCE_CAST |
| 114 | 115 |
| 115 #undef FOR_ALL_RESOURCES | 116 #undef FOR_ALL_RESOURCES |
| 117 |
| 118 template<typename T> scoped_refptr<T> |
| 119 PluginResourceTracker::AdoptBrowserResource(PP_Resource res) { |
| 120 ResourceMap::iterator result = live_resources_.find(res); |
| 121 // Do we have it already? |
| 122 if (result == live_resources_.end()) { |
| 123 // No - try to create a new one. |
| 124 scoped_refptr<T> new_resource = new T(); |
| 125 if (new_resource->InitFromBrowserResource(res)) { |
| 126 AddResource(new_resource, res); |
| 127 return new_resource; |
| 128 } else { |
| 129 return scoped_refptr<T>(); |
| 130 } |
| 131 } else { |
| 132 // Consume one more browser refcount. |
| 133 ++result->second.browser_refcount; |
| 134 return result->second.resource->Cast<T>(); |
| 135 } |
| 136 } |
| 137 |
| 138 template<typename T> |
| 139 scoped_refptr<T> PluginResource::AdoptAs(PP_Resource res) { |
| 140 // Short-circuit if null resource. |
| 141 if (!res) |
| 142 return NULL; |
| 143 |
| 144 // Adopt the resource. |
| 145 return PluginResourceTracker::Get()->AdoptBrowserResource<T>(res); |
| 146 } |
| 147 |
| 116 } // namespace ppapi_proxy | 148 } // namespace ppapi_proxy |
| 117 | 149 |
| 118 #endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_RESOURCE_H_ | 150 #endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_RESOURCE_H_ |
| 119 | 151 |
| OLD | NEW |