improved SDL_GetError() output generated by EGL code

This change attempts to report the EGL error codes generated by SDL's calls
into EGL, along with the name of the EGL function that failed.
This commit is contained in:
David Ludwig 2016-12-29 11:49:18 -05:00
parent 0badbddef9
commit 0cfa0aa11c
4 changed files with 75 additions and 18 deletions

View File

@ -75,6 +75,41 @@ if (!_this->egl_data->NAME) \
return SDL_SetError("Could not retrieve EGL function " #NAME); \ return SDL_SetError("Could not retrieve EGL function " #NAME); \
} }
static const char * SDL_EGL_GetErrorName(EGLint eglErrorCode)
{
#define SDL_EGL_ERROR_TRANSLATE(e) case e: return #e;
switch (eglErrorCode) {
SDL_EGL_ERROR_TRANSLATE(EGL_SUCCESS);
SDL_EGL_ERROR_TRANSLATE(EGL_NOT_INITIALIZED);
SDL_EGL_ERROR_TRANSLATE(EGL_BAD_ACCESS);
SDL_EGL_ERROR_TRANSLATE(EGL_BAD_ALLOC);
SDL_EGL_ERROR_TRANSLATE(EGL_BAD_ATTRIBUTE);
SDL_EGL_ERROR_TRANSLATE(EGL_BAD_CONTEXT);
SDL_EGL_ERROR_TRANSLATE(EGL_BAD_CONFIG);
SDL_EGL_ERROR_TRANSLATE(EGL_BAD_CURRENT_SURFACE);
SDL_EGL_ERROR_TRANSLATE(EGL_BAD_DISPLAY);
SDL_EGL_ERROR_TRANSLATE(EGL_BAD_SURFACE);
SDL_EGL_ERROR_TRANSLATE(EGL_BAD_MATCH);
SDL_EGL_ERROR_TRANSLATE(EGL_BAD_PARAMETER);
SDL_EGL_ERROR_TRANSLATE(EGL_BAD_NATIVE_PIXMAP);
SDL_EGL_ERROR_TRANSLATE(EGL_BAD_NATIVE_WINDOW);
SDL_EGL_ERROR_TRANSLATE(EGL_CONTEXT_LOST);
}
return "";
}
int SDL_EGL_SetErrorEx(const char * message, const char * eglFunctionName, EGLint eglErrorCode)
{
const char * errorText = SDL_EGL_GetErrorName(eglErrorCode);
char altErrorText[32];
if (errorText[0] == '\0') {
/* An unknown-to-SDL error code was reported. Report its hexadecimal value, instead of its name. */
SDL_snprintf(altErrorText, SDL_arraysize(altErrorText), "0x%x", (unsigned int)eglErrorCode);
errorText = altErrorText;
}
return SDL_SetError("%s (call to %s failed, reporting an error of %s)", message, eglFunctionName, errorText);
}
/* EGL implementation of SDL OpenGL ES support */ /* EGL implementation of SDL OpenGL ES support */
#ifdef EGL_KHR_create_context #ifdef EGL_KHR_create_context
static int SDL_EGL_HasExtension(_THIS, const char *ext) static int SDL_EGL_HasExtension(_THIS, const char *ext)
@ -265,6 +300,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa
LOAD_FUNC(eglWaitGL); LOAD_FUNC(eglWaitGL);
LOAD_FUNC(eglBindAPI); LOAD_FUNC(eglBindAPI);
LOAD_FUNC(eglQueryString); LOAD_FUNC(eglQueryString);
LOAD_FUNC(eglGetError);
#if !defined(__WINRT__) #if !defined(__WINRT__)
_this->egl_data->egl_display = _this->egl_data->eglGetDisplay(native_display); _this->egl_data->egl_display = _this->egl_data->eglGetDisplay(native_display);
@ -378,7 +414,7 @@ SDL_EGL_ChooseConfig(_THIS)
configs, SDL_arraysize(configs), configs, SDL_arraysize(configs),
&found_configs) == EGL_FALSE || &found_configs) == EGL_FALSE ||
found_configs == 0) { found_configs == 0) {
return SDL_SetError("Couldn't find matching EGL config"); return SDL_EGL_SetError("Couldn't find matching EGL config", "eglChooseConfig");
} }
/* eglChooseConfig returns a number of configurations that match or exceed the requested attribs. */ /* eglChooseConfig returns a number of configurations that match or exceed the requested attribs. */
@ -497,15 +533,23 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface)
share_context, attribs); share_context, attribs);
if (egl_context == EGL_NO_CONTEXT) { if (egl_context == EGL_NO_CONTEXT) {
SDL_SetError("Could not create EGL context"); SDL_EGL_SetError("Could not create EGL context", "eglCreateContext");
return NULL; return NULL;
} }
_this->egl_data->egl_swapinterval = 0; _this->egl_data->egl_swapinterval = 0;
if (SDL_EGL_MakeCurrent(_this, egl_surface, egl_context) < 0) { if (SDL_EGL_MakeCurrent(_this, egl_surface, egl_context) < 0) {
/* Save the SDL error set by SDL_EGL_MakeCurrent */
char errorText[1024];
SDL_strlcpy(errorText, SDL_GetError(), SDL_arraysize(errorText));
/* Delete the context, which may alter the value returned by SDL_GetError() */
SDL_EGL_DeleteContext(_this, egl_context); SDL_EGL_DeleteContext(_this, egl_context);
SDL_SetError("Could not make EGL context current");
/* Restore the SDL error */
SDL_SetError("%s", errorText);
return NULL; return NULL;
} }
@ -529,7 +573,7 @@ SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context)
} else { } else {
if (!_this->egl_data->eglMakeCurrent(_this->egl_data->egl_display, if (!_this->egl_data->eglMakeCurrent(_this->egl_data->egl_display,
egl_surface, egl_surface, egl_context)) { egl_surface, egl_surface, egl_context)) {
return SDL_SetError("Unable to make EGL context current"); return SDL_EGL_SetError("Unable to make EGL context current", "eglMakeCurrent");
} }
} }
@ -551,7 +595,7 @@ SDL_EGL_SetSwapInterval(_THIS, int interval)
return 0; return 0;
} }
return SDL_SetError("Unable to set the EGL swap interval"); return SDL_EGL_SetError("Unable to set the EGL swap interval", "eglSwapInterval");
} }
int int
@ -569,7 +613,7 @@ int
SDL_EGL_SwapBuffers(_THIS, EGLSurface egl_surface) SDL_EGL_SwapBuffers(_THIS, EGLSurface egl_surface)
{ {
if (!_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, egl_surface)) { if (!_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, egl_surface)) {
return SDL_SetError("eglSwapBuffers() failed"); return SDL_EGL_SetError("unable to show color buffer in an OS-native window", "eglSwapBuffers");
} }
return 0; return 0;
} }
@ -594,6 +638,8 @@ SDL_EGL_DeleteContext(_THIS, SDL_GLContext context)
EGLSurface * EGLSurface *
SDL_EGL_CreateSurface(_THIS, NativeWindowType nw) SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
{ {
EGLSurface * surface;
if (SDL_EGL_ChooseConfig(_this) != 0) { if (SDL_EGL_ChooseConfig(_this) != 0) {
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
@ -612,10 +658,14 @@ SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
} }
#endif #endif
return _this->egl_data->eglCreateWindowSurface( surface = _this->egl_data->eglCreateWindowSurface(
_this->egl_data->egl_display, _this->egl_data->egl_display,
_this->egl_data->egl_config, _this->egl_data->egl_config,
nw, NULL); nw, NULL);
if (surface == EGL_NO_SURFACE) {
SDL_EGL_SetError("unable to create an EGL window surface", "eglCreateWindowSurface");
}
return surface;
} }
void void

