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 class PipelineLibrary;
22 template <typename PipelineDescriptor_>
23 class Pipeline;
24 
25 template <typename T>
27  std::optional<T> descriptor;
28  std::shared_future<std::shared_ptr<Pipeline<T>>> future;
29 
30  const std::shared_ptr<Pipeline<T>> Get() const { return future.get(); }
31 
32  bool IsValid() const { return future.valid(); }
33 };
34 
35 //------------------------------------------------------------------------------
36 /// @brief Describes the fixed function and programmable aspects of
37 /// rendering and compute operations performed by commands submitted
38 /// to the GPU via a command buffer.
39 ///
40 /// A pipeline handle must be allocated upfront and kept alive for
41 /// as long as possible. Do not create a pipeline object within a
42 /// frame workload.
43 ///
44 /// This pipeline object is almost never used directly as it is
45 /// untyped. Use reflected shader information generated by the
46 /// Impeller offline shader compiler to generate a typed pipeline
47 /// object.
48 ///
49 template <typename T>
50 class Pipeline {
51  public:
52  virtual ~Pipeline();
53 
54  virtual bool IsValid() const = 0;
55 
56  //----------------------------------------------------------------------------
57  /// @brief Get the descriptor that was responsible for creating this
58  /// pipeline. It may be copied and modified to create a pipeline
59  /// variant.
60  ///
61  /// @return The descriptor.
62  ///
63  const T& GetDescriptor() const;
64 
66  bool async,
67  std::function<void(T& desc)> descriptor_callback) const;
68 
69  protected:
70  const std::weak_ptr<PipelineLibrary> library_;
71 
72  const T desc_;
73 
74  Pipeline(std::weak_ptr<PipelineLibrary> library, T desc);
75 
76  private:
77  Pipeline(const Pipeline&) = delete;
78 
79  Pipeline& operator=(const Pipeline&) = delete;
80 };
81 
82 /// @brief A raw ptr to a pipeline object.
83 ///
84 /// These pipeline refs are safe to use as the context will keep the
85 /// pipelines alive throughout rendering.
87 
88 extern template class Pipeline<PipelineDescriptor>;
89 extern template class Pipeline<ComputePipelineDescriptor>;
90 
92  const Context& context,
93  std::optional<PipelineDescriptor> desc);
94 
96  const Context& context,
97  std::optional<ComputePipelineDescriptor> desc);
98 
99 /// Holds a reference to a Pipeline used for rendering while also maintaining
100 /// the vertex shader and fragment shader types at compile-time.
101 ///
102 /// See also:
103 /// - impeller::ContentContext::Variants - the typical container for
104 /// RenderPipelineHandles.
105 template <class VertexShader_, class FragmentShader_>
107  static_assert(
109  "The output slots for the fragment shader don't have matches in the "
110  "vertex shader's output slots. This will result in a linker error.");
111 
112  public:
113  using VertexShader = VertexShader_;
114  using FragmentShader = FragmentShader_;
116 
117  explicit RenderPipelineHandle(const Context& context)
119  context,
120  Builder::MakeDefaultPipelineDescriptor(context))) {}
121 
122  explicit RenderPipelineHandle(const Context& context,
123  std::optional<PipelineDescriptor> desc)
124  : RenderPipelineHandle(CreatePipelineFuture(context, desc)) {}
125 
127  : pipeline_future_(std::move(future)) {}
128 
129  std::shared_ptr<Pipeline<PipelineDescriptor>> WaitAndGet() {
130  if (did_wait_) {
131  return pipeline_;
132  }
133  did_wait_ = true;
134  if (pipeline_future_.IsValid()) {
135  pipeline_ = pipeline_future_.Get();
136  }
137  return pipeline_;
138  }
139 
140  std::optional<PipelineDescriptor> GetDescriptor() const {
141  return pipeline_future_.descriptor;
142  }
143 
144  private:
145  PipelineFuture<PipelineDescriptor> pipeline_future_;
146  std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline_;
147  bool did_wait_ = false;
148 
150 
151  RenderPipelineHandle& operator=(const RenderPipelineHandle&) = delete;
152 };
153 
154 template <class ComputeShader_>
156  public:
157  using ComputeShader = ComputeShader_;
159 
160  explicit ComputePipelineHandle(const Context& context)
162  context,
163  Builder::MakeDefaultPipelineDescriptor(context))) {}
164 
166  const Context& context,
167  std::optional<ComputePipelineDescriptor> compute_desc)
168  : ComputePipelineHandle(CreatePipelineFuture(context, compute_desc)) {}
169 
172  : pipeline_future_(std::move(future)) {}
173 
174  std::shared_ptr<Pipeline<ComputePipelineDescriptor>> WaitAndGet() {
175  if (did_wait_) {
176  return pipeline_;
177  }
178  did_wait_ = true;
179  if (pipeline_future_.IsValid()) {
180  pipeline_ = pipeline_future_.Get();
181  }
182  return pipeline_;
183  }
184 
185  private:
187  std::shared_ptr<Pipeline<ComputePipelineDescriptor>> pipeline_;
188  bool did_wait_ = false;
189 
191 
192  ComputePipelineHandle& operator=(const ComputePipelineHandle&) = delete;
193 };
194 
195 } // namespace impeller
196 
197 #endif // FLUTTER_IMPELLER_RENDERER_PIPELINE_H_
ComputePipelineHandle(PipelineFuture< ComputePipelineDescriptor > future)
Definition: pipeline.h:170
ComputePipelineHandle(const Context &context, std::optional< ComputePipelineDescriptor > compute_desc)
Definition: pipeline.h:165
ComputePipelineHandle(const Context &context)
Definition: pipeline.h:160
ComputeShader_ ComputeShader
Definition: pipeline.h:157
std::shared_ptr< Pipeline< ComputePipelineDescriptor > > WaitAndGet()
Definition: pipeline.h:174
To do anything rendering related with Impeller, you need a context.
Definition: context.h:46
Describes the fixed function and programmable aspects of rendering and compute operations performed b...
Definition: pipeline.h:50
PipelineFuture< T > CreateVariant(bool async, std::function< void(T &desc)> descriptor_callback) const
Definition: pipeline.cc:54
const std::weak_ptr< PipelineLibrary > library_
Definition: pipeline.h:70
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:49
RenderPipelineHandle(const Context &context, std::optional< PipelineDescriptor > desc)
Definition: pipeline.h:122
RenderPipelineHandle(PipelineFuture< PipelineDescriptor > future)
Definition: pipeline.h:126
std::shared_ptr< Pipeline< PipelineDescriptor > > WaitAndGet()
Definition: pipeline.h:129
RenderPipelineHandle(const Context &context)
Definition: pipeline.h:117
FragmentShader_ FragmentShader
Definition: pipeline.h:114
std::optional< PipelineDescriptor > GetDescriptor() const
Definition: pipeline.h:140
Checks, at C++ compile-time, if the two pipeline stages are compatible.
PipelineFuture< PipelineDescriptor > CreatePipelineFuture(const Context &context, std::optional< PipelineDescriptor > desc)
Definition: pipeline.cc:24
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:28
const std::shared_ptr< Pipeline< T > > Get() const
Definition: pipeline.h:30
bool IsValid() const
Definition: pipeline.h:32
std::optional< T > descriptor
Definition: pipeline.h:27