From 134d967be2dd4ba9531abb8ba8494c3ac423ca72 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 3 Oct 2018 23:02:45 +1000 Subject: Refactoring and cleanup of GLInterface (now GLContext) --- Source/Core/Common/GL/GLInterface/WGL.cpp | 75 ++++++++++++++----------------- 1 file changed, 33 insertions(+), 42 deletions(-) (limited to 'Source/Core/Common/GL/GLInterface/WGL.cpp') diff --git a/Source/Core/Common/GL/GLInterface/WGL.cpp b/Source/Core/Common/GL/GLInterface/WGL.cpp index 48f4b8c96c..d7c8c87c4f 100644 --- a/Source/Core/Common/GL/GLInterface/WGL.cpp +++ b/Source/Core/Common/GL/GLInterface/WGL.cpp @@ -130,8 +130,8 @@ static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = nullptr; static void LoadWGLExtensions() { - wglSwapIntervalEXT = reinterpret_cast( - GLInterface->GetFuncAddress("wglSwapIntervalEXT")); + wglSwapIntervalEXT = + reinterpret_cast(wglGetProcAddress("wglSwapIntervalEXT")); wglCreateContextAttribsARB = reinterpret_cast( wglGetProcAddress("wglCreateContextAttribsARB")); wglChoosePixelFormatARB = reinterpret_cast( @@ -157,19 +157,24 @@ static void ClearWGLExtensionPointers() wglDestroyPbufferARB = nullptr; } -void cInterfaceWGL::SwapInterval(int Interval) +bool GLContextWGL::IsHeadless() const +{ + return !m_window_handle; +} + +void GLContextWGL::SwapInterval(int interval) { if (wglSwapIntervalEXT) - wglSwapIntervalEXT(Interval); + wglSwapIntervalEXT(interval); else ERROR_LOG(VIDEO, "No support for SwapInterval (framerate clamped to monitor refresh rate)."); } -void cInterfaceWGL::Swap() +void GLContextWGL::Swap() { SwapBuffers(m_dc); } -void* cInterfaceWGL::GetFuncAddress(const std::string& name) +void* GLContextWGL::GetFuncAddress(const std::string& name) { FARPROC func = wglGetProcAddress(name.c_str()); if (func == nullptr) @@ -183,24 +188,9 @@ void* cInterfaceWGL::GetFuncAddress(const std::string& name) return func; } -// Draw messages on top of the screen -bool cInterfaceWGL::PeekMessages() -{ - // TODO: peekmessage - MSG msg; - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) - { - if (msg.message == WM_QUIT) - return FALSE; - TranslateMessage(&msg); - DispatchMessage(&msg); - } - return TRUE; -} - // Create rendering window. // Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() -bool cInterfaceWGL::Create(void* window_handle, bool stereo, bool core) +bool GLContextWGL::Initialize(void* window_handle, bool stereo, bool core) { if (!window_handle) return false; @@ -216,8 +206,8 @@ bool cInterfaceWGL::Create(void* window_handle, bool stereo, bool core) // Control window size and picture scaling int twidth = window_rect.right - window_rect.left; int theight = window_rect.bottom - window_rect.top; - s_backbuffer_width = twidth; - s_backbuffer_height = theight; + m_backbuffer_width = twidth; + m_backbuffer_height = theight; const DWORD stereo_flag = stereo ? PFD_STEREO : 0; @@ -274,8 +264,7 @@ bool cInterfaceWGL::Create(void* window_handle, bool stereo, bool core) } // WGL only supports desktop GL, for now. - if (s_opengl_mode == GLInterfaceMode::MODE_DETECT) - s_opengl_mode = GLInterfaceMode::MODE_OPENGL; + m_opengl_mode = Mode::OpenGL; if (core) { @@ -306,7 +295,7 @@ bool cInterfaceWGL::Create(void* window_handle, bool stereo, bool core) { wglDeleteContext(m_rc); m_rc = core_context; - m_core = true; + m_is_core_context = true; } else { @@ -317,9 +306,11 @@ bool cInterfaceWGL::Create(void* window_handle, bool stereo, bool core) return true; } -bool cInterfaceWGL::Create(cInterfaceBase* main_context) +bool GLContextWGL::Initialize(GLContext* main_context) { - cInterfaceWGL* wgl_main_context = static_cast(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)) @@ -329,14 +320,14 @@ bool cInterfaceWGL::Create(cInterfaceBase* main_context) if (!m_rc) return false; - m_core = true; + m_is_core_context = true; return true; } -std::unique_ptr cInterfaceWGL::CreateSharedContext() +std::unique_ptr GLContextWGL::CreateSharedContext() { - std::unique_ptr context = std::make_unique(); - if (!context->Create(this)) + std::unique_ptr context = std::make_unique(); + if (!context->Initialize(this)) { context->Shutdown(); return nullptr; @@ -345,7 +336,7 @@ std::unique_ptr cInterfaceWGL::CreateSharedContext() return std::move(context); } -HGLRC cInterfaceWGL::CreateCoreContext(HDC dc, HGLRC share_context) +HGLRC GLContextWGL::CreateCoreContext(HDC dc, HGLRC share_context) { if (!wglCreateContextAttribsARB) { @@ -402,8 +393,8 @@ HGLRC cInterfaceWGL::CreateCoreContext(HDC dc, HGLRC share_context) return nullptr; } -bool cInterfaceWGL::CreatePBuffer(HDC onscreen_dc, int width, int height, HANDLE* pbuffer_handle, - HDC* pbuffer_dc) +bool GLContextWGL::CreatePBuffer(HDC onscreen_dc, int width, int height, HANDLE* pbuffer_handle, + HDC* pbuffer_dc) { if (!wglChoosePixelFormatARB || !wglCreatePbufferARB || !wglGetPbufferDCARB || !wglReleasePbufferDCARB || !wglDestroyPbufferARB) @@ -462,29 +453,29 @@ bool cInterfaceWGL::CreatePBuffer(HDC onscreen_dc, int width, int height, HANDLE return true; } -bool cInterfaceWGL::MakeCurrent() +bool GLContextWGL::MakeCurrent() { return wglMakeCurrent(m_dc, m_rc) == TRUE; } -bool cInterfaceWGL::ClearCurrent() +bool GLContextWGL::ClearCurrent() { return wglMakeCurrent(m_dc, nullptr) == TRUE; } // Update window width, size and etc. Called from Render.cpp -void cInterfaceWGL::Update() +void GLContextWGL::Update() { RECT rcWindow; GetClientRect(m_window_handle, &rcWindow); // Get the new window width and height - s_backbuffer_width = rcWindow.right - rcWindow.left; - s_backbuffer_height = rcWindow.bottom - rcWindow.top; + m_backbuffer_width = rcWindow.right - rcWindow.left; + m_backbuffer_height = rcWindow.bottom - rcWindow.top; } // Close backend -void cInterfaceWGL::Shutdown() +void GLContextWGL::Shutdown() { if (m_rc) { -- cgit v1.2.3 From 9c57a98723997736adea94383668fbdf8a993fd8 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 3 Oct 2018 23:03:19 +1000 Subject: GLContext: Use host connection This also removes the need for a sleeping event thread. --- Source/Core/Common/GL/GLInterface/WGL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/Common/GL/GLInterface/WGL.cpp') diff --git a/Source/Core/Common/GL/GLInterface/WGL.cpp b/Source/Core/Common/GL/GLInterface/WGL.cpp index d7c8c87c4f..6d1f072aee 100644 --- a/Source/Core/Common/GL/GLInterface/WGL.cpp +++ b/Source/Core/Common/GL/GLInterface/WGL.cpp @@ -190,7 +190,7 @@ void* GLContextWGL::GetFuncAddress(const std::string& name) // Create rendering window. // Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() -bool GLContextWGL::Initialize(void* window_handle, bool stereo, bool core) +bool GLContextWGL::Initialize(void* display_handle, void* window_handle, bool stereo, bool core) { if (!window_handle) return false; -- cgit v1.2.3 From 4b8d1c2b429485d54d7dad2fdc142ed43b34b992 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 3 Oct 2018 23:03:30 +1000 Subject: GLContext: Combine shared context initialization and creation --- Source/Core/Common/GL/GLInterface/WGL.cpp | 37 +++++++++++++------------------ 1 file changed, 16 insertions(+), 21 deletions(-) (limited to 'Source/Core/Common/GL/GLInterface/WGL.cpp') 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) +std::unique_ptr GLContextWGL::CreateSharedContext() { - 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; -} + HANDLE pbuffer; + HDC dc; + if (!CreatePBuffer(m_dc, 1, 1, &pbuffer, &dc)) + return nullptr; -std::unique_ptr GLContextWGL::CreateSharedContext() -{ - std::unique_ptr context = std::make_unique(); - if (!context->Initialize(this)) + 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) -- cgit v1.2.3 From 025e909773a2761cad8a3954498fe800f6f94963 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 3 Oct 2018 23:03:33 +1000 Subject: GLContext: Use destructor instead of Shutdown() to cleanup Also uses the Initialize() method to make the context current. --- Source/Core/Common/GL/GLInterface/WGL.cpp | 72 +++++++++++++++---------------- 1 file changed, 35 insertions(+), 37 deletions(-) (limited to 'Source/Core/Common/GL/GLInterface/WGL.cpp') diff --git a/Source/Core/Common/GL/GLInterface/WGL.cpp b/Source/Core/Common/GL/GLInterface/WGL.cpp index 032657cf69..98b6bd5a3a 100644 --- a/Source/Core/Common/GL/GLInterface/WGL.cpp +++ b/Source/Core/Common/GL/GLInterface/WGL.cpp @@ -157,6 +157,39 @@ static void ClearWGLExtensionPointers() wglDestroyPbufferARB = nullptr; } +GLContextWGL::~GLContextWGL() +{ + if (m_rc) + { + if (wglGetCurrentContext() == m_rc && !wglMakeCurrent(m_dc, nullptr)) + NOTICE_LOG(VIDEO, "Could not release drawing context."); + + if (!wglDeleteContext(m_rc)) + ERROR_LOG(VIDEO, "Attempt to release rendering context failed."); + + m_rc = nullptr; + } + + if (m_dc) + { + if (m_pbuffer_handle) + { + wglReleasePbufferDCARB(static_cast(m_pbuffer_handle), m_dc); + m_dc = nullptr; + + wglDestroyPbufferARB(static_cast(m_pbuffer_handle)); + m_pbuffer_handle = nullptr; + } + else + { + if (!ReleaseDC(m_window_handle, m_dc)) + ERROR_LOG(VIDEO, "Attempt to release device context failed."); + + m_dc = nullptr; + } + } +} + bool GLContextWGL::IsHeadless() const { return !m_window_handle; @@ -295,7 +328,6 @@ bool GLContextWGL::Initialize(void* display_handle, void* window_handle, bool st { wglDeleteContext(m_rc); m_rc = core_context; - m_is_core_context = true; } else { @@ -303,7 +335,7 @@ bool GLContextWGL::Initialize(void* display_handle, void* window_handle, bool st } } - return true; + return MakeCurrent(); } std::unique_ptr GLContextWGL::CreateSharedContext() @@ -327,7 +359,7 @@ std::unique_ptr GLContextWGL::CreateSharedContext() context->m_dc = dc; context->m_rc = rc; context->m_opengl_mode = m_opengl_mode; - context->m_is_core_context = m_is_core_context; + context->m_is_shared = true; return context; } @@ -468,37 +500,3 @@ void GLContextWGL::Update() m_backbuffer_width = rcWindow.right - rcWindow.left; m_backbuffer_height = rcWindow.bottom - rcWindow.top; } - -// Close backend -void GLContextWGL::Shutdown() -{ - if (m_rc) - { - if (!wglMakeCurrent(m_dc, nullptr)) - NOTICE_LOG(VIDEO, "Could not release drawing context."); - - if (!wglDeleteContext(m_rc)) - ERROR_LOG(VIDEO, "Attempt to release rendering context failed."); - - m_rc = nullptr; - } - - if (m_dc) - { - if (m_pbuffer_handle) - { - wglReleasePbufferDCARB(static_cast(m_pbuffer_handle), m_dc); - m_dc = nullptr; - - wglDestroyPbufferARB(static_cast(m_pbuffer_handle)); - m_pbuffer_handle = nullptr; - } - else - { - if (!ReleaseDC(m_window_handle, m_dc)) - ERROR_LOG(VIDEO, "Attempt to release device context failed."); - - m_dc = nullptr; - } - } -} -- cgit v1.2.3 From 2c6d96433c322b50470705d43005fd6308506d49 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sun, 14 Oct 2018 23:32:50 +1000 Subject: GLContext: Try GL versions 3.2-4.6 when getting a context GLX previously was only creating a 4.0 context. --- Source/Core/Common/GL/GLInterface/WGL.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'Source/Core/Common/GL/GLInterface/WGL.cpp') diff --git a/Source/Core/Common/GL/GLInterface/WGL.cpp b/Source/Core/Common/GL/GLInterface/WGL.cpp index 98b6bd5a3a..e168f94e51 100644 --- a/Source/Core/Common/GL/GLInterface/WGL.cpp +++ b/Source/Core/Common/GL/GLInterface/WGL.cpp @@ -371,12 +371,7 @@ HGLRC GLContextWGL::CreateCoreContext(HDC dc, HGLRC share_context) return nullptr; } - // List of versions to attempt context creation for. (4.5-3.2, geometry shaders is a minimum - // requirement since we're using core profile) - static constexpr std::array, 8> try_versions = { - {{4, 5}, {4, 4}, {4, 3}, {4, 2}, {4, 1}, {4, 0}, {3, 3}, {3, 2}}}; - - for (const auto& version : try_versions) + for (const auto& version : s_desktop_opengl_versions) { // Construct list of attributes. Prefer a forward-compatible, core context. std::array attribs = {WGL_CONTEXT_PROFILE_MASK_ARB, -- cgit v1.2.3