Skip to content
Permalink
Browse files

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.
  • Loading branch information
DavidLudwig committed Dec 29, 2016
1 parent 0badbdd commit 0cfa0aa11c32b5b62a9d7896077f4007eb6dd46f
Showing with 75 additions and 18 deletions.
  1. +59 −9 src/video/SDL_egl.c
  2. +6 −0 src/video/SDL_egl_c.h
  3. +8 −7 src/video/winrt/SDL_winrtopengles.cpp
  4. +2 −2 src/video/winrt/SDL_winrtvideo.cpp
@@ -74,7 +74,42 @@ if (!_this->egl_data->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 */
#ifdef EGL_KHR_create_context
static int SDL_EGL_HasExtension(_THIS, const char *ext)
@@ -265,7 +300,8 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa
LOAD_FUNC(eglWaitGL);
LOAD_FUNC(eglBindAPI);
LOAD_FUNC(eglQueryString);

LOAD_FUNC(eglGetError);

#if !defined(__WINRT__)
_this->egl_data->egl_display = _this->egl_data->eglGetDisplay(native_display);
if (!_this->egl_data->egl_display) {
@@ -378,7 +414,7 @@ SDL_EGL_ChooseConfig(_THIS)
configs, SDL_arraysize(configs),
&found_configs) == EGL_FALSE ||
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. */
@@ -497,15 +533,23 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface)
share_context, attribs);

if (egl_context == EGL_NO_CONTEXT) {
SDL_SetError("Could not create EGL context");
SDL_EGL_SetError("Could not create EGL context", "eglCreateContext");
return NULL;
}

_this->egl_data->egl_swapinterval = 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_SetError("Could not make EGL context current");

/* Restore the SDL error */
SDL_SetError("%s", errorText);

return NULL;
}

@@ -529,7 +573,7 @@ SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context)
} else {
if (!_this->egl_data->eglMakeCurrent(_this->egl_data->egl_display,
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 SDL_SetError("Unable to set the EGL swap interval");
return SDL_EGL_SetError("Unable to set the EGL swap interval", "eglSwapInterval");
}

int
@@ -569,7 +613,7 @@ int
SDL_EGL_SwapBuffers(_THIS, EGLSurface 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;
}
@@ -594,6 +638,8 @@ SDL_EGL_DeleteContext(_THIS, SDL_GLContext context)
EGLSurface *
SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
{
EGLSurface * surface;

if (SDL_EGL_ChooseConfig(_this) != 0) {
return EGL_NO_SURFACE;
}
@@ -612,10 +658,14 @@ SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
}
#endif

return _this->egl_data->eglCreateWindowSurface(
surface = _this->egl_data->eglCreateWindowSurface(
_this->egl_data->egl_display,
_this->egl_data->egl_config,
nw, NULL);
if (surface == EGL_NO_SURFACE) {
SDL_EGL_SetError("unable to create an EGL window surface", "eglCreateWindowSurface");
}
return surface;
}

void
@@ -79,6 +79,8 @@ typedef struct SDL_EGL_VideoData

EGLBoolean(EGLAPIENTRY *eglBindAPI)(EGLenum);

EGLint(EGLAPIENTRY *eglGetError)(void);

} SDL_EGL_VideoData;

/* 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_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 */

#define SDL_EGL_SwapWindow_impl(BACKEND) int \
@@ -28,6 +28,7 @@
extern "C" {
#include "SDL_winrtopengles.h"
#include "SDL_loadso.h"
#include "../SDL_egl_c.h"
}

/* Windows includes */
@@ -87,11 +88,11 @@ WINRT_GLES_LoadLibrary(_THIS, const char *path)
Microsoft::WRL::ComPtr<IUnknown> cpp_display = video_data->winrtEglWindow;
_this->egl_data->egl_display = ((eglGetDisplay_Old_Function)_this->egl_data->eglGetDisplay)(cpp_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) {
return SDL_SetError("Could not initialize Windows 8.0 EGL");
return SDL_EGL_SetError("Could not initialize Windows 8.0 EGL", "eglInitialize");
}
} else {
/* 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");
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)
@@ -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);
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)
@@ -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);
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) {
@@ -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);
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) {
return SDL_SetError("Could not initialize WinRT 8.x+ EGL");
return SDL_EGL_SetError("Could not initialize WinRT 8.x+ EGL", "eglInitialize");
}
}
}
@@ -621,7 +621,7 @@ WINRT_CreateWindow(_THIS, SDL_Window * window)
_this->egl_data->egl_config,
cpp_winrtEglWindow, 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) {
/* Attempt to create a window surface using newer versions of
@@ -634,7 +634,7 @@ WINRT_CreateWindow(_THIS, SDL_Window * window)
coreWindowAsIInspectable,
NULL);
if (data->egl_surface == NULL) {
return SDL_SetError("eglCreateWindowSurface failed");
return SDL_EGL_SetError("unable to create EGL native-window surface", "eglCreateWindowSurface");
}
} else {
return SDL_SetError("No supported means to create an EGL window surface are available");

0 comments on commit 0cfa0aa

Please sign in to comment.