| // 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 |