| Flutter Impeller |

pipeline.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef FLUTTER_IMPELLER_RENDERER_PIPELINE_H_
6 #define FLUTTER_IMPELLER_RENDERER_PIPELINE_H_
7
8 #include <future>
9
10 #include "compute_pipeline_descriptor.h"
11 #include "impeller/core/raw_ptr.h"
12 #include "impeller/renderer/compute_pipeline_builder.h"
13 #include "impeller/renderer/compute_pipeline_descriptor.h"
14 #include "impeller/renderer/context.h"
15 #include "impeller/renderer/pipeline_builder.h"
16 #include "impeller/renderer/pipeline_descriptor.h"
17 #include "impeller/renderer/shader_stage_compatibility_checker.h"
18
19 namespace impeller {
20
21 using PipelineKey = int64_t;
22
23 class PipelineLibrary;
24 template <typename PipelineDescriptor_>
25 class Pipeline;
26
27 template <typename T>
28 struct PipelineFuture {
29 std::optional<T> descriptor;
30 std::shared_future<std::shared_ptr<Pipeline<T>>> future;
31
32 const std::shared_ptr<Pipeline<T>> Get() const { return future.get(); }
33
34 bool IsValid() const { return future.valid(); }
35 };
36
37 //------------------------------------------------------------------------------
38 /// @brief Describes the fixed function and programmable aspects of
39 /// rendering and compute operations performed by commands submitted
40 /// to the GPU via a command buffer.
41 ///
42 /// A pipeline handle must be allocated upfront and kept alive for
43 /// as long as possible. Do not create a pipeline object within a
44 /// frame workload.
45 ///
46 /// This pipeline object is almost never used directly as it is
47 /// untyped. Use reflected shader information generated by the
48 /// Impeller offline shader compiler to generate a typed pipeline
49 /// object.
50 ///
51 template <typename T>
52 class Pipeline {
53 public:
54 virtual ~Pipeline();
55
56 virtual bool IsValid() const = 0;
57
58 //----------------------------------------------------------------------------
59 /// @brief Get the descriptor that was responsible for creating this
60 /// pipeline. It may be copied and modified to create a pipeline
61 /// variant.
62 ///
63 /// @return The descriptor.
64 ///
65 const T& GetDescriptor() const;
66
67 PipelineFuture<T> CreateVariant(
68 bool async,
69 std::function<void(T& desc)> descriptor_callback) const;
70
71 protected:
72 const std::weak_ptr<PipelineLibrary> library_;
73
74 const T desc_;
75
76 Pipeline(std::weak_ptr<PipelineLibrary> library, T desc);
77
78 private:
79 Pipeline(const Pipeline&) = delete;
80
81 Pipeline& operator=(const Pipeline&) = delete;
82 };
83
84 /// @brief A raw ptr to a pipeline object.
85 ///
86 /// These pipeline refs are safe to use as the context will keep the
87 /// pipelines alive throughout rendering.
88 using PipelineRef = raw_ptr<Pipeline<PipelineDescriptor>>;
89
90 extern template class Pipeline<PipelineDescriptor>;
91 extern template class Pipeline<ComputePipelineDescriptor>;
92
93 /// @brief Create a pipeline for the given descriptor.
94 ///
95 /// If `async` is true, the compilation is performed on a worker thread. The
96 /// returned future will complete once that work is done. If `async` is false,
97 /// the work is done on the current thread.
98 ///
99 /// It is more performant to set async to false than to spawn a
100 /// worker and immediately block on the future completion.
101 PipelineFuture<PipelineDescriptor> CreatePipelineFuture(
102 const Context& context,
103 std::optional<PipelineDescriptor> desc,
104 bool async = true);
105
106 PipelineFuture<ComputePipelineDescriptor> CreatePipelineFuture(
107 const Context& context,
108 std::optional<ComputePipelineDescriptor> desc);
109
110 /// Holds a reference to a Pipeline used for rendering while also maintaining
111 /// the vertex shader and fragment shader types at compile-time.
112 ///
113 /// See also:
114 /// - impeller::ContentContext::Variants - the typical container for
115 /// RenderPipelineHandles.
116 template <class VertexShader_, class FragmentShader_>
117 class RenderPipelineHandle {
118 public:
119 using VertexShader = VertexShader_;
120 using FragmentShader = FragmentShader_;
121 using Builder = PipelineBuilder<VertexShader, FragmentShader>;
122
123 explicit RenderPipelineHandle(const Context& context, bool async = true)
124 : RenderPipelineHandle(CreatePipelineFuture(
125 context,
126 Builder::MakeDefaultPipelineDescriptor(context),
127 async)) {}
128
129 explicit RenderPipelineHandle(const Context& context,
130 std::optional<PipelineDescriptor> desc,
131 bool async = true)
132 : RenderPipelineHandle(
133 CreatePipelineFuture(context, desc, /*async=*/async)) {}
134
135 explicit RenderPipelineHandle(PipelineFuture<PipelineDescriptor> future)
136 : pipeline_future_(std::move(future)) {}
137
138 std::shared_ptr<Pipeline<PipelineDescriptor>> WaitAndGet() {
139 if (did_wait_) {
140 return pipeline_;
141 }
142 did_wait_ = true;
143 if (pipeline_future_.IsValid()) {
144 pipeline_ = pipeline_future_.Get();
145 }
146 return pipeline_;
147 }
148
149 std::optional<PipelineDescriptor> GetDescriptor() const {
150 return pipeline_future_.descriptor;
151 }
152
153 private:
154 PipelineFuture<PipelineDescriptor> pipeline_future_;
155 std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline_;
156 bool did_wait_ = false;
157
158 RenderPipelineHandle(const RenderPipelineHandle&) = delete;
159
160 RenderPipelineHandle& operator=(const RenderPipelineHandle&) = delete;
161 };
162
163 template <class ComputeShader_>
164 class ComputePipelineHandle {
165 public:
166 using ComputeShader = ComputeShader_;
167 using Builder = ComputePipelineBuilder<ComputeShader>;
168
169 explicit ComputePipelineHandle(const Context& context)
170 : ComputePipelineHandle(CreatePipelineFuture(
171 context,
172 Builder::MakeDefaultPipelineDescriptor(context))) {}
173
174 explicit ComputePipelineHandle(
175 const Context& context,
176 std::optional<ComputePipelineDescriptor> compute_desc)
177 : ComputePipelineHandle(CreatePipelineFuture(context, compute_desc)) {}
178
179 explicit ComputePipelineHandle(
180 PipelineFuture<ComputePipelineDescriptor> future)
181 : pipeline_future_(std::move(future)) {}
182
183 std::shared_ptr<Pipeline<ComputePipelineDescriptor>> WaitAndGet() {
184 if (did_wait_) {
185 return pipeline_;
186 }
187 did_wait_ = true;
188 if (pipeline_future_.IsValid()) {
189 pipeline_ = pipeline_future_.Get();
190 }
191 return pipeline_;
192 }
193
194 private:
195 PipelineFuture<ComputePipelineDescriptor> pipeline_future_;
196 std::shared_ptr<Pipeline<ComputePipelineDescriptor>> pipeline_;
197 bool did_wait_ = false;
198
199 ComputePipelineHandle(const ComputePipelineHandle&) = delete;
200
201 ComputePipelineHandle& operator=(const ComputePipelineHandle&) = delete;
202 };
203
204 } // namespace impeller
205
206 #endif // FLUTTER_IMPELLER_RENDERER_PIPELINE_H_
impeller::ComputePipelineHandle
Definition: pipeline.h:164
impeller::ComputePipelineHandle::ComputePipelineHandle
ComputePipelineHandle(PipelineFuture< ComputePipelineDescriptor > future)
Definition: pipeline.h:179
impeller::ComputePipelineHandle::ComputePipelineHandle
ComputePipelineHandle(const Context &context, std::optional< ComputePipelineDescriptor > compute_desc)
Definition: pipeline.h:174
impeller::ComputePipelineHandle::ComputePipelineHandle
ComputePipelineHandle(const Context &context)
Definition: pipeline.h:169
impeller::ComputePipelineHandle::ComputeShader
ComputeShader_ ComputeShader
Definition: pipeline.h:166
impeller::ComputePipelineHandle::WaitAndGet
std::shared_ptr< Pipeline< ComputePipelineDescriptor > > WaitAndGet()
Definition: pipeline.h:183
impeller::Context
To do anything rendering related with Impeller, you need a context.
Definition: context.h:47
impeller::Pipeline
Describes the fixed function and programmable aspects of rendering and compute operations performed b...
Definition: pipeline.h:52
impeller::Pipeline::~Pipeline
virtual ~Pipeline()
impeller::Pipeline::CreateVariant
PipelineFuture< T > CreateVariant(bool async, std::function< void(T &desc)> descriptor_callback) const
Definition: pipeline.cc:56
impeller::Pipeline::library_
const std::weak_ptr< PipelineLibrary > library_
Definition: pipeline.h:72
impeller::Pipeline::IsValid
virtual bool IsValid() const =0
impeller::Pipeline::desc_
const T desc_
Definition: pipeline.h:74
impeller::Pipeline::Pipeline
Pipeline(std::weak_ptr< PipelineLibrary > library, T desc)
Definition: pipeline.cc:18
impeller::Pipeline::GetDescriptor
const T & GetDescriptor() const
Get the descriptor that was responsible for creating this pipeline. It may be copied and modified to ...
Definition: pipeline.cc:51
impeller::PipelineLibrary
Definition: pipeline_library.h:29
impeller::RenderPipelineHandle
Definition: pipeline.h:117
impeller::RenderPipelineHandle::RenderPipelineHandle
RenderPipelineHandle(const Context &context, std::optional< PipelineDescriptor > desc, bool async=true)
Definition: pipeline.h:129
impeller::RenderPipelineHandle::VertexShader
VertexShader_ VertexShader
Definition: pipeline.h:119
impeller::RenderPipelineHandle::RenderPipelineHandle
RenderPipelineHandle(const Context &context, bool async=true)
Definition: pipeline.h:123
impeller::RenderPipelineHandle::RenderPipelineHandle
RenderPipelineHandle(PipelineFuture< PipelineDescriptor > future)
Definition: pipeline.h:135
impeller::RenderPipelineHandle::WaitAndGet
std::shared_ptr< Pipeline< PipelineDescriptor > > WaitAndGet()
Definition: pipeline.h:138
impeller::RenderPipelineHandle::FragmentShader
FragmentShader_ FragmentShader
Definition: pipeline.h:120
impeller::RenderPipelineHandle::GetDescriptor
std::optional< PipelineDescriptor > GetDescriptor() const
Definition: pipeline.h:149
impeller::raw_ptr< Pipeline< PipelineDescriptor > >
compute_pipeline_builder.h
compute_pipeline_descriptor.h
impeller
Definition: allocation.cc:12
impeller::CreatePipelineFuture
PipelineFuture< PipelineDescriptor > CreatePipelineFuture(const Context &context, std::optional< PipelineDescriptor > desc, bool async)
Create a pipeline for the given descriptor.
Definition: pipeline.cc:24
impeller::PipelineKey
int64_t PipelineKey
Definition: pipeline.h:21
std
Definition: comparable.h:95
pipeline_builder.h
pipeline_descriptor.h
raw_ptr.h
context.h
shader_stage_compatibility_checker.h
impeller::ComputePipelineBuilder
An optional (but highly recommended) utility for creating pipelines from reflected shader information...
Definition: compute_pipeline_builder.h:25
impeller::PipelineBuilder
An optional (but highly recommended) utility for creating pipelines from reflected shader information...
Definition: pipeline_builder.h:30
impeller::PipelineFuture
Definition: pipeline.h:28
impeller::PipelineFuture::future
std::shared_future< std::shared_ptr< Pipeline< T > > > future
Definition: pipeline.h:30
impeller::PipelineFuture::Get
const std::shared_ptr< Pipeline< T > > Get() const
Definition: pipeline.h:32
impeller::PipelineFuture::IsValid
bool IsValid() const
Definition: pipeline.h:34
impeller::PipelineFuture::descriptor
std::optional< T > descriptor
Definition: pipeline.h:29