Common: Add DRM display helper class and GBM GL context
This commit is contained in:
@ -1,6 +1,8 @@
|
||||
#include "context_egl.h"
|
||||
#include "../assert.h"
|
||||
#include "../log.h"
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
Log_SetChannel(GL::ContextEGL);
|
||||
|
||||
namespace GL {
|
||||
@ -33,12 +35,8 @@ bool ContextEGL::Initialize(const Version* versions_to_try, size_t num_versions_
|
||||
return false;
|
||||
}
|
||||
|
||||
m_display = eglGetDisplay(static_cast<EGLNativeDisplayType>(m_wi.display_connection));
|
||||
if (!m_display)
|
||||
{
|
||||
Log_ErrorPrintf("eglGetDisplay() failed: %d", eglGetError());
|
||||
if (!SetDisplay())
|
||||
return false;
|
||||
}
|
||||
|
||||
int egl_major, egl_minor;
|
||||
if (!eglInitialize(m_display, &egl_major, &egl_minor))
|
||||
@ -66,6 +64,18 @@ bool ContextEGL::Initialize(const Version* versions_to_try, size_t num_versions_
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ContextEGL::SetDisplay()
|
||||
{
|
||||
m_display = eglGetDisplay(static_cast<EGLNativeDisplayType>(m_wi.display_connection));
|
||||
if (!m_display)
|
||||
{
|
||||
Log_ErrorPrintf("eglGetDisplay() failed: %d", eglGetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void* ContextEGL::GetProcAddress(const char* name)
|
||||
{
|
||||
return reinterpret_cast<void*>(eglGetProcAddress(name));
|
||||
@ -216,6 +226,36 @@ bool ContextEGL::CreatePBufferSurface()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContextEGL::CheckConfigSurfaceFormat(EGLConfig config, WindowInfo::SurfaceFormat format) const
|
||||
{
|
||||
int red_size, green_size, blue_size, alpha_size;
|
||||
if (!eglGetConfigAttrib(m_display, config, EGL_RED_SIZE, &red_size) ||
|
||||
!eglGetConfigAttrib(m_display, config, EGL_GREEN_SIZE, &green_size) ||
|
||||
!eglGetConfigAttrib(m_display, config, EGL_BLUE_SIZE, &blue_size) ||
|
||||
!eglGetConfigAttrib(m_display, config, EGL_ALPHA_SIZE, &alpha_size))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case WindowInfo::SurfaceFormat::Auto:
|
||||
return true;
|
||||
|
||||
case WindowInfo::SurfaceFormat::RGB8:
|
||||
return (red_size == 8 && green_size == 8 && blue_size == 8);
|
||||
|
||||
case WindowInfo::SurfaceFormat::RGBA8:
|
||||
return (red_size == 8 && green_size == 8 && blue_size == 8 && alpha_size == 8);
|
||||
|
||||
case WindowInfo::SurfaceFormat::RGB565:
|
||||
return (red_size == 5 && green_size == 6 && blue_size == 5);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ContextEGL::CreateContext(const Version& version, EGLContext share_context)
|
||||
{
|
||||
Log_DevPrintf(
|
||||
@ -263,6 +303,9 @@ bool ContextEGL::CreateContext(const Version& version, EGLContext share_context)
|
||||
surface_attribs[nsurface_attribs++] = 5;
|
||||
break;
|
||||
|
||||
case WindowInfo::SurfaceFormat::Auto:
|
||||
break;
|
||||
|
||||
default:
|
||||
UnreachableCode();
|
||||
break;
|
||||
@ -272,13 +315,36 @@ bool ContextEGL::CreateContext(const Version& version, EGLContext share_context)
|
||||
surface_attribs[nsurface_attribs++] = 0;
|
||||
|
||||
EGLint num_configs;
|
||||
EGLConfig config;
|
||||
if (!eglChooseConfig(m_display, surface_attribs, &config, 1, &num_configs) || num_configs == 0)
|
||||
if (!eglChooseConfig(m_display, surface_attribs, nullptr, 0, &num_configs) || num_configs == 0)
|
||||
{
|
||||
Log_ErrorPrintf("eglChooseConfig() failed: %d", eglGetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<EGLConfig> configs(static_cast<u32>(num_configs));
|
||||
if (!eglChooseConfig(m_display, surface_attribs, configs.data(), num_configs, &num_configs))
|
||||
{
|
||||
Log_ErrorPrintf("eglChooseConfig() failed: %d", eglGetError());
|
||||
return false;
|
||||
}
|
||||
configs.resize(static_cast<u32>(num_configs));
|
||||
|
||||
std::optional<EGLConfig> config;
|
||||
for (EGLConfig check_config : configs)
|
||||
{
|
||||
if (CheckConfigSurfaceFormat(check_config, m_wi.surface_format))
|
||||
{
|
||||
config = check_config;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!config.has_value())
|
||||
{
|
||||
Log_WarningPrintf("No EGL configs matched exactly, using first.");
|
||||
config = configs.front();
|
||||
}
|
||||
|
||||
int attribs[8];
|
||||
int nattribs = 0;
|
||||
if (version.profile != Profile::NoProfile)
|
||||
@ -297,7 +363,7 @@ bool ContextEGL::CreateContext(const Version& version, EGLContext share_context)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_context = eglCreateContext(m_display, config, share_context, attribs);
|
||||
m_context = eglCreateContext(m_display, config.value(), share_context, attribs);
|
||||
if (!m_context)
|
||||
{
|
||||
Log_ErrorPrintf("eglCreateContext() failed: %d", eglGetError());
|
||||
@ -308,7 +374,7 @@ bool ContextEGL::CreateContext(const Version& version, EGLContext share_context)
|
||||
"Got version %u.%u (%s)", version.major_version, version.minor_version,
|
||||
version.profile == Context::Profile::ES ? "ES" : (version.profile == Context::Profile::Core ? "Core" : "None"));
|
||||
|
||||
m_config = config;
|
||||
m_config = config.value();
|
||||
m_version = version;
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user