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);
|
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++)
|
for (size_t i = 0; i < num_versions_to_try; i++)
|
||||||
{
|
{
|
||||||
if (CreateContextAndSurface(versions_to_try[i], nullptr, true))
|
if (CreateContextAndSurface(versions_to_try[i], nullptr, true))
|
||||||
|
@ -75,7 +84,7 @@ bool ContextEGL::ChangeSurface(const WindowInfo& new_wi)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_wi = new_wi;
|
m_wi = new_wi;
|
||||||
if (m_wi.type != WindowInfo::Type::Surfaceless && !CreateSurface())
|
if (!CreateSurface())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (was_current && !eglMakeCurrent(m_display, m_surface, m_surface, m_context))
|
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);
|
std::unique_ptr<ContextEGL> context = std::make_unique<ContextEGL>(wi);
|
||||||
context->m_display = m_display;
|
context->m_display = m_display;
|
||||||
|
context->m_supports_surfaceless = m_supports_surfaceless;
|
||||||
|
|
||||||
if (!context->CreateContextAndSurface(m_version, m_context, false))
|
if (!context->CreateContextAndSurface(m_version, m_context, false))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -153,6 +163,14 @@ EGLNativeWindowType ContextEGL::GetNativeWindow(EGLConfig config)
|
||||||
|
|
||||||
bool ContextEGL::CreateSurface()
|
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);
|
EGLNativeWindowType native_window = GetNativeWindow(m_config);
|
||||||
m_surface = eglCreateWindowSurface(m_display, m_config, native_window, nullptr);
|
m_surface = eglCreateWindowSurface(m_display, m_config, native_window, nullptr);
|
||||||
if (!m_surface)
|
if (!m_surface)
|
||||||
|
@ -177,6 +195,27 @@ bool ContextEGL::CreateSurface()
|
||||||
return true;
|
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)
|
bool ContextEGL::CreateContext(const Version& version, EGLContext share_context)
|
||||||
{
|
{
|
||||||
int surface_attribs[16] = {
|
int surface_attribs[16] = {
|
||||||
|
@ -264,7 +303,7 @@ bool ContextEGL::CreateContextAndSurface(const Version& version, EGLContext shar
|
||||||
if (!CreateContext(version, share_context))
|
if (!CreateContext(version, share_context))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (m_wi.type != WindowInfo::Type::Surfaceless && !CreateSurface())
|
if (!CreateSurface())
|
||||||
{
|
{
|
||||||
Log_ErrorPrintf("Failed to create surface for context");
|
Log_ErrorPrintf("Failed to create surface for context");
|
||||||
eglDestroyContext(m_display, m_context);
|
eglDestroyContext(m_display, m_context);
|
||||||
|
|
|
@ -30,12 +30,15 @@ protected:
|
||||||
bool CreateContext(const Version& version, EGLContext share_context);
|
bool CreateContext(const Version& version, EGLContext share_context);
|
||||||
bool CreateContextAndSurface(const Version& version, EGLContext share_context, bool make_current);
|
bool CreateContextAndSurface(const Version& version, EGLContext share_context, bool make_current);
|
||||||
bool CreateSurface();
|
bool CreateSurface();
|
||||||
|
bool CreatePBufferSurface();
|
||||||
|
|
||||||
EGLDisplay m_display = EGL_NO_DISPLAY;
|
EGLDisplay m_display = EGL_NO_DISPLAY;
|
||||||
EGLSurface m_surface = EGL_NO_SURFACE;
|
EGLSurface m_surface = EGL_NO_SURFACE;
|
||||||
EGLContext m_context = EGL_NO_CONTEXT;
|
EGLContext m_context = EGL_NO_CONTEXT;
|
||||||
|
|
||||||
EGLConfig m_config = {};
|
EGLConfig m_config = {};
|
||||||
|
|
||||||
|
bool m_supports_surfaceless = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace GL
|
} // namespace GL
|
||||||
|
|
Loading…
Reference in New Issue