// ===================================================================================================================== // fennec, a free and open source game engine // Copyright © 2025 Medusa Slockbower // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // ===================================================================================================================== #include #include #include #include namespace fennec { static gfxcontext* _create_egl_context(display* display) { eglcontext* ctx = new eglcontext(display); if (not ctx->connected()) { delete ctx, ctx = nullptr; } return ctx; } STATIC_CONSTRUCTOR(_egl_init) { platform::add_driver(_create_egl_context, 1); } eglcontext::eglcontext(display* display) : gfxcontext(display, "EGL", this) { const display::pixel_format& fmt = _display->get_color_format(); EGLint context_attrs[] = { #if FENNEC_GRAPHICS_OPENGL EGL_CONTEXT_MAJOR_VERSION, 4, EGL_CONTEXT_MINOR_VERSION, 3, #elif FENNEC_GRAPHICS_GLES3 EGL_CONTEXT_MAJOR_VERSION, 3, EGL_CONTEXT_MINOR_VERSION, 2, #elif FENNEC_GRAPHICS_GLES2 EGL_CONTEXT_MAJOR_VERSION, 2, EGL_CONTEXT_MINOR_VERSION, 0, #endif EGL_NONE }; EGLint config_attrs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_DEPTH_SIZE, fmt.depth, EGL_RED_SIZE, fmt.r, EGL_RED_SIZE, fmt.g, EGL_RED_SIZE, fmt.b, EGL_RENDERABLE_TYPE, #if FENNEC_GRAPHICS_OPENGL EGL_OPENGL_BIT, #elif FENNEC_GRAPHICS_GLES3 EGL_OPENGL_ES3_BIT, #elif FENNEC_GRAPHICS_GLES2 EGL_OPENGL_ES2_BIT, #endif EGL_NONE }; _egldisplay = eglGetDisplay(_display->get_native_handle()); if (_egldisplay == nullptr) { cleanup(); return; } if (not eglInitialize(_egldisplay, &_eglvmajor, &_eglvminor)) { cleanup(); return; } #if FENNEC_GRAPHICS_OPENGL if (not eglBindAPI(EGL_OPENGL_API)) { #elif FENNEC_GRAPHICS_GLES3 or FENNEC_GRAPHICS_GLES2 if (not eglBindAPI(EGL_OPENGL_ES_API)) { #endif cleanup(); return; } EGLint n; if (not eglChooseConfig(_egldisplay, config_attrs, &_eglconfig, 1, &n)) { cleanup(); return; } _eglcontext = eglCreateContext(_egldisplay, _eglconfig, EGL_NO_CONTEXT, context_attrs); if (_eglcontext == nullptr) { cleanup(); return; } } eglcontext::~eglcontext() { cleanup(); } bool eglcontext::connected() { return _eglcontext != nullptr; } void eglcontext::make_current(gfxsurface*) { } void eglcontext::cleanup() { eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(_display, _eglcontext); eglTerminate(_display); eglReleaseThread(); _egldisplay = nullptr; _eglconfig = nullptr; _eglcontext = nullptr; _eglvmajor = 0; _eglvminor = 0; } }