Mac Overlays: Make ImageTransportSurfaceOverlayMac observe GPU switches
[chromium-blink-merge.git] / cc / resources / resource_provider.h
blob324df1bab3a701f52f4c8d1afc8e334ba2ff8748
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_
8 #include <deque>
9 #include <set>
10 #include <string>
11 #include <utility>
12 #include <vector>
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"
39 class GrContext;
41 namespace gpu {
42 class GpuMemoryBufferManager;
43 namespace gles {
44 class GLES2Interface;
48 namespace gfx {
49 class GpuMemoryBuffer;
50 class Rect;
51 class Vector2d;
54 namespace cc {
55 class BlockingTaskRunner;
56 class IdAllocator;
57 class SharedBitmap;
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 {
64 private:
65 struct Resource;
67 public:
68 typedef std::vector<ResourceId> ResourceIdArray;
69 typedef base::hash_set<ResourceId> ResourceIdSet;
70 typedef base::hash_map<ResourceId, ResourceId> ResourceIdMap;
71 enum TextureHint {
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
78 enum ResourceType {
79 RESOURCE_TYPE_GL_TEXTURE,
80 RESOURCE_TYPE_BITMAP,
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,
127 GLint wrap_mode,
128 TextureHint hint,
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,
134 GLenum target,
135 GLint wrap_mode,
136 TextureHint hint,
137 ResourceFormat format);
139 // You can also explicitly create a specific resource type.
140 ResourceId CreateGLTexture(const gfx::Size& size,
141 GLenum target,
142 GLenum texture_pool,
143 GLint wrap_mode,
144 TextureHint hint,
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
165 // the resource).
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
190 // "in use".
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
202 // wait on it.
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
215 // wait on it.
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
222 // by assertions.
223 class CC_EXPORT ScopedReadLockGL {
224 public:
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; }
232 protected:
233 ResourceProvider* resource_provider_;
234 ResourceId resource_id_;
236 private:
237 const ResourceProvider::Resource* resource_;
239 DISALLOW_COPY_AND_ASSIGN(ScopedReadLockGL);
242 class CC_EXPORT ScopedSamplerGL : public ScopedReadLockGL {
243 public:
244 ScopedSamplerGL(ResourceProvider* resource_provider,
245 ResourceId resource_id,
246 GLenum filter);
247 ScopedSamplerGL(ResourceProvider* resource_provider,
248 ResourceId resource_id,
249 GLenum unit,
250 GLenum filter);
251 ~ScopedSamplerGL() override;
253 GLenum target() const { return target_; }
255 private:
256 GLenum unit_;
257 GLenum target_;
259 DISALLOW_COPY_AND_ASSIGN(ScopedSamplerGL);
262 class CC_EXPORT ScopedWriteLockGL {
263 public:
264 ScopedWriteLockGL(ResourceProvider* resource_provider,
265 ResourceId resource_id);
266 ~ScopedWriteLockGL();
268 unsigned texture_id() const { return texture_id_; }
270 private:
271 ResourceProvider* resource_provider_;
272 ResourceProvider::Resource* resource_;
273 unsigned texture_id_;
275 DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockGL);
278 class CC_EXPORT ScopedReadLockSoftware {
279 public:
280 ScopedReadLockSoftware(ResourceProvider* resource_provider,
281 ResourceId resource_id);
282 ~ScopedReadLockSoftware();
284 const SkBitmap* sk_bitmap() const {
285 DCHECK(valid());
286 return &sk_bitmap_;
288 GLint wrap_mode() const { return wrap_mode_; }
290 bool valid() const { return !!sk_bitmap_.getPixels(); }
292 private:
293 ResourceProvider* resource_provider_;
294 ResourceId resource_id_;
295 SkBitmap sk_bitmap_;
296 GLint wrap_mode_;
298 DISALLOW_COPY_AND_ASSIGN(ScopedReadLockSoftware);
301 class CC_EXPORT ScopedWriteLockSoftware {
302 public:
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(); }
310 private:
311 ResourceProvider* resource_provider_;
312 ResourceProvider::Resource* resource_;
313 SkBitmap sk_bitmap_;
314 base::ThreadChecker thread_checker_;
316 DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockSoftware);
319 class CC_EXPORT ScopedWriteLockGpuMemoryBuffer {
320 public:
321 ScopedWriteLockGpuMemoryBuffer(ResourceProvider* resource_provider,
322 ResourceId resource_id);
323 ~ScopedWriteLockGpuMemoryBuffer();
325 gfx::GpuMemoryBuffer* GetGpuMemoryBuffer();
327 private:
328 ResourceProvider* resource_provider_;
329 ResourceProvider::Resource* resource_;
330 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_;
331 gfx::GpuMemoryBuffer* gpu_memory_buffer_;
332 gfx::Size size_;
333 ResourceFormat format_;
334 base::ThreadChecker thread_checker_;
336 DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockGpuMemoryBuffer);
339 class CC_EXPORT ScopedWriteLockGr {
340 public:
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_; }
353 private:
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> {
363 public:
364 Fence() {}
366 virtual void Set() = 0;
367 virtual bool HasPassed() = 0;
368 virtual void Wait() = 0;
370 protected:
371 friend class base::RefCounted<Fence>;
372 virtual ~Fence() {}
374 private:
375 DISALLOW_COPY_AND_ASSIGN(Fence);
378 class SynchronousFence : public ResourceProvider::Fence {
379 public:
380 explicit SynchronousFence(gpu::gles2::GLES2Interface* gl);
382 // Overridden from Fence:
383 void Set() override;
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_; }
390 private:
391 ~SynchronousFence() override;
393 void Synchronize();
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);
417 // For tests only!
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,
432 ResourceId dest_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_; }
453 protected:
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);
463 void Initialize();
465 private:
466 struct Resource {
467 enum Origin { INTERNAL, EXTERNAL, DELEGATED };
469 ~Resource();
470 Resource(unsigned texture_id,
471 const gfx::Size& size,
472 Origin origin,
473 GLenum target,
474 GLenum filter,
475 GLenum texture_pool,
476 GLint wrap_mode,
477 TextureHint hint,
478 ResourceFormat format);
479 Resource(uint8_t* pixels,
480 SharedBitmap* bitmap,
481 const gfx::Size& size,
482 Origin origin,
483 GLenum filter,
484 GLint wrap_mode);
485 Resource(const SharedBitmapId& bitmap_id,
486 const gfx::Size& size,
487 Origin origin,
488 GLenum filter,
489 GLint wrap_mode);
491 int child_id;
492 unsigned gl_id;
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;
501 uint8_t* pixels;
502 int lock_for_read_count;
503 int imported_count;
504 int exported_count;
505 bool dirty_image : 1;
506 bool locked_for_write : 1;
507 bool lost : 1;
508 bool marked_for_deletion : 1;
509 bool pending_set_pixels : 1;
510 bool set_pixels_completion_forced : 1;
511 bool allocated : 1;
512 bool read_lock_fences_enabled : 1;
513 bool has_shared_bitmap_id : 1;
514 scoped_refptr<Fence> read_lock_fence;
515 gfx::Size size;
516 Origin origin;
517 GLenum target;
518 // TODO(skyostil): Use a separate sampler object for filter state.
519 GLenum original_filter;
520 GLenum filter;
521 unsigned image_id;
522 unsigned bound_image_id;
523 GLenum texture_pool;
524 GLint wrap_mode;
525 TextureHint hint;
526 ResourceType type;
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;
534 struct Child {
535 Child();
536 ~Child();
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,
562 ResourceId id,
563 TransferableResource* resource);
564 enum DeleteStyle {
565 NORMAL,
566 FOR_SHUTDOWN,
568 void DeleteResourceInternal(ResourceMap::iterator it, DeleteStyle style);
569 void DeleteAndReturnUnusedResourcesToChild(ChildMap::iterator child_it,
570 DeleteStyle style,
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_;
592 ResourceId next_id_;
593 ResourceMap resources_;
594 int next_child_;
595 ChildMap children_;
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.
624 int tracing_id_;
626 DISALLOW_COPY_AND_ASSIGN(ResourceProvider);
629 } // namespace cc
631 #endif // CC_RESOURCES_RESOURCE_PROVIDER_H_