blob: eef517b30c8473071fd3c26f85547d53320d7645 [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/pipeline_descriptor.h"
#include "impeller/core/formats.h"
#include "impeller/renderer/shader_function.h"
#include "impeller/renderer/shader_library.h"
#include "impeller/renderer/vertex_descriptor.h"
namespace impeller {
PipelineDescriptor::PipelineDescriptor() = default;
PipelineDescriptor::~PipelineDescriptor() = default;
// Comparable<PipelineDescriptor>
std::size_t PipelineDescriptor::GetHash() const {
auto seed = fml::HashCombine();
fml::HashCombineSeed(seed, label_);
fml::HashCombineSeed(seed, sample_count_);
for (const auto& entry : entrypoints_) {
fml::HashCombineSeed(seed, entry.first);
if (auto second = entry.second) {
fml::HashCombineSeed(seed, second->GetHash());
}
}
for (const auto& des : color_attachment_descriptors_) {
fml::HashCombineSeed(seed, des.first);
fml::HashCombineSeed(seed, des.second.Hash());
}
if (vertex_descriptor_) {
fml::HashCombineSeed(seed, vertex_descriptor_->GetHash());
}
fml::HashCombineSeed(seed, depth_pixel_format_);
fml::HashCombineSeed(seed, stencil_pixel_format_);
fml::HashCombineSeed(seed, depth_attachment_descriptor_);
fml::HashCombineSeed(seed, front_stencil_attachment_descriptor_);
fml::HashCombineSeed(seed, back_stencil_attachment_descriptor_);
fml::HashCombineSeed(seed, winding_order_);
fml::HashCombineSeed(seed, cull_mode_);
fml::HashCombineSeed(seed, primitive_type_);
fml::HashCombineSeed(seed, polygon_mode_);
return seed;
}
// Comparable<PipelineDescriptor>
bool PipelineDescriptor::IsEqual(const PipelineDescriptor& other) const {
return label_ == other.label_ && sample_count_ == other.sample_count_ &&
DeepCompareMap(entrypoints_, other.entrypoints_) &&
color_attachment_descriptors_ == other.color_attachment_descriptors_ &&
DeepComparePointer(vertex_descriptor_, other.vertex_descriptor_) &&
stencil_pixel_format_ == other.stencil_pixel_format_ &&
depth_pixel_format_ == other.depth_pixel_format_ &&
depth_attachment_descriptor_ == other.depth_attachment_descriptor_ &&
front_stencil_attachment_descriptor_ ==
other.front_stencil_attachment_descriptor_ &&
back_stencil_attachment_descriptor_ ==
other.back_stencil_attachment_descriptor_ &&
winding_order_ == other.winding_order_ &&
cull_mode_ == other.cull_mode_ &&
primitive_type_ == other.primitive_type_ &&
polygon_mode_ == other.polygon_mode_;
}
PipelineDescriptor& PipelineDescriptor::SetLabel(std::string label) {
label_ = std::move(label);
return *this;
}
PipelineDescriptor& PipelineDescriptor::SetSampleCount(SampleCount samples) {
sample_count_ = samples;
return *this;
}
PipelineDescriptor& PipelineDescriptor::AddStageEntrypoint(
std::shared_ptr<const ShaderFunction> function) {
if (!function) {
return *this;
}
if (function->GetStage() == ShaderStage::kUnknown) {
return *this;
}
entrypoints_[function->GetStage()] = std::move(function);
return *this;
}
PipelineDescriptor& PipelineDescriptor::SetVertexDescriptor(
std::shared_ptr<VertexDescriptor> vertex_descriptor) {
vertex_descriptor_ = std::move(vertex_descriptor);
return *this;
}
size_t PipelineDescriptor::GetMaxColorAttacmentBindIndex() const {
size_t max = 0;
for (const auto& color : color_attachment_descriptors_) {
max = std::max(color.first, max);
}
return max;
}
PipelineDescriptor& PipelineDescriptor::SetColorAttachmentDescriptor(
size_t index,
ColorAttachmentDescriptor desc) {
color_attachment_descriptors_[index] = desc;
return *this;
}
PipelineDescriptor& PipelineDescriptor::SetColorAttachmentDescriptors(
std::map<size_t /* index */, ColorAttachmentDescriptor> descriptors) {
color_attachment_descriptors_ = std::move(descriptors);
return *this;
}
const ColorAttachmentDescriptor*
PipelineDescriptor::GetColorAttachmentDescriptor(size_t index) const {
auto found = color_attachment_descriptors_.find(index);
return found == color_attachment_descriptors_.end() ? nullptr
: &found->second;
}
const ColorAttachmentDescriptor*
PipelineDescriptor::GetLegacyCompatibleColorAttachment() const {
// Legacy renderers may only render to a single color attachment at index 0u.
if (color_attachment_descriptors_.size() != 1u) {
return nullptr;
}
return GetColorAttachmentDescriptor(0u);
}
PipelineDescriptor& PipelineDescriptor::SetDepthPixelFormat(
PixelFormat format) {
depth_pixel_format_ = format;
return *this;
}
PipelineDescriptor& PipelineDescriptor::SetStencilPixelFormat(
PixelFormat format) {
stencil_pixel_format_ = format;
return *this;
}
PipelineDescriptor& PipelineDescriptor::SetDepthStencilAttachmentDescriptor(
std::optional<DepthAttachmentDescriptor> desc) {
depth_attachment_descriptor_ = desc;
return *this;
}
PipelineDescriptor& PipelineDescriptor::SetStencilAttachmentDescriptors(
std::optional<StencilAttachmentDescriptor> front_and_back) {
return SetStencilAttachmentDescriptors(front_and_back, front_and_back);
}
PipelineDescriptor& PipelineDescriptor::SetStencilAttachmentDescriptors(
std::optional<StencilAttachmentDescriptor> front,
std::optional<StencilAttachmentDescriptor> back) {
front_stencil_attachment_descriptor_ = front;
back_stencil_attachment_descriptor_ = back;
return *this;
}
void PipelineDescriptor::ClearStencilAttachments() {
back_stencil_attachment_descriptor_.reset();
front_stencil_attachment_descriptor_.reset();
SetStencilPixelFormat(impeller::PixelFormat::kUnknown);
}
void PipelineDescriptor::ClearDepthAttachment() {
depth_attachment_descriptor_.reset();
SetDepthPixelFormat(impeller::PixelFormat::kUnknown);
}
void PipelineDescriptor::ClearColorAttachment(size_t index) {
if (color_attachment_descriptors_.find(index) ==
color_attachment_descriptors_.end()) {
return;
}
color_attachment_descriptors_.erase(index);
}
void PipelineDescriptor::ResetAttachments() {
color_attachment_descriptors_.clear();
depth_attachment_descriptor_.reset();
front_stencil_attachment_descriptor_.reset();
back_stencil_attachment_descriptor_.reset();
}
PixelFormat PipelineDescriptor::GetStencilPixelFormat() const {
return stencil_pixel_format_;
}
std::optional<StencilAttachmentDescriptor>
PipelineDescriptor::GetFrontStencilAttachmentDescriptor() const {
return front_stencil_attachment_descriptor_;
}
std::optional<DepthAttachmentDescriptor>
PipelineDescriptor::GetDepthStencilAttachmentDescriptor() const {
return depth_attachment_descriptor_;
}
const std::map<size_t /* index */, ColorAttachmentDescriptor>&
PipelineDescriptor::GetColorAttachmentDescriptors() const {
return color_attachment_descriptors_;
}
const std::shared_ptr<VertexDescriptor>&
PipelineDescriptor::GetVertexDescriptor() const {
return vertex_descriptor_;
}
const std::map<ShaderStage, std::shared_ptr<const ShaderFunction>>&
PipelineDescriptor::GetStageEntrypoints() const {
return entrypoints_;
}
std::shared_ptr<const ShaderFunction> PipelineDescriptor::GetEntrypointForStage(
ShaderStage stage) const {
if (auto found = entrypoints_.find(stage); found != entrypoints_.end()) {
return found->second;
}
return nullptr;
}
const std::string& PipelineDescriptor::GetLabel() const {
return label_;
}
PixelFormat PipelineDescriptor::GetDepthPixelFormat() const {
return depth_pixel_format_;
}
std::optional<StencilAttachmentDescriptor>
PipelineDescriptor::GetBackStencilAttachmentDescriptor() const {
return back_stencil_attachment_descriptor_;
}
bool PipelineDescriptor::HasStencilAttachmentDescriptors() const {
return front_stencil_attachment_descriptor_.has_value() ||
back_stencil_attachment_descriptor_.has_value();
}
void PipelineDescriptor::SetCullMode(CullMode mode) {
cull_mode_ = mode;
}
CullMode PipelineDescriptor::GetCullMode() const {
return cull_mode_;
}
void PipelineDescriptor::SetWindingOrder(WindingOrder order) {
winding_order_ = order;
}
WindingOrder PipelineDescriptor::GetWindingOrder() const {
return winding_order_;
}
void PipelineDescriptor::SetPrimitiveType(PrimitiveType type) {
primitive_type_ = type;
}
PrimitiveType PipelineDescriptor::GetPrimitiveType() const {
return primitive_type_;
}
void PipelineDescriptor::SetPolygonMode(PolygonMode mode) {
polygon_mode_ = mode;
}
PolygonMode PipelineDescriptor::GetPolygonMode() const {
return polygon_mode_;
}
} // namespace impeller