// 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. #ifndef FLUTTER_IMPELLER_RENDERER_COMMAND_BUFFER_H_ #define FLUTTER_IMPELLER_RENDERER_COMMAND_BUFFER_H_ #include #include #include "impeller/renderer/blit_pass.h" #include "impeller/renderer/compute_pass.h" namespace impeller { class ComputePass; class Context; class RenderPass; class RenderTarget; class CommandQueue; namespace testing { class CommandBufferMock; } //------------------------------------------------------------------------------ /// @brief A collection of encoded commands to be submitted to the GPU for /// execution. A command buffer is obtained from a graphics /// `Context`. /// /// To submit commands to the GPU, acquire a `RenderPass` from the /// command buffer and record `Command`s into that pass. A /// `RenderPass` describes the configuration of the various /// attachments when the command is submitted. /// /// A command buffer is only meant to be used on a single thread. If /// a frame workload needs to be encoded from multiple threads, /// set up and record into multiple command buffers. The order of /// submission of commands encoded in multiple command buffers can /// be controlled via either the order in which the command buffers /// were created, or, using the `ReserveSpotInQueue` command which /// allows for encoding commands for submission in an order that is /// different from the encoding order. /// class CommandBuffer { friend class testing::CommandBufferMock; public: enum class Status { kPending, kError, kCompleted, }; using CompletionCallback = std::function; virtual ~CommandBuffer(); virtual bool IsValid() const = 0; virtual void SetLabel(const std::string& label) const = 0; //---------------------------------------------------------------------------- /// @brief Force execution of pending GPU commands. /// void WaitUntilScheduled(); //---------------------------------------------------------------------------- /// @brief Create a render pass to record render commands into. /// /// @param[in] render_target The description of the render target this pass /// will target. /// /// @return A valid render pass or null. /// std::shared_ptr CreateRenderPass( const RenderTarget& render_target); //---------------------------------------------------------------------------- /// @brief Create a blit pass to record blit commands into. /// /// @return A valid blit pass or null. /// std::shared_ptr CreateBlitPass(); //---------------------------------------------------------------------------- /// @brief Create a compute pass to record compute commands into. /// /// @return A valid compute pass or null. /// std::shared_ptr CreateComputePass(); protected: std::weak_ptr context_; explicit CommandBuffer(std::weak_ptr context); virtual std::shared_ptr OnCreateRenderPass( RenderTarget render_target) = 0; virtual std::shared_ptr OnCreateBlitPass() = 0; [[nodiscard]] virtual bool OnSubmitCommands(CompletionCallback callback) = 0; virtual void OnWaitUntilScheduled() = 0; virtual std::shared_ptr OnCreateComputePass() = 0; private: friend class CommandQueue; //---------------------------------------------------------------------------- /// @brief Schedule the command encoded by render passes within this /// command buffer on the GPU. The encoding of these commnands is /// performed immediately on the calling thread. /// /// A command buffer may only be committed once. /// /// @param[in] callback The completion callback. /// [[nodiscard]] bool SubmitCommands(const CompletionCallback& callback); [[nodiscard]] bool SubmitCommands(); CommandBuffer(const CommandBuffer&) = delete; CommandBuffer& operator=(const CommandBuffer&) = delete; }; } // namespace impeller #endif // FLUTTER_IMPELLER_RENDERER_COMMAND_BUFFER_H_