| // Copyright 2018 The Chromium Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_SHARED_IMAGE_REPRESENTATION_H_ | |
| #define GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_SHARED_IMAGE_REPRESENTATION_H_ | |
| #include <dawn/dawn_proc_table.h> | |
| #include <dawn/webgpu_cpp.h> | |
| #include <memory> | |
| #include "base/functional/callback.h" | |
| #include "base/memory/raw_ptr.h" | |
| #include "base/memory/ref_counted.h" | |
| #include "base/memory/scoped_refptr.h" | |
| #include "base/types/pass_key.h" | |
| #include "build/build_config.h" | |
| #include "gpu/command_buffer/common/shared_image_usage.h" | |
| #include "gpu/command_buffer/service/shared_image/shared_image_backing.h" | |
| #include "gpu/gpu_gles2_export.h" | |
| #include "gpu/vulkan/buildflags.h" | |
| #include "skia/buildflags.h" | |
| #include "third_party/skia/include/core/SkImage.h" | |
| #include "third_party/skia/include/core/SkSurface.h" | |
| #include "third_party/skia/include/gpu/ganesh/GrDirectContext.h" | |
| #include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" | |
| #include "third_party/skia/include/gpu/graphite/BackendTexture.h" | |
| #include "third_party/skia/include/private/chromium/GrPromiseImageTexture.h" | |
| #include "ui/gfx/color_space.h" | |
| #include "ui/gfx/geometry/rect.h" | |
| #include "ui/gfx/geometry/size.h" | |
| #include "ui/gfx/gpu_fence.h" | |
| #if BUILDFLAG(ENABLE_VULKAN) | |
| #include <vulkan/vulkan_core.h> | |
| namespace gpu { | |
| class VulkanDeviceQueue; | |
| class VulkanImage; | |
| class VulkanImplementation; | |
| } // namespace gpu | |
| #endif // BUILDFLAG(ENABLE_VULKAN) | |
| #if BUILDFLAG(IS_WIN) | |
| #include <d3d11.h> | |
| #include <d3d12.h> | |
| #include <wrl/client.h> | |
| #include "ui/gl/dc_layer_overlay_image.h" | |
| #endif // BUILDFLAG(IS_WIN) | |
| #if BUILDFLAG(IS_APPLE) | |
| #include "ui/gfx/mac/io_surface.h" | |
| #include "ui/gfx/mac/mtl_shared_event_fence.h" | |
| #endif // BUILDFLAG(IS_APPLE) | |
| #if BUILDFLAG(IS_ANDROID) | |
| #include "base/android/scoped_hardware_buffer_fence_sync.h" | |
| extern "C" typedef struct AHardwareBuffer AHardwareBuffer; | |
| #endif // BUILDFLAG(IS_ANDROID) | |
| typedef unsigned int GLenum; | |
| namespace skgpu { | |
| class MutableTextureState; | |
| } | |
| namespace cc { | |
| class PaintOpBuffer; | |
| } // namespace cc | |
| namespace gfx { | |
| class NativePixmap; | |
| } // namespace gfx | |
| namespace gpu { | |
| class SharedImageManager; | |
| class TextureBase; | |
| namespace gles2 { | |
| class Texture; | |
| class TexturePassthrough; | |
| } // namespace gles2 | |
| enum class RepresentationAccessMode { | |
| kNone, | |
| kRead, | |
| kWrite, | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////// | |
| // SharedImageRepresentation | |
| // A representation of a SharedImageBacking for use with a specific use case / | |
| // api. | |
| class GPU_GLES2_EXPORT SharedImageRepresentation { | |
| public: | |
| using AccessMode = RepresentationAccessMode; | |
| // Used by derived classes. | |
| enum class AllowUnclearedAccess { kYes, kNo }; | |
| SharedImageRepresentation(SharedImageManager* manager, | |
| SharedImageBacking* backing, | |
| MemoryTypeTracker* tracker); | |
| virtual ~SharedImageRepresentation(); | |
| viz::SharedImageFormat format() const { return backing_->format(); } | |
| const gfx::Size& size() const { return backing_->size(); } | |
| const gfx::ColorSpace& color_space() const { return backing_->color_space(); } | |
| GrSurfaceOrigin surface_origin() const { return backing_->surface_origin(); } | |
| SkAlphaType alpha_type() const { return backing_->alpha_type(); } | |
| SharedImageUsageSet usage() const { return backing_->usage(); } | |
| uint32_t array_layers() const { return backing_->array_layers(); } | |
| const gpu::Mailbox& mailbox() const { return backing_->mailbox(); } | |
| const std::string& debug_label() const { return backing_->debug_label(); } | |
| const char* backing_name() const { return backing_->GetName(); } | |
| MemoryTypeTracker* tracker() { return tracker_; } | |
| bool IsCleared() const; | |
| void SetCleared(); | |
| virtual gfx::Rect ClearedRect() const; | |
| virtual void SetClearedRect(const gfx::Rect& cleared_rect); | |
| // Indicates that the underlying graphics context has been lost, and the | |
| // backing should be treated as destroyed. | |
| virtual void OnContextLost(); | |
| // Returns the number of image planes expected based on the backing format. | |
| size_t NumPlanesExpected() const; | |
| protected: | |
| SharedImageManager* manager() const { return manager_; } | |
| SharedImageBacking* backing() const { return backing_; } | |
| bool has_context() const { return has_context_; } | |
| // Helper class for derived classes' Scoped*Access objects. Has tracking to | |
| // ensure a Scoped*Access does not outlive the representation it's associated | |
| // with. | |
| template <typename RepresentationClass> | |
| class ScopedAccessBase { | |
| public: | |
| ScopedAccessBase(RepresentationClass* representation, | |
| AccessMode access_mode) | |
| : representation_(representation) { | |
| CHECK_EQ(representation_->access_mode_, AccessMode::kNone); | |
| representation_->access_mode_ = access_mode; | |
| } | |
| ScopedAccessBase(const ScopedAccessBase&) = delete; | |
| ScopedAccessBase& operator=(const ScopedAccessBase&) = delete; | |
| ~ScopedAccessBase() { | |
| CHECK_NE(representation_->access_mode_, AccessMode::kNone); | |
| representation_->access_mode_ = AccessMode::kNone; | |
| } | |
| RepresentationClass* representation() { return representation_; } | |
| const RepresentationClass* representation() const { | |
| return representation_; | |
| } | |
| private: | |
| // Uses UnprotectedInRelease for performance reasons (based on analysis of | |
| // MotionMark). | |
| const raw_ptr<RepresentationClass, UnprotectedInRelease> representation_ = | |
| nullptr; | |
| }; | |
| private: | |
| // Uses UnprotectedInRelease for performance reasons (based on analysis of | |
| // MotionMark). | |
| const raw_ptr<SharedImageManager, UnprotectedInRelease> manager_ = nullptr; | |
| raw_ptr<SharedImageBacking, DanglingUntriaged | UnprotectedInRelease> | |
| backing_ = nullptr; | |
| const raw_ptr<MemoryTypeTracker, UnprotectedInRelease> tracker_ = nullptr; | |
| bool has_context_ = true; | |
| AccessMode access_mode_ = AccessMode::kNone; | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////// | |
| // SharedImageRepresentationFactoryRef | |
| class SharedImageRepresentationFactoryRef : public SharedImageRepresentation { | |
| public: | |
| SharedImageRepresentationFactoryRef(SharedImageManager* manager, | |
| SharedImageBacking* backing, | |
| MemoryTypeTracker* tracker, | |
| bool is_primary); | |
| ~SharedImageRepresentationFactoryRef() override; | |
| const Mailbox& mailbox() const { return backing()->mailbox(); } | |
| bool CopyToGpuMemoryBuffer() { return backing()->CopyToGpuMemoryBuffer(); } | |
| void CopyToGpuMemoryBufferAsync(base::OnceCallback<void(bool)> callback) { | |
| backing()->CopyToGpuMemoryBufferAsync(std::move(callback)); | |
| } | |
| void GetGpuMemoryBufferHandleInfo(gfx::GpuMemoryBufferHandle& handle, | |
| gfx::BufferUsage& buffer_usage) { | |
| handle = backing()->GetGpuMemoryBufferHandle(); | |
| buffer_usage = backing()->buffer_usage().value(); | |
| } | |
| void SetSharedImagePoolId(SharedImagePoolId pool_id) { | |
| backing()->SetSharedImagePoolId(std::move(pool_id)); | |
| } | |
| private: | |
| const bool is_primary_; | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////// | |
| // GLTextureImageRepresentationBase | |
| class GPU_GLES2_EXPORT GLTextureImageRepresentationBase | |
| : public SharedImageRepresentation { | |
| public: | |
| static constexpr GLenum kReadAccessMode = 0x8AF6; | |
| class ScopedAccess | |
| : public ScopedAccessBase<GLTextureImageRepresentationBase> { | |
| public: | |
| ScopedAccess(base::PassKey<GLTextureImageRepresentationBase> pass_key, | |
| GLTextureImageRepresentationBase* representation, | |
| AccessMode access_mode) | |
| : ScopedAccessBase(representation, access_mode) {} | |
| ~ScopedAccess() { | |
| representation()->UpdateClearedStateOnEndAccess(); | |
| representation()->EndAccess(); | |
| } | |
| }; | |
| GLTextureImageRepresentationBase(SharedImageManager* manager, | |
| SharedImageBacking* backing, | |
| MemoryTypeTracker* tracker) | |
| : SharedImageRepresentation(manager, backing, tracker) {} | |
| std::unique_ptr<ScopedAccess> BeginScopedAccess( | |
| GLenum mode, | |
| AllowUnclearedAccess allow_uncleared); | |
| // Gets the texture associated with the `plane_index` for SharedImageFormat. | |
| virtual gpu::TextureBase* GetTextureBase(size_t plane_index) = 0; | |
| // Calls GetTextureBase with `plane_index` = 0 for single planar formats eg. | |
| // RGB. | |
| gpu::TextureBase* GetTextureBase(); | |
| protected: | |
| friend class SkiaGLImageRepresentation; | |
| friend class DawnEGLImageRepresentation; | |
| friend class DawnGLTextureRepresentation; | |
| friend class GLTextureGLCommonRepresentation; | |
| // Can be overridden to handle clear state tracking when GL access begins or | |
| // ends. | |
| virtual void UpdateClearedStateOnBeginAccess() {} | |
| virtual void UpdateClearedStateOnEndAccess() {} | |
| virtual bool BeginAccess(GLenum mode) = 0; | |
| virtual void EndAccess() = 0; | |
| virtual bool SupportsMultipleConcurrentReadAccess(); | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////// | |
| // GLTextureImageRepresentation | |
| class GPU_GLES2_EXPORT GLTextureImageRepresentation | |
| : public GLTextureImageRepresentationBase { | |
| public: | |
| GLTextureImageRepresentation(SharedImageManager* manager, | |
| SharedImageBacking* backing, | |
| MemoryTypeTracker* tracker) | |
| : GLTextureImageRepresentationBase(manager, backing, tracker) {} | |
| // Gets the texture associated with the `plane_index` for SharedImageFormat. | |
| virtual gles2::Texture* GetTexture(size_t plane_index) = 0; | |
| // Calls GetTexture with `plane_index` = 0 for single planar formats eg. RGB. | |
| gles2::Texture* GetTexture(); | |
| gpu::TextureBase* GetTextureBase(size_t plane_index) override; | |
| protected: | |
| friend class WrappedGLTextureCompoundImageRepresentation; | |
| void UpdateClearedStateOnBeginAccess() override; | |
| void UpdateClearedStateOnEndAccess() override; | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////// | |
| // GLTexturePassthroughImageRepresentation | |
| class GPU_GLES2_EXPORT GLTexturePassthroughImageRepresentation | |
| : public GLTextureImageRepresentationBase { | |
| public: | |
| GLTexturePassthroughImageRepresentation(SharedImageManager* manager, | |
| SharedImageBacking* backing, | |
| MemoryTypeTracker* tracker) | |
| : GLTextureImageRepresentationBase(manager, backing, tracker) {} | |
| // Gets the passthrough texture associated with the `plane_index` for | |
| // SharedImageFormat. | |
| virtual const scoped_refptr<gles2::TexturePassthrough>& GetTexturePassthrough( | |
| size_t plane_index) = 0; | |
| // Calls GetTexturePassthrough with `plane_index` = 0 for single planar | |
| // formats eg. RGB. | |
| const scoped_refptr<gles2::TexturePassthrough>& GetTexturePassthrough(); | |
| gpu::TextureBase* GetTextureBase(size_t plane_index) override; | |
| // Returns true if access must be suspended in between GL decoder tasks due to | |
| // DXGI keyed mutex. Only implemented for D3D GL representation. | |
| virtual bool NeedsSuspendAccessForDXGIKeyedMutex() const; | |
| private: | |
| friend class WrappedGLTexturePassthroughCompoundImageRepresentation; | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////// | |
| // SkiaImageRepresentation | |
| class GPU_GLES2_EXPORT SkiaImageRepresentation | |
| : public SharedImageRepresentation { | |
| public: | |
| // Object that holds skgpu::graphite::BackendTexture. | |
| class GPU_GLES2_EXPORT GraphiteTextureHolder | |
| : public base::RefCountedThreadSafe<GraphiteTextureHolder> { | |
| public: | |
| explicit GraphiteTextureHolder(skgpu::graphite::BackendTexture texture); | |
| const skgpu::graphite::BackendTexture& texture() { return texture_; } | |
| protected: | |
| friend class base::RefCountedThreadSafe<GraphiteTextureHolder>; | |
| virtual ~GraphiteTextureHolder(); | |
| skgpu::graphite::BackendTexture texture_; | |
| }; | |
| class GPU_GLES2_EXPORT ScopedWriteAccess | |
| : public ScopedAccessBase<SkiaImageRepresentation> { | |
| public: | |
| virtual ~ScopedWriteAccess(); | |
| // NOTE: All references to the returned SkSurface(s) must be destroyed | |
| // before ScopedWriteAccess is destroyed. | |
| bool has_surfaces() const { return !surfaces_.empty(); } | |
| SkSurface* surface() const { | |
| // Writes do not support external sampler. | |
| CHECK(representation()->format().is_single_plane()); | |
| return surface(0); | |
| } | |
| SkSurface* surface(size_t plane_index) const { | |
| return surfaces_[plane_index].get(); | |
| } | |
| GrPromiseImageTexture* promise_image_texture(size_t plane_index) const { | |
| return promise_image_textures_[plane_index].get(); | |
| } | |
| skgpu::graphite::BackendTexture graphite_texture(size_t plane_index) const { | |
| return graphite_texture_holder(plane_index)->texture(); | |
| } | |
| const scoped_refptr<GraphiteTextureHolder>& graphite_texture_holder( | |
| size_t plane_index) const { | |
| return graphite_texture_holders_[plane_index]; | |
| } | |
| // Return the representations's implementation. | |
| bool NeedGraphiteContextSubmit(); | |
| // NOTE: Implemented only for Ganesh. | |
| // Checks if there's a need to apply skgpu::MutableTextureState. | |
| virtual bool HasBackendSurfaceEndState() = 0; | |
| // NOTE: Implemented only for Ganesh. | |
| // Applies the skgpu::MutableTextureState for Vulkan layout and external | |
| // queue transitions needed for Vulkan/GL interop. | |
| virtual void ApplyBackendSurfaceEndState() = 0; | |
| protected: | |
| ScopedWriteAccess(SkiaImageRepresentation* representation, | |
| std::vector<sk_sp<SkSurface>> surfaces); | |
| ScopedWriteAccess( | |
| SkiaImageRepresentation* representation, | |
| std::vector<sk_sp<GrPromiseImageTexture>> promise_image_textures); | |
| ScopedWriteAccess( | |
| SkiaImageRepresentation* representation, | |
| std::vector<scoped_refptr<GraphiteTextureHolder>> graphite_textures); | |
| // A vector of surfaces, promise textures and graphite backend textures | |
| // corresponding to the number of planes in SharedImageFormat. | |
| std::vector<sk_sp<SkSurface>> surfaces_; | |
| // NOTE: Used only for Ganesh. | |
| std::vector<sk_sp<GrPromiseImageTexture>> promise_image_textures_; | |
| // NOTE: Used only for Graphite. | |
| std::vector<scoped_refptr<GraphiteTextureHolder>> graphite_texture_holders_; | |
| }; | |
| class GPU_GLES2_EXPORT ScopedReadAccess | |
| : public ScopedAccessBase<SkiaImageRepresentation> { | |
| public: | |
| virtual ~ScopedReadAccess(); | |
| GrPromiseImageTexture* promise_image_texture() const { | |
| CHECK_EQ(representation()->NumPlanesExpected(), 1u); | |
| return promise_image_texture(0); | |
| } | |
| GrPromiseImageTexture* promise_image_texture(size_t plane_index) const { | |
| return promise_image_textures_[plane_index].get(); | |
| } | |
| skgpu::graphite::BackendTexture graphite_texture() const { | |
| CHECK_EQ(representation()->NumPlanesExpected(), 1u); | |
| return graphite_texture(0); | |
| } | |
| skgpu::graphite::BackendTexture graphite_texture(size_t plane_index) const { | |
| return graphite_texture_holder(plane_index)->texture(); | |
| } | |
| const scoped_refptr<GraphiteTextureHolder>& graphite_texture_holder( | |
| size_t plane_index) const { | |
| return graphite_texture_holders_[plane_index]; | |
| } | |
| // Return the representations's implementation. | |
| bool NeedGraphiteContextSubmit(); | |
| // Creates an SkImage from BackendTexture for single planar formats or if | |
| // format prefers external sampler. Creates an SkImage from | |
| // YUVABackendTexture for multiplanar formats. | |
| virtual sk_sp<SkImage> CreateSkImage( | |
| SharedContextState* context_state, | |
| SkImages::TextureReleaseProc texture_release_proc = nullptr, | |
| SkImages::ReleaseContext release_context = nullptr) = 0; | |
| // Creates an SkImage for the given `plane_index` for | |
| // multiplanar formats. | |
| virtual sk_sp<SkImage> CreateSkImageForPlane( | |
| size_t plane_index, | |
| SharedContextState* context_state, | |
| SkImages::TextureReleaseProc texture_release_proc = nullptr, | |
| SkImages::ReleaseContext release_context = nullptr) = 0; | |
| // NOTE: Implemented only for Ganesh. | |
| // Checks if there's a need to apply skgpu::MutableTextureState. | |
| virtual bool HasBackendSurfaceEndState() = 0; | |
| // Applies the skgpu::MutableTextureState for Vulkan layout and external | |
| // queue transitions needed for Vulkan/GL interop. | |
| virtual void ApplyBackendSurfaceEndState() = 0; | |
| protected: | |
| ScopedReadAccess( | |
| SkiaImageRepresentation* representation, | |
| std::vector<sk_sp<GrPromiseImageTexture>> promise_image_textures); | |
| ScopedReadAccess( | |
| SkiaImageRepresentation* representation, | |
| std::vector<scoped_refptr<GraphiteTextureHolder>> graphite_textures); | |
| // A vector of promise textures and graphite backend textures corresponding | |
| // to the number of planes in SharedImageFormat. NOTE: Used only for Ganesh. | |
| std::vector<sk_sp<GrPromiseImageTexture>> promise_image_textures_; | |
| // NOTE: Used only for Graphite. | |
| std::vector<scoped_refptr<GraphiteTextureHolder>> graphite_texture_holders_; | |
| }; | |
| SkiaImageRepresentation(SharedImageManager* manager, | |
| SharedImageBacking* backing, | |
| MemoryTypeTracker* tracker, | |
| bool is_graphite); | |
| ~SkiaImageRepresentation() override; | |
| // Note: See BeginWriteAccess below for a description of the semaphore | |
| // parameters. | |
| virtual std::unique_ptr<ScopedWriteAccess> BeginScopedWriteAccess( | |
| int final_msaa_count, | |
| const SkSurfaceProps& surface_props, | |
| const gfx::Rect& update_rect, | |
| std::vector<GrBackendSemaphore>* begin_semaphores, | |
| std::vector<GrBackendSemaphore>* end_semaphores, | |
| AllowUnclearedAccess allow_uncleared, | |
| bool use_sk_surface = true) = 0; | |
| virtual std::unique_ptr<ScopedWriteAccess> BeginScopedWriteAccess( | |
| int final_msaa_count, | |
| const SkSurfaceProps& surface_props, | |
| std::vector<GrBackendSemaphore>* begin_semaphores, | |
| std::vector<GrBackendSemaphore>* end_semaphores, | |
| AllowUnclearedAccess allow_uncleared, | |
| bool use_sk_surface = true) = 0; | |
| virtual std::unique_ptr<ScopedWriteAccess> BeginScopedWriteAccess( | |
| std::vector<GrBackendSemaphore>* begin_semaphores, | |
| std::vector<GrBackendSemaphore>* end_semaphores, | |
| AllowUnclearedAccess allow_uncleared, | |
| bool use_sk_surface = true) = 0; | |
| // Note: See BeginReadAccess below for a description of the semaphore | |
| // parameters. | |
| virtual std::unique_ptr<ScopedReadAccess> BeginScopedReadAccess( | |
| std::vector<GrBackendSemaphore>* begin_semaphores, | |
| std::vector<GrBackendSemaphore>* end_semaphores) = 0; | |
| // Return whether we need to submit graphite's commands before EndAccess. | |
| // NOTE: Implemented only for Graphite. | |
| bool NeedGraphiteContextSubmitBeforeEndAccess(); | |
| virtual bool SupportsMultipleConcurrentReadAccess(); | |
| protected: | |
| // Return whether the graphite context submission can be deferred even after | |
| // the backing is destroyed. | |
| virtual bool SupportsDeferredGraphiteSubmit(); | |
| virtual void EndWriteAccess() = 0; | |
| virtual void EndReadAccess() = 0; | |
| const bool is_graphite_; | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////// | |
| // SkiaGaneshImageRepresentation | |
| class GPU_GLES2_EXPORT SkiaGaneshImageRepresentation | |
| : public SkiaImageRepresentation { | |
| public: | |
| class GPU_GLES2_EXPORT ScopedGaneshWriteAccess : public ScopedWriteAccess { | |
| public: | |
| ScopedGaneshWriteAccess( | |
| base::PassKey<SkiaGaneshImageRepresentation> pass_key, | |
| SkiaImageRepresentation* representation, | |
| std::vector<sk_sp<SkSurface>> surfaces, | |
| std::unique_ptr<skgpu::MutableTextureState> end_state); | |
| ScopedGaneshWriteAccess( | |
| base::PassKey<SkiaGaneshImageRepresentation> pass_key, | |
| SkiaImageRepresentation* representation, | |
| std::vector<sk_sp<GrPromiseImageTexture>> promise_image_textures, | |
| std::unique_ptr<skgpu::MutableTextureState> end_state); | |
| ~ScopedGaneshWriteAccess() override; | |
| // Checks if there's a need to apply skgpu::MutableTextureState. | |
| bool HasBackendSurfaceEndState() override; | |
| // Applies the skgpu::MutableTextureState for Vulkan layout and external | |
| // queue transitions needed for Vulkan/GL interop. | |
| void ApplyBackendSurfaceEndState() override; | |
| private: | |
| SkiaGaneshImageRepresentation* ganesh_representation() { | |
| return static_cast<SkiaGaneshImageRepresentation*>(representation()); | |
| } | |
| std::unique_ptr<skgpu::MutableTextureState> end_state_; | |
| }; | |
| class GPU_GLES2_EXPORT ScopedGaneshReadAccess : public ScopedReadAccess { | |
| public: | |
| ScopedGaneshReadAccess( | |
| base::PassKey<SkiaGaneshImageRepresentation> pass_key, | |
| SkiaImageRepresentation* representation, | |
| std::vector<sk_sp<GrPromiseImageTexture>> promise_image_textures, | |
| std::unique_ptr<skgpu::MutableTextureState> end_state); | |
| ~ScopedGaneshReadAccess() override; | |
| // Creates an SkImage from GrBackendTexture for single planar formats or if | |
| // format prefers external sampler. Creates an SkImage from | |
| // GrYUVABackendTexture for multiplanar formats. | |
| sk_sp<SkImage> CreateSkImage( | |
| SharedContextState* context_state, | |
| SkImages::TextureReleaseProc texture_release_proc = nullptr, | |
| SkImages::ReleaseContext release_context = nullptr) override; | |
| // Creates an SkImage for the given `plane_index` from GrBackendTexture for | |
| // multiplanar formats. | |
| sk_sp<SkImage> CreateSkImageForPlane( | |
| size_t plane_index, | |
| SharedContextState* context_state, | |
| SkImages::TextureReleaseProc texture_release_proc = nullptr, | |
| SkImages::ReleaseContext release_context = nullptr) override; | |
| // Checks if there's a need to apply skgpu::MutableTextureState. | |
| bool HasBackendSurfaceEndState() override; | |
| // Applies the skgpu::MutableTextureState for Vulkan layout and external | |
| // queue transitions needed for Vulkan/GL interop. | |
| void ApplyBackendSurfaceEndState() override; | |
| private: | |
| SkiaGaneshImageRepresentation* ganesh_representation() { | |
| return static_cast<SkiaGaneshImageRepresentation*>(representation()); | |
| } | |
| std::unique_ptr<skgpu::MutableTextureState> end_state_; | |
| }; | |
| SkiaGaneshImageRepresentation(GrDirectContext* gr_context, | |
| SharedImageManager* manager, | |
| SharedImageBacking* backing, | |
| MemoryTypeTracker* tracker); | |
| GrDirectContext* gr_context() const { return gr_context_; } | |
| // Note: See BeginWriteAccess below for a description of the semaphore | |
| // parameters. | |
| std::unique_ptr<ScopedWriteAccess> BeginScopedWriteAccess( | |
| int final_msaa_count, | |
| const SkSurfaceProps& surface_props, | |
| const gfx::Rect& update_rect, | |
| std::vector<GrBackendSemaphore>* begin_semaphores, | |
| std::vector<GrBackendSemaphore>* end_semaphores, | |
| AllowUnclearedAccess allow_uncleared, | |
| bool use_sk_surface = true) override; | |
| std::unique_ptr<ScopedWriteAccess> BeginScopedWriteAccess( | |
| int final_msaa_count, | |
| const SkSurfaceProps& surface_props, | |
| std::vector<GrBackendSemaphore>* begin_semaphores, | |
| std::vector<GrBackendSemaphore>* end_semaphores, | |
| AllowUnclearedAccess allow_uncleared, | |
| bool use_sk_surface = true) override; | |
| std::unique_ptr<ScopedWriteAccess> BeginScopedWriteAccess( | |
| std::vector<GrBackendSemaphore>* begin_semaphores, | |
| std::vector<GrBackendSemaphore>* end_semaphores, | |
| AllowUnclearedAccess allow_uncleared, | |
| bool use_sk_surface = true) override; | |
| // Note: See BeginReadAccess below for a description of the semaphore | |
| // parameters. | |
| std::unique_ptr<ScopedReadAccess> BeginScopedReadAccess( | |
| std::vector<GrBackendSemaphore>* begin_semaphores, | |
| std::vector<GrBackendSemaphore>* end_semaphores) override; | |
| protected: | |
| friend class WrappedSkiaGaneshCompoundImageRepresentation; | |
| // Begin the write access. | |
| // | |
| // update_rect is a hint to the backend about the portion of the image that | |
| // will be drawn to. Callers shouldn't draw outside of this area, but aren't | |
| // required to overwrite every pixel inside it. | |
| // | |
| // The implementations should insert semaphores into begin_semaphores vector | |
| // which client will wait on before writing the backing. The ownership of | |
| // begin_semaphores is not passed to client. The implementations can also | |
| // optionally insert semaphores into end_semaphores. If using end_semaphores, | |
| // the client must submit them with drawing operations which use the backing. | |
| // The ownership of end_semaphores are not passed to client. And client must | |
| // submit the end_semaphores before calling EndWriteAccess(). | |
| // | |
| // The backing can assign end_state, and the caller must reset backing's state | |
| // to the end_state before calling EndWriteAccess(). | |
| // Returns an empty vector on failure. | |
| virtual std::vector<sk_sp<SkSurface>> BeginWriteAccess( | |
| int final_msaa_count, | |
| const SkSurfaceProps& surface_props, | |
| const gfx::Rect& update_rect, | |
| std::vector<GrBackendSemaphore>* begin_semaphores, | |
| std::vector<GrBackendSemaphore>* end_semaphores, | |
| std::unique_ptr<skgpu::MutableTextureState>* end_state) = 0; | |
| virtual std::vector<sk_sp<GrPromiseImageTexture>> BeginWriteAccess( | |
| std::vector<GrBackendSemaphore>* begin_semaphores, | |
| std::vector<GrBackendSemaphore>* end_semaphores, | |
| std::unique_ptr<skgpu::MutableTextureState>* end_state) = 0; | |
| // Begin the read access. The implementations should insert semaphores into | |
| // begin_semaphores vector which client will wait on before reading the | |
| // backing. The ownership of begin_semaphores is not passed to client. | |
| // The implementations can also optionally insert semaphores into | |
| // end_semaphores. If using end_semaphores, the client must submit them with | |
| // drawing operations which use the backing. The ownership of end_semaphores | |
| // are not passed to client. And client must submit the end_semaphores before | |
| // calling EndReadAccess(). | |
| // The backing can assign end_state, and the caller must reset backing's state | |
| // to the end_state before calling EndReadAccess(). | |
| // Returns an empty vector on failure. | |
| virtual std::vector<sk_sp<GrPromiseImageTexture>> BeginReadAccess( | |
| std::vector<GrBackendSemaphore>* begin_semaphores, | |
| std::vector<GrBackendSemaphore>* end_semaphores, | |
| std::unique_ptr<skgpu::MutableTextureState>* end_state) = 0; | |
| private: | |
| raw_ptr<GrDirectContext> gr_context_ = nullptr; | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////// | |
| // SkiaGraphiteImageRepresentation | |
| class GPU_GLES2_EXPORT SkiaGraphiteImageRepresentation | |
| : public SkiaImageRepresentation { | |
| public: | |
| class GPU_GLES2_EXPORT ScopedGraphiteWriteAccess : public ScopedWriteAccess { | |
| public: | |
| ScopedGraphiteWriteAccess( | |
| base::PassKey<SkiaGraphiteImageRepresentation> pass_key, | |
| SkiaImageRepresentation* representation, | |
| std::vector<sk_sp<SkSurface>> surfaces); | |
| ScopedGraphiteWriteAccess( | |
| base::PassKey<SkiaGraphiteImageRepresentation> pass_key, | |
| SkiaImageRepresentation* representation, | |
| std::vector<scoped_refptr<GraphiteTextureHolder>> graphite_textures); | |
| ~ScopedGraphiteWriteAccess() override; | |
| bool HasBackendSurfaceEndState() override; | |
| void ApplyBackendSurfaceEndState() override; | |
| }; | |
| class GPU_GLES2_EXPORT ScopedGraphiteReadAccess : public ScopedReadAccess { | |
| public: | |
| ScopedGraphiteReadAccess( | |
| base::PassKey<SkiaGraphiteImageRepresentation> pass_key, | |
| SkiaImageRepresentation* representation, | |
| std::vector<scoped_refptr<GraphiteTextureHolder>> graphite_textures); | |
| ~ScopedGraphiteReadAccess() override; | |
| // Creates an SkImage from BackendTexture for single planar formats or if | |
| // format prefers external sampler. Creates an SkImage from | |
| // YUVABackendTexture for multiplanar formats. | |
| sk_sp<SkImage> CreateSkImage( | |
| SharedContextState* context_state, | |
| SkImages::TextureReleaseProc texture_release_proc = nullptr, | |
| SkImages::ReleaseContext release_context = nullptr) override; | |
| // Creates an SkImage for the given `plane_index` from BackendTexture for | |
| // multiplanar formats. | |
| sk_sp<SkImage> CreateSkImageForPlane( | |
| size_t plane_index, | |
| SharedContextState* context_state, | |
| SkImages::TextureReleaseProc texture_release_proc = nullptr, | |
| SkImages::ReleaseContext release_context = nullptr) override; | |
| bool HasBackendSurfaceEndState() override; | |
| void ApplyBackendSurfaceEndState() override; | |
| }; | |
| SkiaGraphiteImageRepresentation(SharedImageManager* manager, | |
| SharedImageBacking* backing, | |
| MemoryTypeTracker* tracker); | |
| // Note: See BeginWriteAccess below for a description of the semaphore | |
| // parameters. | |
| std::unique_ptr<ScopedWriteAccess> BeginScopedWriteAccess( | |
| int final_msaa_count, | |
| const SkSurfaceProps& surface_props, | |
| const gfx::Rect& update_rect, | |
| std::vector<GrBackendSemaphore>* begin_semaphores, | |
| std::vector<GrBackendSemaphore>* end_semaphores, | |
| AllowUnclearedAccess allow_uncleared, | |
| bool use_sk_surface = true) override; | |
| std::unique_ptr<ScopedWriteAccess> BeginScopedWriteAccess( | |
| int final_msaa_count, | |
| const SkSurfaceProps& surface_props, | |
| std::vector<GrBackendSemaphore>* begin_semaphores, | |
| std::vector<GrBackendSemaphore>* end_semaphores, | |
| AllowUnclearedAccess allow_uncleared, | |
| bool use_sk_surface = true) override; | |
| std::unique_ptr<ScopedWriteAccess> BeginScopedWriteAccess( | |
| std::vector<GrBackendSemaphore>* begin_semaphores, | |
| std::vector<GrBackendSemaphore>* end_semaphores, | |
| AllowUnclearedAccess allow_uncleared, | |
| bool use_sk_surface = true) override; | |
| // Note: See BeginReadAccess below for a description of the semaphore | |
| // parameters. | |
| std::unique_ptr<ScopedReadAccess> BeginScopedReadAccess( | |
| std::vector<GrBackendSemaphore>* begin_semaphores, | |
| std::vector<GrBackendSemaphore>* end_semaphores) override; | |
| protected: | |
| friend class WrappedSkiaGraphiteCompoundImageRepresentation; | |
| std::string WrappedTextureDebugLabel(int plane) const; | |
| // Begin the write access. Returns an empty vector on failure. | |
| // | |
| // update_rect is a hint to the backend about the portion of the image that | |
| // will be drawn to. Callers shouldn't draw outside of this area, but aren't | |
| // required to overwrite every pixel inside it. | |
| virtual std::vector<sk_sp<SkSurface>> BeginWriteAccess( | |
| const SkSurfaceProps& surface_props, | |
| const gfx::Rect& update_rect) = 0; | |
| // Returns a vector of ref counted GraphiteTextureHolder that holds | |
| // skgpu::graphite::BackendTexture which graphite can use for writing. | |
| // Notes: | |
| // - If `NeedGraphiteContextSubmitBeforeEndAccess()` returns true: it's only | |
| // safe to use the contained BackendTexture within the access' scope. | |
| // - If `NeedGraphiteContextSubmitBeforeEndAccess()` returns false: the | |
| // contained BackendTexture is safe to be used as long as the holder is | |
| // intact. For example, in some scenarios the BackendTexture would be used in | |
| // a command buffer, but its submission needs to be deferred later, even after | |
| // the SI's backing is destroyed. In those cases, we can pass | |
| // refptr<GraphiteTextureHolder> to Graphite's release proc in order to keep | |
| // the BackendTexture alive until Graphite finishes using it. | |
| // - This function will return an empty vector on failure. | |
| virtual std::vector<scoped_refptr<GraphiteTextureHolder>> | |
| BeginWriteAccess() = 0; | |
| // Same as above but return holders of skgpu::graphite::BackendTexture for | |
| // reading in graphite. | |
| virtual std::vector<scoped_refptr<GraphiteTextureHolder>> | |
| BeginReadAccess() = 0; | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////// | |
| // DawnImageRepresentation | |
| class GPU_GLES2_EXPORT DawnImageRepresentation | |
| : public SharedImageRepresentation { | |
| public: | |
| static constexpr wgpu::TextureUsage kWriteUsage = | |
| wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment | | |
| wgpu::TextureUsage::StorageBinding; | |
| DawnImageRepresentation(SharedImageManager* manager, | |
| SharedImageBacking* backing, | |
| MemoryTypeTracker* tracker) | |
| : SharedImageRepresentation(manager, backing, tracker) {} | |
| class GPU_GLES2_EXPORT ScopedAccess | |
| : public ScopedAccessBase<DawnImageRepresentation> { | |
| public: | |
| ScopedAccess(base::PassKey<DawnImageRepresentation> pass_key, | |
| DawnImageRepresentation* representation, | |
| wgpu::Texture texture, | |
| AccessMode access_mode); | |
| ~ScopedAccess(); | |
| // Get the unowned texture handle. The caller should take a reference | |
| // if necessary by doing wgpu::Texture texture(access->texture()); | |
| const wgpu::Texture& texture() const { return texture_; } | |
| private: | |
| wgpu::Texture texture_; | |
| }; | |
| // Calls BeginAccess and returns a ScopedAccess object which will EndAccess | |
| // when it goes out of scope. The Representation must outlive the returned | |
| // ScopedAccess. | |
| std::unique_ptr<ScopedAccess> BeginScopedAccess( | |
| wgpu::TextureUsage usage, | |
| AllowUnclearedAccess allow_uncleared); | |
| // Allawos passing internal usages to the created Dawn texture. | |
| std::unique_ptr<ScopedAccess> BeginScopedAccess( | |
| wgpu::TextureUsage usage, | |
| wgpu::TextureUsage internal_usage, | |
| AllowUnclearedAccess allow_uncleared); | |
| // For write usage, the update_rect is a hint to the backend about the portion | |
| // of the image that will be drawn to. Callers shouldn't draw outside of this | |
| // area, but aren't required to overwrite every pixel inside it. | |
| // For non-write usage, the update_rect can be ignored. | |
| std::unique_ptr<ScopedAccess> BeginScopedAccess( | |
| wgpu::TextureUsage usage, | |
| AllowUnclearedAccess allow_uncleared, | |
| const gfx::Rect& update_rect); | |
| std::unique_ptr<ScopedAccess> BeginScopedAccess( | |
| wgpu::TextureUsage usage, | |
| wgpu::TextureUsage internal_usage, | |
| AllowUnclearedAccess allow_uncleared, | |
| const gfx::Rect& update_rect); | |
| private: | |
| friend class WrappedDawnCompoundImageRepresentation; | |
| // This can return null in case of a Dawn validation error, for example if | |
| // usage is invalid. | |
| virtual wgpu::Texture BeginAccess(wgpu::TextureUsage usage, | |
| wgpu::TextureUsage internal_usage) = 0; | |
| virtual wgpu::Texture BeginAccess(wgpu::TextureUsage usage, | |
| wgpu::TextureUsage internal_usage, | |
| const gfx::Rect& update_rect); | |
| virtual void EndAccess() = 0; | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////// | |
| // DawnBufferRepresentation | |
| class GPU_GLES2_EXPORT DawnBufferRepresentation | |
| : public SharedImageRepresentation { | |
| public: | |
| DawnBufferRepresentation(SharedImageManager* manager, | |
| SharedImageBacking* backing, | |
| MemoryTypeTracker* tracker) | |
| : SharedImageRepresentation(manager, backing, tracker) {} | |
| class GPU_GLES2_EXPORT ScopedAccess | |
| : public ScopedAccessBase<DawnBufferRepresentation> { | |
| public: | |
| ScopedAccess(base::PassKey<DawnBufferRepresentation> pass_key, | |
| DawnBufferRepresentation* representation, | |
| wgpu::Buffer buffer, | |
| AccessMode access_mode); | |
| ~ScopedAccess(); | |
| std::unique_ptr<ScopedAccess> BeginScopedAccess(wgpu::BufferUsage usage); | |
| const wgpu::Buffer& buffer() const { return buffer_; } | |
| private: | |
| wgpu::Buffer buffer_; | |
| }; | |
| // Allows passing usages to the created Dawn buffer. | |
| std::unique_ptr<ScopedAccess> BeginScopedAccess(wgpu::BufferUsage usage); | |
| protected: | |
| friend class WrappedDawnBufferCompoundImageRepresentation; | |
| virtual wgpu::Buffer BeginAccess(wgpu::BufferUsage usage) = 0; | |
| virtual void EndAccess() = 0; | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////// | |
| // WebNNTensorRepresentation | |
| class GPU_GLES2_EXPORT WebNNTensorRepresentation | |
| : public SharedImageRepresentation { | |
| public: | |
| WebNNTensorRepresentation(SharedImageManager* manager, | |
| SharedImageBacking* backing, | |
| MemoryTypeTracker* tracker) | |
| : SharedImageRepresentation(manager, backing, tracker) {} | |
| class GPU_GLES2_EXPORT ScopedAccess | |
| : public ScopedAccessBase<WebNNTensorRepresentation> { | |
| public: | |
| ScopedAccess(base::PassKey<WebNNTensorRepresentation> pass_key, | |
| WebNNTensorRepresentation* representation, | |
| AccessMode access_mode); | |
| ~ScopedAccess(); | |
| #if BUILDFLAG(IS_WIN) | |
| scoped_refptr<gfx::D3DSharedFence> GetAcquireFence() const; | |
| void SetReleaseFence(scoped_refptr<gfx::D3DSharedFence> release_fence); | |
| #endif | |
| }; | |
| bool is_thread_safe() const; | |
| std::unique_ptr<ScopedAccess> BeginScopedAccess(); | |
| #if BUILDFLAG(IS_WIN) | |
| virtual Microsoft::WRL::ComPtr<ID3D12Resource> GetD3D12Buffer() const; | |
| virtual base::win::ScopedHandle GetD3D12HeapHandle() const; | |
| #endif // BUILDFLAG(IS_WIN) | |
| #if BUILDFLAG(IS_APPLE) | |
| virtual IOSurfaceRef GetIOSurface() const; | |
| #endif // BUILDFLAG(IS_APPLE) | |
| protected: | |
| friend class WrappedWebNNTensorCompoundImageRepresentation; | |
| #if BUILDFLAG(IS_WIN) | |
| virtual scoped_refptr<gfx::D3DSharedFence> GetAcquireFence() const = 0; | |
| virtual void SetReleaseFence( | |
| scoped_refptr<gfx::D3DSharedFence> release_fence) = 0; | |
| #endif // BUILDFLAG(IS_WIN) | |
| virtual bool BeginAccess() = 0; | |
| virtual void EndAccess() = 0; | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////// | |
| // OverlayImageRepresentation | |
| class GPU_GLES2_EXPORT OverlayImageRepresentation | |
| : public SharedImageRepresentation { | |
| public: | |
| OverlayImageRepresentation(SharedImageManager* manager, | |
| SharedImageBacking* backing, | |
| MemoryTypeTracker* tracker) | |
| : SharedImageRepresentation(manager, backing, tracker) {} | |
| class GPU_GLES2_EXPORT ScopedReadAccess | |
| : public ScopedAccessBase<OverlayImageRepresentation> { | |
| public: | |
| ScopedReadAccess(base::PassKey<OverlayImageRepresentation> pass_key, | |
| OverlayImageRepresentation* representation, | |
| gfx::GpuFenceHandle acquire_fence); | |
| ~ScopedReadAccess(); | |
| #if BUILDFLAG(IS_ANDROID) | |
| AHardwareBuffer* GetAHardwareBuffer() { | |
| return representation()->GetAHardwareBuffer(); | |
| } | |
| // Deprecated. All code should use GetAHardwareBuffer() above, this function | |
| // will be deleted when GLSurfaceEGLSurface control will be able to deliver | |
| // fences via EndAccess. | |
| std::unique_ptr<base::android::ScopedHardwareBufferFenceSync> | |
| GetAHardwareBufferFenceSync() { | |
| return representation()->GetAHardwareBufferFenceSync(); | |
| } | |
| #elif BUILDFLAG(IS_OZONE) | |
| scoped_refptr<gfx::NativePixmap> GetNativePixmap() { | |
| return representation()->GetNativePixmap(); | |
| } | |
| #elif BUILDFLAG(IS_WIN) | |
| std::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() { | |
| return representation()->GetDCLayerOverlayImage(); | |
| } | |
| #elif BUILDFLAG(IS_APPLE) | |
| gfx::ScopedIOSurface GetIOSurface() const { | |
| return representation()->GetIOSurface(); | |
| } | |
| std::vector<gfx::MTLSharedEventFence> GetBackpressureFences() const { | |
| return representation()->GetBackpressureFences(); | |
| } | |
| bool IsInUseByWindowServer() const { | |
| return representation()->IsInUseByWindowServer(); | |
| } | |
| #endif | |
| gfx::GpuFenceHandle TakeAcquireFence() { return std::move(acquire_fence_); } | |
| void SetReleaseFence(gfx::GpuFenceHandle release_fence) { | |
| // Note: We overwrite previous fence. In case if window manager uses fence | |
| // for each frame we schedule overlay and the same image is scheduled for | |
| // multiple frames this will be updated after each frame. It's safe to | |
| // wait only for the last frame's fence. | |
| release_fence_ = std::move(release_fence); | |
| } | |
| private: | |
| gfx::GpuFenceHandle acquire_fence_; | |
| gfx::GpuFenceHandle release_fence_; | |
| }; | |
| std::unique_ptr<ScopedReadAccess> BeginScopedReadAccess(); | |
| protected: | |
| friend class WrappedOverlayCompoundImageRepresentation; | |
| // Notifies the backing that an access will start. Returns false if there is a | |
| // conflict. Otherwise, returns true and: | |
| // - Set a gpu fence to |acquire_fence| that should be waited on before the | |
| // SharedImage is ready to be displayed. This fence is fired when the gpu | |
| // has finished writing. | |
| virtual bool BeginReadAccess(gfx::GpuFenceHandle& acquire_fence) = 0; | |
| // |release_fence| is a fence that will be signaled when the image can be | |
| // safely re-used. Note, on some platforms window manager doesn't support | |
| // release fences and return image when it's already safe to re-use. | |
| // |release_fence| will be null in that case. | |
| virtual void EndReadAccess(gfx::GpuFenceHandle release_fence) = 0; | |
| #if BUILDFLAG(IS_ANDROID) | |
| virtual AHardwareBuffer* GetAHardwareBuffer(); | |
| virtual std::unique_ptr<base::android::ScopedHardwareBufferFenceSync> | |
| GetAHardwareBufferFenceSync(); | |
| #elif BUILDFLAG(IS_OZONE) | |
| scoped_refptr<gfx::NativePixmap> GetNativePixmap(); | |
| #elif BUILDFLAG(IS_WIN) | |
| virtual std::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage(); | |
| #elif BUILDFLAG(IS_APPLE) | |
| virtual gfx::ScopedIOSurface GetIOSurface() const; | |
| virtual std::vector<gfx::MTLSharedEventFence> GetBackpressureFences() const; | |
| // Return true if the macOS WindowServer is currently using the underlying | |
| // storage for the image. | |
| virtual bool IsInUseByWindowServer() const; | |
| #endif | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////// | |
| // LegacyOverlayImageRepresentation | |
| #if BUILDFLAG(IS_ANDROID) | |
| class GPU_GLES2_EXPORT LegacyOverlayImageRepresentation | |
| : public SharedImageRepresentation { | |
| public: | |
| LegacyOverlayImageRepresentation(SharedImageManager* manager, | |
| SharedImageBacking* backing, | |
| MemoryTypeTracker* tracker) | |
| : SharedImageRepresentation(manager, backing, tracker) {} | |
| // Renders shared image to SurfaceView/Dialog overlay. Should only be called | |
| // if the image already promoted to overlay. | |
| virtual void RenderToOverlay() = 0; | |
| // Notifies legacy overlay system about overlay promotion. | |
| virtual void NotifyOverlayPromotion(bool promotion, | |
| const gfx::Rect& bounds) = 0; | |
| }; | |
| #endif | |
| /////////////////////////////////////////////////////////////////////////////// | |
| // MemoryImageRepresentation | |
| class GPU_GLES2_EXPORT MemoryImageRepresentation | |
| : public SharedImageRepresentation { | |
| public: | |
| class GPU_GLES2_EXPORT ScopedReadAccess | |
| : public ScopedAccessBase<MemoryImageRepresentation> { | |
| public: | |
| ScopedReadAccess(base::PassKey<MemoryImageRepresentation> pass_key, | |
| MemoryImageRepresentation* representation, | |
| SkPixmap pixmap); | |
| ~ScopedReadAccess(); | |
| SkPixmap pixmap() { return pixmap_; } | |
| private: | |
| SkPixmap pixmap_; | |
| }; | |
| MemoryImageRepresentation(SharedImageManager* manager, | |
| SharedImageBacking* backing, | |
| MemoryTypeTracker* tracker) | |
| : SharedImageRepresentation(manager, backing, tracker) {} | |
| std::unique_ptr<ScopedReadAccess> BeginScopedReadAccess(); | |
| protected: | |
| friend class WrappedMemoryCompoundImageRepresentation; | |
| virtual SkPixmap BeginReadAccess() = 0; | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////// | |
| // RasterImageRepresentation | |
| // Representation of a SharedImageBacking for raster work. | |
| // This representation is used for raster work and compositor. The raster work | |
| // will be converted to a cc::PaintOpBuffer and stored in the | |
| // SharedImageBacking. And then the the compositor will access the stored | |
| // cc::PaintOpBuffer and execute paint ops in it. | |
| class GPU_GLES2_EXPORT RasterImageRepresentation | |
| : public SharedImageRepresentation { | |
| public: | |
| class GPU_GLES2_EXPORT ScopedReadAccess | |
| : public ScopedAccessBase<RasterImageRepresentation> { | |
| public: | |
| ScopedReadAccess(base::PassKey<RasterImageRepresentation> pass_key, | |
| RasterImageRepresentation* representation, | |
| const cc::PaintOpBuffer* paint_op_buffer, | |
| const std::optional<SkColor4f>& clear_color); | |
| ~ScopedReadAccess(); | |
| const cc::PaintOpBuffer* paint_op_buffer() const { | |
| return paint_op_buffer_; | |
| } | |
| const std::optional<SkColor4f>& clear_color() const { return clear_color_; } | |
| private: | |
| const raw_ptr<const cc::PaintOpBuffer> paint_op_buffer_; | |
| std::optional<SkColor4f> clear_color_; | |
| }; | |
| class GPU_GLES2_EXPORT ScopedWriteAccess | |
| : public ScopedAccessBase<RasterImageRepresentation> { | |
| public: | |
| ScopedWriteAccess(base::PassKey<RasterImageRepresentation> pass_key, | |
| RasterImageRepresentation* representation, | |
| cc::PaintOpBuffer* paint_op_buffer); | |
| ~ScopedWriteAccess(); | |
| cc::PaintOpBuffer* paint_op_buffer() { return paint_op_buffer_; } | |
| // An optional callback which will be called when the all paint ops in the | |
| // |paint_op_buffer_| are released. | |
| void set_callback(base::OnceClosure callback) { | |
| DCHECK(!callback_); | |
| DCHECK(callback); | |
| callback_ = std::move(callback); | |
| } | |
| private: | |
| const raw_ptr<cc::PaintOpBuffer> paint_op_buffer_; | |
| base::OnceClosure callback_; | |
| }; | |
| RasterImageRepresentation(SharedImageManager* manager, | |
| SharedImageBacking* backing, | |
| MemoryTypeTracker* tracker) | |
| : SharedImageRepresentation(manager, backing, tracker) {} | |
| std::unique_ptr<ScopedReadAccess> BeginScopedReadAccess(); | |
| std::unique_ptr<ScopedWriteAccess> BeginScopedWriteAccess( | |
| scoped_refptr<SharedContextState> context_state, | |
| int final_msaa_count, | |
| const SkSurfaceProps& surface_props, | |
| const std::optional<SkColor4f>& clear_color, | |
| bool visible); | |
| protected: | |
| virtual cc::PaintOpBuffer* BeginReadAccess( | |
| std::optional<SkColor4f>& clear_color) = 0; | |
| virtual void EndReadAccess() = 0; | |
| virtual cc::PaintOpBuffer* BeginWriteAccess( | |
| scoped_refptr<SharedContextState> context_state, | |
| int final_msaa_count, | |
| const SkSurfaceProps& surface_props, | |
| const std::optional<SkColor4f>& clear_color, | |
| bool visible) = 0; | |
| virtual void EndWriteAccess(base::OnceClosure callback) = 0; | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////// | |
| // VideoImageRepresentation | |
| #if BUILDFLAG(IS_WIN) | |
| // Holds a D3D11 texture array, and index into it. | |
| struct GPU_GLES2_EXPORT D3D11TextureAndArrayIndex { | |
| D3D11TextureAndArrayIndex(Microsoft::WRL::ComPtr<ID3D11Texture2D> texture, | |
| size_t array_index); | |
| D3D11TextureAndArrayIndex(const D3D11TextureAndArrayIndex& other); | |
| D3D11TextureAndArrayIndex(D3D11TextureAndArrayIndex&& other); | |
| ~D3D11TextureAndArrayIndex(); | |
| Microsoft::WRL::ComPtr<ID3D11Texture2D> texture; | |
| size_t array_index = 0; | |
| }; | |
| #endif // BUILDFLAG(IS_WIN) | |
| class GPU_GLES2_EXPORT VideoImageRepresentation | |
| : public SharedImageRepresentation { | |
| public: | |
| class GPU_GLES2_EXPORT ScopedWriteAccess | |
| : public ScopedAccessBase<VideoImageRepresentation> { | |
| public: | |
| ScopedWriteAccess(base::PassKey<VideoImageRepresentation> pass_key, | |
| VideoImageRepresentation* representation); | |
| ~ScopedWriteAccess(); | |
| #if BUILDFLAG(IS_WIN) | |
| D3D11TextureAndArrayIndex GetD3D11Texture() const { | |
| return representation()->GetD3D11Texture(); | |
| } | |
| #endif // BUILDFLAG(IS_WIN) | |
| }; | |
| class GPU_GLES2_EXPORT ScopedReadAccess | |
| : public ScopedAccessBase<VideoImageRepresentation> { | |
| public: | |
| ScopedReadAccess(base::PassKey<VideoImageRepresentation> pass_key, | |
| VideoImageRepresentation* representation); | |
| ~ScopedReadAccess(); | |
| #if BUILDFLAG(IS_WIN) | |
| D3D11TextureAndArrayIndex GetD3D11Texture() const { | |
| return representation()->GetD3D11Texture(); | |
| } | |
| #endif // BUILDFLAG(IS_WIN) | |
| #if BUILDFLAG(IS_ANDROID) | |
| AHardwareBuffer* GetAHardwareBuffer() const { | |
| return representation()->GetAHardwareBuffer(); | |
| } | |
| #endif // BUILDFLAG(IS_ANDROID) | |
| }; | |
| VideoImageRepresentation(SharedImageManager* manager, | |
| SharedImageBacking* backing, | |
| MemoryTypeTracker* tracker); | |
| ~VideoImageRepresentation() override; | |
| virtual std::unique_ptr<ScopedWriteAccess> BeginScopedWriteAccess(); | |
| virtual std::unique_ptr<ScopedReadAccess> BeginScopedReadAccess(); | |
| protected: | |
| friend class WrappedVideoCompoundImageRepresentation; | |
| #if BUILDFLAG(IS_WIN) | |
| virtual D3D11TextureAndArrayIndex GetD3D11Texture() const = 0; | |
| #endif // BUILDFLAG(IS_WIN) | |
| #if BUILDFLAG(IS_ANDROID) | |
| virtual AHardwareBuffer* GetAHardwareBuffer() const = 0; | |
| #endif // BUILDFLAG(IS_ANDROID) | |
| virtual bool BeginWriteAccess() = 0; | |
| virtual void EndWriteAccess() = 0; | |
| virtual bool BeginReadAccess() = 0; | |
| virtual void EndReadAccess() = 0; | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////// | |
| // VulkanImageRepresentation | |
| #if BUILDFLAG(ENABLE_VULKAN) | |
| class GPU_GLES2_EXPORT VulkanImageRepresentation | |
| : public SharedImageRepresentation { | |
| public: | |
| VulkanImageRepresentation(SharedImageManager* manager, | |
| SharedImageBacking* backing, | |
| MemoryTypeTracker* tracker, | |
| std::unique_ptr<gpu::VulkanImage> vulkan_image, | |
| gpu::VulkanDeviceQueue* vulkan_device_queue, | |
| gpu::VulkanImplementation& vulkan_impl); | |
| ~VulkanImageRepresentation() override; | |
| class ScopedAccess : public ScopedAccessBase<VulkanImageRepresentation> { | |
| public: | |
| ScopedAccess( | |
| VulkanImageRepresentation* representation, | |
| AccessMode access_mode, | |
| std::vector<base::RawPtrIfPtrT<VkSemaphore, DanglingUntriaged>> | |
| begin_semaphores, | |
| base::RawPtrIfPtrT<VkSemaphore, DanglingUntriaged> end_semaphore); | |
| ~ScopedAccess(); | |
| gpu::VulkanImage& GetVulkanImage(); | |
| private: | |
| bool is_read_only_; | |
| std::vector<base::RawPtrIfPtrT<VkSemaphore, DanglingUntriaged>> | |
| begin_semaphores_; | |
| base::RawPtrIfPtrT<VkSemaphore, DanglingUntriaged> end_semaphore_; | |
| }; | |
| std::unique_ptr<ScopedAccess> BeginScopedAccess( | |
| AccessMode access_mode, | |
| std::vector<VkSemaphore>& begin_semaphores, | |
| std::vector<VkSemaphore>& end_semaphores); | |
| virtual bool BeginAccess( | |
| AccessMode access_mode, | |
| std::vector<base::RawPtrIfPtrT<VkSemaphore, DanglingUntriaged>>& | |
| begin_semaphores, | |
| std::vector<base::RawPtrIfPtrT<VkSemaphore, DanglingUntriaged>>& | |
| end_semaphores) = 0; | |
| virtual void EndAccess(bool is_read_only, VkSemaphore end_semaphore) = 0; | |
| virtual gpu::VulkanImage& GetVulkanImage(); | |
| protected: | |
| friend class WrappedVulkanCompoundImageRepresentation; | |
| std::unique_ptr<gpu::VulkanImage> vulkan_image_; | |
| raw_ptr<gpu::VulkanDeviceQueue> vulkan_device_queue_; | |
| raw_ref<VulkanImplementation> vulkan_impl_; | |
| }; | |
| #endif | |
| } // namespace gpu | |
| #endif // GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_SHARED_IMAGE_REPRESENTATION_H_ |