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_
14 #include "base/basictypes.h"
15 #include "base/callback.h"
16 #include "base/containers/hash_tables.h"
17 #include "base/memory/linked_ptr.h"
18 #include "base/memory/scoped_ptr.h"
19 #include "base/threading/thread_checker.h"
20 #include "base/trace_event/memory_allocator_dump.h"
21 #include "base/trace_event/memory_dump_provider.h"
22 #include "cc/base/cc_export.h"
23 #include "cc/base/resource_id.h"
24 #include "cc/output/context_provider.h"
25 #include "cc/output/output_surface.h"
26 #include "cc/resources/release_callback_impl.h"
27 #include "cc/resources/resource_format.h"
28 #include "cc/resources/return_callback.h"
29 #include "cc/resources/shared_bitmap.h"
30 #include "cc/resources/single_release_callback_impl.h"
31 #include "cc/resources/texture_mailbox.h"
32 #include "cc/resources/transferable_resource.h"
33 #include "third_party/khronos/GLES2/gl2.h"
34 #include "third_party/khronos/GLES2/gl2ext.h"
35 #include "third_party/skia/include/core/SkBitmap.h"
36 #include "third_party/skia/include/core/SkCanvas.h"
37 #include "ui/gfx/geometry/size.h"
42 class GpuMemoryBufferManager
;
49 class GpuMemoryBuffer
;
55 class BlockingTaskRunner
;
58 class SharedBitmapManager
;
60 // This class is not thread-safe and can only be called from the thread it was
61 // created on (in practice, the impl thread).
62 class CC_EXPORT ResourceProvider
63 : public base::trace_event::MemoryDumpProvider
{
68 typedef std::vector
<ResourceId
> ResourceIdArray
;
69 typedef base::hash_set
<ResourceId
> ResourceIdSet
;
70 typedef base::hash_map
<ResourceId
, ResourceId
> ResourceIdMap
;
72 TEXTURE_HINT_DEFAULT
= 0x0,
73 TEXTURE_HINT_IMMUTABLE
= 0x1,
74 TEXTURE_HINT_FRAMEBUFFER
= 0x2,
75 TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER
=
76 TEXTURE_HINT_IMMUTABLE
| TEXTURE_HINT_FRAMEBUFFER
79 RESOURCE_TYPE_GL_TEXTURE
,
83 static scoped_ptr
<ResourceProvider
> Create(
84 OutputSurface
* output_surface
,
85 SharedBitmapManager
* shared_bitmap_manager
,
86 gpu::GpuMemoryBufferManager
* gpu_memory_buffer_manager
,
87 BlockingTaskRunner
* blocking_main_thread_task_runner
,
88 int highp_threshold_min
,
89 bool use_rgba_4444_texture_format
,
90 size_t id_allocation_chunk_size
,
91 bool use_persistent_map_for_gpu_memory_buffers
,
92 const std::vector
<unsigned>& use_image_texture_targets
);
93 ~ResourceProvider() override
;
95 void DidLoseOutputSurface() { lost_output_surface_
= true; }
97 int max_texture_size() const { return max_texture_size_
; }
98 ResourceFormat
memory_efficient_texture_format() const {
99 return use_rgba_4444_texture_format_
? RGBA_4444
: best_texture_format_
;
101 ResourceFormat
best_texture_format() const { return best_texture_format_
; }
102 ResourceFormat
best_render_buffer_format() const {
103 return best_render_buffer_format_
;
105 ResourceFormat
yuv_resource_format() const { return yuv_resource_format_
; }
106 bool use_sync_query() const { return use_sync_query_
; }
107 bool use_persistent_map_for_gpu_memory_buffers() const {
108 return use_persistent_map_for_gpu_memory_buffers_
;
110 size_t num_resources() const { return resources_
.size(); }
112 // Checks whether a resource is in use by a consumer.
113 bool InUseByConsumer(ResourceId id
);
115 bool IsLost(ResourceId id
);
117 void LoseResourceForTesting(ResourceId id
);
118 void EnableReadLockFencesForTesting(ResourceId id
);
120 // Producer interface.
122 ResourceType
default_resource_type() const { return default_resource_type_
; }
123 ResourceType
GetResourceType(ResourceId id
);
125 // Creates a resource of the default resource type.
126 ResourceId
CreateResource(const gfx::Size
& size
,
129 ResourceFormat format
);
131 // Creates a resource which is tagged as being managed for GPU memory
132 // accounting purposes.
133 ResourceId
CreateManagedResource(const gfx::Size
& size
,
137 ResourceFormat format
);
139 // You can also explicitly create a specific resource type.
140 ResourceId
CreateGLTexture(const gfx::Size
& size
,
145 ResourceFormat format
);
147 ResourceId
CreateBitmap(const gfx::Size
& size
, GLint wrap_mode
);
148 // Wraps an IOSurface into a GL resource.
149 ResourceId
CreateResourceFromIOSurface(const gfx::Size
& size
,
150 unsigned io_surface_id
);
152 // Wraps an external texture mailbox into a GL resource.
153 ResourceId
CreateResourceFromTextureMailbox(
154 const TextureMailbox
& mailbox
,
155 scoped_ptr
<SingleReleaseCallbackImpl
> release_callback_impl
);
157 ResourceId
CreateResourceFromTextureMailbox(
158 const TextureMailbox
& mailbox
,
159 scoped_ptr
<SingleReleaseCallbackImpl
> release_callback_impl
,
160 bool read_lock_fences_enabled
);
162 void DeleteResource(ResourceId id
);
164 // Update pixels from image, copying source_rect (in image) to dest_offset (in
166 void CopyToResource(ResourceId id
,
167 const uint8_t* image
,
168 const gfx::Size
& image_size
);
170 // Only flush the command buffer if supported.
171 // Returns true if the shallow flush occurred, false otherwise.
172 bool ShallowFlushIfSupported();
174 // Creates accounting for a child. Returns a child ID.
175 int CreateChild(const ReturnCallback
& return_callback
);
177 // Destroys accounting for the child, deleting all accounted resources.
178 void DestroyChild(int child
);
180 // Sets whether resources need sync points set on them when returned to this
181 // child. Defaults to true.
182 void SetChildNeedsSyncPoints(int child
, bool needs_sync_points
);
184 // Gets the child->parent resource ID map.
185 const ResourceIdMap
& GetChildToParentMap(int child
) const;
187 // Prepares resources to be transfered to the parent, moving them to
188 // mailboxes and serializing meta-data into TransferableResources.
189 // Resources are not removed from the ResourceProvider, but are marked as
191 void PrepareSendToParent(const ResourceIdArray
& resources
,
192 TransferableResourceArray
* transferable_resources
);
194 // Receives resources from a child, moving them from mailboxes. Resource IDs
195 // passed are in the child namespace, and will be translated to the parent
196 // namespace, added to the child->parent map.
197 // This adds the resources to the working set in the ResourceProvider without
198 // declaring which resources are in use. Use DeclareUsedResourcesFromChild
199 // after calling this method to do that. All calls to ReceiveFromChild should
200 // be followed by a DeclareUsedResourcesFromChild.
201 // NOTE: if the sync_point is set on any TransferableResource, this will
203 void ReceiveFromChild(
204 int child
, const TransferableResourceArray
& transferable_resources
);
206 // Once a set of resources have been received, they may or may not be used.
207 // This declares what set of resources are currently in use from the child,
208 // releasing any other resources back to the child.
209 void DeclareUsedResourcesFromChild(int child
,
210 const ResourceIdSet
& resources_from_child
);
212 // Receives resources from the parent, moving them from mailboxes. Resource
213 // IDs passed are in the child namespace.
214 // NOTE: if the sync_point is set on any TransferableResource, this will
216 void ReceiveReturnsFromParent(
217 const ReturnedResourceArray
& transferable_resources
);
219 // The following lock classes are part of the ResourceProvider API and are
220 // needed to read and write the resource contents. The user must ensure
221 // that they only use GL locks on GL resources, etc, and this is enforced
223 class CC_EXPORT ScopedReadLockGL
{
225 ScopedReadLockGL(ResourceProvider
* resource_provider
,
226 ResourceId resource_id
);
227 virtual ~ScopedReadLockGL();
229 unsigned texture_id() const { return resource_
->gl_id
; }
230 GLenum
target() const { return resource_
->target
; }
233 ResourceProvider
* resource_provider_
;
234 ResourceId resource_id_
;
237 const ResourceProvider::Resource
* resource_
;
239 DISALLOW_COPY_AND_ASSIGN(ScopedReadLockGL
);
242 class CC_EXPORT ScopedSamplerGL
: public ScopedReadLockGL
{
244 ScopedSamplerGL(ResourceProvider
* resource_provider
,
245 ResourceId resource_id
,
247 ScopedSamplerGL(ResourceProvider
* resource_provider
,
248 ResourceId resource_id
,
251 ~ScopedSamplerGL() override
;
253 GLenum
target() const { return target_
; }
259 DISALLOW_COPY_AND_ASSIGN(ScopedSamplerGL
);
262 class CC_EXPORT ScopedWriteLockGL
{
264 ScopedWriteLockGL(ResourceProvider
* resource_provider
,
265 ResourceId resource_id
);
266 ~ScopedWriteLockGL();
268 unsigned texture_id() const { return texture_id_
; }
271 ResourceProvider
* resource_provider_
;
272 ResourceProvider::Resource
* resource_
;
273 unsigned texture_id_
;
275 DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockGL
);
278 class CC_EXPORT ScopedReadLockSoftware
{
280 ScopedReadLockSoftware(ResourceProvider
* resource_provider
,
281 ResourceId resource_id
);
282 ~ScopedReadLockSoftware();
284 const SkBitmap
* sk_bitmap() const {
288 GLint
wrap_mode() const { return wrap_mode_
; }
290 bool valid() const { return !!sk_bitmap_
.getPixels(); }
293 ResourceProvider
* resource_provider_
;
294 ResourceId resource_id_
;
298 DISALLOW_COPY_AND_ASSIGN(ScopedReadLockSoftware
);
301 class CC_EXPORT ScopedWriteLockSoftware
{
303 ScopedWriteLockSoftware(ResourceProvider
* resource_provider
,
304 ResourceId resource_id
);
305 ~ScopedWriteLockSoftware();
307 SkBitmap
& sk_bitmap() { return sk_bitmap_
; }
308 bool valid() const { return !!sk_bitmap_
.getPixels(); }
311 ResourceProvider
* resource_provider_
;
312 ResourceProvider::Resource
* resource_
;
314 base::ThreadChecker thread_checker_
;
316 DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockSoftware
);
319 class CC_EXPORT ScopedWriteLockGpuMemoryBuffer
{
321 ScopedWriteLockGpuMemoryBuffer(ResourceProvider
* resource_provider
,
322 ResourceId resource_id
);
323 ~ScopedWriteLockGpuMemoryBuffer();
325 gfx::GpuMemoryBuffer
* GetGpuMemoryBuffer();
328 ResourceProvider
* resource_provider_
;
329 ResourceProvider::Resource
* resource_
;
330 gpu::GpuMemoryBufferManager
* gpu_memory_buffer_manager_
;
331 gfx::GpuMemoryBuffer
* gpu_memory_buffer_
;
333 ResourceFormat format_
;
334 base::ThreadChecker thread_checker_
;
336 DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockGpuMemoryBuffer
);
339 class CC_EXPORT ScopedWriteLockGr
{
341 ScopedWriteLockGr(ResourceProvider
* resource_provider
,
342 ResourceId resource_id
);
343 ~ScopedWriteLockGr();
345 void InitSkSurface(bool use_distance_field_text
,
346 bool can_use_lcd_text
,
347 int msaa_sample_count
);
348 void ReleaseSkSurface();
350 SkSurface
* sk_surface() { return sk_surface_
.get(); }
351 ResourceProvider::Resource
* resource() { return resource_
; }
354 ResourceProvider
* resource_provider_
;
355 ResourceProvider::Resource
* resource_
;
356 base::ThreadChecker thread_checker_
;
357 skia::RefPtr
<SkSurface
> sk_surface_
;
359 DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockGr
);
362 class Fence
: public base::RefCounted
<Fence
> {
366 virtual void Set() = 0;
367 virtual bool HasPassed() = 0;
368 virtual void Wait() = 0;
371 friend class base::RefCounted
<Fence
>;
375 DISALLOW_COPY_AND_ASSIGN(Fence
);
378 class SynchronousFence
: public ResourceProvider::Fence
{
380 explicit SynchronousFence(gpu::gles2::GLES2Interface
* gl
);
382 // Overridden from Fence:
384 bool HasPassed() override
;
385 void Wait() override
;
387 // Returns true if fence has been set but not yet synchornized.
388 bool has_synchronized() const { return has_synchronized_
; }
391 ~SynchronousFence() override
;
395 gpu::gles2::GLES2Interface
* gl_
;
396 bool has_synchronized_
;
398 DISALLOW_COPY_AND_ASSIGN(SynchronousFence
);
401 // Acquire pixel buffer for resource. The pixel buffer can be used to
402 // set resource pixels without performing unnecessary copying.
403 void AcquirePixelBuffer(ResourceId resource
);
404 void ReleasePixelBuffer(ResourceId resource
);
405 // Map/unmap the acquired pixel buffer.
406 uint8_t* MapPixelBuffer(ResourceId id
, int* stride
);
407 void UnmapPixelBuffer(ResourceId id
);
408 // Asynchronously update pixels from acquired pixel buffer.
409 void BeginSetPixels(ResourceId id
);
410 void ForceSetPixelsToComplete(ResourceId id
);
411 bool DidSetPixelsComplete(ResourceId id
);
413 // For tests only! This prevents detecting uninitialized reads.
414 // Use SetPixels or LockForWrite to allocate implicitly.
415 void AllocateForTesting(ResourceId id
);
418 void CreateForTesting(ResourceId id
);
420 GLenum
TargetForTesting(ResourceId id
);
422 // Sets the current read fence. If a resource is locked for read
423 // and has read fences enabled, the resource will not allow writes
424 // until this fence has passed.
425 void SetReadLockFence(Fence
* fence
) { current_read_lock_fence_
= fence
; }
427 // Indicates if we can currently lock this resource for write.
428 bool CanLockForWrite(ResourceId id
);
430 // Copy |rect| pixels from source to destination.
431 void CopyResource(ResourceId source_id
,
433 const gfx::Rect
& rect
);
435 void WaitSyncPointIfNeeded(ResourceId id
);
437 void WaitReadLockIfNeeded(ResourceId id
);
439 static GLint
GetActiveTextureUnit(gpu::gles2::GLES2Interface
* gl
);
441 OutputSurface
* output_surface() { return output_surface_
; }
443 void ValidateResource(ResourceId id
) const;
445 GLenum
GetImageTextureTarget(ResourceFormat format
);
447 // base::trace_event::MemoryDumpProvider implementation.
448 bool OnMemoryDump(const base::trace_event::MemoryDumpArgs
& args
,
449 base::trace_event::ProcessMemoryDump
* pmd
) override
;
451 int tracing_id() const { return tracing_id_
; }
454 ResourceProvider(OutputSurface
* output_surface
,
455 SharedBitmapManager
* shared_bitmap_manager
,
456 gpu::GpuMemoryBufferManager
* gpu_memory_buffer_manager
,
457 BlockingTaskRunner
* blocking_main_thread_task_runner
,
458 int highp_threshold_min
,
459 bool use_rgba_4444_texture_format
,
460 size_t id_allocation_chunk_size
,
461 bool use_persistent_map_for_gpu_memory_buffers
,
462 const std::vector
<unsigned>& use_image_texture_targets
);
467 enum Origin
{ INTERNAL
, EXTERNAL
, DELEGATED
};
470 Resource(unsigned texture_id
,
471 const gfx::Size
& size
,
478 ResourceFormat format
);
479 Resource(uint8_t* pixels
,
480 SharedBitmap
* bitmap
,
481 const gfx::Size
& size
,
485 Resource(const SharedBitmapId
& bitmap_id
,
486 const gfx::Size
& size
,
493 // Pixel buffer used for set pixels without unnecessary copying.
494 unsigned gl_pixel_buffer_id
;
495 // Query used to determine when asynchronous set pixels complete.
496 unsigned gl_upload_query_id
;
497 // Query used to determine when read lock fence has passed.
498 unsigned gl_read_lock_query_id
;
499 TextureMailbox mailbox
;
500 ReleaseCallbackImpl release_callback_impl
;
502 int lock_for_read_count
;
505 bool dirty_image
: 1;
506 bool locked_for_write
: 1;
508 bool marked_for_deletion
: 1;
509 bool pending_set_pixels
: 1;
510 bool set_pixels_completion_forced
: 1;
512 bool read_lock_fences_enabled
: 1;
513 bool has_shared_bitmap_id
: 1;
514 scoped_refptr
<Fence
> read_lock_fence
;
518 // TODO(skyostil): Use a separate sampler object for filter state.
519 GLenum original_filter
;
522 unsigned bound_image_id
;
527 ResourceFormat format
;
528 SharedBitmapId shared_bitmap_id
;
529 SharedBitmap
* shared_bitmap
;
530 gfx::GpuMemoryBuffer
* gpu_memory_buffer
;
532 typedef base::hash_map
<ResourceId
, Resource
> ResourceMap
;
538 ResourceIdMap child_to_parent_map
;
539 ResourceIdMap parent_to_child_map
;
540 ReturnCallback return_callback
;
541 bool marked_for_deletion
;
542 bool needs_sync_points
;
544 typedef base::hash_map
<int, Child
> ChildMap
;
546 bool ReadLockFenceHasPassed(const Resource
* resource
) {
547 return !resource
->read_lock_fence
.get() ||
548 resource
->read_lock_fence
->HasPassed();
551 Resource
* InsertResource(ResourceId id
, const Resource
& resource
);
552 Resource
* GetResource(ResourceId id
);
553 const Resource
* LockForRead(ResourceId id
);
554 void UnlockForRead(ResourceId id
);
555 Resource
* LockForWrite(ResourceId id
);
556 void UnlockForWrite(Resource
* resource
);
558 static void PopulateSkBitmapWithResource(SkBitmap
* sk_bitmap
,
559 const Resource
* resource
);
561 void TransferResource(gpu::gles2::GLES2Interface
* gl
,
563 TransferableResource
* resource
);
568 void DeleteResourceInternal(ResourceMap::iterator it
, DeleteStyle style
);
569 void DeleteAndReturnUnusedResourcesToChild(ChildMap::iterator child_it
,
571 const ResourceIdArray
& unused
);
572 void DestroyChildInternal(ChildMap::iterator it
, DeleteStyle style
);
573 void LazyCreate(Resource
* resource
);
574 void LazyAllocate(Resource
* resource
);
576 void BindImageForSampling(Resource
* resource
);
577 // Binds the given GL resource to a texture target for sampling using the
578 // specified filter for both minification and magnification. Returns the
579 // texture target used. The resource must be locked for reading.
580 GLenum
BindForSampling(ResourceId resource_id
, GLenum unit
, GLenum filter
);
582 // Returns NULL if the output_surface_ does not have a ContextProvider.
583 gpu::gles2::GLES2Interface
* ContextGL() const;
584 class GrContext
* GrContext(bool worker_context
) const;
586 OutputSurface
* output_surface_
;
587 SharedBitmapManager
* shared_bitmap_manager_
;
588 gpu::GpuMemoryBufferManager
* gpu_memory_buffer_manager_
;
589 BlockingTaskRunner
* blocking_main_thread_task_runner_
;
590 bool lost_output_surface_
;
591 int highp_threshold_min_
;
593 ResourceMap resources_
;
597 ResourceType default_resource_type_
;
598 bool use_texture_storage_ext_
;
599 bool use_texture_format_bgra_
;
600 bool use_texture_usage_hint_
;
601 bool use_compressed_texture_etc1_
;
602 ResourceFormat yuv_resource_format_
;
603 int max_texture_size_
;
604 ResourceFormat best_texture_format_
;
605 ResourceFormat best_render_buffer_format_
;
607 base::ThreadChecker thread_checker_
;
609 scoped_refptr
<Fence
> current_read_lock_fence_
;
610 bool use_rgba_4444_texture_format_
;
612 const size_t id_allocation_chunk_size_
;
613 scoped_ptr
<IdAllocator
> texture_id_allocator_
;
614 scoped_ptr
<IdAllocator
> buffer_id_allocator_
;
616 bool use_sync_query_
;
617 bool use_persistent_map_for_gpu_memory_buffers_
;
618 // Fence used for CopyResource if CHROMIUM_sync_query is not supported.
619 scoped_refptr
<SynchronousFence
> synchronous_fence_
;
620 std::vector
<unsigned> use_image_texture_targets_
;
622 // A process-unique ID used for disambiguating memory dumps from different
623 // resource providers.
626 DISALLOW_COPY_AND_ASSIGN(ResourceProvider
);
631 #endif // CC_RESOURCES_RESOURCE_PROVIDER_H_