24 return "GL_INVALID_ENUM";
25 case GL_INVALID_VALUE:
26 return "GL_INVALID_VALUE";
27 case GL_INVALID_OPERATION:
28 return "GL_INVALID_OPERATION";
29 case GL_INVALID_FRAMEBUFFER_OPERATION:
30 return "GL_INVALID_FRAMEBUFFER_OPERATION";
31 case GL_FRAMEBUFFER_COMPLETE:
32 return "GL_FRAMEBUFFER_COMPLETE";
33 case GL_OUT_OF_MEMORY:
34 return "GL_OUT_OF_MEMORY";
44 case GL_INVALID_VALUE:
45 case GL_INVALID_OPERATION:
46 case GL_INVALID_FRAMEBUFFER_OPERATION:
47 case GL_OUT_OF_MEMORY:
55 return [resolver](
const char* function_name) ->
void* {
56 auto resolved = resolver(function_name);
62 auto function = std::string{function_name};
65 return resolver(truncated.c_str());
69 return resolver(truncated.c_str());
86 auto error_fn =
reinterpret_cast<PFNGLGETERRORPROC
>(resolver(
"glGetError"));
92#define IMPELLER_PROC(proc_ivar) \
93 if (auto fn_ptr = resolver(proc_ivar.name.data())) { \
94 proc_ivar.function = \
95 reinterpret_cast<decltype(proc_ivar.function)>(fn_ptr); \
96 proc_ivar.error_fn = error_fn; \
98 VALIDATION_LOG << "Could not resolve " << proc_ivar.name; \
104 description_ = std::make_unique<DescriptionGLES>(*
this);
106 if (!description_->IsValid()) {
110 if (description_->IsES()) {
118#define IMPELLER_PROC(proc_ivar) \
119 if (auto fn_ptr = resolver(proc_ivar.name.data())) { \
120 proc_ivar.function = \
121 reinterpret_cast<decltype(proc_ivar.function)>(fn_ptr); \
122 proc_ivar.error_fn = error_fn; \
125 if (description_->GetGlVersion().IsAtLeast(
Version(3))) {
134 PushDebugGroupKHR.Reset();
135 PopDebugGroupKHR.Reset();
136 ObjectLabelKHR.Reset();
138 GetIntegerv(GL_MAX_LABEL_LENGTH_KHR, &debug_label_max_length_);
141 if (!description_->HasExtension(
"GL_EXT_discard_framebuffer")) {
142 DiscardFramebufferEXT.Reset();
145 if (!description_->HasExtension(
"GL_ANGLE_framebuffer_blit")) {
146 BlitFramebufferANGLE.Reset();
149 if (!description_->HasExtension(
"GL_EXT_instanced_arrays")) {
150 VertexAttribDivisorEXT.Reset();
153 if (!description_->HasExtension(
"GL_EXT_draw_instanced")) {
154 DrawArraysInstancedEXT.Reset();
155 DrawElementsInstancedEXT.Reset();
158 capabilities_ = std::make_shared<CapabilitiesGLES>(*
this);
172 const std::vector<Scalar>& defines)
const {
173 if (defines.empty()) {
174 const GLchar* sources[] = {
175 reinterpret_cast<const GLchar*
>(mapping.
GetMapping())};
176 const GLint lengths[] = {
static_cast<GLint
>(mapping.
GetSize())};
177 ShaderSource(shader, 1u, sources, lengths);
181 if (!shader_source.has_value()) {
186 const GLchar* sources[] = {
187 reinterpret_cast<const GLchar*
>(shader_source->c_str())};
188 const GLint lengths[] = {
static_cast<GLint
>(shader_source->size())};
189 ShaderSource(shader, 1u, sources, lengths);
195 const std::vector<Scalar>& defines)
const {
196 std::string shader_source = std::string{
201 size_t index = shader_source.find(
'\n');
202 if (index == std::string::npos) {
207 std::stringstream ss;
209 for (
auto i = 0u;
i < defines.size();
i++) {
210 ss <<
"#define SPIRV_CROSS_CONSTANT_ID_" <<
i <<
" " << defines[
i] <<
'\n';
212 auto define_string = ss.str();
213 shader_source.insert(index + 1, define_string);
214 return shader_source;
218 return description_.get();
223 return capabilities_;
228 case GL_FRAMEBUFFER_COMPLETE:
229 return "GL_FRAMEBUFFER_COMPLETE";
230 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
231 return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
233 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
234 return "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
236 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
237 return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
238 case GL_FRAMEBUFFER_UNSUPPORTED:
239 return "GL_FRAMEBUFFER_UNSUPPORTED";
240 case GL_INVALID_ENUM:
241 return "GL_INVALID_ENUM";
244 return "Unknown FBO Error Status";
249 case GL_RENDERBUFFER:
250 return "GL_RENDERBUFFER";
257 return "Unknown Type";
262 GLint
type = GL_NONE;
263 gl.GetFramebufferAttachmentParameteriv(
266 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
270 if (
type != GL_NONE) {
271 GLint
object = GL_NONE;
272 gl.GetFramebufferAttachmentParameteriv(
275 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
278 std::stringstream stream;
283 return "No Attachment";
287 GLint framebuffer = GL_NONE;
288 GetIntegerv(GL_FRAMEBUFFER_BINDING, &framebuffer);
289 if (framebuffer == GL_NONE) {
290 return "The default framebuffer (FBO0) was bound.";
292 if (IsFramebuffer(framebuffer) == GL_FALSE) {
294 "The framebuffer binding ({}) was not a valid framebuffer.",
298 GLenum status = CheckFramebufferStatus(GL_FRAMEBUFFER);
299 std::stringstream stream;
301 << ((framebuffer == GL_NONE) ?
"(Default)"
302 : std::to_string(framebuffer))
305 stream <<
"Framebuffer is complete." << std::endl;
307 stream <<
"Framebuffer is incomplete." << std::endl;
309 stream <<
"Description: " << std::endl;
310 stream <<
"Color Attachment: "
313 stream <<
"Depth Attachment: "
316 stream <<
"Stencil Attachment: "
323 GLint framebuffer = GL_NONE;
324 GetIntegerv(GL_FRAMEBUFFER_BINDING, &framebuffer);
325 if (IsFramebuffer(framebuffer) == GL_FALSE) {
329 GLenum status = CheckFramebufferStatus(GL_FRAMEBUFFER);
330 return status == GL_FRAMEBUFFER_COMPLETE;
338 return GL_BUFFER_KHR;
340 return GL_PROGRAM_KHR;
342 return GL_SHADER_KHR;
344 return GL_RENDERBUFFER;
346 return GL_FRAMEBUFFER;
348 return GL_SYNC_FENCE;
358 return gl.IsTexture(
name);
360 return gl.IsBuffer(
name);
362 return gl.IsProgram(
name);
364 return gl.IsShader(
name);
366 return gl.IsRenderbuffer(
name);
368 return gl.IsFramebuffer(
name);
376 if (debug_label_max_length_ <= 0) {
379 if (!ObjectLabelKHR.IsAvailable()) {
387 std::string_view label)
const {
395 const auto label_length =
396 std::min<GLsizei>(debug_label_max_length_ - 1, label.size());
397 if (!identifier.has_value()) {
400 ObjectLabelKHR(identifier.value(),
410 if (debug_label_max_length_ <= 0) {
415 const auto label_length =
416 std::min<GLsizei>(debug_label_max_length_ - 1, label.size());
417 PushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION_KHR,
418 static_cast<GLuint
>(
id.
id),
427 if (debug_label_max_length_ <= 0) {
437 GetProgramiv(program, GL_INFO_LOG_LENGTH, &
length);
447 GetProgramInfoLog(program,
450 reinterpret_cast<GLchar*
>(allocation.
GetBuffer())
455 return std::string{
reinterpret_cast<const char*
>(allocation.
GetBuffer()),
456 static_cast<size_t>(
length)};
461 return CheckFramebufferStatus(
target);
463 return GL_FRAMEBUFFER_COMPLETE;
virtual const uint8_t * GetMapping() const =0
virtual size_t GetSize() const =0
Describes an allocation on the heap.
uint8_t * GetBuffer() const
Gets the pointer to the start of the allocation.
bool Truncate(Bytes length, bool npot=true)
Resize the underlying allocation to at least given number of bytes.
std::optional< std::string > ComputeShaderWithDefines(const fml::Mapping &mapping, const std::vector< Scalar > &defines) const
void PopDebugGroup() const
bool SetDebugLabel(DebugResourceType type, GLint name, std::string_view label) const
std::function< void *(const char *function_name)> Resolver
void ShaderSourceMapping(GLuint shader, const fml::Mapping &mapping, const std::vector< Scalar > &defines={}) const
Set the source for the attached [shader].
std::string GetProgramInfoLogString(GLuint program) const
GLenum CheckFramebufferStatusDebug(GLenum target) const
bool SupportsDebugLabels() const
std::string DescribeCurrentFramebuffer() const
const std::shared_ptr< const CapabilitiesGLES > & GetCapabilities() const
bool IsCurrentFramebufferComplete() const
ProcTableGLES(Resolver resolver)
void PushDebugGroup(const std::string &string) const
const DescriptionGLES * GetDescription() const
#define FML_UNREACHABLE()
Dart_NativeFunction function
ProcTableGLES::Resolver WrappedResolver(const ProcTableGLES::Resolver &resolver)
std::string_view GLErrorToString(GLenum value)
bool GLErrorIsFatal(GLenum value)
static std::optional< GLenum > ToDebugIdentifier(DebugResourceType type)
static const char * FramebufferStatusToString(GLenum status)
static const char * AttachmentTypeString(GLint type)
static bool ResourceIsLive(const ProcTableGLES &gl, DebugResourceType type, GLint name)
static std::string DescribeFramebufferAttachment(const ProcTableGLES &gl, GLenum attachment)
#define IMPELLER_PROC(proc_ivar)
#define FOR_EACH_IMPELLER_EXT_PROC(PROC)
#define FOR_EACH_IMPELLER_GLES3_PROC(PROC)
#define FOR_EACH_IMPELLER_DESKTOP_ONLY_PROC(PROC)
#define IP_ENABLE_GLES_LABELING
Enable to allow GLES to push/pop labels for usage in GPU traces.
#define FOR_EACH_IMPELLER_ES_ONLY_PROC(PROC)
#define FOR_EACH_IMPELLER_PROC(PROC)
impeller::ShaderType type