// ===================================================================================================================== // 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 namespace fennec { static const cstring& egl_translate_type(EGLint type) { static constexpr cstring opengl = "OpenGL"; static constexpr cstring gles = "GLES"; static constexpr cstring openvg = "OpenVG"; // this should never be used switch (type) { default: case EGL_OPENGL_API: return opengl; case EGL_OPENGL_ES_API: return gles; case EGL_OPENVG_API: return openvg; } } eglcontext::eglcontext(display_server* display) : glcontext(display) { EGLint config_attrs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, // 4 EGL_NONE }; EGLint context_attrs[] = { EGL_NONE }; // Get the EGL display from the display server _egldisplay = eglGetDisplay(display->get_native_handle()); assertf(_egldisplay, "Failed to connect to egl display."); // Initialize EGL assertf(eglInitialize(_egldisplay, &_eglvmajor, &_eglvminor), "Failed to initialize egl."); // Attempt to bind to OpenGL or GLES if (not eglBindAPI(EGL_OPENGL_API)) { config_attrs[4] = EGL_OPENGL_ES_BIT; assertf(eglBindAPI(EGL_OPENGL_ES_API), "Failed to find suitable OpenGL API."); } // Select a configuration EGLint n; assertf(eglChooseConfig(_egldisplay, config_attrs, &_eglconfig, 1, &n), "Failed to find suitable OpenGL configuration."); // Create a context from the configuration and display _eglcontext = eglCreateContext(_egldisplay, _eglconfig, EGL_NO_CONTEXT, context_attrs); assertf(_eglcontext, "Failed to create OpenGL Context."); // Make the created context the current context to query some info eglMakeCurrent(_egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, _eglcontext); // Query version information eglQueryContext(_egldisplay, _eglcontext, EGL_CONTEXT_CLIENT_TYPE, &_eglctype); glGetIntegerv(GL_MAJOR_VERSION, &_eglvmajor); glGetIntegerv(GL_MINOR_VERSION, &_eglvminor); // Set the version fields version.major = _eglvmajor; version.minor = _eglvminor; version.patch = 0; version.str = format("{} v{}.{}", egl_translate_type(_eglctype), _eglvmajor, _eglvminor); } eglcontext::~eglcontext() { eglMakeCurrent(_egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(_egldisplay, _eglcontext); eglTerminate(_egldisplay); eglReleaseThread(); _egldisplay = nullptr; _eglconfig = nullptr; _eglcontext = nullptr; _eglvmajor = 0; _eglvminor = 0; version.major = 0; version.minor = 0; version.patch = 0; version.str = ""; } bool eglcontext::is_valid() { return _egldisplay != nullptr; } }