Merge pull request #3546 from Sonicadvance1/egl_shared_context
Implement shared contexts in the EGL context.
This commit is contained in:
commit
c50efb17e5
|
@ -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)
|
||||
{
|
||||
|
@ -137,28 +138,28 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
|
|||
};
|
||||
switch (s_opengl_mode)
|
||||
{
|
||||
case GLInterfaceMode::MODE_OPENGL:
|
||||
attribs[1] = EGL_OPENGL_BIT;
|
||||
ctx_attribs[0] = EGL_NONE;
|
||||
break;
|
||||
case GLInterfaceMode::MODE_OPENGLES2:
|
||||
attribs[1] = EGL_OPENGL_ES2_BIT;
|
||||
ctx_attribs[1] = 2;
|
||||
break;
|
||||
case GLInterfaceMode::MODE_OPENGLES3:
|
||||
attribs[1] = (1 << 6); /* EGL_OPENGL_ES3_BIT_KHR */
|
||||
ctx_attribs[1] = 3;
|
||||
break;
|
||||
default:
|
||||
ERROR_LOG(VIDEO, "Unknown opengl mode set\n");
|
||||
return false;
|
||||
break;
|
||||
case GLInterfaceMode::MODE_OPENGL:
|
||||
attribs[1] = EGL_OPENGL_BIT;
|
||||
ctx_attribs[0] = EGL_NONE;
|
||||
break;
|
||||
case GLInterfaceMode::MODE_OPENGLES2:
|
||||
attribs[1] = EGL_OPENGL_ES2_BIT;
|
||||
ctx_attribs[1] = 2;
|
||||
break;
|
||||
case GLInterfaceMode::MODE_OPENGLES3:
|
||||
attribs[1] = (1 << 6); /* EGL_OPENGL_ES3_BIT_KHR */
|
||||
ctx_attribs[1] = 3;
|
||||
break;
|
||||
default:
|
||||
ERROR_LOG(VIDEO, "Unknown opengl mode set\n");
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue