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