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.
5 #ifndef CC_RESOURCES_RESOURCE_PROVIDER_H_
6 #define CC_RESOURCES_RESOURCE_PROVIDER_H_
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/resources/texture_mailbox.h"
23 #include "cc/resources/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"
30 class WebGraphicsContext3D
;
39 class TextureUploader
;
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
{
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
{
51 TextureUsageFramebuffer
,
58 static scoped_ptr
<ResourceProvider
> Create(OutputSurface
* output_surface
,
59 int highp_threshold_min
);
61 virtual ~ResourceProvider();
63 WebKit::WebGraphicsContext3D
* GraphicsContext3D();
64 TextureCopier
* texture_copier() const { return texture_copier_
.get(); }
65 int max_texture_size() const { return max_texture_size_
; }
66 GLenum
best_texture_format() const { return best_texture_format_
; }
67 unsigned num_resources() const { return resources_
.size(); }
69 // Checks whether a resource is in use by a consumer.
70 bool InUseByConsumer(ResourceId id
);
73 // Producer interface.
75 void set_default_resource_type(ResourceType type
) {
76 default_resource_type_
= type
;
78 ResourceType
default_resource_type() const { return default_resource_type_
; }
79 ResourceType
GetResourceType(ResourceId id
);
81 // Creates a resource of the default resource type.
82 ResourceId
CreateResource(gfx::Size size
,
84 TextureUsageHint hint
);
86 // Creates a resource which is tagged as being managed for GPU memory
87 // accounting purposes.
88 ResourceId
CreateManagedResource(gfx::Size size
,
90 TextureUsageHint hint
);
92 // You can also explicitly create a specific resource type.
93 ResourceId
CreateGLTexture(gfx::Size size
,
96 TextureUsageHint hint
);
98 ResourceId
CreateBitmap(gfx::Size size
);
99 // Wraps an external texture into a GL resource.
100 ResourceId
CreateResourceFromExternalTexture(unsigned texture_id
);
102 // Wraps an external texture mailbox into a GL resource.
103 ResourceId
CreateResourceFromTextureMailbox(const TextureMailbox
& mailbox
);
105 void DeleteResource(ResourceId id
);
107 // Update pixels from image, copying source_rect (in image) to dest_offset (in
109 void SetPixels(ResourceId id
,
110 const uint8_t* image
,
111 gfx::Rect image_rect
,
112 gfx::Rect source_rect
,
113 gfx::Vector2d dest_offset
);
115 // Check upload status.
116 size_t NumBlockingUploads();
117 void MarkPendingUploadsAsNonBlocking();
118 double EstimatedUploadsPerSecond();
120 void ReleaseCachedData();
122 // Flush all context operations, kicking uploads and ensuring ordering with
123 // respect to other contexts.
126 // Only flush the command buffer if supported.
127 // Returns true if the shallow flush occurred, false otherwise.
128 bool ShallowFlushIfSupported();
130 // Creates accounting for a child. Returns a child ID.
133 // Destroys accounting for the child, deleting all accounted resources.
134 void DestroyChild(int child
);
136 // Gets the child->parent resource ID map.
137 const ResourceIdMap
& GetChildToParentMap(int child
) const;
139 // Prepares resources to be transfered to the parent, moving them to
140 // mailboxes and serializing meta-data into TransferableResources.
141 // Resources are not removed from the ResourceProvider, but are marked as
143 void PrepareSendToParent(const ResourceIdArray
& resources
,
144 TransferableResourceArray
* transferable_resources
);
146 // Prepares resources to be transfered back to the child, moving them to
147 // mailboxes and serializing meta-data into TransferableResources.
148 // Resources are removed from the ResourceProvider. Note: the resource IDs
149 // passed are in the parent namespace and will be translated to the child
150 // namespace when returned.
151 void PrepareSendToChild(int child
,
152 const ResourceIdArray
& resources
,
153 TransferableResourceArray
* transferable_resources
);
155 // Receives resources from a child, moving them from mailboxes. Resource IDs
156 // passed are in the child namespace, and will be translated to the parent
157 // namespace, added to the child->parent map.
158 // NOTE: if the sync_point is set on any TransferableResource, this will
160 void ReceiveFromChild(
161 int child
, const TransferableResourceArray
& transferable_resources
);
163 // Receives resources from the parent, moving them from mailboxes. Resource
164 // IDs passed are in the child namespace.
165 // NOTE: if the sync_point is set on any TransferableResource, this will
167 void ReceiveFromParent(
168 const TransferableResourceArray
& transferable_resources
);
170 // Bind the given GL resource to a texture target for sampling using the
171 // specified filter for both minification and magnification. The resource
172 // must be locked for reading.
173 void BindForSampling(ResourceProvider::ResourceId resource_id
,
177 // The following lock classes are part of the ResourceProvider API and are
178 // needed to read and write the resource contents. The user must ensure
179 // that they only use GL locks on GL resources, etc, and this is enforced
181 class CC_EXPORT ScopedReadLockGL
{
183 ScopedReadLockGL(ResourceProvider
* resource_provider
,
184 ResourceProvider::ResourceId resource_id
);
187 unsigned texture_id() const { return texture_id_
; }
190 ResourceProvider
* resource_provider_
;
191 ResourceProvider::ResourceId resource_id_
;
192 unsigned texture_id_
;
194 DISALLOW_COPY_AND_ASSIGN(ScopedReadLockGL
);
197 class CC_EXPORT ScopedSamplerGL
: public ScopedReadLockGL
{
199 ScopedSamplerGL(ResourceProvider
* resource_provider
,
200 ResourceProvider::ResourceId resource_id
,
205 DISALLOW_COPY_AND_ASSIGN(ScopedSamplerGL
);
208 class CC_EXPORT ScopedWriteLockGL
{
210 ScopedWriteLockGL(ResourceProvider
* resource_provider
,
211 ResourceProvider::ResourceId resource_id
);
212 ~ScopedWriteLockGL();
214 unsigned texture_id() const { return texture_id_
; }
217 ResourceProvider
* resource_provider_
;
218 ResourceProvider::ResourceId resource_id_
;
219 unsigned texture_id_
;
221 DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockGL
);
224 class CC_EXPORT ScopedReadLockSoftware
{
226 ScopedReadLockSoftware(ResourceProvider
* resource_provider
,
227 ResourceProvider::ResourceId resource_id
);
228 ~ScopedReadLockSoftware();
230 const SkBitmap
* sk_bitmap() const { return &sk_bitmap_
; }
233 ResourceProvider
* resource_provider_
;
234 ResourceProvider::ResourceId resource_id_
;
237 DISALLOW_COPY_AND_ASSIGN(ScopedReadLockSoftware
);
240 class CC_EXPORT ScopedWriteLockSoftware
{
242 ScopedWriteLockSoftware(ResourceProvider
* resource_provider
,
243 ResourceProvider::ResourceId resource_id
);
244 ~ScopedWriteLockSoftware();
246 SkCanvas
* sk_canvas() { return sk_canvas_
.get(); }
249 ResourceProvider
* resource_provider_
;
250 ResourceProvider::ResourceId resource_id_
;
252 scoped_ptr
<SkCanvas
> sk_canvas_
;
254 DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockSoftware
);
257 class Fence
: public base::RefCounted
<Fence
> {
260 virtual bool HasPassed() = 0;
263 friend class base::RefCounted
<Fence
>;
266 DISALLOW_COPY_AND_ASSIGN(Fence
);
269 // Acquire pixel buffer for resource. The pixel buffer can be used to
270 // set resource pixels without performing unnecessary copying.
271 void AcquirePixelBuffer(ResourceId id
);
272 void ReleasePixelBuffer(ResourceId id
);
274 // Map/unmap the acquired pixel buffer.
275 uint8_t* MapPixelBuffer(ResourceId id
);
276 void UnmapPixelBuffer(ResourceId id
);
278 // Update pixels from acquired pixel buffer.
279 void SetPixelsFromBuffer(ResourceId id
);
281 // Asynchronously update pixels from acquired pixel buffer.
282 void BeginSetPixels(ResourceId id
);
283 void ForceSetPixelsToComplete(ResourceId id
);
284 bool DidSetPixelsComplete(ResourceId id
);
285 void AbortSetPixels(ResourceId id
);
287 // For tests only! This prevents detecting uninitialized reads.
288 // Use SetPixels or LockForWrite to allocate implicitly.
289 void AllocateForTesting(ResourceId id
);
291 // Sets the current read fence. If a resource is locked for read
292 // and has read fences enabled, the resource will not allow writes
293 // until this fence has passed.
294 void SetReadLockFence(scoped_refptr
<Fence
> fence
) {
295 current_read_lock_fence_
= fence
;
297 Fence
* GetReadLockFence() { return current_read_lock_fence_
; }
299 // Enable read lock fences for a specific resource.
300 void EnableReadLockFences(ResourceProvider::ResourceId id
, bool enable
);
302 // Indicates if we can currently lock this resource for write.
303 bool CanLockForWrite(ResourceId id
);
305 cc::ContextProvider
* offscreen_context_provider() {
306 return offscreen_context_provider_
.get();
308 void set_offscreen_context_provider(
309 scoped_refptr
<cc::ContextProvider
> offscreen_context_provider
) {
310 offscreen_context_provider_
= offscreen_context_provider
;
317 Resource(unsigned texture_id
, gfx::Size size
, GLenum format
, GLenum filter
);
318 Resource(uint8_t* pixels
, gfx::Size size
, GLenum format
, GLenum filter
);
321 // Pixel buffer used for set pixels without unnecessary copying.
322 unsigned gl_pixel_buffer_id
;
323 // Query used to determine when asynchronous set pixels complete.
324 unsigned gl_upload_query_id
;
325 TextureMailbox mailbox
;
327 uint8_t* pixel_buffer
;
328 int lock_for_read_count
;
329 bool locked_for_write
;
332 bool marked_for_deletion
;
333 bool pending_set_pixels
;
334 bool set_pixels_completion_forced
;
336 bool enable_read_lock_fences
;
337 scoped_refptr
<Fence
> read_lock_fence
;
340 // TODO(skyostil): Use a separate sampler object for filter state.
344 typedef base::hash_map
<ResourceId
, Resource
> ResourceMap
;
349 ResourceIdMap child_to_parent_map
;
350 ResourceIdMap parent_to_child_map
;
352 typedef base::hash_map
<int, Child
> ChildMap
;
354 bool ReadLockFenceHasPassed(Resource
* resource
) {
355 return !resource
->read_lock_fence
||
356 resource
->read_lock_fence
->HasPassed();
359 explicit ResourceProvider(OutputSurface
* output_surface
);
360 bool Initialize(int highp_threshold_min
);
362 const Resource
* LockForRead(ResourceId id
);
363 void UnlockForRead(ResourceId id
);
364 const Resource
* LockForWrite(ResourceId id
);
365 void UnlockForWrite(ResourceId id
);
366 static void PopulateSkBitmapWithResource(SkBitmap
* sk_bitmap
,
367 const Resource
* resource
);
369 bool TransferResource(WebKit::WebGraphicsContext3D
* context
,
371 TransferableResource
* resource
);
372 void DeleteResourceInternal(ResourceMap::iterator it
);
373 void LazyAllocate(Resource
* resource
);
375 OutputSurface
* output_surface_
;
377 ResourceMap resources_
;
381 ResourceType default_resource_type_
;
382 bool use_texture_storage_ext_
;
383 bool use_texture_usage_hint_
;
384 bool use_shallow_flush_
;
385 scoped_ptr
<TextureUploader
> texture_uploader_
;
386 scoped_ptr
<AcceleratedTextureCopier
> texture_copier_
;
387 int max_texture_size_
;
388 GLenum best_texture_format_
;
390 scoped_refptr
<cc::ContextProvider
> offscreen_context_provider_
;
392 base::ThreadChecker thread_checker_
;
394 scoped_refptr
<Fence
> current_read_lock_fence_
;
396 DISALLOW_COPY_AND_ASSIGN(ResourceProvider
);
401 #endif // CC_RESOURCES_RESOURCE_PROVIDER_H_