mirror of
https://github.com/SFML/SFML.git
synced 2024-11-25 04:41:05 +08:00
Simplify and extend [E]GLCheck implementation
This commit is contained in:
parent
2dd72be036
commit
e2ea1d8a7c
@ -31,81 +31,52 @@
|
|||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
namespace sf::priv
|
namespace sf::priv
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void glCheckError(const std::filesystem::path& file, unsigned int line, std::string_view expression)
|
bool glCheckError(const std::filesystem::path& file, unsigned int line, std::string_view expression)
|
||||||
{
|
{
|
||||||
// Get the last error
|
const auto logError = [&](const char* error, const char* description)
|
||||||
const GLenum errorCode = glGetError();
|
|
||||||
|
|
||||||
if (errorCode != GL_NO_ERROR)
|
|
||||||
{
|
{
|
||||||
std::string error = "Unknown error";
|
|
||||||
std::string description = "No description";
|
|
||||||
|
|
||||||
// Decode the error code
|
|
||||||
switch (errorCode)
|
|
||||||
{
|
|
||||||
case GL_INVALID_ENUM:
|
|
||||||
{
|
|
||||||
error = "GL_INVALID_ENUM";
|
|
||||||
description = "An unacceptable value has been specified for an enumerated argument.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case GL_INVALID_VALUE:
|
|
||||||
{
|
|
||||||
error = "GL_INVALID_VALUE";
|
|
||||||
description = "A numeric argument is out of range.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case GL_INVALID_OPERATION:
|
|
||||||
{
|
|
||||||
error = "GL_INVALID_OPERATION";
|
|
||||||
description = "The specified operation is not allowed in the current state.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case GL_STACK_OVERFLOW:
|
|
||||||
{
|
|
||||||
error = "GL_STACK_OVERFLOW";
|
|
||||||
description = "This command would cause a stack overflow.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case GL_STACK_UNDERFLOW:
|
|
||||||
{
|
|
||||||
error = "GL_STACK_UNDERFLOW";
|
|
||||||
description = "This command would cause a stack underflow.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case GL_OUT_OF_MEMORY:
|
|
||||||
{
|
|
||||||
error = "GL_OUT_OF_MEMORY";
|
|
||||||
description = "There is not enough memory left to execute the command.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case GLEXT_GL_INVALID_FRAMEBUFFER_OPERATION:
|
|
||||||
{
|
|
||||||
error = "GL_INVALID_FRAMEBUFFER_OPERATION";
|
|
||||||
description = "The object bound to FRAMEBUFFER_BINDING is not \"framebuffer complete\".";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log the error
|
|
||||||
err() << "An internal OpenGL call failed in " << file.filename() << "(" << line << ")."
|
err() << "An internal OpenGL call failed in " << file.filename() << "(" << line << ")."
|
||||||
<< "\nExpression:\n " << expression << "\nError description:\n " << error << "\n " << description << '\n'
|
<< "\nExpression:\n " << expression << "\nError description:\n " << error << "\n " << description << '\n'
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (glGetError())
|
||||||
|
{
|
||||||
|
case GL_NO_ERROR:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case GL_INVALID_ENUM:
|
||||||
|
return logError("GL_INVALID_ENUM", "An unacceptable value has been specified for an enumerated argument.");
|
||||||
|
|
||||||
|
case GL_INVALID_VALUE:
|
||||||
|
return logError("GL_INVALID_VALUE", "A numeric argument is out of range.");
|
||||||
|
|
||||||
|
case GL_INVALID_OPERATION:
|
||||||
|
return logError("GL_INVALID_OPERATION", "The specified operation is not allowed in the current state.");
|
||||||
|
|
||||||
|
case GL_STACK_OVERFLOW:
|
||||||
|
return logError("GL_STACK_OVERFLOW", "This command would cause a stack overflow.");
|
||||||
|
|
||||||
|
case GL_STACK_UNDERFLOW:
|
||||||
|
return logError("GL_STACK_UNDERFLOW", "This command would cause a stack underflow.");
|
||||||
|
|
||||||
|
case GL_OUT_OF_MEMORY:
|
||||||
|
return logError("GL_OUT_OF_MEMORY", "There is not enough memory left to execute the command.");
|
||||||
|
|
||||||
|
case GLEXT_GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||||
|
return logError("GL_INVALID_FRAMEBUFFER_OPERATION",
|
||||||
|
"The object bound to FRAMEBUFFER_BINDING is not \"framebuffer complete\".");
|
||||||
|
|
||||||
|
default:
|
||||||
|
return logError("Unknown error", "Unknown description");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf::priv
|
||||||
|
@ -63,7 +63,9 @@ namespace sf::priv
|
|||||||
/// \param line Line number of the source file where the call is located
|
/// \param line Line number of the source file where the call is located
|
||||||
/// \param expression The evaluated expression as a string
|
/// \param expression The evaluated expression as a string
|
||||||
///
|
///
|
||||||
|
/// \return `false` if an error occurred, `true` otherwise
|
||||||
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void glCheckError(const std::filesystem::path& file, unsigned int line, std::string_view expression);
|
bool glCheckError(const std::filesystem::path& file, unsigned int line, std::string_view expression);
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf::priv
|
||||||
|
@ -33,139 +33,88 @@
|
|||||||
#include <glad/egl.h>
|
#include <glad/egl.h>
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
namespace sf::priv
|
namespace sf::priv
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void eglCheckError(const std::filesystem::path& file, unsigned int line, std::string_view expression)
|
bool eglCheckError(const std::filesystem::path& file, unsigned int line, std::string_view expression)
|
||||||
{
|
{
|
||||||
// Obtain information about the success or failure of the most recent EGL
|
const auto logError = [&](const char* error, const char* description)
|
||||||
// function called in the current thread
|
|
||||||
const EGLint errorCode = eglGetError();
|
|
||||||
|
|
||||||
if (errorCode != EGL_SUCCESS)
|
|
||||||
{
|
{
|
||||||
std::string error = "unknown error";
|
|
||||||
std::string description = "no description";
|
|
||||||
|
|
||||||
// Decode the error code returned
|
|
||||||
switch (errorCode)
|
|
||||||
{
|
|
||||||
case EGL_NOT_INITIALIZED:
|
|
||||||
{
|
|
||||||
error = "EGL_NOT_INITIALIZED";
|
|
||||||
description = "EGL is not initialized, or could not be initialized, for the specified display";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EGL_BAD_ACCESS:
|
|
||||||
{
|
|
||||||
error = "EGL_BAD_ACCESS";
|
|
||||||
description =
|
|
||||||
"EGL cannot access a requested resource (for example, a context is bound in another thread)";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EGL_BAD_ALLOC:
|
|
||||||
{
|
|
||||||
error = "EGL_BAD_ALLOC";
|
|
||||||
description = "EGL failed to allocate resources for the requested operation";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EGL_BAD_ATTRIBUTE:
|
|
||||||
{
|
|
||||||
error = "EGL_BAD_ATTRIBUTE";
|
|
||||||
description = "an unrecognized attribute or attribute value was passed in an attribute list";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EGL_BAD_CONTEXT:
|
|
||||||
{
|
|
||||||
error = "EGL_BAD_CONTEXT";
|
|
||||||
description = "an EGLContext argument does not name a valid EGLContext";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EGL_BAD_CONFIG:
|
|
||||||
{
|
|
||||||
error = "EGL_BAD_CONFIG";
|
|
||||||
description = "an EGLConfig argument does not name a valid EGLConfig";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EGL_BAD_CURRENT_SURFACE:
|
|
||||||
{
|
|
||||||
error = "EGL_BAD_CURRENT_SURFACE";
|
|
||||||
description =
|
|
||||||
"the current surface of the calling thread is a window, pbuffer, or pixmap that is no longer valid";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EGL_BAD_DISPLAY:
|
|
||||||
{
|
|
||||||
error = "EGL_BAD_DISPLAY";
|
|
||||||
description =
|
|
||||||
"an EGLDisplay argument does not name a valid EGLDisplay; or, EGL is not initialized on the "
|
|
||||||
"specified EGLDisplay";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
case EGL_BAD_SURFACE:
|
|
||||||
{
|
|
||||||
error = "EGL_BAD_SURFACE";
|
|
||||||
description =
|
|
||||||
"an EGLSurface argument does not name a valid surface (window, pbuffer, or pixmap) configured for "
|
|
||||||
"rendering";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EGL_BAD_MATCH:
|
|
||||||
{
|
|
||||||
error = "EGL_BAD_MATCH";
|
|
||||||
description =
|
|
||||||
"arguments are inconsistent; for example, an otherwise valid context requires buffers (e.g. depth "
|
|
||||||
"or stencil) not allocated by an otherwise valid surface";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EGL_BAD_PARAMETER:
|
|
||||||
{
|
|
||||||
error = "EGL_BAD_PARAMETER";
|
|
||||||
description = "one or more argument values are invalid";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EGL_BAD_NATIVE_PIXMAP:
|
|
||||||
{
|
|
||||||
error = "EGL_BAD_NATIVE_PIXMAP";
|
|
||||||
description = "an EGLNativePixmapType argument does not refer to a valid native pixmap";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EGL_BAD_NATIVE_WINDOW:
|
|
||||||
{
|
|
||||||
error = "EGL_BAD_NATIVE_WINDOW";
|
|
||||||
description = "an EGLNativeWindowType argument does not refer to a valid native window";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EGL_CONTEXT_LOST:
|
|
||||||
{
|
|
||||||
error = "EGL_CONTEXT_LOST";
|
|
||||||
description =
|
|
||||||
"a power management event has occurred. The application must destroy all contexts and reinitialize "
|
|
||||||
"client API state and objects to continue rendering";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log the error
|
|
||||||
err() << "An internal EGL call failed in " << file.filename() << " (" << line << ") : "
|
err() << "An internal EGL call failed in " << file.filename() << " (" << line << ") : "
|
||||||
<< "\nExpression:\n " << expression << "\nError description:\n " << error << "\n " << description << '\n'
|
<< "\nExpression:\n " << expression << "\nError description:\n " << error << "\n " << description << '\n'
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (eglGetError())
|
||||||
|
{
|
||||||
|
case EGL_SUCCESS:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case EGL_NOT_INITIALIZED:
|
||||||
|
return logError("EGL_NOT_INITIALIZED",
|
||||||
|
"EGL is not initialized, or could not be initialized, for the specified display");
|
||||||
|
|
||||||
|
case EGL_BAD_ACCESS:
|
||||||
|
return logError("EGL_BAD_ACCESS",
|
||||||
|
"EGL cannot access a requested resource (for example, a context is bound in another "
|
||||||
|
"thread)");
|
||||||
|
|
||||||
|
case EGL_BAD_ALLOC:
|
||||||
|
return logError("EGL_BAD_ALLOC", "EGL failed to allocate resources for the requested operation");
|
||||||
|
|
||||||
|
case EGL_BAD_ATTRIBUTE:
|
||||||
|
return logError("EGL_BAD_ATTRIBUTE",
|
||||||
|
"an unrecognized attribute or attribute value was passed in an attribute list");
|
||||||
|
|
||||||
|
case EGL_BAD_CONTEXT:
|
||||||
|
return logError("EGL_BAD_CONTEXT", "an EGLContext argument does not name a valid EGLContext");
|
||||||
|
|
||||||
|
case EGL_BAD_CONFIG:
|
||||||
|
return logError("EGL_BAD_CONFIG", "an EGLConfig argument does not name a valid EGLConfig");
|
||||||
|
|
||||||
|
case EGL_BAD_CURRENT_SURFACE:
|
||||||
|
return logError("EGL_BAD_CURRENT_SURFACE",
|
||||||
|
"the current surface of the calling thread is a window, pbuffer, or pixmap that is no "
|
||||||
|
"longer valid");
|
||||||
|
|
||||||
|
case EGL_BAD_DISPLAY:
|
||||||
|
return logError("EGL_BAD_DISPLAY",
|
||||||
|
"an EGLDisplay argument does not name a valid EGLDisplay; or, EGL is not initialized on "
|
||||||
|
"the specified EGLDisplay");
|
||||||
|
|
||||||
|
|
||||||
|
case EGL_BAD_SURFACE:
|
||||||
|
return logError("EGL_BAD_SURFACE",
|
||||||
|
"an EGLSurface argument does not name a valid surface (window, pbuffer, or pixmap) "
|
||||||
|
"configured for rendering");
|
||||||
|
|
||||||
|
case EGL_BAD_MATCH:
|
||||||
|
return logError("EGL_BAD_MATCH",
|
||||||
|
"arguments are inconsistent; for example, an otherwise valid context requires buffers "
|
||||||
|
"(e.g. depth or stencil) not allocated by an otherwise valid surface");
|
||||||
|
|
||||||
|
case EGL_BAD_PARAMETER:
|
||||||
|
return logError("EGL_BAD_PARAMETER", "one or more argument values are invalid");
|
||||||
|
|
||||||
|
case EGL_BAD_NATIVE_PIXMAP:
|
||||||
|
return logError("EGL_BAD_NATIVE_PIXMAP",
|
||||||
|
"an EGLNativePixmapType argument does not refer to a valid native pixmap");
|
||||||
|
|
||||||
|
case EGL_BAD_NATIVE_WINDOW:
|
||||||
|
return logError("EGL_BAD_NATIVE_WINDOW",
|
||||||
|
"an EGLNativeWindowType argument does not refer to a valid native window");
|
||||||
|
|
||||||
|
case EGL_CONTEXT_LOST:
|
||||||
|
return logError("EGL_CONTEXT_LOST",
|
||||||
|
"a power management event has occurred. The application must destroy all contexts and "
|
||||||
|
"reinitialize client API state and objects to continue rendering");
|
||||||
|
|
||||||
|
default:
|
||||||
|
return logError("Unknown error", "Unknown description");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,9 @@ namespace sf::priv
|
|||||||
/// \param line Line number of the source file where the call is located
|
/// \param line Line number of the source file where the call is located
|
||||||
/// \param expression The evaluated expression as a string
|
/// \param expression The evaluated expression as a string
|
||||||
///
|
///
|
||||||
|
/// \return `false` if an error occurred, `true` otherwise
|
||||||
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void eglCheckError(const std::filesystem::path& file, unsigned int line, std::string_view expression);
|
bool eglCheckError(const std::filesystem::path& file, unsigned int line, std::string_view expression);
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf::priv
|
||||||
|
Loading…
Reference in New Issue
Block a user