10#include "flutter/fml/container.h"
11#include "flutter/fml/trace_event.h"
20 : reactor_(
std::move(reactor)) {}
24 gl.GetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
25 if (log_length == 0) {
29 reinterpret_cast<char*
>(
std::calloc(log_length,
sizeof(
char)));
30 gl.GetShaderInfoLog(shader, log_length, &log_length, log_buffer);
31 auto log_string = std::string(log_buffer, log_length);
32 std::free(log_buffer);
51 const std::string&
name,
55 stream <<
"Failed to compile ";
60 case ShaderStage::kVertex:
63 case ShaderStage::kFragment:
66 case ShaderStage::kCompute:
70 stream <<
" shader for '" <<
name <<
"' with error:" << std::endl;
72 stream <<
"Shader source was: " << std::endl;
79 const std::shared_ptr<PipelineGLES>& pipeline,
80 const std::shared_ptr<const ShaderFunction>& vert_function,
81 const std::shared_ptr<const ShaderFunction>& frag_function) {
84 const auto& descriptor = pipeline->GetDescriptor();
87 ShaderFunctionGLES::Cast(*vert_function).GetSourceMapping();
89 ShaderFunctionGLES::Cast(*frag_function).GetSourceMapping();
93 auto vert_shader =
gl.CreateShader(GL_VERTEX_SHADER);
94 auto frag_shader =
gl.CreateShader(GL_FRAGMENT_SHADER);
96 if (vert_shader == 0 || frag_shader == 0) {
101 gl.SetDebugLabel(DebugResourceType::kShader, vert_shader,
102 SPrintF(
"%s Vertex Shader", descriptor.GetLabel().c_str()));
104 DebugResourceType::kShader, frag_shader,
105 SPrintF(
"%s Fragment Shader", descriptor.GetLabel().c_str()));
108 [&
gl, vert_shader]() {
gl.DeleteShader(vert_shader); });
110 [&
gl, frag_shader]() {
gl.DeleteShader(frag_shader); });
112 gl.ShaderSourceMapping(vert_shader, *vert_mapping,
113 descriptor.GetSpecializationConstants());
114 gl.ShaderSourceMapping(frag_shader, *frag_mapping,
115 descriptor.GetSpecializationConstants());
117 gl.CompileShader(vert_shader);
118 gl.CompileShader(frag_shader);
120 GLint vert_status = GL_FALSE;
121 GLint frag_status = GL_FALSE;
123 gl.GetShaderiv(vert_shader, GL_COMPILE_STATUS, &vert_status);
124 gl.GetShaderiv(frag_shader, GL_COMPILE_STATUS, &frag_status);
126 if (vert_status != GL_TRUE) {
128 *vert_mapping, ShaderStage::kVertex);
132 if (frag_status != GL_TRUE) {
134 *frag_mapping, ShaderStage::kFragment);
138 auto program = reactor.
GetGLHandle(pipeline->GetProgramHandle());
139 if (!program.has_value()) {
144 gl.AttachShader(*program, vert_shader);
145 gl.AttachShader(*program, frag_shader);
148 [&
gl, program = *program, vert_shader]() {
149 gl.DetachShader(program, vert_shader);
152 [&
gl, program = *program, frag_shader]() {
153 gl.DetachShader(program, frag_shader);
156 for (
const auto& stage_input :
157 descriptor.GetVertexDescriptor()->GetStageInputs()) {
158 gl.BindAttribLocation(*program,
159 static_cast<GLuint
>(stage_input.location),
164 gl.LinkProgram(*program);
166 GLint link_status = GL_FALSE;
167 gl.GetProgramiv(*program, GL_LINK_STATUS, &link_status);
169 if (link_status != GL_TRUE) {
171 <<
gl.GetProgramInfoLogString(*program);
178bool PipelineLibraryGLES::IsValid()
const {
179 return reactor_ !=
nullptr;
183PipelineFuture<PipelineDescriptor> PipelineLibraryGLES::GetPipeline(
184 PipelineDescriptor descriptor,
186 if (
auto found = pipelines_.find(descriptor); found != pipelines_.end()) {
187 return found->second;
193 RealizedFuture<std::shared_ptr<Pipeline<PipelineDescriptor>>>(
nullptr)};
196 auto vert_function = descriptor.GetEntrypointForStage(ShaderStage::kVertex);
197 auto frag_function = descriptor.GetEntrypointForStage(ShaderStage::kFragment);
199 if (!vert_function || !frag_function) {
201 <<
"Could not find stage entrypoint functions in pipeline descriptor.";
204 RealizedFuture<std::shared_ptr<Pipeline<PipelineDescriptor>>>(
nullptr)};
207 auto promise = std::make_shared<
208 std::promise<std::shared_ptr<Pipeline<PipelineDescriptor>>>>();
209 auto pipeline_future =
210 PipelineFuture<PipelineDescriptor>{descriptor, promise->get_future()};
211 pipelines_[descriptor] = pipeline_future;
212 auto weak_this = weak_from_this();
214 auto result = reactor_->AddOperation(
215 [promise, weak_this, reactor_ptr = reactor_, descriptor, vert_function,
216 frag_function](
const ReactorGLES& reactor) {
217 auto strong_this = weak_this.lock();
219 promise->set_value(
nullptr);
220 VALIDATION_LOG <<
"Library was collected before a pending pipeline "
221 "creation could finish.";
224 auto pipeline = std::shared_ptr<PipelineGLES>(
225 new PipelineGLES(reactor_ptr, strong_this, descriptor));
226 auto program = reactor.GetGLHandle(pipeline->GetProgramHandle());
227 if (!program.has_value()) {
228 promise->set_value(
nullptr);
238 promise->set_value(
nullptr);
242 if (!pipeline->BuildVertexDescriptor(reactor.GetProcTable(),
244 promise->set_value(
nullptr);
248 if (!pipeline->IsValid()) {
249 promise->set_value(
nullptr);
253 promise->set_value(std::move(pipeline));
257 return pipeline_future;
261PipelineFuture<ComputePipelineDescriptor> PipelineLibraryGLES::GetPipeline(
262 ComputePipelineDescriptor descriptor,
264 auto promise = std::make_shared<
265 std::promise<std::shared_ptr<Pipeline<ComputePipelineDescriptor>>>>();
267 promise->set_value(
nullptr);
268 return {descriptor, promise->get_future()};
272void PipelineLibraryGLES::RemovePipelinesWithEntryPoint(
273 std::shared_ptr<const ShaderFunction>
function) {
275 return item->first.GetEntrypointForStage(
function->GetStage())
281PipelineLibraryGLES::~PipelineLibraryGLES() =
default;
Wraps a closure that is invoked in the destructor unless released by the caller.
The reactor attempts to make thread-safe usage of OpenGL ES easier to reason about.
std::optional< GLuint > GetGLHandle(const HandleGLES &handle) const
Returns the OpenGL handle for a reactor handle if one is available. This is typically only safe to ca...
const ProcTableGLES & GetProcTable() const
Get the OpenGL proc. table the reactor uses to manage handles.
std::shared_ptr< ReactorGLES > Ref
#define FML_CHECK(condition)
Dart_NativeFunction function
void * malloc(size_t size)
void * calloc(size_t n, size_t size)
DEF_SWITCHES_START aot vmservice shared library name
void erase_if(Collection &container, std::function< bool(typename Collection::iterator)> predicate)
static std::string GetShaderSource(const ProcTableGLES &gl, GLuint shader)
std::string SPrintF(const char *format,...)
static std::string GetShaderInfoLog(const ProcTableGLES &gl, GLuint shader)
static void LogShaderCompilationFailure(const ProcTableGLES &gl, GLuint shader, const std::string &name, const fml::Mapping &source_mapping, ShaderStage stage)
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)
std::shared_ptr< const fml::Mapping > data
#define TRACE_EVENT0(category_group, name)