#include "core/event.h" #include "core/renderer.h" #include "core/window.h" #include "internal/utils.h" #include #include #include /* Get human-readable EGL error string */ const char *egl_error_string(EGLint error) { switch (error) { case EGL_SUCCESS: return "EGL_SUCCESS"; case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED"; case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS"; case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC"; case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE"; case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG"; case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT"; case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE"; case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY"; case EGL_BAD_MATCH: return "EGL_BAD_MATCH"; case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP"; case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW"; case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER"; case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE"; case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST"; default: return "UNKNOWN_EGL_ERROR"; } } /* Crash with EGL error information * */ void crash_egl(const char *expr, const char *file, int line) { EGLint error = eglGetError(); fprintf(stderr, "EGL Error at %s:%d\n", file, line); fprintf(stderr, "Expression: %s\n", expr); fprintf(stderr, "Error code: 0x%x (%s)\n", error, egl_error_string(error)); abort(); } /* Macro for checking EGL boolean returns (EGL_TRUE/EGL_FALSE) */ #define assert_egl(expr) \ do { \ if (!(expr)) \ crash_egl(#expr, __FILE__, __LINE__); \ } while (0) void RuimInitEGL(RuimToplevel *toplevel) { RuimSurfaceEGL ruimSurface; EGLint version_major, version_minor; EGLConfig config; EGLint num_config; struct toplevel_x11 *x11_toplevel = (struct toplevel_x11 *)toplevel->data; struct backend_x11 *x11_backend = (struct backend_x11 *)toplevel->backend->data; EGLint constraints[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 24, EGL_NONE, }; /* egl-contexts collect all state descriptions needed required for operation */ EGLint ctxattr[] = {EGL_CONTEXT_MAJOR_VERSION, 3, EGL_CONTEXT_MINOR_VERSION, 0, EGL_NONE}; const char *client_extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); if (!client_extensions) { abort(); } if (!strstr(client_extensions, "EGL_EXT_platform_xcb")) { abort(); } ruimSurface.display = eglGetPlatformDisplay(EGL_PLATFORM_XCB_EXT, x11_backend->connection, NULL); assert_egl(ruimSurface.display); assert_egl( eglInitialize(ruimSurface.display, &version_major, &version_minor)); ; assert_egl(eglChooseConfig(ruimSurface.display, constraints, &config, 1, &num_config)); assert_egl(eglBindAPI(EGL_OPENGL_ES_API)); ruimSurface.surface = eglCreatePlatformWindowSurface( ruimSurface.display, config, &x11_toplevel->window, NULL); assert_egl(ruimSurface.surface); ruimSurface.context = eglCreateContext(ruimSurface.display, config, EGL_NO_CONTEXT, ctxattr); assert_egl(ruimSurface.context); assert_egl(eglMakeCurrent(ruimSurface.display, ruimSurface.surface, ruimSurface.surface, ruimSurface.context)); assert_egl(eglSwapInterval(ruimSurface.display, 1)); x11_backend->surface = ruimSurface; } EGLBoolean RuimSwapEGL(RuimToplevel *toplevel) { struct backend_x11 *x11_backend = (struct backend_x11 *)toplevel->backend->data; return eglSwapBuffers(x11_backend->surface.display, x11_backend->surface.surface); } void RuimDeinitEGL(RuimSurfaceEGL *eglCtx) { assert_egl(eglMakeCurrent(eglCtx->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); assert_egl(eglDestroyContext(eglCtx->display, eglCtx->context)); assert_egl(eglDestroySurface(eglCtx->display, eglCtx->surface)); assert_egl(eglTerminate(eglCtx->display)); }