blob: 3fc4f50d16b632aca5d6d3f028d4412fb980a625 [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_pass.h"
#include "fml/status.h"
namespace impeller {
RenderPass::RenderPass(std::shared_ptr<const Context> context,
const RenderTarget& target)
: context_(std::move(context)),
sample_count_(target.GetSampleCount()),
pixel_format_(target.GetRenderTargetPixelFormat()),
has_depth_attachment_(target.GetDepthAttachment().has_value()),
has_stencil_attachment_(target.GetStencilAttachment().has_value()),
render_target_size_(target.GetRenderTargetSize()),
render_target_(target),
orthographic_(Matrix::MakeOrthographic(render_target_size_)) {}
RenderPass::~RenderPass() {}
SampleCount RenderPass::GetSampleCount() const {
return sample_count_;
}
PixelFormat RenderPass::GetRenderTargetPixelFormat() const {
return pixel_format_;
}
bool RenderPass::HasDepthAttachment() const {
return has_depth_attachment_;
}
bool RenderPass::HasStencilAttachment() const {
return has_stencil_attachment_;
}
const RenderTarget& RenderPass::GetRenderTarget() const {
return render_target_;
}
ISize RenderPass::GetRenderTargetSize() const {
return render_target_size_;
}
const Matrix& RenderPass::GetOrthographicTransform() const {
return orthographic_;
}
void RenderPass::SetLabel(std::string label) {
if (label.empty()) {
return;
}
OnSetLabel(std::move(label));
}
bool RenderPass::AddCommand(Command&& command) {
if (!command.IsValid()) {
VALIDATION_LOG << "Attempted to add an invalid command to the render pass.";
return false;
}
if (command.scissor.has_value()) {
auto target_rect = IRect::MakeSize(render_target_.GetRenderTargetSize());
if (!target_rect.Contains(command.scissor.value())) {
VALIDATION_LOG << "Cannot apply a scissor that lies outside the bounds "
"of the render target.";
return false;
}
}
if (command.vertex_buffer.vertex_count == 0u ||
command.instance_count == 0u) {
// Essentially a no-op. Don't record the command but this is not necessary
// an error either.
return true;
}
commands_.emplace_back(std::move(command));
return true;
}
bool RenderPass::EncodeCommands() const {
return OnEncodeCommands(*context_);
}
const std::shared_ptr<const Context>& RenderPass::GetContext() const {
return context_;
}
void RenderPass::SetPipeline(
const std::shared_ptr<Pipeline<PipelineDescriptor>>& pipeline) {
pending_.pipeline = pipeline;
}
void RenderPass::SetCommandLabel(std::string_view label) {
#ifdef IMPELLER_DEBUG
pending_.label = std::string(label);
#endif // IMPELLER_DEBUG
}
void RenderPass::SetStencilReference(uint32_t value) {
pending_.stencil_reference = value;
}
void RenderPass::SetBaseVertex(uint64_t value) {
pending_.base_vertex = value;
}
void RenderPass::SetViewport(Viewport viewport) {
pending_.viewport = viewport;
}
void RenderPass::SetScissor(IRect scissor) {
pending_.scissor = scissor;
}
void RenderPass::SetInstanceCount(size_t count) {
pending_.instance_count = count;
}
bool RenderPass::SetVertexBuffer(VertexBuffer buffer) {
return pending_.BindVertices(std::move(buffer));
}
fml::Status RenderPass::Draw() {
auto result = AddCommand(std::move(pending_));
pending_ = Command{};
if (result) {
return fml::Status();
}
return fml::Status(fml::StatusCode::kInvalidArgument,
"Failed to encode command");
}
// |ResourceBinder|
bool RenderPass::BindResource(ShaderStage stage,
DescriptorType type,
const ShaderUniformSlot& slot,
const ShaderMetadata& metadata,
BufferView view) {
return pending_.BindResource(stage, type, slot, metadata, view);
}
bool RenderPass::BindResource(
ShaderStage stage,
DescriptorType type,
const ShaderUniformSlot& slot,
const std::shared_ptr<const ShaderMetadata>& metadata,
BufferView view) {
return pending_.BindResource(stage, type, slot, metadata, std::move(view));
}
// |ResourceBinder|
bool RenderPass::BindResource(ShaderStage stage,
DescriptorType type,
const SampledImageSlot& slot,
const ShaderMetadata& metadata,
std::shared_ptr<const Texture> texture,
const std::unique_ptr<const Sampler>& sampler) {
return pending_.BindResource(stage, type, slot, metadata, std::move(texture),
sampler);
}
} // namespace impeller