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