OLD | NEW |
| (Empty) |
1 // Copyright 2012 The Chromium 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 CC_RESOURCE_PROVIDER_H_ | |
6 #define CC_RESOURCE_PROVIDER_H_ | |
7 | |
8 #include <deque> | |
9 #include <set> | |
10 #include <string> | |
11 #include <vector> | |
12 | |
13 #include "base/basictypes.h" | |
14 #include "base/callback.h" | |
15 #include "base/hash_tables.h" | |
16 #include "base/memory/scoped_ptr.h" | |
17 #include "base/threading/thread_checker.h" | |
18 #include "cc/base/cc_export.h" | |
19 #include "cc/output/context_provider.h" | |
20 #include "cc/output/output_surface.h" | |
21 #include "cc/output/texture_copier.h" | |
22 #include "cc/texture_mailbox.h" | |
23 #include "cc/transferable_resource.h" | |
24 #include "third_party/khronos/GLES2/gl2.h" | |
25 #include "third_party/skia/include/core/SkBitmap.h" | |
26 #include "third_party/skia/include/core/SkCanvas.h" | |
27 #include "ui/gfx/size.h" | |
28 | |
29 namespace WebKit { | |
30 class WebGraphicsContext3D; | |
31 } | |
32 | |
33 namespace gfx { | |
34 class Rect; | |
35 class Vector2d; | |
36 } | |
37 | |
38 namespace cc { | |
39 class TextureUploader; | |
40 | |
41 // This class is not thread-safe and can only be called from the thread it was | |
42 // created on (in practice, the impl thread). | |
43 class CC_EXPORT ResourceProvider { | |
44 public: | |
45 typedef unsigned ResourceId; | |
46 typedef std::vector<ResourceId> ResourceIdArray; | |
47 typedef std::set<ResourceId> ResourceIdSet; | |
48 typedef base::hash_map<ResourceId, ResourceId> ResourceIdMap; | |
49 enum TextureUsageHint { | |
50 TextureUsageAny, | |
51 TextureUsageFramebuffer, | |
52 }; | |
53 enum ResourceType { | |
54 GLTexture = 1, | |
55 Bitmap, | |
56 }; | |
57 | |
58 static scoped_ptr<ResourceProvider> Create(OutputSurface* output_surface); | |
59 | |
60 virtual ~ResourceProvider(); | |
61 | |
62 WebKit::WebGraphicsContext3D* GraphicsContext3D(); | |
63 TextureCopier* texture_copier() const { return texture_copier_.get(); } | |
64 int max_texture_size() const { return max_texture_size_; } | |
65 GLenum best_texture_format() const { return best_texture_format_; } | |
66 unsigned num_resources() const { return resources_.size(); } | |
67 | |
68 // Checks whether a resource is in use by a consumer. | |
69 bool InUseByConsumer(ResourceId id); | |
70 | |
71 | |
72 // Producer interface. | |
73 | |
74 void set_default_resource_type(ResourceType type) { | |
75 default_resource_type_ = type; | |
76 } | |
77 ResourceType default_resource_type() const { return default_resource_type_; } | |
78 ResourceType GetResourceType(ResourceId id); | |
79 | |
80 // Creates a resource of the default resource type. | |
81 ResourceId CreateResource(gfx::Size size, | |
82 GLenum format, | |
83 TextureUsageHint hint); | |
84 | |
85 // Creates a resource which is tagged as being managed for GPU memory | |
86 // accounting purposes. | |
87 ResourceId CreateManagedResource(gfx::Size size, | |
88 GLenum format, | |
89 TextureUsageHint hint); | |
90 | |
91 // You can also explicitly create a specific resource type. | |
92 ResourceId CreateGLTexture(gfx::Size size, | |
93 GLenum format, | |
94 GLenum texture_pool, | |
95 TextureUsageHint hint); | |
96 | |
97 ResourceId CreateBitmap(gfx::Size size); | |
98 // Wraps an external texture into a GL resource. | |
99 ResourceId CreateResourceFromExternalTexture(unsigned texture_id); | |
100 | |
101 // Wraps an external texture mailbox into a GL resource. | |
102 ResourceId CreateResourceFromTextureMailbox(const TextureMailbox& mailbox); | |
103 | |
104 void DeleteResource(ResourceId id); | |
105 | |
106 // Update pixels from image, copying source_rect (in image) to dest_offset (in | |
107 // the resource). | |
108 void SetPixels(ResourceId id, | |
109 const uint8_t* image, | |
110 gfx::Rect image_rect, | |
111 gfx::Rect source_rect, | |
112 gfx::Vector2d dest_offset); | |
113 | |
114 // Check upload status. | |
115 size_t NumBlockingUploads(); | |
116 void MarkPendingUploadsAsNonBlocking(); | |
117 double EstimatedUploadsPerSecond(); | |
118 void FlushUploads(); | |
119 void ReleaseCachedData(); | |
120 | |
121 // Flush all context operations, kicking uploads and ensuring ordering with | |
122 // respect to other contexts. | |
123 void Flush(); | |
124 | |
125 // Only flush the command buffer if supported. | |
126 // Returns true if the shallow flush occurred, false otherwise. | |
127 bool ShallowFlushIfSupported(); | |
128 | |
129 // Creates accounting for a child. Returns a child ID. | |
130 int CreateChild(); | |
131 | |
132 // Destroys accounting for the child, deleting all accounted resources. | |
133 void DestroyChild(int child); | |
134 | |
135 // Gets the child->parent resource ID map. | |
136 const ResourceIdMap& GetChildToParentMap(int child) const; | |
137 | |
138 // Prepares resources to be transfered to the parent, moving them to | |
139 // mailboxes and serializing meta-data into TransferableResources. | |
140 // Resources are not removed from the ResourceProvider, but are marked as | |
141 // "in use". | |
142 void PrepareSendToParent(const ResourceIdArray& resources, | |
143 TransferableResourceArray* transferable_resources); | |
144 | |
145 // Prepares resources to be transfered back to the child, moving them to | |
146 // mailboxes and serializing meta-data into TransferableResources. | |
147 // Resources are removed from the ResourceProvider. Note: the resource IDs | |
148 // passed are in the parent namespace and will be translated to the child | |
149 // namespace when returned. | |
150 void PrepareSendToChild(int child, | |
151 const ResourceIdArray& resources, | |
152 TransferableResourceArray* transferable_resources); | |
153 | |
154 // Receives resources from a child, moving them from mailboxes. Resource IDs | |
155 // passed are in the child namespace, and will be translated to the parent | |
156 // namespace, added to the child->parent map. | |
157 // NOTE: if the sync_point is set on any TransferableResource, this will | |
158 // wait on it. | |
159 void ReceiveFromChild( | |
160 int child, const TransferableResourceArray& transferable_resources); | |
161 | |
162 // Receives resources from the parent, moving them from mailboxes. Resource | |
163 // IDs passed are in the child namespace. | |
164 // NOTE: if the sync_point is set on any TransferableResource, this will | |
165 // wait on it. | |
166 void ReceiveFromParent( | |
167 const TransferableResourceArray& transferable_resources); | |
168 | |
169 // Bind the given GL resource to a texture target for sampling using the | |
170 // specified filter for both minification and magnification. The resource | |
171 // must be locked for reading. | |
172 void BindForSampling(ResourceProvider::ResourceId resource_id, | |
173 GLenum target, | |
174 GLenum filter); | |
175 | |
176 // The following lock classes are part of the ResourceProvider API and are | |
177 // needed to read and write the resource contents. The user must ensure | |
178 // that they only use GL locks on GL resources, etc, and this is enforced | |
179 // by assertions. | |
180 class CC_EXPORT ScopedReadLockGL { | |
181 public: | |
182 ScopedReadLockGL(ResourceProvider* resource_provider, | |
183 ResourceProvider::ResourceId resource_id); | |
184 ~ScopedReadLockGL(); | |
185 | |
186 unsigned texture_id() const { return texture_id_; } | |
187 | |
188 private: | |
189 ResourceProvider* resource_provider_; | |
190 ResourceProvider::ResourceId resource_id_; | |
191 unsigned texture_id_; | |
192 | |
193 DISALLOW_COPY_AND_ASSIGN(ScopedReadLockGL); | |
194 }; | |
195 | |
196 class CC_EXPORT ScopedSamplerGL : public ScopedReadLockGL { | |
197 public: | |
198 ScopedSamplerGL(ResourceProvider* resource_provider, | |
199 ResourceProvider::ResourceId resource_id, | |
200 GLenum target, | |
201 GLenum filter); | |
202 | |
203 private: | |
204 DISALLOW_COPY_AND_ASSIGN(ScopedSamplerGL); | |
205 }; | |
206 | |
207 class CC_EXPORT ScopedWriteLockGL { | |
208 public: | |
209 ScopedWriteLockGL(ResourceProvider* resource_provider, | |
210 ResourceProvider::ResourceId resource_id); | |
211 ~ScopedWriteLockGL(); | |
212 | |
213 unsigned texture_id() const { return texture_id_; } | |
214 | |
215 private: | |
216 ResourceProvider* resource_provider_; | |
217 ResourceProvider::ResourceId resource_id_; | |
218 unsigned texture_id_; | |
219 | |
220 DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockGL); | |
221 }; | |
222 | |
223 class CC_EXPORT ScopedReadLockSoftware { | |
224 public: | |
225 ScopedReadLockSoftware(ResourceProvider* resource_provider, | |
226 ResourceProvider::ResourceId resource_id); | |
227 ~ScopedReadLockSoftware(); | |
228 | |
229 const SkBitmap* sk_bitmap() const { return &sk_bitmap_; } | |
230 | |
231 private: | |
232 ResourceProvider* resource_provider_; | |
233 ResourceProvider::ResourceId resource_id_; | |
234 SkBitmap sk_bitmap_; | |
235 | |
236 DISALLOW_COPY_AND_ASSIGN(ScopedReadLockSoftware); | |
237 }; | |
238 | |
239 class CC_EXPORT ScopedWriteLockSoftware { | |
240 public: | |
241 ScopedWriteLockSoftware(ResourceProvider* resource_provider, | |
242 ResourceProvider::ResourceId resource_id); | |
243 ~ScopedWriteLockSoftware(); | |
244 | |
245 SkCanvas* sk_canvas() { return sk_canvas_.get(); } | |
246 | |
247 private: | |
248 ResourceProvider* resource_provider_; | |
249 ResourceProvider::ResourceId resource_id_; | |
250 SkBitmap sk_bitmap_; | |
251 scoped_ptr<SkCanvas> sk_canvas_; | |
252 | |
253 DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockSoftware); | |
254 }; | |
255 | |
256 class Fence : public base::RefCounted<Fence> { | |
257 public: | |
258 Fence() {} | |
259 virtual bool HasPassed() = 0; | |
260 | |
261 protected: | |
262 friend class base::RefCounted<Fence>; | |
263 virtual ~Fence() {} | |
264 | |
265 DISALLOW_COPY_AND_ASSIGN(Fence); | |
266 }; | |
267 | |
268 // Acquire pixel buffer for resource. The pixel buffer can be used to | |
269 // set resource pixels without performing unnecessary copying. | |
270 void AcquirePixelBuffer(ResourceId id); | |
271 void ReleasePixelBuffer(ResourceId id); | |
272 | |
273 // Map/unmap the acquired pixel buffer. | |
274 uint8_t* MapPixelBuffer(ResourceId id); | |
275 void UnmapPixelBuffer(ResourceId id); | |
276 | |
277 // Update pixels from acquired pixel buffer. | |
278 void SetPixelsFromBuffer(ResourceId id); | |
279 | |
280 // Asynchronously update pixels from acquired pixel buffer. | |
281 void BeginSetPixels(ResourceId id); | |
282 void ForceSetPixelsToComplete(ResourceId id); | |
283 bool DidSetPixelsComplete(ResourceId id); | |
284 void AbortSetPixels(ResourceId id); | |
285 | |
286 // For tests only! This prevents detecting uninitialized reads. | |
287 // Use SetPixels or LockForWrite to allocate implicitly. | |
288 void AllocateForTesting(ResourceId id); | |
289 | |
290 // Sets the current read fence. If a resource is locked for read | |
291 // and has read fences enabled, the resource will not allow writes | |
292 // until this fence has passed. | |
293 void SetReadLockFence(scoped_refptr<Fence> fence) { | |
294 current_read_lock_fence_ = fence; | |
295 } | |
296 Fence* GetReadLockFence() { return current_read_lock_fence_; } | |
297 | |
298 // Enable read lock fences for a specific resource. | |
299 void EnableReadLockFences(ResourceProvider::ResourceId id, bool enable); | |
300 | |
301 // Indicates if we can currently lock this resource for write. | |
302 bool CanLockForWrite(ResourceId id); | |
303 | |
304 cc::ContextProvider* offscreen_context_provider() { | |
305 return offscreen_context_provider_.get(); | |
306 } | |
307 void set_offscreen_context_provider( | |
308 scoped_refptr<cc::ContextProvider> offscreen_context_provider) { | |
309 offscreen_context_provider_ = offscreen_context_provider; | |
310 } | |
311 | |
312 private: | |
313 struct Resource { | |
314 Resource(); | |
315 ~Resource(); | |
316 Resource(unsigned texture_id, gfx::Size size, GLenum format, GLenum filter); | |
317 Resource(uint8_t* pixels, gfx::Size size, GLenum format, GLenum filter); | |
318 | |
319 unsigned gl_id; | |
320 // Pixel buffer used for set pixels without unnecessary copying. | |
321 unsigned gl_pixel_buffer_id; | |
322 // Query used to determine when asynchronous set pixels complete. | |
323 unsigned gl_upload_query_id; | |
324 TextureMailbox mailbox; | |
325 uint8_t* pixels; | |
326 uint8_t* pixel_buffer; | |
327 int lock_for_read_count; | |
328 bool locked_for_write; | |
329 bool external; | |
330 bool exported; | |
331 bool marked_for_deletion; | |
332 bool pending_set_pixels; | |
333 bool set_pixels_completion_forced; | |
334 bool allocated; | |
335 bool enable_read_lock_fences; | |
336 scoped_refptr<Fence> read_lock_fence; | |
337 gfx::Size size; | |
338 GLenum format; | |
339 // TODO(skyostil): Use a separate sampler object for filter state. | |
340 GLenum filter; | |
341 ResourceType type; | |
342 }; | |
343 typedef base::hash_map<ResourceId, Resource> ResourceMap; | |
344 struct Child { | |
345 Child(); | |
346 ~Child(); | |
347 | |
348 ResourceIdMap child_to_parent_map; | |
349 ResourceIdMap parent_to_child_map; | |
350 }; | |
351 typedef base::hash_map<int, Child> ChildMap; | |
352 | |
353 bool ReadLockFenceHasPassed(Resource* resource) { | |
354 return !resource->read_lock_fence || | |
355 resource->read_lock_fence->HasPassed(); | |
356 } | |
357 | |
358 explicit ResourceProvider(OutputSurface* output_surface); | |
359 bool Initialize(); | |
360 | |
361 const Resource* LockForRead(ResourceId id); | |
362 void UnlockForRead(ResourceId id); | |
363 const Resource* LockForWrite(ResourceId id); | |
364 void UnlockForWrite(ResourceId id); | |
365 static void PopulateSkBitmapWithResource(SkBitmap* sk_bitmap, | |
366 const Resource* resource); | |
367 | |
368 bool TransferResource(WebKit::WebGraphicsContext3D* context, | |
369 ResourceId id, | |
370 TransferableResource* resource); | |
371 void DeleteResourceInternal(ResourceMap::iterator it); | |
372 void LazyAllocate(Resource* resource); | |
373 | |
374 OutputSurface* output_surface_; | |
375 ResourceId next_id_; | |
376 ResourceMap resources_; | |
377 int next_child_; | |
378 ChildMap children_; | |
379 | |
380 ResourceType default_resource_type_; | |
381 bool use_texture_storage_ext_; | |
382 bool use_texture_usage_hint_; | |
383 bool use_shallow_flush_; | |
384 scoped_ptr<TextureUploader> texture_uploader_; | |
385 scoped_ptr<AcceleratedTextureCopier> texture_copier_; | |
386 int max_texture_size_; | |
387 GLenum best_texture_format_; | |
388 | |
389 scoped_refptr<cc::ContextProvider> offscreen_context_provider_; | |
390 | |
391 base::ThreadChecker thread_checker_; | |
392 | |
393 scoped_refptr<Fence> current_read_lock_fence_; | |
394 | |
395 DISALLOW_COPY_AND_ASSIGN(ResourceProvider); | |
396 }; | |
397 | |
398 } | |
399 | |
400 #endif // CC_RESOURCE_PROVIDER_H_ | |
OLD | NEW |