GL/ContextEGL: Use pbuffer when surfaceless not supported
This commit is contained in:
parent
b6ec587e5b
commit
ac89379ca6
|
@ -48,6 +48,15 @@ bool ContextEGL::Initialize(const Version* versions_to_try, size_t num_versions_
|
|||
}
|
||||
Log_InfoPrintf("EGL Version: %d.%d", egl_major, egl_minor);
|
||||
|
||||
const char* extensions = eglQueryString(m_display, EGL_EXTENSIONS);
|
||||
if (extensions)
|
||||
{
|
||||
Log_InfoPrintf("EGL Extensions: %s", extensions);
|
||||
m_supports_surfaceless = std::strstr(extensions, "EGL_KHR_surfaceless_context") != nullptr;
|
||||
}
|
||||
if (!m_supports_surfaceless)
|
||||
Log_WarningPrint("EGL implementation does not support surfaceless contexts, emulating with pbuffers");
|
||||
|
||||
for (size_t i = 0; i < num_versions_to_try; i++)
|
||||
{
|
||||
if (CreateContextAndSurface(versions_to_try[i], nullptr, true))
|
||||
|
@ -75,7 +84,7 @@ bool ContextEGL::ChangeSurface(const WindowInfo& new_wi)
|
|||
}
|
||||
|
||||
m_wi = new_wi;
|
||||
if (m_wi.type != WindowInfo::Type::Surfaceless && !CreateSurface())
|
||||
if (!CreateSurface())
|
||||
return false;
|
||||
|
||||
if (was_current && !eglMakeCurrent(m_display, m_surface, m_surface, m_context))
|
||||
|
@ -139,6 +148,7 @@ std::unique_ptr<Context> ContextEGL::CreateSharedContext(const WindowInfo& wi)
|
|||
{
|
||||
std::unique_ptr<ContextEGL> context = std::make_unique<ContextEGL>(wi);
|
||||
context->m_display = m_display;
|
||||
context->m_supports_surfaceless = m_supports_surfaceless;
|
||||
|
||||
if (!context->CreateContextAndSurface(m_version, m_context, false))
|
||||
return nullptr;
|
||||
|
@ -153,6 +163,14 @@ EGLNativeWindowType ContextEGL::GetNativeWindow(EGLConfig config)
|
|||
|
||||
bool ContextEGL::CreateSurface()
|
||||
{
|
||||
if (m_wi.type == WindowInfo::Type::Surfaceless)
|
||||
{
|
||||
if (m_supports_surfaceless)
|
||||
return true;
|
||||
else
|
||||
return CreatePBufferSurface();
|
||||
}
|
||||
|
||||
EGLNativeWindowType native_window = GetNativeWindow(m_config);
|
||||
m_surface = eglCreateWindowSurface(m_display, m_config, native_window, nullptr);
|
||||
if (!m_surface)
|
||||
|
@ -177,6 +195,27 @@ bool ContextEGL::CreateSurface()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ContextEGL::CreatePBufferSurface()
|
||||
{
|
||||
const u32 width = std::max<u32>(m_wi.surface_width, 1);
|
||||
const u32 height = std::max<u32>(m_wi.surface_height, 1);
|
||||
|
||||
// TODO: Format
|
||||
EGLint attrib_list[] = {
|
||||
EGL_WIDTH, static_cast<EGLint>(width), EGL_HEIGHT, static_cast<EGLint>(height), EGL_NONE,
|
||||
};
|
||||
|
||||
m_surface = eglCreatePbufferSurface(m_display, m_config, attrib_list);
|
||||
if (!m_surface)
|
||||
{
|
||||
Log_ErrorPrintf("eglCreatePbufferSurface() failed: %d", eglGetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
Log_DevPrintf("Created %ux%u pbuffer surface", width, height);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContextEGL::CreateContext(const Version& version, EGLContext share_context)
|
||||
{
|
||||
int surface_attribs[16] = {
|
||||
|
@ -264,7 +303,7 @@ bool ContextEGL::CreateContextAndSurface(const Version& version, EGLContext shar
|
|||
if (!CreateContext(version, share_context))
|
||||
return false;
|
||||
|
||||
if (m_wi.type != WindowInfo::Type::Surfaceless && !CreateSurface())
|
||||
if (!CreateSurface())
|
||||
{
|
||||
Log_ErrorPrintf("Failed to create surface for context");
|
||||
eglDestroyContext(m_display, m_context);
|
||||
|
|
|
@ -30,12 +30,15 @@ protected:
|
|||
bool CreateContext(const Version& version, EGLContext share_context);
|
||||
bool CreateContextAndSurface(const Version& version, EGLContext share_context, bool make_current);
|
||||
bool CreateSurface();
|
||||
bool CreatePBufferSurface();
|
||||
|
||||
EGLDisplay m_display = EGL_NO_DISPLAY;
|
||||
EGLSurface m_surface = EGL_NO_SURFACE;
|
||||
EGLContext m_context = EGL_NO_CONTEXT;
|
||||
|
||||
EGLConfig m_config = {};
|
||||
|
||||
bool m_supports_surfaceless = false;
|
||||
};
|
||||
|
||||
} // namespace GL
|
||||
|
|
Loading…
Reference in New Issue