| 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.
111 ///
112 /// @see RenderPipelineHandle the templated subclass that stores compile-time
113 /// shader information.
114 class GenericRenderPipelineHandle {
115 public:
116 explicit GenericRenderPipelineHandle(const Context& context,
117 std::optional<PipelineDescriptor> desc,
118 bool async = true)
119 : GenericRenderPipelineHandle(
120 CreatePipelineFuture(context, std::move(desc), /*async=*/async)) {}
121
122 explicit GenericRenderPipelineHandle(
123 PipelineFuture<PipelineDescriptor> future)
124 : pipeline_future_(std::move(future)) {}
125
126 virtual ~GenericRenderPipelineHandle() = default;
127
128 std::shared_ptr<Pipeline<PipelineDescriptor>> WaitAndGet() {
129 if (did_wait_) {
130 return pipeline_;
131 }
132 did_wait_ = true;
133 if (pipeline_future_.IsValid()) {
134 pipeline_ = pipeline_future_.Get();
135 }
136 return pipeline_;
137 }
138
139 std::optional<PipelineDescriptor> GetDescriptor() const {
140 return pipeline_future_.descriptor;
141 }
142
143 private:
144 PipelineFuture<PipelineDescriptor> pipeline_future_;
145 std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline_;
146 bool did_wait_ = false;
147
148 GenericRenderPipelineHandle(const GenericRenderPipelineHandle&) = delete;
149
150 GenericRenderPipelineHandle& operator=(const GenericRenderPipelineHandle&) =
151 delete;
152 };
153
154 /// Holds a reference to a Pipeline used for rendering while also maintaining
155 /// the vertex shader and fragment shader types at compile-time.
156 ///
157 /// See also:
158 /// - impeller::ContentContext::Variants - the typical container for
159 /// RenderPipelineHandles.
160 template <class VertexShader_, class FragmentShader_>
161 class RenderPipelineHandle : public GenericRenderPipelineHandle {
162 public:
163 using VertexShader = VertexShader_;
164 using FragmentShader = FragmentShader_;
165 using Builder = PipelineBuilder<VertexShader, FragmentShader>;
166
167 explicit RenderPipelineHandle(const Context& context, bool async = true)
168 : GenericRenderPipelineHandle(CreatePipelineFuture(
169 context,
170 Builder::MakeDefaultPipelineDescriptor(context),
171 async)) {}
172
173 explicit RenderPipelineHandle(const Context& context,
174 std::optional<PipelineDescriptor> desc,
175 bool async = true)
176 : GenericRenderPipelineHandle(context, desc, async) {}
177
178 explicit RenderPipelineHandle(PipelineFuture<PipelineDescriptor> future)
179 : GenericRenderPipelineHandle(std::move(future)) {}
180
181 private:
182 RenderPipelineHandle(const RenderPipelineHandle&) = delete;
183
184 RenderPipelineHandle& operator=(const RenderPipelineHandle&) = delete;
185 };
186
187 template <class ComputeShader_>
188 class ComputePipelineHandle {
189 public:
190 using ComputeShader = ComputeShader_;
191 using Builder = ComputePipelineBuilder<ComputeShader>;
192
193 explicit ComputePipelineHandle(const Context& context)
194 : ComputePipelineHandle(CreatePipelineFuture(
195 context,
196 Builder::MakeDefaultPipelineDescriptor(context))) {}
197
198 explicit ComputePipelineHandle(
199 const Context& context,
200 std::optional<ComputePipelineDescriptor> compute_desc)
201 : ComputePipelineHandle(CreatePipelineFuture(context, compute_desc)) {}
202
203 explicit ComputePipelineHandle(
204 PipelineFuture<ComputePipelineDescriptor> future)
205 : pipeline_future_(std::move(future)) {}
206
207 std::shared_ptr<Pipeline<ComputePipelineDescriptor>> WaitAndGet() {
208 if (did_wait_) {
209 return pipeline_;
210 }
211 did_wait_ = true;
212 if (pipeline_future_.IsValid()) {
213 pipeline_ = pipeline_future_.Get();
214 }
215 return pipeline_;
216 }
217
218 private:
219 PipelineFuture<ComputePipelineDescriptor> pipeline_future_;
220 std::shared_ptr<Pipeline<ComputePipelineDescriptor>> pipeline_;
221 bool did_wait_ = false;
222
223 ComputePipelineHandle(const ComputePipelineHandle&) = delete;
224
225 ComputePipelineHandle& operator=(const ComputePipelineHandle&) = delete;
226 };
227
228 } // namespace impeller
229
230 #endif // FLUTTER_IMPELLER_RENDERER_PIPELINE_H_
impeller::ComputePipelineHandle
Definition: pipeline.h:188
impeller::ComputePipelineHandle::ComputePipelineHandle
ComputePipelineHandle(PipelineFuture< ComputePipelineDescriptor > future)
Definition: pipeline.h:203
impeller::ComputePipelineHandle::ComputePipelineHandle
ComputePipelineHandle(const Context &context, std::optional< ComputePipelineDescriptor > compute_desc)
Definition: pipeline.h:198
impeller::ComputePipelineHandle::ComputePipelineHandle
ComputePipelineHandle(const Context &context)
Definition: pipeline.h:193
impeller::ComputePipelineHandle::ComputeShader
ComputeShader_ ComputeShader
Definition: pipeline.h:190
impeller::ComputePipelineHandle::WaitAndGet
std::shared_ptr< Pipeline< ComputePipelineDescriptor > > WaitAndGet()
Definition: pipeline.h:207
impeller::Context
To do anything rendering related with Impeller, you need a context.
Definition: context.h:65
impeller::GenericRenderPipelineHandle
Definition: pipeline.h:114
impeller::GenericRenderPipelineHandle::~GenericRenderPipelineHandle
virtual ~GenericRenderPipelineHandle()=default
impeller::GenericRenderPipelineHandle::GetDescriptor
std::optional< PipelineDescriptor > GetDescriptor() const
Definition: pipeline.h:139
impeller::GenericRenderPipelineHandle::GenericRenderPipelineHandle
GenericRenderPipelineHandle(PipelineFuture< PipelineDescriptor > future)
Definition: pipeline.h:122
impeller::GenericRenderPipelineHandle::GenericRenderPipelineHandle
GenericRenderPipelineHandle(const Context &context, std::optional< PipelineDescriptor > desc, bool async=true)
Definition: pipeline.h:116
impeller::GenericRenderPipelineHandle::WaitAndGet
std::shared_ptr< Pipeline< PipelineDescriptor > > WaitAndGet()
Definition: pipeline.h:128
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:30
impeller::RenderPipelineHandle
Definition: pipeline.h:161
impeller::RenderPipelineHandle::RenderPipelineHandle
RenderPipelineHandle(const Context &context, std::optional< PipelineDescriptor > desc, bool async=true)
Definition: pipeline.h:173
impeller::RenderPipelineHandle::VertexShader
VertexShader_ VertexShader
Definition: pipeline.h:163
impeller::RenderPipelineHandle::RenderPipelineHandle
RenderPipelineHandle(const Context &context, bool async=true)
Definition: pipeline.h:167
impeller::RenderPipelineHandle::RenderPipelineHandle
RenderPipelineHandle(PipelineFuture< PipelineDescriptor > future)
Definition: pipeline.h:178
impeller::RenderPipelineHandle::FragmentShader
FragmentShader_ FragmentShader
Definition: pipeline.h:164
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