summaryrefslogtreecommitdiff
path: root/Source/Core/Common/GL/GLInterface/EGL.cpp
diff options
context:
space:
mode:
authorRyan Houdek <Sonicadvance1@gmail.com>2016-01-21 19:03:58 -0600
committerRyan Houdek <Sonicadvance1@gmail.com>2016-01-27 13:15:02 -0600
commitaed693eded4bea4be9610f2bbd132288236d06b4 (patch)
treef57e94d5f3e1012af786c40877204bbb9259c098 /Source/Core/Common/GL/GLInterface/EGL.cpp
parentfdf6fb47e04101e5773db99e937e00313a63d094 (diff)
Implement shared contexts in the EGL context.
This is being implemented here first under EGL since the infrastructure is already in place for this due to the Android code requiring some bits. The rest of the interfaces will come in a little bit. This will be required for threaded shader compiling in the near future.
Diffstat (limited to 'Source/Core/Common/GL/GLInterface/EGL.cpp')
-rw-r--r--Source/Core/Common/GL/GLInterface/EGL.cpp116
1 files changed, 91 insertions, 25 deletions
diff --git a/Source/Core/Common/GL/GLInterface/EGL.cpp b/Source/Core/Common/GL/GLInterface/EGL.cpp
index e61627cbdf..3edee9e478 100644
--- a/Source/Core/Common/GL/GLInterface/EGL.cpp
+++ b/Source/Core/Common/GL/GLInterface/EGL.cpp
@@ -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)
}
}
+ if (!CreateWindowSurface())
+ {
+ ERROR_LOG(VIDEO, "Error: CreateWindowSurface failed 0x%04x\n", eglGetError());
+ return false;
+ }
+ return true;
+}
- 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;
}
-void cInterfaceEGL::CreateWindowSurface()
+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;
}