View File

@ -79,6 +79,8 @@ typedef struct SDL_EGL_VideoData
EGLBoolean(EGLAPIENTRY *eglBindAPI)(EGLenum); EGLBoolean(EGLAPIENTRY *eglBindAPI)(EGLenum);
EGLint(EGLAPIENTRY *eglGetError)(void);
} SDL_EGL_VideoData; } SDL_EGL_VideoData;
/* OpenGLES functions */ /* OpenGLES functions */
@ -98,6 +100,10 @@ extern SDL_GLContext SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface);
extern int SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context); extern int SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context);
extern int SDL_EGL_SwapBuffers(_THIS, EGLSurface egl_surface); extern int SDL_EGL_SwapBuffers(_THIS, EGLSurface egl_surface);
/* SDL Error-reporting */
extern int SDL_EGL_SetErrorEx(const char * message, const char * eglFunctionName, EGLint eglErrorCode);
#define SDL_EGL_SetError(message, eglFunctionName) SDL_EGL_SetErrorEx(message, eglFunctionName, _this->egl_data->eglGetError())
/* A few of useful macros */ /* A few of useful macros */
#define SDL_EGL_SwapWindow_impl(BACKEND) int \ #define SDL_EGL_SwapWindow_impl(BACKEND) int \

View File

@ -28,6 +28,7 @@
extern "C" { extern "C" {
#include "SDL_winrtopengles.h" #include "SDL_winrtopengles.h"
#include "SDL_loadso.h" #include "SDL_loadso.h"
#include "../SDL_egl_c.h"
} }
/* Windows includes */ /* Windows includes */
@ -87,11 +88,11 @@ WINRT_GLES_LoadLibrary(_THIS, const char *path)
Microsoft::WRL::ComPtr<IUnknown> cpp_display = video_data->winrtEglWindow; Microsoft::WRL::ComPtr<IUnknown> cpp_display = video_data->winrtEglWindow;
_this->egl_data->egl_display = ((eglGetDisplay_Old_Function)_this->egl_data->eglGetDisplay)(cpp_display); _this->egl_data->egl_display = ((eglGetDisplay_Old_Function)_this->egl_data->eglGetDisplay)(cpp_display);
if (!_this->egl_data->egl_display) { if (!_this->egl_data->egl_display) {
return SDL_SetError("Could not get Windows 8.0 EGL display"); return SDL_EGL_SetError("Could not get Windows 8.0 EGL display", "eglGetDisplay");
} }
if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) { if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
return SDL_SetError("Could not initialize Windows 8.0 EGL"); return SDL_EGL_SetError("Could not initialize Windows 8.0 EGL", "eglInitialize");
} }
} else { } else {
/* Declare some ANGLE/EGL initialization property-sets, as suggested by /* Declare some ANGLE/EGL initialization property-sets, as suggested by
@ -132,7 +133,7 @@ WINRT_GLES_LoadLibrary(_THIS, const char *path)
*/ */
eglGetPlatformDisplayEXT_Function eglGetPlatformDisplayEXT = (eglGetPlatformDisplayEXT_Function)_this->egl_data->eglGetProcAddress("eglGetPlatformDisplayEXT"); eglGetPlatformDisplayEXT_Function eglGetPlatformDisplayEXT = (eglGetPlatformDisplayEXT_Function)_this->egl_data->eglGetProcAddress("eglGetPlatformDisplayEXT");
if (!eglGetPlatformDisplayEXT) { if (!eglGetPlatformDisplayEXT) {
return SDL_SetError("Could not retrieve ANGLE/WinRT display function(s)"); return SDL_EGL_SetError("Could not retrieve ANGLE/WinRT display function(s)", "eglGetProcAddress");
} }
#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) #if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
@ -141,7 +142,7 @@ WINRT_GLES_LoadLibrary(_THIS, const char *path)
*/ */
_this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes); _this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes);
if (!_this->egl_data->egl_display) { if (!_this->egl_data->egl_display) {
return SDL_SetError("Could not get 10_0+ EGL display"); return SDL_EGL_SetError("Could not get EGL display for Direct3D 10_0+", "eglGetPlatformDisplayEXT");
} }
if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE)
@ -153,7 +154,7 @@ WINRT_GLES_LoadLibrary(_THIS, const char *path)
*/ */
_this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes); _this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes);
if (!_this->egl_data->egl_display) { if (!_this->egl_data->egl_display) {
return SDL_SetError("Could not get 9_3 EGL display"); return SDL_EGL_SetError("Could not get EGL display for Direct3D 9_3", "eglGetPlatformDisplayEXT");
} }
if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) { if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
@ -162,11 +163,11 @@ WINRT_GLES_LoadLibrary(_THIS, const char *path)
*/ */
_this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes); _this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes);
if (!_this->egl_data->egl_display) { if (!_this->egl_data->egl_display) {
return SDL_SetError("Could not get WARP EGL display"); return SDL_EGL_SetError("Could not get EGL display for Direct3D WARP", "eglGetPlatformDisplayEXT");
} }
if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) { if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
return SDL_SetError("Could not initialize WinRT 8.x+ EGL"); return SDL_EGL_SetError("Could not initialize WinRT 8.x+ EGL", "eglInitialize");
} }
} }
} }

