// 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); // 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_ = 0; GLenum target_ = GL_TEXTURE_2D; 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 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); }; // Maintains set of lock for external use. class CC_EXPORT LockSetForExternalUse { public: explicit LockSetForExternalUse(DisplayResourceProvider* resource_provider); ~LockSetForExternalUse(); // Lock a resource for external use. viz::ResourceMetadata LockResource(viz::ResourceId resource_id); // Unlock all locked resources with a |sync_token|. // See UnlockForExternalUse for the detail. All resources must be unlocked // before destroying this class. void UnlockResources(const gpu::SyncToken& sync_token); private: DisplayResourceProvider* const resource_provider_; std::vector resources_; DISALLOW_COPY_AND_ASSIGN(LockSetForExternalUse); }; // 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& 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: const viz::internal::Resource* LockForRead(viz::ResourceId id); void UnlockForRead(viz::ResourceId id); // Lock a resource for external use. viz::ResourceMetadata LockForExternalUse(viz::ResourceId id); // Unlock a resource which locked by LockForExternalUse. // The |sync_token| should be waited on before reusing the resouce's backing // to ensure that any external use of it is completed. This |sync_token| // should have been verified. void UnlockForExternalUse(viz::ResourceId id, const gpu::SyncToken& sync_token); void TryReleaseResource(ResourceMap::iterator it); // 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; void DeleteAndReturnUnusedResourcesToChild(ChildMap::iterator child_it, DeleteStyle style, const ResourceIdArray& unused); void DestroyChildInternal(ChildMap::iterator it, DeleteStyle style); void SetBatchReturnResources(bool aggregate); scoped_refptr current_read_lock_fence_; ChildMap children_; // Used as child id when creating a child. int next_child_ = 1; base::flat_map> 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> 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_