Merge pull request #3546 from Sonicadvance1/egl_shared_context

Implement shared contexts in the EGL context.
This commit is contained in:
Ryan Houdek 2016-01-29 19:33:52 -05:00
commit c50efb17e5
3 changed files with 102 additions and 30 deletions

View File

@ -104,6 +104,7 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
egl_dpy = OpenDisplay();
m_host_window = (EGLNativeWindowType) window_handle;
m_has_handle = !!window_handle;
m_core = false;
if (!egl_dpy)
{
@ -158,7 +159,7 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
if (!eglChooseConfig( egl_dpy, attribs, &m_config, 1, &num_configs))
{
INFO_LOG(VIDEO, "Error: couldn't get an EGL visual config\n");
exit(1);
return false;
}
if (s_opengl_mode == GLInterfaceMode::MODE_OPENGL)
@ -170,7 +171,7 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
if (!egl_ctx)
{
INFO_LOG(VIDEO, "Error: eglCreateContext failed\n");
exit(1);
return false;
}
std::string tmp;
@ -184,12 +185,76 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
}
}
CreateWindowSurface();
if (!CreateWindowSurface())
{
ERROR_LOG(VIDEO, "Error: CreateWindowSurface failed 0x%04x\n", eglGetError());
return false;
}
return true;
}
void cInterfaceEGL::CreateWindowSurface()
std::unique_ptr<cInterfaceBase> cInterfaceEGL::CreateSharedContext()
{
std::unique_ptr<cInterfaceBase> context = std::make_unique<cInterfaceEGL>();
if (!context->Create(this))
return nullptr;
return context;
}
bool cInterfaceEGL::Create(cInterfaceBase* main_context)
{
cInterfaceEGL* egl_context = static_cast<cInterfaceEGL*>(main_context);
egl_dpy = egl_context->egl_dpy;
m_core = egl_context->m_core;
m_config = egl_context->m_config;
m_supports_surfaceless = egl_context->m_supports_surfaceless;
m_is_shared = true;
m_has_handle = false;
EGLint ctx_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
switch (egl_context->GetMode())
{
case GLInterfaceMode::MODE_OPENGL:
ctx_attribs[0] = EGL_NONE;
break;
case GLInterfaceMode::MODE_OPENGLES2:
ctx_attribs[1] = 2;
break;
case GLInterfaceMode::MODE_OPENGLES3:
ctx_attribs[1] = 3;
break;
default:
INFO_LOG(VIDEO, "Unknown opengl mode set\n");
return false;
break;
}
if (egl_context->GetMode() == GLInterfaceMode::MODE_OPENGL)
eglBindAPI(EGL_OPENGL_API);
else
eglBindAPI(EGL_OPENGL_ES_API);
egl_ctx = eglCreateContext(egl_dpy, m_config, egl_context->egl_ctx, ctx_attribs );
if (!egl_ctx)
{
INFO_LOG(VIDEO, "Error: eglCreateContext failed 0x%04x\n", eglGetError());
return false;
}
if (!CreateWindowSurface())
{
ERROR_LOG(VIDEO, "Error: CreateWindowSurface failed 0x%04x\n", eglGetError());
return false;
}
return true;
}
bool cInterfaceEGL::CreateWindowSurface()
{
if (m_has_handle)
{
@ -198,7 +263,7 @@ void cInterfaceEGL::CreateWindowSurface()
if (!egl_surf)
{
INFO_LOG(VIDEO, "Error: eglCreateWindowSurface failed\n");
exit(1);
return false;
}
}
else if (!m_supports_surfaceless)
@ -211,13 +276,14 @@ void cInterfaceEGL::CreateWindowSurface()
if (!egl_surf)
{
INFO_LOG(VIDEO, "Error: eglCreatePbufferSurface failed");
exit(2);
return false;
}
}
else
{
egl_surf = EGL_NO_SURFACE;
}
return true;
}
void cInterfaceEGL::DestroyWindowSurface()
@ -255,15 +321,15 @@ bool cInterfaceEGL::ClearCurrent()
void cInterfaceEGL::Shutdown()
{
ShutdownPlatform();
if (egl_ctx && !eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx))
NOTICE_LOG(VIDEO, "Could not release drawing context.");
if (egl_ctx)
{
if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx))
NOTICE_LOG(VIDEO, "Could not release drawing context.");
eglMakeCurrent(egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (!eglDestroyContext(egl_dpy, egl_ctx))
NOTICE_LOG(VIDEO, "Could not destroy drawing context.");
DestroyWindowSurface();
if (!eglTerminate(egl_dpy))
if (!m_is_shared && !eglTerminate(egl_dpy))
NOTICE_LOG(VIDEO, "Could not destroy display connection.");
egl_ctx = nullptr;
}

View File

@ -17,7 +17,7 @@ private:
EGLNativeWindowType m_host_window;
bool m_supports_surfaceless = false;
void CreateWindowSurface();
bool CreateWindowSurface();
void DestroyWindowSurface();
protected:
@ -26,9 +26,9 @@ protected:
EGLContext egl_ctx;
EGLDisplay egl_dpy;
virtual EGLDisplay OpenDisplay() = 0;
virtual EGLNativeWindowType InitializePlatform(EGLNativeWindowType host_window, EGLConfig config) = 0;
virtual void ShutdownPlatform() = 0;
virtual EGLDisplay OpenDisplay() { return EGL_NO_DISPLAY; }
virtual EGLNativeWindowType InitializePlatform(EGLNativeWindowType host_window, EGLConfig config) { return (EGLNativeWindowType)EGL_DEFAULT_DISPLAY; }
virtual void ShutdownPlatform() {}
public:
void Swap() override;
@ -36,9 +36,11 @@ public:
void SetMode(GLInterfaceMode mode) override { s_opengl_mode = mode; }
void* GetFuncAddress(const std::string& name) override;
bool Create(void* window_handle, bool core) override;
bool Create(cInterfaceBase* main_context) override;
bool MakeCurrent() override;
bool ClearCurrent() override;
void Shutdown() override;
void UpdateHandle(void* window_handle) override;
void UpdateSurface() override;
std::unique_ptr<cInterfaceBase> CreateSharedContext() override;
};

View File

@ -23,6 +23,8 @@ protected:
// Window dimensions.
u32 s_backbuffer_width = 0;
u32 s_backbuffer_height = 0;
bool m_core = false;
bool m_is_shared = false;
GLInterfaceMode s_opengl_mode = GLInterfaceMode::MODE_DETECT;
public:
@ -32,6 +34,7 @@ public:
virtual GLInterfaceMode GetMode() { return s_opengl_mode; }
virtual void* GetFuncAddress(const std::string& name) { return nullptr; }
virtual bool Create(void *window_handle, bool core = true) { return true; }
virtual bool Create(cInterfaceBase* main_context) { return true; }
virtual bool MakeCurrent() { return true; }
virtual bool ClearCurrent() { return true; }
virtual void Shutdown() {}
@ -44,6 +47,7 @@ public:
virtual bool PeekMessages() { return false; }
virtual void UpdateHandle(void* window_handle) {}
virtual void UpdateSurface() {}
virtual std::unique_ptr<cInterfaceBase> CreateSharedContext() { return nullptr; }
};
extern std::unique_ptr<cInterfaceBase> GLInterface;