View File

@ -621,7 +621,7 @@ WINRT_CreateWindow(_THIS, SDL_Window * window)
_this->egl_data->egl_config, _this->egl_data->egl_config,
cpp_winrtEglWindow, NULL); cpp_winrtEglWindow, NULL);
if (data->egl_surface == NULL) { if (data->egl_surface == NULL) {
return SDL_SetError("eglCreateWindowSurface failed"); return SDL_EGL_SetError("unable to create EGL native-window surface", "eglCreateWindowSurface");
} }
} else if (data->coreWindow.Get() != nullptr) { } else if (data->coreWindow.Get() != nullptr) {
/* Attempt to create a window surface using newer versions of /* Attempt to create a window surface using newer versions of
@ -634,7 +634,7 @@ WINRT_CreateWindow(_THIS, SDL_Window * window)
coreWindowAsIInspectable, coreWindowAsIInspectable,
NULL); NULL);
if (data->egl_surface == NULL) { if (data->egl_surface == NULL) {
return SDL_SetError("eglCreateWindowSurface failed"); return SDL_EGL_SetError("unable to create EGL native-window surface", "eglCreateWindowSurface");
} }
} else { } else {
return SDL_SetError("No supported means to create an EGL window surface are available"); return SDL_SetError("No supported means to create an EGL window surface are available");