Index: ppapi/native_client/src/shared/ppapi_proxy/plugin_resource.h |
=================================================================== |
--- ppapi/native_client/src/shared/ppapi_proxy/plugin_resource.h (revision 0) |
+++ ppapi/native_client/src/shared/ppapi_proxy/plugin_resource.h (revision 0) |
@@ -0,0 +1,149 @@ |
+// Copyright (c) 2011 The Native Client 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 NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_RESOURCE_H_ |
+#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_RESOURCE_H_ |
+ |
+#include "native_client/src/include/nacl_base.h" |
+#include "native_client/src/include/ref_counted.h" |
+#include "native_client/src/shared/ppapi_proxy/plugin_resource_tracker.h" |
+#include "ppapi/c/pp_resource.h" |
+ |
+namespace ppapi_proxy { |
+ |
+// If you inherit from resource, make sure you add the class name here. |
+#define FOR_ALL_RESOURCES(F) \ |
+ F(PluginAudio) \ |
+ F(PluginAudioConfig) \ |
+ F(PluginBuffer) \ |
+ F(PluginFont) \ |
+ F(PluginGraphics2D) \ |
+ F(PluginGraphics3D) \ |
+ F(PluginImageData) \ |
+ F(PluginInputEvent) |
+ |
+// Forward declaration of PluginResource classes. |
+#define DECLARE_RESOURCE_CLASS(RESOURCE) class RESOURCE; |
+FOR_ALL_RESOURCES(DECLARE_RESOURCE_CLASS) |
+#undef DECLARE_RESOURCE_CLASS |
+ |
+class PluginResource : public nacl::RefCounted<PluginResource> { |
+ public: |
+ PluginResource(); |
+ virtual ~PluginResource(); |
+ |
+ // Returns NULL if the resource is invalid or is a different type. |
+ template<typename T> |
+ static scoped_refptr<T> GetAs(PP_Resource res) { |
+ // See if we have the resource cached. |
+ scoped_refptr<PluginResource> resource = |
+ PluginResourceTracker::Get()->GetExistingResource(res); |
+ |
+ return resource ? resource->Cast<T>() : NULL; |
+ } |
+ |
+ // Adopt the given PP_Resource as type T. Use this function for resources that |
+ // the browser provides to the plugin with an incremented ref count (i.e., |
+ // calls AddRefResource); it initializes the browser refcount to 1 or |
+ // increments it if the resource already exists. |
+ // Returns NULL if the resource is invalid or is a different type. |
+ template<typename T> |
+ static scoped_refptr<T> AdoptAs(PP_Resource res); |
+ |
+ // Adopt the given PP_Resource as type T. Use this function for resources |
+ // when the browser drops the refcount immediately. These resources are |
+ // typically meant to be cached on the plugin side, with little or no |
+ // interaction back to the browser. For an example, see PluginInputEvent. |
+ // This is like AdoptAs above, except it initializes the browser_refcount to |
+ // 0 for resources that are new to the plugin, and does not increment the |
+ // browser_refcount for resources that exist. |
+ // Returns NULL if the resource is invalid or is a different type. |
+ template<typename T> |
+ static scoped_refptr<T> AdoptAsWithNoBrowserCount(PP_Resource res); |
+ |
+ // Cast the resource into a specified type. This will return NULL if the |
+ // resource does not match the specified type. Specializations of this |
+ // template call into As* functions. |
+ template <typename T> T* Cast() { return NULL; } |
+ |
+ protected: |
+ virtual bool InitFromBrowserResource(PP_Resource resource) = 0; |
+ |
+ 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() |
+ // function. |
+ #define DEFINE_TYPE_GETTER(RESOURCE) \ |
+ virtual RESOURCE* As##RESOURCE() { return NULL; } |
+ FOR_ALL_RESOURCES(DEFINE_TYPE_GETTER) |
+ #undef DEFINE_TYPE_GETTER |
+ |
+ // Call this macro in the derived class declaration to actually implement the |
+ // type getter. |
+ #define IMPLEMENT_RESOURCE(RESOURCE) \ |
+ virtual RESOURCE* As##RESOURCE() { return this; } |
+ |
+ DISALLOW_COPY_AND_ASSIGN(PluginResource); |
+}; |
+ |
+// Cast() specializations. |
+#define DEFINE_RESOURCE_CAST(Type) \ |
+ template <> inline Type* PluginResource::Cast<Type>() { \ |
+ return As##Type(); \ |
+ } |
+ |
+FOR_ALL_RESOURCES(DEFINE_RESOURCE_CAST) |
+#undef DEFINE_RESOURCE_CAST |
+ |
+#undef FOR_ALL_RESOURCES |
+ |
+template<typename T> scoped_refptr<T> |
+PluginResourceTracker::AdoptBrowserResource(PP_Resource res, |
+ size_t browser_refcount) { |
+ ResourceMap::iterator result = live_resources_.find(res); |
+ // Do we have it already? |
+ if (result == live_resources_.end()) { |
+ // No - try to create a new one. |
+ scoped_refptr<T> new_resource = new T(); |
+ if (new_resource->InitFromBrowserResource(res)) { |
+ AddResource(new_resource, res, browser_refcount); |
+ return new_resource; |
+ } else { |
+ return scoped_refptr<T>(); |
+ } |
+ } else { |
+ // Consume more browser refcounts (unless browser_refcount is 0). |
+ result->second.browser_refcount += browser_refcount; |
+ return result->second.resource->Cast<T>(); |
+ } |
+} |
+ |
+template<typename T> |
+scoped_refptr<T> PluginResource::AdoptAs(PP_Resource res) { |
+ // Short-circuit if null resource. |
+ if (!res) |
+ return NULL; |
+ |
+ // Adopt the resource with 1 browser-side refcount. |
+ const size_t browser_refcount = 1; |
+ return PluginResourceTracker::Get()->AdoptBrowserResource<T>( |
+ res, browser_refcount); |
+} |
+ |
+template<typename T> |
+scoped_refptr<T> PluginResource::AdoptAsWithNoBrowserCount(PP_Resource res) { |
+ // Short-circuit if null resource. |
+ if (!res) |
+ return NULL; |
+ |
+ // Adopt the resource with 0 browser-side refcount. |
+ const size_t browser_refcount = 0; |
+ return PluginResourceTracker::Get()->AdoptBrowserResource<T>( |
+ res, browser_refcount); |
+} |
+ |
+} // namespace ppapi_proxy |
+ |
+#endif // NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PLUGIN_RESOURCE_H_ |
+ |