| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CC_RESOURCES_DISPLAY_RESOURCE_PROVIDER_H_ |
| #define CC_RESOURCES_DISPLAY_RESOURCE_PROVIDER_H_ |
| |
| #include "build/build_config.h" |
| #include "cc/output/overlay_candidate.h" |
| #include "cc/resources/resource_provider.h" |
| #include "components/viz/common/resources/resource_fence.h" |
| #include "components/viz/common/resources/resource_metadata.h" |
| |
| namespace viz { |
| class SharedBitmapManager; |
| } // namespace viz |
| |
| namespace cc { |
| |
| // This class is not thread-safe and can only be called from the thread it was |
| // created on. |
| class CC_EXPORT DisplayResourceProvider : public ResourceProvider { |
| public: |
| DisplayResourceProvider(viz::ContextProvider* compositor_context_provider, |
| viz::SharedBitmapManager* shared_bitmap_manager); |
| ~DisplayResourceProvider() override; |
| |
| #if defined(OS_ANDROID) |
| // Send an overlay promotion hint to all resources that requested it via |
| // |wants_promotion_hints_set_|. |promotable_hints| contains all the |
| // resources that should be told that they're promotable. Others will be told |
| // that they're not promotable right now. |
| void SendPromotionHints( |
| const OverlayCandidateList::PromotionHintInfoMap& promotion_hints); |
| |
| // Indicates if this resource is backed by an Android SurfaceTexture, and thus |
| // can't really be promoted to an overlay. |
| bool IsBackedBySurfaceTexture(viz::ResourceId id); |
| |
| // Indicates if this resource wants to receive promotion hints. |
| bool WantsPromotionHintForTesting(viz::ResourceId id); |
| |
| // Return the number of resources that request promotion hints. |
| size_t CountPromotionHintRequestsForTesting(); |
| #endif |
| |
| viz::ResourceType GetResourceType(viz::ResourceId id); |
| |
| // Return the format of the underlying buffer that can be used for scanout. |
| gfx::BufferFormat GetBufferFormat(viz::ResourceId id); |
| |
| // Indicates if this resource may be used for a hardware overlay plane. |
| bool IsOverlayCandidate(viz::ResourceId id); |
| |
| void WaitSyncToken(viz::ResourceId id); |
| |
| // Checks whether a resource is in use. |
| bool InUse(viz::ResourceId id); |
| |
| // Get the resource metadata for external use. |
| // The |release_sync_token| should be one that can be waited on in a command |
| // buffer to ensure that any external use of it is completed, before reusing |
| // the resource's backing. |
| viz::ResourceMetadata GetResourceMetadataForExternalUse( |
| viz::ResourceId id, |
| const gpu::SyncToken& release_sync_token); |
| |
| // The following lock classes are part of the DisplayResourceProvider API and |
| // are needed to read the resource contents. The user must ensure that they |
| // only use GL locks on GL resources, etc, and this is enforced by assertions. |
| class CC_EXPORT ScopedReadLockGL { |
| public: |
| ScopedReadLockGL(DisplayResourceProvider* resource_provider, |
| viz::ResourceId resource_id); |
| ~ScopedReadLockGL(); |
| |
| GLuint texture_id() const { return texture_id_; } |
| GLenum target() const { return target_; } |
| const gfx::Size& size() const { return size_; } |
| const gfx::ColorSpace& color_space() const { return color_space_; } |
| |
| private: |
| DisplayResourceProvider* const resource_provider_; |
| const viz::ResourceId resource_id_; |
| |
| GLuint texture_id_; |
| GLenum target_; |
| gfx::Size size_; |
| gfx::ColorSpace color_space_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ScopedReadLockGL); |
| }; |
| |
| class CC_EXPORT ScopedSamplerGL { |
| public: |
| ScopedSamplerGL(DisplayResourceProvider* resource_provider, |
| viz::ResourceId resource_id, |
| GLenum filter); |
| ScopedSamplerGL(DisplayResourceProvider* resource_provider, |
| viz::ResourceId resource_id, |
| GLenum unit, |
| GLenum filter); |
| ~ScopedSamplerGL(); |
| |
| GLuint texture_id() const { return resource_lock_.texture_id(); } |
| GLenum target() const { return target_; } |
| const gfx::ColorSpace& color_space() const { |
| return resource_lock_.color_space(); |
| } |
| |
| private: |
| const ScopedReadLockGL resource_lock_; |
| const GLenum unit_; |
| const GLenum target_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ScopedSamplerGL); |
| }; |
| |
| class CC_EXPORT ScopedReadLockSkImage { |
| public: |
| ScopedReadLockSkImage(DisplayResourceProvider* resource_provider, |
| viz::ResourceId resource_id); |
| ~ScopedReadLockSkImage(); |
| |
| const SkImage* sk_image() const { return sk_image_.get(); } |
| |
| bool valid() const { return !!sk_image_; } |
| |
| private: |
| DisplayResourceProvider* const resource_provider_; |
| const viz::ResourceId resource_id_; |
| sk_sp<SkImage> sk_image_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ScopedReadLockSkImage); |
| }; |
| |
| class CC_EXPORT ScopedReadLockSoftware { |
| public: |
| ScopedReadLockSoftware(DisplayResourceProvider* resource_provider, |
| viz::ResourceId resource_id); |
| ~ScopedReadLockSoftware(); |
| |
| const SkBitmap* sk_bitmap() const { |
| DCHECK(valid()); |
| return &sk_bitmap_; |
| } |
| |
| bool valid() const { return !!sk_bitmap_.getPixels(); } |
| |
| private: |
| DisplayResourceProvider* const resource_provider_; |
| const viz::ResourceId resource_id_; |
| SkBitmap sk_bitmap_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ScopedReadLockSoftware); |
| }; |
| |
| // All resources that are returned to children while an instance of this |
| // class exists will be stored and returned when the instance is destroyed. |
| class CC_EXPORT ScopedBatchReturnResources { |
| public: |
| explicit ScopedBatchReturnResources( |
| DisplayResourceProvider* resource_provider); |
| ~ScopedBatchReturnResources(); |
| |
| private: |
| DisplayResourceProvider* const resource_provider_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ScopedBatchReturnResources); |
| }; |
| |
| class CC_EXPORT SynchronousFence : public viz::ResourceFence { |
| public: |
| explicit SynchronousFence(gpu::gles2::GLES2Interface* gl); |
| |
| // viz::ResourceFence implementation. |
| void Set() override; |
| bool HasPassed() override; |
| void Wait() override; |
| |
| // Returns true if fence has been set but not yet synchornized. |
| bool has_synchronized() const { return has_synchronized_; } |
| |
| private: |
| ~SynchronousFence() override; |
| |
| void Synchronize(); |
| |
| gpu::gles2::GLES2Interface* gl_; |
| bool has_synchronized_; |
| |
| DISALLOW_COPY_AND_ASSIGN(SynchronousFence); |
| }; |
| |
| // Sets the current read fence. If a resource is locked for read |
| // and has read fences enabled, the resource will not allow writes |
| // until this fence has passed. |
| void SetReadLockFence(viz::ResourceFence* fence) { |
| current_read_lock_fence_ = fence; |
| } |
| |
| // Creates accounting for a child. Returns a child ID. |
| int CreateChild(const ReturnCallback& return_callback); |
| |
| // Destroys accounting for the child, deleting all accounted resources. |
| void DestroyChild(int child); |
| |
| // Sets whether resources need sync points set on them when returned to this |
| // child. Defaults to true. |
| void SetChildNeedsSyncTokens(int child, bool needs_sync_tokens); |
| |
| // Gets the child->parent resource ID map. |
| const ResourceIdMap& GetChildToParentMap(int child) const; |
| |
| // Receives resources from a child, moving them from mailboxes. ResourceIds |
| // passed are in the child namespace, and will be translated to the parent |
| // namespace, added to the child->parent map. |
| // This adds the resources to the working set in the ResourceProvider without |
| // declaring which resources are in use. Use DeclareUsedResourcesFromChild |
| // after calling this method to do that. All calls to ReceiveFromChild should |
| // be followed by a DeclareUsedResourcesFromChild. |
| // NOTE: if the sync_token is set on any viz::TransferableResource, this will |
| // wait on it. |
| void ReceiveFromChild( |
| int child, |
| const std::vector<viz::TransferableResource>& transferable_resources); |
| |
| // Once a set of resources have been received, they may or may not be used. |
| // This declares what set of resources are currently in use from the child, |
| // releasing any other resources back to the child. |
| void DeclareUsedResourcesFromChild( |
| int child, |
| const viz::ResourceIdSet& resources_from_child); |
| |
| private: |
| friend class ScopedBatchReturnResources; |
| |
| const viz::internal::Resource* LockForRead(viz::ResourceId id); |
| void UnlockForRead(viz::ResourceId id); |
| // Binds the given GL resource to a texture target for sampling using the |
| // specified filter for both minification and magnification. Returns the |
| // texture target used. The resource must be locked for reading. |
| GLenum BindForSampling(viz::ResourceId resource_id, |
| GLenum unit, |
| GLenum filter); |
| bool ReadLockFenceHasPassed(const viz::internal::Resource* resource); |
| #if defined(OS_ANDROID) |
| void DeletePromotionHint(ResourceMap::iterator it, DeleteStyle style); |
| #endif |
| |
| struct Child { |
| Child(); |
| Child(const Child& other); |
| ~Child(); |
| |
| ResourceIdMap child_to_parent_map; |
| ReturnCallback return_callback; |
| bool marked_for_deletion; |
| bool needs_sync_tokens; |
| }; |
| using ChildMap = std::unordered_map<int, Child>; |
| |
| void DeleteAndReturnUnusedResourcesToChild(ChildMap::iterator child_it, |
| DeleteStyle style, |
| const ResourceIdArray& unused); |
| void DestroyChildInternal(ChildMap::iterator it, DeleteStyle style); |
| |
| void SetBatchReturnResources(bool aggregate); |
| |
| scoped_refptr<viz::ResourceFence> current_read_lock_fence_; |
| ChildMap children_; |
| // Used as child id when creating a child. |
| int next_child_ = 1; |
| base::flat_map<viz::ResourceId, sk_sp<SkImage>> resource_sk_image_; |
| viz::ResourceId next_id_; |
| viz::SharedBitmapManager* shared_bitmap_manager_; |
| // Keep track of whether deleted resources should be batched up or returned |
| // immediately. |
| bool batch_return_resources_ = false; |
| // Maps from a child id to the set of resources to be returned to it. |
| base::small_map<std::map<int, ResourceIdArray>> batched_returning_resources_; |
| #if defined(OS_ANDROID) |
| // Set of ResourceIds that would like to be notified about promotion hints. |
| viz::ResourceIdSet wants_promotion_hints_set_; |
| #endif |
| |
| DISALLOW_COPY_AND_ASSIGN(DisplayResourceProvider); |
| }; |
| |
| } // namespace cc |
| |
| #endif // CC_RESOURCES_DISPLAY_RESOURCE_PROVIDER_H_ |