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 |