From 4b8d1c2b429485d54d7dad2fdc142ed43b34b992 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 3 Oct 2018 23:03:30 +1000 Subject: [PATCH] GLContext: Combine shared context initialization and creation --- Source/Core/Common/GL/GLContext.cpp | 5 --- Source/Core/Common/GL/GLContext.h | 1 - Source/Core/Common/GL/GLInterface/AGL.h | 1 - Source/Core/Common/GL/GLInterface/AGL.mm | 31 ++++++-------- Source/Core/Common/GL/GLInterface/EGL.cpp | 48 +++++++++------------- Source/Core/Common/GL/GLInterface/EGL.h | 1 - Source/Core/Common/GL/GLInterface/GLX.cpp | 49 ++++++++++------------- Source/Core/Common/GL/GLInterface/GLX.h | 1 - Source/Core/Common/GL/GLInterface/WGL.cpp | 39 ++++++++---------- Source/Core/Common/GL/GLInterface/WGL.h | 1 - 10 files changed, 68 insertions(+), 109 deletions(-) diff --git a/Source/Core/Common/GL/GLContext.cpp b/Source/Core/Common/GL/GLContext.cpp index d56d048d1b..90cb833302 100644 --- a/Source/Core/Common/GL/GLContext.cpp +++ b/Source/Core/Common/GL/GLContext.cpp @@ -30,11 +30,6 @@ bool GLContext::Initialize(void* display_handle, void* window_handle, bool stere return false; } -bool GLContext::Initialize(GLContext* main_context) -{ - return false; -} - bool GLContext::IsHeadless() const { return true; diff --git a/Source/Core/Common/GL/GLContext.h b/Source/Core/Common/GL/GLContext.h index 89dba55286..48e261bae7 100644 --- a/Source/Core/Common/GL/GLContext.h +++ b/Source/Core/Common/GL/GLContext.h @@ -50,7 +50,6 @@ public: protected: virtual bool Initialize(void* display_handle, void* window_handle, bool stereo, bool core); - virtual bool Initialize(GLContext* main_context); Mode m_opengl_mode = Mode::Detect; diff --git a/Source/Core/Common/GL/GLInterface/AGL.h b/Source/Core/Common/GL/GLInterface/AGL.h index 00978535f8..5e4052caa8 100644 --- a/Source/Core/Common/GL/GLInterface/AGL.h +++ b/Source/Core/Common/GL/GLInterface/AGL.h @@ -32,7 +32,6 @@ public: protected: bool Initialize(void* display_handle, void* window_handle, bool stereo, bool core) override; - bool Initialize(GLContext* main_context) override; NSView* m_view = nullptr; NSOpenGLContext* m_context = nullptr; diff --git a/Source/Core/Common/GL/GLInterface/AGL.mm b/Source/Core/Common/GL/GLInterface/AGL.mm index 4998fab40e..2cd0cb7f60 100644 --- a/Source/Core/Common/GL/GLInterface/AGL.mm +++ b/Source/Core/Common/GL/GLInterface/AGL.mm @@ -86,28 +86,21 @@ bool GLContextAGL::Initialize(void* display_handle, void* window_handle, bool st return AttachContextToView(m_context, m_view, &m_backbuffer_width, &m_backbuffer_height); } -bool GLContextAGL::Initialize(GLContext* main_context) -{ - GLContextAGL* agl_context = static_cast(main_context); - NSOpenGLPixelFormat* pixel_format = agl_context->m_pixel_format; - NSOpenGLContext* share_context = agl_context->m_context; - - m_context = [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:share_context]; - if (m_context == nil) - { - ERROR_LOG(VIDEO, "failed to create shared context"); - return false; - } - - return true; -} - std::unique_ptr GLContextAGL::CreateSharedContext() { - std::unique_ptr context = std::make_unique(); - if (!context->Initialize(this)) + NSOpenGLContext* new_agl_context = + [[NSOpenGLContext alloc] initWithFormat:m_pixel_format shareContext:m_context]; + if (new_agl_context == nil) + { + ERROR_LOG(VIDEO, "failed to create shared context"); return nullptr; - return context; + } + + std::unique_ptr new_context = std::make_unique(); + new_context->m_context = new_agl_context; + new_context->m_pixel_format = m_pixel_format; + [new_context->m_pixel_format retain]; + return new_context; } bool GLContextAGL::MakeCurrent() diff --git a/Source/Core/Common/GL/GLInterface/EGL.cpp b/Source/Core/Common/GL/GLInterface/EGL.cpp index eebe5e2e0e..534bf82ec5 100644 --- a/Source/Core/Common/GL/GLInterface/EGL.cpp +++ b/Source/Core/Common/GL/GLInterface/EGL.cpp @@ -289,43 +289,31 @@ bool GLContextEGL::Initialize(void* display_handle, void* window_handle, bool st std::unique_ptr GLContextEGL::CreateSharedContext() { - std::unique_ptr context = std::make_unique(); - if (!context->Initialize(this)) - return nullptr; - return context; -} - -bool GLContextEGL::Initialize(GLContext* main_context) -{ - GLContextEGL* egl_context = static_cast(main_context); - - m_opengl_mode = egl_context->m_opengl_mode; - m_host_display = egl_context->m_host_display; - m_egl_display = egl_context->m_egl_display; - m_is_core_context = egl_context->m_is_core_context; - m_config = egl_context->m_config; - m_supports_surfaceless = egl_context->m_supports_surfaceless; - m_is_shared = true; - - if (egl_context->GetMode() == Mode::OpenGL) - eglBindAPI(EGL_OPENGL_API); - else - eglBindAPI(EGL_OPENGL_ES_API); - - m_egl_context = eglCreateContext(m_egl_display, m_config, egl_context->m_egl_context, - egl_context->m_attribs.data()); - if (!m_egl_context) + eglBindAPI(m_opengl_mode == Mode::OpenGL ? EGL_OPENGL_API : EGL_OPENGL_ES_API); + EGLContext new_egl_context = + eglCreateContext(m_egl_display, m_config, m_egl_context, m_attribs.data()); + if (!new_egl_context) { INFO_LOG(VIDEO, "Error: eglCreateContext failed 0x%04x", eglGetError()); - return false; + return nullptr; } - if (!CreateWindowSurface()) + std::unique_ptr new_context = std::make_unique(); + new_context->m_opengl_mode = m_opengl_mode; + new_context->m_egl_context = new_egl_context; + new_context->m_host_display = m_host_display; + new_context->m_egl_display = m_egl_display; + new_context->m_is_core_context = m_is_core_context; + new_context->m_config = m_config; + new_context->m_supports_surfaceless = m_supports_surfaceless; + new_context->m_is_shared = true; + if (!new_context->CreateWindowSurface()) { ERROR_LOG(VIDEO, "Error: CreateWindowSurface failed 0x%04x", eglGetError()); - return false; + return nullptr; } - return true; + + return new_context; } bool GLContextEGL::CreateWindowSurface() diff --git a/Source/Core/Common/GL/GLInterface/EGL.h b/Source/Core/Common/GL/GLInterface/EGL.h index 52c183e21c..c20552f126 100644 --- a/Source/Core/Common/GL/GLInterface/EGL.h +++ b/Source/Core/Common/GL/GLInterface/EGL.h @@ -36,7 +36,6 @@ protected: virtual EGLNativeWindowType GetEGLNativeWindow(EGLConfig config); bool Initialize(void* display_handle, void* window_handle, bool stereo, bool core) override; - bool Initialize(GLContext* main_context) override; bool CreateWindowSurface(); void DestroyWindowSurface(); diff --git a/Source/Core/Common/GL/GLInterface/GLX.cpp b/Source/Core/Common/GL/GLInterface/GLX.cpp index c2569bd153..7a8e67f109 100644 --- a/Source/Core/Common/GL/GLInterface/GLX.cpp +++ b/Source/Core/Common/GL/GLInterface/GLX.cpp @@ -30,6 +30,11 @@ static int ctxErrorHandler(Display* dpy, XErrorEvent* ev) return 0; } +bool GLContextGLX::IsHeadless() const +{ + return m_render_window == nullptr; +} + void GLContextGLX::SwapInterval(int Interval) { if (!m_drawable) @@ -200,50 +205,38 @@ bool GLContextGLX::Initialize(void* display_handle, void* window_handle, bool st return true; } -bool GLContextGLX::Initialize(GLContext* main_context) +std::unique_ptr GLContextGLX::CreateSharedContext() { - GLContextGLX* glx_context = static_cast(main_context); - - m_opengl_mode = glx_context->m_opengl_mode; - m_supports_pbuffer = glx_context->m_supports_pbuffer; - m_display = glx_context->m_display; - m_fbconfig = glx_context->m_fbconfig; s_glxError = false; XErrorHandler oldHandler = XSetErrorHandler(&ctxErrorHandler); - m_context = glXCreateContextAttribs(m_display, m_fbconfig, glx_context->m_context, True, - &glx_context->m_attribs[0]); + GLXContext new_glx_context = + glXCreateContextAttribs(m_display, m_fbconfig, m_context, True, &m_attribs[0]); XSync(m_display, False); - if (!m_context || s_glxError) + if (!new_glx_context || s_glxError) { ERROR_LOG(VIDEO, "Unable to create GL context."); XSetErrorHandler(oldHandler); - return false; + return nullptr; } - if (m_supports_pbuffer && !CreateWindowSurface(None)) + std::unique_ptr new_context = std::make_unique(); + new_context->m_context = new_glx_context; + new_context->m_opengl_mode = m_opengl_mode; + new_context->m_supports_pbuffer = m_supports_pbuffer; + new_context->m_display = m_display; + new_context->m_fbconfig = m_fbconfig; + + if (m_supports_pbuffer && !new_context->CreateWindowSurface(None)) { - ERROR_LOG(VIDEO, "Error: CreateWindowSurface failed\n"); + ERROR_LOG(VIDEO, "Error: CreateWindowSurface failed"); XSetErrorHandler(oldHandler); - return false; + return nullptr; } XSetErrorHandler(oldHandler); - return true; -} - -bool GLContextGLX::IsHeadless() const -{ - return m_render_window == nullptr; -} - -std::unique_ptr GLContextGLX::CreateSharedContext() -{ - std::unique_ptr context = std::make_unique(); - if (!context->Initialize(this)) - return nullptr; - return context; + return new_context; } bool GLContextGLX::CreateWindowSurface(Window window_handle) diff --git a/Source/Core/Common/GL/GLInterface/GLX.h b/Source/Core/Common/GL/GLInterface/GLX.h index ef90e0ba5e..16443b706a 100644 --- a/Source/Core/Common/GL/GLInterface/GLX.h +++ b/Source/Core/Common/GL/GLInterface/GLX.h @@ -33,7 +33,6 @@ public: protected: bool Initialize(void* display_handle, void* window_handle, bool stereo, bool core) override; - bool Initialize(GLContext* main_context) override; Display* m_display = nullptr; std::unique_ptr m_render_window; diff --git a/Source/Core/Common/GL/GLInterface/WGL.cpp b/Source/Core/Common/GL/GLInterface/WGL.cpp index 6d1f072aee..032657cf69 100644 --- a/Source/Core/Common/GL/GLInterface/WGL.cpp +++ b/Source/Core/Common/GL/GLInterface/WGL.cpp @@ -306,34 +306,29 @@ bool GLContextWGL::Initialize(void* display_handle, void* window_handle, bool st return true; } -bool GLContextWGL::Initialize(GLContext* main_context) -{ - GLContextWGL* wgl_main_context = static_cast(main_context); - - m_opengl_mode = wgl_main_context->m_opengl_mode; - - // WGL does not support surfaceless contexts, so we use a 1x1 pbuffer instead. - if (!CreatePBuffer(wgl_main_context->m_dc, 1, 1, &m_pbuffer_handle, &m_dc)) - return false; - - m_rc = CreateCoreContext(m_dc, wgl_main_context->m_rc); - if (!m_rc) - return false; - - m_is_core_context = true; - return true; -} - std::unique_ptr GLContextWGL::CreateSharedContext() { - std::unique_ptr context = std::make_unique(); - if (!context->Initialize(this)) + // WGL does not support surfaceless contexts, so we use a 1x1 pbuffer instead. + HANDLE pbuffer; + HDC dc; + if (!CreatePBuffer(m_dc, 1, 1, &pbuffer, &dc)) + return nullptr; + + HGLRC rc = CreateCoreContext(dc, m_rc); + if (!rc) { - context->Shutdown(); + wglReleasePbufferDCARB(static_cast(pbuffer), dc); + wglDestroyPbufferARB(static_cast(pbuffer)); return nullptr; } - return std::move(context); + std::unique_ptr context = std::make_unique(); + context->m_pbuffer_handle = pbuffer; + context->m_dc = dc; + context->m_rc = rc; + context->m_opengl_mode = m_opengl_mode; + context->m_is_core_context = m_is_core_context; + return context; } HGLRC GLContextWGL::CreateCoreContext(HDC dc, HGLRC share_context) diff --git a/Source/Core/Common/GL/GLInterface/WGL.h b/Source/Core/Common/GL/GLInterface/WGL.h index e253a1accd..40d86ee6d0 100644 --- a/Source/Core/Common/GL/GLInterface/WGL.h +++ b/Source/Core/Common/GL/GLInterface/WGL.h @@ -28,7 +28,6 @@ public: protected: bool Initialize(void* display_handle, void* window_handle, bool stereo, bool core) override; - bool Initialize(GLContext* main_context) override; static HGLRC CreateCoreContext(HDC dc, HGLRC share_context); static bool CreatePBuffer(HDC onscreen_dc, int width, int height, HANDLE* pbuffer_handle,