blob: 844692ef4be7235496a6a16cc7b9112a69aafb7d [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/renderer/render_target_builder.h"
#include "impeller/base/strings.h"
#include "impeller/base/validation.h"
#include "impeller/renderer/allocator.h"
#include "impeller/renderer/context.h"
#include "impeller/renderer/texture.h"
namespace impeller {
RenderTargetBuilder::RenderTargetBuilder() = default;
RenderTargetBuilder::~RenderTargetBuilder() = default;
RenderTarget RenderTargetBuilder::Build(const Context& context) const {
if (render_target_type_ == RenderTargetType::kOffscreen) {
return CreateOffscreen(context);
} else if (render_target_type_ == RenderTargetType::kOffscreenMSAA) {
return CreateOffscreenMSAA(context);
} else {
return {};
}
}
RenderTarget RenderTargetBuilder::CreateOffscreen(
const Context& context) const {
if (size_.IsEmpty()) {
return {};
}
TextureDescriptor color_tex0;
color_tex0.storage_mode = color_storage_mode_;
color_tex0.format = PixelFormat::kDefaultColor;
color_tex0.size = size_;
color_tex0.usage = static_cast<uint64_t>(TextureUsage::kRenderTarget) |
static_cast<uint64_t>(TextureUsage::kShaderRead);
TextureDescriptor stencil_tex0;
stencil_tex0.storage_mode = stencil_storage_mode_;
stencil_tex0.format = PixelFormat::kDefaultStencil;
stencil_tex0.size = size_;
stencil_tex0.usage =
static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
ColorAttachment color0;
color0.clear_color = Color::BlackTransparent();
color0.load_action = color_load_action_;
color0.store_action = color_store_action_;
color0.texture = context.GetResourceAllocator()->CreateTexture(color_tex0);
if (!color0.texture) {
return {};
}
color0.texture->SetLabel(SPrintF("%s Color Texture", label_.c_str()));
StencilAttachment stencil0;
stencil0.load_action = stencil_load_action_;
stencil0.store_action = stencil_store_action_;
stencil0.clear_stencil = 0u;
stencil0.texture =
context.GetResourceAllocator()->CreateTexture(stencil_tex0);
if (!stencil0.texture) {
return {};
}
stencil0.texture->SetLabel(SPrintF("%s Stencil Texture", label_.c_str()));
RenderTarget target;
target.SetColorAttachment(std::move(color0), 0u);
target.SetStencilAttachment(std::move(stencil0));
return target;
}
RenderTarget RenderTargetBuilder::CreateOffscreenMSAA(
const Context& context) const {
if (size_.IsEmpty()) {
return {};
}
// Create MSAA color texture.
TextureDescriptor color0_tex_desc;
color0_tex_desc.storage_mode = color_storage_mode_;
color0_tex_desc.type = TextureType::kTexture2DMultisample;
color0_tex_desc.sample_count = SampleCount::kCount4;
color0_tex_desc.format = PixelFormat::kDefaultColor;
color0_tex_desc.size = size_;
color0_tex_desc.usage = static_cast<uint64_t>(TextureUsage::kRenderTarget);
auto color0_msaa_tex =
context.GetResourceAllocator()->CreateTexture(color0_tex_desc);
if (!color0_msaa_tex) {
VALIDATION_LOG << "Could not create multisample color texture.";
return {};
}
color0_msaa_tex->SetLabel(
SPrintF("%s Color Texture (Multisample)", label_.c_str()));
// Create color resolve texture.
TextureDescriptor color0_resolve_tex_desc;
color0_resolve_tex_desc.storage_mode = color_resolve_storage_mode_;
color0_resolve_tex_desc.format = PixelFormat::kDefaultColor;
color0_resolve_tex_desc.size = size_;
color0_resolve_tex_desc.usage =
static_cast<uint64_t>(TextureUsage::kRenderTarget) |
static_cast<uint64_t>(TextureUsage::kShaderRead);
auto color0_resolve_tex =
context.GetResourceAllocator()->CreateTexture(color0_resolve_tex_desc);
if (!color0_resolve_tex) {
VALIDATION_LOG << "Could not create color texture.";
return {};
}
color0_resolve_tex->SetLabel(SPrintF("%s Color Texture", label_.c_str()));
// Color attachment.
ColorAttachment color0;
color0.clear_color = Color::BlackTransparent();
color0.load_action = color_load_action_;
color0.store_action = color_store_action_;
color0.texture = color0_msaa_tex;
color0.resolve_texture = color0_resolve_tex;
// Create MSAA stencil texture.
TextureDescriptor stencil_tex0;
stencil_tex0.storage_mode = stencil_storage_mode_;
stencil_tex0.type = TextureType::kTexture2DMultisample;
stencil_tex0.sample_count = SampleCount::kCount4;
stencil_tex0.format = PixelFormat::kDefaultStencil;
stencil_tex0.size = size_;
stencil_tex0.usage =
static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
StencilAttachment stencil0;
stencil0.load_action = stencil_load_action_;
stencil0.store_action = stencil_store_action_;
stencil0.clear_stencil = 0u;
stencil0.texture =
context.GetResourceAllocator()->CreateTexture(stencil_tex0);
if (!stencil0.texture) {
return {};
}
stencil0.texture->SetLabel(SPrintF("%s Stencil Texture", label_.c_str()));
RenderTarget target;
target.SetColorAttachment(std::move(color0), 0u);
target.SetStencilAttachment(std::move(stencil0));
return target;
}
RenderTargetBuilder& RenderTargetBuilder::SetSize(ISize size) {
size_ = size;
return *this;
}
RenderTargetBuilder& RenderTargetBuilder::SetLabel(std::string label) {
label_ = label;
return *this;
}
RenderTargetBuilder& RenderTargetBuilder::SetColorStorageMode(
StorageMode mode) {
color_storage_mode_ = mode;
return *this;
}
RenderTargetBuilder& RenderTargetBuilder::SetColorLoadAction(
LoadAction action) {
color_load_action_ = action;
return *this;
}
RenderTargetBuilder& RenderTargetBuilder::SetColorStoreAction(
StoreAction action) {
color_store_action_ = action;
return *this;
}
RenderTargetBuilder& RenderTargetBuilder::SetStencilStorageMode(
StorageMode mode) {
stencil_storage_mode_ = mode;
return *this;
}
RenderTargetBuilder& RenderTargetBuilder::SetStencilLoadAction(
LoadAction action) {
stencil_load_action_ = action;
return *this;
}
RenderTargetBuilder& RenderTargetBuilder::SetStencilStoreAction(
StoreAction action) {
stencil_store_action_ = action;
return *this;
}
RenderTargetBuilder& RenderTargetBuilder::SetColorResolveStorageMode(
StorageMode mode) {
color_resolve_storage_mode_ = mode;
return *this;
}
RenderTargetBuilder& RenderTargetBuilder::SetRenderTargetType(
RenderTargetType type) {
render_target_type_ = type;
return *this;
}
} // namespace impeller