164 lines
4.3 KiB
C++
164 lines
4.3 KiB
C++
#include "egl_context.h"
|
|
#include "logger.h"
|
|
#include <glad/gles2.h>
|
|
#include <glad/egl.h>
|
|
#include <android/native_window_jni.h>
|
|
#include <vector>
|
|
#include <format>
|
|
|
|
static void debug_handler(GLenum source, GLenum type,
|
|
GLuint id, GLenum severity, GLsizei length, const GLchar* message,
|
|
const void* userParam)
|
|
{
|
|
Logger::Log(std::format("GL Error: {}", std::string_view(message, length)));
|
|
}
|
|
|
|
bool egl::Context::create(ANativeWindow* window)
|
|
{
|
|
int version = gladLoaderLoadEGL(EGL_NO_DISPLAY);
|
|
if (version == 0)
|
|
{
|
|
Logger::Log("glad failed to load EGL");
|
|
return false;
|
|
}
|
|
if (m_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
|
m_display == EGL_NO_DISPLAY)
|
|
{
|
|
Logger::Log("eglGetDisplay failed");
|
|
return false;
|
|
}
|
|
EGLint major, minor;
|
|
if (!eglInitialize(m_display, &major, &minor))
|
|
{
|
|
Logger::Log("eglInitialize failed");
|
|
return false;
|
|
}
|
|
version = gladLoadEGL(m_display, eglGetProcAddress);
|
|
std::vector<EGLint> config_attribs =
|
|
{
|
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT,
|
|
};
|
|
if (window)
|
|
{
|
|
config_attribs.append_range(std::to_array({
|
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
|
EGL_BLUE_SIZE, 8,
|
|
EGL_GREEN_SIZE, 8,
|
|
EGL_RED_SIZE, 8,
|
|
}));
|
|
}
|
|
config_attribs.push_back(EGL_NONE);
|
|
EGLint num_configs;
|
|
if (!eglChooseConfig(m_display, config_attribs.data(), &m_config, 1, &num_configs) || num_configs == 0)
|
|
{
|
|
Logger::Log("eglChooseConfig failed");
|
|
return false;
|
|
}
|
|
const EGLint context_attribs[] =
|
|
{
|
|
EGL_CONTEXT_MAJOR_VERSION, 3,
|
|
EGL_CONTEXT_MINOR_VERSION, 2,
|
|
EGL_NONE,
|
|
};
|
|
if (m_context = eglCreateContext(m_display, m_config, EGL_NO_CONTEXT, context_attribs);
|
|
m_context == EGL_NO_CONTEXT)
|
|
{
|
|
Logger::Log("eglCreateContext failed");
|
|
return false;
|
|
}
|
|
if (window)
|
|
{
|
|
m_surface = eglCreateWindowSurface(m_display, m_config, window, nullptr);
|
|
ANativeWindow_acquire(window);
|
|
m_native_window = window;
|
|
}
|
|
if (!eglMakeCurrent(m_display, m_surface, m_surface, m_context))
|
|
{
|
|
Logger::Log("eglMakeCurrent failed");
|
|
return false;
|
|
}
|
|
int gl_version = gladLoaderLoadGLES2();
|
|
if (gl_version == 0)
|
|
{
|
|
Logger::Log("glad failed to load GLES2");
|
|
return false;
|
|
}
|
|
if (glDebugMessageCallback)
|
|
{
|
|
glDebugMessageCallback(debug_handler, nullptr);
|
|
glEnable(GL_DEBUG_OUTPUT);
|
|
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void egl::Context::destroy()
|
|
{
|
|
if (m_display != EGL_NO_DISPLAY)
|
|
{
|
|
eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
|
if (m_surface != EGL_NO_SURFACE)
|
|
{
|
|
eglDestroySurface(m_display, m_surface);
|
|
}
|
|
if (m_context != EGL_NO_CONTEXT)
|
|
{
|
|
eglDestroyContext(m_display, m_context);
|
|
}
|
|
if (m_native_window)
|
|
{
|
|
ANativeWindow_release(m_native_window);
|
|
}
|
|
eglTerminate(m_display);
|
|
}
|
|
m_display = EGL_NO_DISPLAY;
|
|
m_context = EGL_NO_CONTEXT;
|
|
m_config = EGL_NO_CONFIG_KHR;
|
|
m_surface = EGL_NO_SURFACE;
|
|
m_native_window = nullptr;
|
|
}
|
|
|
|
egl::Context::Context() :
|
|
m_display(EGL_NO_DISPLAY), m_config(EGL_NO_CONFIG_KHR),
|
|
m_context(EGL_NO_CONTEXT), m_surface(EGL_NO_SURFACE),
|
|
m_native_window(nullptr)
|
|
{
|
|
Logger::Log("egl::Context::Context");
|
|
}
|
|
|
|
void egl::Context::swap()
|
|
{
|
|
eglSwapBuffers(m_display, m_surface);
|
|
}
|
|
|
|
bool egl::Context::make_current(ANativeWindow* window)
|
|
{
|
|
if (window == m_native_window)
|
|
{
|
|
return true;
|
|
}
|
|
eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
|
if (m_surface != EGL_NO_SURFACE)
|
|
{
|
|
eglDestroySurface(m_display, m_surface);
|
|
m_surface = EGL_NO_SURFACE;
|
|
}
|
|
if (m_native_window)
|
|
{
|
|
ANativeWindow_release(m_native_window);
|
|
m_native_window = nullptr;
|
|
}
|
|
if (window)
|
|
{
|
|
m_surface = eglCreateWindowSurface(m_display, m_config, window, nullptr);
|
|
ANativeWindow_acquire(window);
|
|
m_native_window = window;
|
|
if (!eglMakeCurrent(m_display, m_surface, m_surface, m_context))
|
|
{
|
|
Logger::Log("eglMakeCurrent failed");
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|