// Copyright 2013 The Flutter 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 FLUTTER_IMPELLER_RENDERER_RENDER_TARGET_H_ #define FLUTTER_IMPELLER_RENDERER_RENDER_TARGET_H_ #include #include #include #include "flutter/fml/hash_combine.h" #include "impeller/core/allocator.h" #include "impeller/core/formats.h" #include "impeller/geometry/size.h" namespace impeller { class Context; struct RenderTargetConfig { ISize size = ISize{0, 0}; size_t mip_count = 0; bool has_msaa = false; bool has_depth_stencil = false; constexpr bool operator==(const RenderTargetConfig& o) const { return size == o.size && mip_count == o.mip_count && has_msaa == o.has_msaa && has_depth_stencil == o.has_depth_stencil; } constexpr size_t Hash() const { return fml::HashCombine(size.width, size.height, mip_count, has_msaa, has_depth_stencil); } }; class RenderTarget final { public: struct AttachmentConfig { StorageMode storage_mode; LoadAction load_action; StoreAction store_action; Color clear_color; }; struct AttachmentConfigMSAA { StorageMode storage_mode; StorageMode resolve_storage_mode; LoadAction load_action; StoreAction store_action; Color clear_color; }; static constexpr AttachmentConfig kDefaultColorAttachmentConfig = { .storage_mode = StorageMode::kDevicePrivate, .load_action = LoadAction::kClear, .store_action = StoreAction::kStore, .clear_color = Color::BlackTransparent()}; static constexpr AttachmentConfigMSAA kDefaultColorAttachmentConfigMSAA = { .storage_mode = StorageMode::kDeviceTransient, .resolve_storage_mode = StorageMode::kDevicePrivate, .load_action = LoadAction::kClear, .store_action = StoreAction::kMultisampleResolve, .clear_color = Color::BlackTransparent()}; static constexpr AttachmentConfig kDefaultStencilAttachmentConfig = { .storage_mode = StorageMode::kDeviceTransient, .load_action = LoadAction::kClear, .store_action = StoreAction::kDontCare, .clear_color = Color::BlackTransparent()}; RenderTarget(); ~RenderTarget(); bool IsValid() const; void SetupDepthStencilAttachments( const Context& context, Allocator& allocator, ISize size, bool msaa, const std::string& label = "Offscreen", RenderTarget::AttachmentConfig stencil_attachment_config = RenderTarget::kDefaultStencilAttachmentConfig, const std::shared_ptr& depth_stencil_texture = nullptr); SampleCount GetSampleCount() const; bool HasColorAttachment(size_t index) const; ISize GetRenderTargetSize() const; std::shared_ptr GetRenderTargetTexture() const; PixelFormat GetRenderTargetPixelFormat() const; std::optional GetColorAttachmentSize(size_t index) const; RenderTarget& SetColorAttachment(const ColorAttachment& attachment, size_t index); RenderTarget& SetDepthAttachment(std::optional attachment); RenderTarget& SetStencilAttachment( std::optional attachment); size_t GetMaxColorAttacmentBindIndex() const; const std::map& GetColorAttachments() const; const std::optional& GetDepthAttachment() const; const std::optional& GetStencilAttachment() const; size_t GetTotalAttachmentCount() const; void IterateAllAttachments( const std::function& iterator) const; std::string ToString() const; RenderTargetConfig ToConfig() const { auto& color_attachment = GetColorAttachments().find(0)->second; return RenderTargetConfig{ .size = color_attachment.texture->GetSize(), .mip_count = color_attachment.texture->GetMipCount(), .has_msaa = color_attachment.resolve_texture != nullptr, .has_depth_stencil = depth_.has_value() && stencil_.has_value()}; } private: std::map colors_; std::optional depth_; std::optional stencil_; }; /// @brief a wrapper around the impeller [Allocator] instance that can be used /// to provide caching of allocated render target textures. class RenderTargetAllocator { public: explicit RenderTargetAllocator(std::shared_ptr allocator); virtual ~RenderTargetAllocator() = default; virtual RenderTarget CreateOffscreen( const Context& context, ISize size, int mip_count, const std::string& label = "Offscreen", RenderTarget::AttachmentConfig color_attachment_config = RenderTarget::kDefaultColorAttachmentConfig, std::optional stencil_attachment_config = RenderTarget::kDefaultStencilAttachmentConfig, const std::shared_ptr& existing_color_texture = nullptr, const std::shared_ptr& existing_depth_stencil_texture = nullptr); virtual RenderTarget CreateOffscreenMSAA( const Context& context, ISize size, int mip_count, const std::string& label = "Offscreen MSAA", RenderTarget::AttachmentConfigMSAA color_attachment_config = RenderTarget::kDefaultColorAttachmentConfigMSAA, std::optional stencil_attachment_config = RenderTarget::kDefaultStencilAttachmentConfig, const std::shared_ptr& existing_color_msaa_texture = nullptr, const std::shared_ptr& existing_color_resolve_texture = nullptr, const std::shared_ptr& existing_depth_stencil_texture = nullptr); /// @brief Mark the beginning of a frame workload. /// /// This may be used to reset any tracking state on whether or not a /// particular texture instance is still in use. virtual void Start(); /// @brief Mark the end of a frame workload. /// /// This may be used to deallocate any unused textures. virtual void End(); private: std::shared_ptr allocator_; }; } // namespace impeller #endif // FLUTTER_IMPELLER_RENDERER_RENDER_TARGET_H_