| 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 class PipelineLibrary;
22 template <typename PipelineDescriptor_>
23 class Pipeline;
24
25 template <typename T>
26 struct PipelineFuture {
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
65 PipelineFuture<T> CreateVariant(
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.
86 using PipelineRef = raw_ptr<Pipeline<PipelineDescriptor>>;
87
88 extern template class Pipeline<PipelineDescriptor>;
89 extern template class Pipeline<ComputePipelineDescriptor>;
90
91 PipelineFuture<PipelineDescriptor> CreatePipelineFuture(
92 const Context& context,
93 std::optional<PipelineDescriptor> desc);
94
95 PipelineFuture<ComputePipelineDescriptor> CreatePipelineFuture(
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_>
106 class RenderPipelineHandle {
107 static_assert(
108 ShaderStageCompatibilityChecker<VertexShader_, FragmentShader_>::Check(),
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_;
115 using Builder = PipelineBuilder<VertexShader, FragmentShader>;
116
117 explicit RenderPipelineHandle(const Context& context)
118 : RenderPipelineHandle(CreatePipelineFuture(
119 context,
120 Builder::MakeDefaultPipelineDescriptor(context))) {}
121
122 explicit RenderPipelineHandle(const Context& context,
123 std::optional<PipelineDescriptor> desc)
124 : RenderPipelineHandle(CreatePipelineFuture(context, desc)) {}
125
126 explicit RenderPipelineHandle(PipelineFuture<PipelineDescriptor> future)
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
149 RenderPipelineHandle(const RenderPipelineHandle&) = delete;
150
151 RenderPipelineHandle& operator=(const RenderPipelineHandle&) = delete;
152 };
153
154 template <class ComputeShader_>
155 class ComputePipelineHandle {
156 public:
157 using ComputeShader = ComputeShader_;
158 using Builder = ComputePipelineBuilder<ComputeShader>;
159
160 explicit ComputePipelineHandle(const Context& context)
161 : ComputePipelineHandle(CreatePipelineFuture(
162 context,
163 Builder::MakeDefaultPipelineDescriptor(context))) {}
164
165 explicit ComputePipelineHandle(
166 const Context& context,
167 std::optional<ComputePipelineDescriptor> compute_desc)
168 : ComputePipelineHandle(CreatePipelineFuture(context, compute_desc)) {}
169
170 explicit ComputePipelineHandle(
171 PipelineFuture<ComputePipelineDescriptor> future)
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:
186 PipelineFuture<ComputePipelineDescriptor> pipeline_future_;
187 std::shared_ptr<Pipeline<ComputePipelineDescriptor>> pipeline_;
188 bool did_wait_ = false;
189
190 ComputePipelineHandle(const ComputePipelineHandle&) = delete;
191
192 ComputePipelineHandle& operator=(const ComputePipelineHandle&) = delete;
193 };
194
195 } // namespace impeller
196
197 #endif // FLUTTER_IMPELLER_RENDERER_PIPELINE_H_
impeller::ComputePipelineHandle
Definition: pipeline.h:155
impeller::ComputePipelineHandle::ComputePipelineHandle
ComputePipelineHandle(PipelineFuture< ComputePipelineDescriptor > future)
Definition: pipeline.h:170
impeller::ComputePipelineHandle::ComputePipelineHandle
ComputePipelineHandle(const Context &context, std::optional< ComputePipelineDescriptor > compute_desc)
Definition: pipeline.h:165
impeller::ComputePipelineHandle::ComputePipelineHandle
ComputePipelineHandle(const Context &context)
Definition: pipeline.h:160
impeller::ComputePipelineHandle::ComputeShader
ComputeShader_ ComputeShader
Definition: pipeline.h:157
impeller::ComputePipelineHandle::WaitAndGet
std::shared_ptr< Pipeline< ComputePipelineDescriptor > > WaitAndGet()
Definition: pipeline.h:174
impeller::Context
To do anything rendering related with Impeller, you need a context.
Definition: context.h:46
impeller::Pipeline
Describes the fixed function and programmable aspects of rendering and compute operations performed b...
Definition: pipeline.h:50
impeller::Pipeline::~Pipeline
virtual ~Pipeline()
impeller::Pipeline::CreateVariant
PipelineFuture< T > CreateVariant(bool async, std::function< void(T &desc)> descriptor_callback) const
Definition: pipeline.cc:54
impeller::Pipeline::library_
const std::weak_ptr< PipelineLibrary > library_
Definition: pipeline.h:70
impeller::Pipeline::IsValid
virtual bool IsValid() const =0
impeller::Pipeline::desc_
const T desc_
Definition: pipeline.h:72
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:49
impeller::RenderPipelineHandle
Definition: pipeline.h:106
impeller::RenderPipelineHandle::RenderPipelineHandle
RenderPipelineHandle(const Context &context, std::optional< PipelineDescriptor > desc)
Definition: pipeline.h:122
impeller::RenderPipelineHandle::VertexShader
VertexShader_ VertexShader
Definition: pipeline.h:113
impeller::RenderPipelineHandle::RenderPipelineHandle
RenderPipelineHandle(PipelineFuture< PipelineDescriptor > future)
Definition: pipeline.h:126
impeller::RenderPipelineHandle::WaitAndGet
std::shared_ptr< Pipeline< PipelineDescriptor > > WaitAndGet()
Definition: pipeline.h:129
impeller::RenderPipelineHandle::RenderPipelineHandle
RenderPipelineHandle(const Context &context)
Definition: pipeline.h:117
impeller::RenderPipelineHandle::FragmentShader
FragmentShader_ FragmentShader
Definition: pipeline.h:114
impeller::RenderPipelineHandle::GetDescriptor
std::optional< PipelineDescriptor > GetDescriptor() const
Definition: pipeline.h:140
impeller::ShaderStageCompatibilityChecker
Checks, at C++ compile-time, if the two pipeline stages are compatible.
Definition: shader_stage_compatibility_checker.h:39
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)
Definition: pipeline.cc:24
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:26
impeller::PipelineFuture::future
std::shared_future< std::shared_ptr< Pipeline< T > > > future
Definition: pipeline.h:28
impeller::PipelineFuture::Get
const std::shared_ptr< Pipeline< T > > Get() const
Definition: pipeline.h:30
impeller::PipelineFuture::IsValid
bool IsValid() const
Definition: pipeline.h:32
impeller::PipelineFuture::descriptor
std::optional< T > descriptor
Definition: pipeline.h:27