184 {
185 if (auto found = pipelines_.find(descriptor); found != pipelines_.end()) {
186 return found->second;
187 }
188
189 if (!reactor_) {
190 return {
191 descriptor,
192 RealizedFuture<std::shared_ptr<Pipeline<PipelineDescriptor>>>(nullptr)};
193 }
194
197
198 if (!vert_function || !frag_function) {
200 << "Could not find stage entrypoint functions in pipeline descriptor.";
201 return {
202 descriptor,
203 RealizedFuture<std::shared_ptr<Pipeline<PipelineDescriptor>>>(nullptr)};
204 }
205
206 auto promise = std::make_shared<
207 std::promise<std::shared_ptr<Pipeline<PipelineDescriptor>>>>();
208 auto pipeline_future =
209 PipelineFuture<PipelineDescriptor>{descriptor, promise->get_future()};
210 pipelines_[descriptor] = pipeline_future;
211 auto weak_this = weak_from_this();
212
213 auto result = reactor_->AddOperation(
214 [promise, weak_this, reactor_ptr = reactor_, descriptor, vert_function,
215 frag_function](const ReactorGLES& reactor) {
216 auto strong_this = weak_this.lock();
217 if (!strong_this) {
218 promise->set_value(nullptr);
219 VALIDATION_LOG <<
"Library was collected before a pending pipeline "
220 "creation could finish.";
221 return;
222 }
223 auto pipeline = std::shared_ptr<PipelineGLES>(
224 new PipelineGLES(reactor_ptr, strong_this, descriptor));
225 auto program = reactor.GetGLHandle(pipeline->GetProgramHandle());
226 if (!program.has_value()) {
227 promise->set_value(nullptr);
229 return;
230 }
232 pipeline,
233 vert_function,
234 frag_function
235 );
236 if (!link_result) {
237 promise->set_value(nullptr);
239 return;
240 }
241 if (!pipeline->BuildVertexDescriptor(reactor.GetProcTable(),
242 program.value())) {
243 promise->set_value(nullptr);
245 return;
246 }
247 if (!pipeline->IsValid()) {
248 promise->set_value(nullptr);
250 return;
251 }
252 promise->set_value(std::move(pipeline));
253 });
255
256 return pipeline_future;
257}
#define FML_CHECK(condition)
static bool LinkProgram(const ReactorGLES &reactor, const std::shared_ptr< PipelineGLES > &pipeline, const std::shared_ptr< const ShaderFunction > &vert_function, const std::shared_ptr< const ShaderFunction > &frag_function)