From aed693eded4bea4be9610f2bbd132288236d06b4 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Thu, 21 Jan 2016 19:03:58 -0600 Subject: 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. --- Source/Core/Common/GL/GLInterface/EGL.cpp | 116 +++++++++++++++++++++++------- 1 file changed, 91 insertions(+), 25 deletions(-) (limited to 'Source/Core/Common/GL/GLInterface/EGL.cpp') 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 cInterfaceEGL::CreateSharedContext() +{ + std::unique_ptr context = std::make_unique(); + if (!context->Create(this)) + return nullptr; + return context; +} + +bool cInterfaceEGL::Create(cInterfaceBase* main_context) +{ + cInterfaceEGL* egl_context = static_cast(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; } -- cgit v1.2.3