snes9x/common/video/wayland_egl_context.cpp

150 lines
3.8 KiB
C++
Raw Normal View History

/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
2018-10-21 23:03:35 +00:00
#include <stdio.h>
#include <string.h>
2023-05-31 23:11:01 +00:00
#include "wayland_egl_context.hpp"
2018-10-21 23:03:35 +00:00
WaylandEGLContext::WaylandEGLContext()
2018-10-21 23:03:35 +00:00
{
egl_display = NULL;
egl_surface = NULL;
egl_context = NULL;
egl_config = NULL;
egl_window = NULL;
x = 0;
y = 0;
2018-10-21 23:03:35 +00:00
}
WaylandEGLContext::~WaylandEGLContext()
2018-10-21 23:03:35 +00:00
{
if (egl_context)
eglDestroyContext(egl_display, egl_context);
2018-10-21 23:03:35 +00:00
if (egl_surface)
eglDestroySurface(egl_display, egl_surface);
2018-10-21 23:03:35 +00:00
if (egl_window)
wl_egl_window_destroy(egl_window);
2018-10-21 23:03:35 +00:00
}
bool WaylandEGLContext::attach(wl_display *display, wl_surface *surface, WaylandSurface::Metrics m)
2018-10-21 23:03:35 +00:00
{
wayland_surface = std::make_unique<WaylandSurface>();
wayland_surface->attach(display, surface, m);
2022-01-31 03:23:33 +00:00
2018-10-21 23:03:35 +00:00
return true;
}
bool WaylandEGLContext::create_context()
2018-10-21 23:03:35 +00:00
{
EGLint surface_attribs[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_RED_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
2023-03-23 21:53:43 +00:00
EGL_ALPHA_SIZE, 0,
2018-10-21 23:03:35 +00:00
EGL_NONE
};
EGLint core_context_attribs[] = {
EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
EGL_CONTEXT_MAJOR_VERSION, 3,
EGL_CONTEXT_MINOR_VERSION, 3,
EGL_NONE
};
EGLint compatibility_context_attribs[] = {
2018-10-21 23:03:35 +00:00
EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT,
EGL_NONE
};
EGLint num_configs = 0;
2023-05-31 23:11:01 +00:00
if (!gladLoaderLoadEGL(nullptr))
{
printf("Couldn't load EGL.\n");
return false;
}
egl_display = eglGetDisplay((EGLNativeDisplayType)wayland_surface->display);
2023-05-31 23:11:01 +00:00
int major, minor;
eglInitialize(egl_display, &major, &minor);
// Load the rest of the functions only after calling eglInitialize.
if (!gladLoaderLoadEGL(egl_display))
{
printf("Couldn't load EGL functions.\n");
}
2018-10-21 23:03:35 +00:00
if (!eglChooseConfig(egl_display, surface_attribs, &egl_config, 1, &num_configs))
2018-10-21 23:03:35 +00:00
{
printf("Couldn't find matching config.\n");
2018-10-21 23:03:35 +00:00
return false;
}
std::tie(width, height) = wayland_surface->get_size();
egl_window = wl_egl_window_create(wayland_surface->child, width, height);
2018-10-21 23:03:35 +00:00
if (!egl_window)
{
printf("Couldn't create window.\n");
2018-10-21 23:03:35 +00:00
return false;
}
egl_surface = eglCreateWindowSurface(egl_display, egl_config, (EGLNativeWindowType)egl_window, NULL);
2018-10-21 23:03:35 +00:00
if (!egl_surface)
{
printf("Couldn't create surface.\n");
2018-10-21 23:03:35 +00:00
return false;
}
2023-05-31 23:11:01 +00:00
eglBindAPI(EGL_OPENGL_API);
egl_context = eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, core_context_attribs);
2018-10-21 23:03:35 +00:00
if (!egl_context)
{
egl_context = eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, compatibility_context_attribs);
if (!egl_context)
{
printf("Couldn't create context.\n");
return false;
}
2018-10-21 23:03:35 +00:00
}
return true;
}
void WaylandEGLContext::resize(WaylandSurface::Metrics m)
2018-10-21 23:03:35 +00:00
{
wayland_surface->resize(m);
2023-05-31 23:11:01 +00:00
std::tie(width, height) = wayland_surface->get_size();
wl_egl_window_resize(egl_window, width, height, 0, 0);
2018-10-21 23:03:35 +00:00
make_current();
2018-10-21 23:03:35 +00:00
}
void WaylandEGLContext::swap_buffers()
2018-10-21 23:03:35 +00:00
{
eglSwapBuffers(egl_display, egl_surface);
wl_surface_commit(wayland_surface->child);
2018-10-21 23:03:35 +00:00
}
bool WaylandEGLContext::ready()
2018-10-21 23:03:35 +00:00
{
return true;
2018-10-21 23:03:35 +00:00
}
void WaylandEGLContext::make_current()
2018-10-21 23:03:35 +00:00
{
eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);
2018-10-21 23:03:35 +00:00
}
void WaylandEGLContext::swap_interval(int frames)
{
eglSwapInterval(egl_display, frames);
}