9 #include "fml/closure.h"
23 return "GL_INVALID_ENUM";
24 case GL_INVALID_VALUE:
25 return "GL_INVALID_VALUE";
26 case GL_INVALID_OPERATION:
27 return "GL_INVALID_OPERATION";
28 case GL_INVALID_FRAMEBUFFER_OPERATION:
29 return "GL_INVALID_FRAMEBUFFER_OPERATION";
30 case GL_FRAMEBUFFER_COMPLETE:
31 return "GL_FRAMEBUFFER_COMPLETE";
32 case GL_OUT_OF_MEMORY:
33 return "GL_OUT_OF_MEMORY";
43 case GL_INVALID_VALUE:
44 case GL_INVALID_OPERATION:
45 case GL_INVALID_FRAMEBUFFER_OPERATION:
46 case GL_OUT_OF_MEMORY:
54 return [resolver](
const char* function_name) ->
void* {
55 auto resolved = resolver(function_name);
61 auto function = std::string{function_name};
62 if (
function.find(
"KHR",
function.size() - 3) != std::string::npos) {
63 auto truncated =
function.substr(0u,
function.size() - 3);
64 return resolver(truncated.c_str());
66 if (
function.find(
"EXT",
function.size() - 3) != std::string::npos) {
67 auto truncated =
function.substr(0u,
function.size() - 3);
68 return resolver(truncated.c_str());
81 auto error_fn =
reinterpret_cast<PFNGLGETERRORPROC
>(resolver(
"glGetError"));
88 #define IMPELLER_PROC(proc_ivar) \
89 if (auto fn_ptr = resolver(proc_ivar.name)) { \
90 proc_ivar.function = \
91 reinterpret_cast<decltype(proc_ivar.function)>(fn_ptr); \
92 proc_ivar.error_fn = error_fn; \
94 VALIDATION_LOG << "Could not resolve " << proc_ivar.name; \
102 #define IMPELLER_PROC(proc_ivar) \
103 if (auto fn_ptr = resolver(proc_ivar.name)) { \
104 proc_ivar.function = \
105 reinterpret_cast<decltype(proc_ivar.function)>(fn_ptr); \
106 proc_ivar.error_fn = error_fn; \
113 description_ = std::make_unique<DescriptionGLES>(*
this);
115 if (!description_->IsValid()) {
119 if (!description_->HasDebugExtension()) {
120 PushDebugGroupKHR.Reset();
121 PopDebugGroupKHR.Reset();
122 ObjectLabelKHR.Reset();
124 GetIntegerv(GL_MAX_LABEL_LENGTH_KHR, &debug_label_max_length_);
127 if (!description_->HasExtension(
"GL_EXT_discard_framebuffer")) {
128 DiscardFramebufferEXT.Reset();
131 capabilities_ = std::make_shared<CapabilitiesGLES>(*
this);
144 const fml::Mapping& mapping,
145 const std::vector<Scalar>& defines)
const {
146 if (defines.empty()) {
147 const GLchar* sources[] = {
148 reinterpret_cast<const GLchar*
>(mapping.GetMapping())};
149 const GLint lengths[] = {
static_cast<GLint
>(mapping.GetSize())};
150 ShaderSource(shader, 1u, sources, lengths);
154 if (!shader_source.has_value()) {
159 const GLchar* sources[] = {
160 reinterpret_cast<const GLchar*
>(shader_source->c_str())};
161 const GLint lengths[] = {
static_cast<GLint
>(shader_source->size())};
162 ShaderSource(shader, 1u, sources, lengths);
167 const fml::Mapping& mapping,
168 const std::vector<Scalar>& defines)
const {
169 auto shader_source = std::string{
170 reinterpret_cast<const char*
>(mapping.GetMapping()), mapping.GetSize()};
174 auto index = shader_source.find(
'\n');
175 if (index == std::string::npos) {
180 std::stringstream ss;
182 for (
auto i = 0u; i < defines.size(); i++) {
183 ss <<
"#define SPIRV_CROSS_CONSTANT_ID_" << i <<
" " << defines[i] <<
'\n';
185 auto define_string = ss.str();
186 shader_source.insert(index + 1, define_string);
187 return shader_source;
191 return description_.get();
196 return capabilities_;
201 case GL_FRAMEBUFFER_COMPLETE:
202 return "GL_FRAMEBUFFER_COMPLETE";
203 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
204 return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
205 #if GL_ES_VERSION_2_0
206 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
207 return "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
209 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
210 return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
211 case GL_FRAMEBUFFER_UNSUPPORTED:
212 return "GL_FRAMEBUFFER_UNSUPPORTED";
213 case GL_INVALID_ENUM:
214 return "GL_INVALID_ENUM";
217 return "Unknown FBO Error Status";
222 case GL_RENDERBUFFER:
223 return "GL_RENDERBUFFER";
230 return "Unknown Type";
235 GLint param = GL_NONE;
236 gl.GetFramebufferAttachmentParameteriv(
239 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
243 if (param != GL_NONE) {
245 gl.GetFramebufferAttachmentParameteriv(
248 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
251 std::stringstream stream;
256 return "No Attachment";
260 GLint framebuffer = GL_NONE;
261 GetIntegerv(GL_FRAMEBUFFER_BINDING, &framebuffer);
262 if (IsFramebuffer(framebuffer) == GL_FALSE) {
263 return "No framebuffer or the default window framebuffer is bound.";
266 GLenum status = CheckFramebufferStatus(framebuffer);
267 std::stringstream stream;
269 << ((framebuffer == GL_NONE) ?
"(Default)"
270 : std::to_string(framebuffer))
273 stream <<
"Framebuffer is complete." << std::endl;
275 stream <<
"Framebuffer is incomplete." << std::endl;
277 stream <<
"Description: " << std::endl;
278 stream <<
"Color Attachment: "
281 stream <<
"Color Attachment: "
284 stream <<
"Color Attachment: "
291 GLint framebuffer = GL_NONE;
292 GetIntegerv(GL_FRAMEBUFFER_BINDING, &framebuffer);
293 if (IsFramebuffer(framebuffer) == GL_FALSE) {
297 GLenum status = CheckFramebufferStatus(framebuffer);
298 return status == GL_FRAMEBUFFER_COMPLETE;
306 return GL_BUFFER_KHR;
308 return GL_PROGRAM_KHR;
310 return GL_SHADER_KHR;
312 return GL_RENDERBUFFER;
314 return GL_FRAMEBUFFER;
324 return gl.IsTexture(name);
326 return gl.IsBuffer(name);
328 return gl.IsProgram(name);
330 return gl.IsShader(name);
332 return gl.IsRenderbuffer(name);
334 return gl.IsFramebuffer(name);
341 const std::string& label)
const {
342 if (debug_label_max_length_ <= 0) {
345 if (!ObjectLabelKHR.IsAvailable()) {
352 const auto label_length =
353 std::min<GLsizei>(debug_label_max_length_ - 1, label.size());
354 if (!identifier.has_value()) {
357 ObjectLabelKHR(identifier.value(),
366 #ifdef IMPELLER_DEBUG
367 if (debug_label_max_length_ <= 0) {
372 const auto label_length =
373 std::min<GLsizei>(debug_label_max_length_ - 1, label.size());
374 PushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION_KHR,
375 static_cast<GLuint
>(
id.
id),
379 #endif // IMPELLER_DEBUG
383 #ifdef IMPELLER_DEBUG
384 if (debug_label_max_length_ <= 0) {
389 #endif // IMPELLER_DEBUG
394 GetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
399 length = std::min<GLint>(length, 1024);
401 if (!allocation.
Truncate(length,
false)) {
404 GetProgramInfoLog(program,
407 reinterpret_cast<GLchar*
>(allocation.
GetBuffer())
412 return std::string{
reinterpret_cast<const char*
>(allocation.
GetBuffer()),
413 static_cast<size_t>(length)};