blob: c96dc6a065accd2e1969d84f9613569b6adc800a [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.
#include "impeller/entity/render_target_cache.h"
#include "impeller/renderer/render_target.h"
namespace impeller {
RenderTargetCache::RenderTargetCache(std::shared_ptr<Allocator> allocator)
: RenderTargetAllocator(std::move(allocator)) {}
void RenderTargetCache::Start() {
for (auto& td : render_target_data_) {
td.used_this_frame = false;
}
}
void RenderTargetCache::End() {
std::vector<RenderTargetData> retain;
for (const auto& td : render_target_data_) {
if (td.used_this_frame) {
retain.push_back(td);
}
}
render_target_data_.swap(retain);
}
RenderTarget RenderTargetCache::CreateOffscreen(
const Context& context,
ISize size,
int mip_count,
const std::string& label,
RenderTarget::AttachmentConfig color_attachment_config,
std::optional<RenderTarget::AttachmentConfig> stencil_attachment_config,
const std::shared_ptr<Texture>& existing_color_texture,
const std::shared_ptr<Texture>& existing_depth_stencil_texture) {
if (size.IsEmpty()) {
return {};
}
FML_DCHECK(existing_color_texture == nullptr &&
existing_depth_stencil_texture == nullptr);
auto config = RenderTargetConfig{
.size = size,
.mip_count = static_cast<size_t>(mip_count),
.has_msaa = false,
.has_depth_stencil = stencil_attachment_config.has_value(),
};
for (auto& render_target_data : render_target_data_) {
const auto other_config = render_target_data.config;
if (!render_target_data.used_this_frame && other_config == config) {
render_target_data.used_this_frame = true;
auto color0 = render_target_data.render_target.GetColorAttachments()
.find(0u)
->second;
auto depth = render_target_data.render_target.GetDepthAttachment();
std::shared_ptr<Texture> depth_tex = depth ? depth->texture : nullptr;
return RenderTargetAllocator::CreateOffscreen(
context, size, mip_count, label, color_attachment_config,
stencil_attachment_config, color0.texture, depth_tex);
}
}
RenderTarget created_target = RenderTargetAllocator::CreateOffscreen(
context, size, mip_count, label, color_attachment_config,
stencil_attachment_config);
if (!created_target.IsValid()) {
return created_target;
}
render_target_data_.push_back(
RenderTargetData{.used_this_frame = true,
.config = config,
.render_target = created_target});
return created_target;
}
RenderTarget RenderTargetCache::CreateOffscreenMSAA(
const Context& context,
ISize size,
int mip_count,
const std::string& label,
RenderTarget::AttachmentConfigMSAA color_attachment_config,
std::optional<RenderTarget::AttachmentConfig> stencil_attachment_config,
const std::shared_ptr<Texture>& existing_color_msaa_texture,
const std::shared_ptr<Texture>& existing_color_resolve_texture,
const std::shared_ptr<Texture>& existing_depth_stencil_texture) {
if (size.IsEmpty()) {
return {};
}
FML_DCHECK(existing_color_msaa_texture == nullptr &&
existing_color_resolve_texture == nullptr &&
existing_depth_stencil_texture == nullptr);
auto config = RenderTargetConfig{
.size = size,
.mip_count = static_cast<size_t>(mip_count),
.has_msaa = true,
.has_depth_stencil = stencil_attachment_config.has_value(),
};
for (auto& render_target_data : render_target_data_) {
const auto other_config = render_target_data.config;
if (!render_target_data.used_this_frame && other_config == config) {
render_target_data.used_this_frame = true;
auto color0 = render_target_data.render_target.GetColorAttachments()
.find(0u)
->second;
auto depth = render_target_data.render_target.GetDepthAttachment();
std::shared_ptr<Texture> depth_tex = depth ? depth->texture : nullptr;
return RenderTargetAllocator::CreateOffscreenMSAA(
context, size, mip_count, label, color_attachment_config,
stencil_attachment_config, color0.texture, color0.resolve_texture,
depth_tex);
}
}
RenderTarget created_target = RenderTargetAllocator::CreateOffscreenMSAA(
context, size, mip_count, label, color_attachment_config,
stencil_attachment_config);
if (!created_target.IsValid()) {
return created_target;
}
render_target_data_.push_back(
RenderTargetData{.used_this_frame = true,
.config = config,
.render_target = created_target});
return created_target;
}
size_t RenderTargetCache::CachedTextureCount() const {
return render_target_data_.size();
}
} // namespace impeller