blob: 6d635276ec1faf79501b94dfa2de7f66a17e30c2 [file] [log] [blame]
// 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 <functional>
#include <map>
#include <optional>
#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<Texture>& depth_stencil_texture = nullptr);
SampleCount GetSampleCount() const;
bool HasColorAttachment(size_t index) const;
ISize GetRenderTargetSize() const;
std::shared_ptr<Texture> GetRenderTargetTexture() const;
PixelFormat GetRenderTargetPixelFormat() const;
std::optional<ISize> GetColorAttachmentSize(size_t index) const;
RenderTarget& SetColorAttachment(const ColorAttachment& attachment,
size_t index);
RenderTarget& SetDepthAttachment(std::optional<DepthAttachment> attachment);
RenderTarget& SetStencilAttachment(
std::optional<StencilAttachment> attachment);
size_t GetMaxColorAttacmentBindIndex() const;
const std::map<size_t, ColorAttachment>& GetColorAttachments() const;
const std::optional<DepthAttachment>& GetDepthAttachment() const;
const std::optional<StencilAttachment>& GetStencilAttachment() const;
size_t GetTotalAttachmentCount() const;
void IterateAllAttachments(
const std::function<bool(const Attachment& attachment)>& 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<size_t, ColorAttachment> colors_;
std::optional<DepthAttachment> depth_;
std::optional<StencilAttachment> 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> 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<RenderTarget::AttachmentConfig> stencil_attachment_config =
RenderTarget::kDefaultStencilAttachmentConfig,
const std::shared_ptr<Texture>& existing_color_texture = nullptr,
const std::shared_ptr<Texture>& 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<RenderTarget::AttachmentConfig> stencil_attachment_config =
RenderTarget::kDefaultStencilAttachmentConfig,
const std::shared_ptr<Texture>& existing_color_msaa_texture = nullptr,
const std::shared_ptr<Texture>& existing_color_resolve_texture = nullptr,
const std::shared_ptr<Texture>& 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> allocator_;
};
} // namespace impeller
#endif // FLUTTER_IMPELLER_RENDERER_RENDER_TARGET_H_