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 
11 #include "impeller/core/raw_ptr.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>
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 
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.
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.
102  const Context& context,
103  std::optional<PipelineDescriptor> desc,
104  bool async = true);
105 
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_>
118  public:
119  using VertexShader = VertexShader_;
120  using FragmentShader = FragmentShader_;
122 
123  explicit RenderPipelineHandle(const Context& context, bool async = true)
125  context,
126  Builder::MakeDefaultPipelineDescriptor(context),
127  async)) {}
128 
129  explicit RenderPipelineHandle(const Context& context,
130  std::optional<PipelineDescriptor> desc,
131  bool async = true)
133  CreatePipelineFuture(context, desc, /*async=*/async)) {}
134 
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 
159 
160  RenderPipelineHandle& operator=(const RenderPipelineHandle&) = delete;
161 };
162 
163 template <class ComputeShader_>
165  public:
166  using ComputeShader = ComputeShader_;
168 
169  explicit ComputePipelineHandle(const Context& context)
171  context,
172  Builder::MakeDefaultPipelineDescriptor(context))) {}
173 
175  const Context& context,
176  std::optional<ComputePipelineDescriptor> compute_desc)
177  : ComputePipelineHandle(CreatePipelineFuture(context, compute_desc)) {}
178 
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:
196  std::shared_ptr<Pipeline<ComputePipelineDescriptor>> pipeline_;
197  bool did_wait_ = false;
198 
200 
201  ComputePipelineHandle& operator=(const ComputePipelineHandle&) = delete;
202 };
203 
204 } // namespace impeller
205 
206 #endif // FLUTTER_IMPELLER_RENDERER_PIPELINE_H_
ComputePipelineHandle(PipelineFuture< ComputePipelineDescriptor > future)
Definition: pipeline.h:179
ComputePipelineHandle(const Context &context, std::optional< ComputePipelineDescriptor > compute_desc)
Definition: pipeline.h:174
ComputePipelineHandle(const Context &context)
Definition: pipeline.h:169
ComputeShader_ ComputeShader
Definition: pipeline.h:166
std::shared_ptr< Pipeline< ComputePipelineDescriptor > > WaitAndGet()
Definition: pipeline.h:183
To do anything rendering related with Impeller, you need a context.
Definition: context.h:47
Describes the fixed function and programmable aspects of rendering and compute operations performed b...
Definition: pipeline.h:52
PipelineFuture< T > CreateVariant(bool async, std::function< void(T &desc)> descriptor_callback) const
Definition: pipeline.cc:56
const std::weak_ptr< PipelineLibrary > library_
Definition: pipeline.h:72
virtual bool IsValid() const =0
Pipeline(std::weak_ptr< PipelineLibrary > library, T desc)
Definition: pipeline.cc:18
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
RenderPipelineHandle(const Context &context, std::optional< PipelineDescriptor > desc, bool async=true)
Definition: pipeline.h:129
RenderPipelineHandle(const Context &context, bool async=true)
Definition: pipeline.h:123
RenderPipelineHandle(PipelineFuture< PipelineDescriptor > future)
Definition: pipeline.h:135
std::shared_ptr< Pipeline< PipelineDescriptor > > WaitAndGet()
Definition: pipeline.h:138
FragmentShader_ FragmentShader
Definition: pipeline.h:120
std::optional< PipelineDescriptor > GetDescriptor() const
Definition: pipeline.h:149
PipelineFuture< PipelineDescriptor > CreatePipelineFuture(const Context &context, std::optional< PipelineDescriptor > desc, bool async)
Create a pipeline for the given descriptor.
Definition: pipeline.cc:24
int64_t PipelineKey
Definition: pipeline.h:21
Definition: comparable.h:95
An optional (but highly recommended) utility for creating pipelines from reflected shader information...
An optional (but highly recommended) utility for creating pipelines from reflected shader information...
std::shared_future< std::shared_ptr< Pipeline< T > > > future
Definition: pipeline.h:30
const std::shared_ptr< Pipeline< T > > Get() const
Definition: pipeline.h:32
bool IsValid() const
Definition: pipeline.h:34
std::optional< T > descriptor
Definition: pipeline.h:29