diff options
| author | Stenzek <stenzek@users.noreply.github.com> | 2018-10-24 14:51:21 +1100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-10-24 14:51:21 +1100 |
| commit | c4d1e4adffcd380cc87b841069ce2fe8b62d7b60 (patch) | |
| tree | c61a0a07c14ccc3c1f7247bdcc82927a82c145bb /Source/Core/Common/GL/GLInterface/WGL.cpp | |
| parent | 9c9d598ec006527bc47aea306e5171d03c12c5f5 (diff) | |
| parent | 2c6d96433c322b50470705d43005fd6308506d49 (diff) | |
Merge pull request #7450 from stenzek/glcontext
GLInterface refactoring/cleanup and runtime platform selection
Diffstat (limited to 'Source/Core/Common/GL/GLInterface/WGL.cpp')
| -rw-r--r-- | Source/Core/Common/GL/GLInterface/WGL.cpp | 169 |
1 files changed, 74 insertions, 95 deletions
diff --git a/Source/Core/Common/GL/GLInterface/WGL.cpp b/Source/Core/Common/GL/GLInterface/WGL.cpp index 48f4b8c96c..e168f94e51 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<PFNWGLSWAPINTERVALEXTPROC>( - GLInterface->GetFuncAddress("wglSwapIntervalEXT")); + wglSwapIntervalEXT = + reinterpret_cast<PFNWGLSWAPINTERVALEXTPROC>(wglGetProcAddress("wglSwapIntervalEXT")); wglCreateContextAttribsARB = reinterpret_cast<PFNWGLCREATECONTEXTATTRIBSARBPROC>( wglGetProcAddress("wglCreateContextAttribsARB")); wglChoosePixelFormatARB = reinterpret_cast<PFNWGLCHOOSEPIXELFORMATARBPROC>( @@ -157,19 +157,57 @@ static void ClearWGLExtensionPointers() wglDestroyPbufferARB = nullptr; } -void cInterfaceWGL::SwapInterval(int Interval) +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<HPBUFFERARB>(m_pbuffer_handle), m_dc); + m_dc = nullptr; + + wglDestroyPbufferARB(static_cast<HPBUFFERARB>(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; +} + +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 +221,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* display_handle, void* window_handle, bool stereo, bool core) { if (!window_handle) return false; @@ -216,8 +239,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 +297,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 +328,6 @@ bool cInterfaceWGL::Create(void* window_handle, bool stereo, bool core) { wglDeleteContext(m_rc); m_rc = core_context; - m_core = true; } else { @@ -314,38 +335,35 @@ bool cInterfaceWGL::Create(void* window_handle, bool stereo, bool core) } } - return true; + return MakeCurrent(); } -bool cInterfaceWGL::Create(cInterfaceBase* main_context) +std::unique_ptr<GLContext> GLContextWGL::CreateSharedContext() { - cInterfaceWGL* wgl_main_context = static_cast<cInterfaceWGL*>(main_context); - // 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_core = true; - return true; -} + HANDLE pbuffer; + HDC dc; + if (!CreatePBuffer(m_dc, 1, 1, &pbuffer, &dc)) + return nullptr; -std::unique_ptr<cInterfaceBase> cInterfaceWGL::CreateSharedContext() -{ - std::unique_ptr<cInterfaceWGL> context = std::make_unique<cInterfaceWGL>(); - if (!context->Create(this)) + HGLRC rc = CreateCoreContext(dc, m_rc); + if (!rc) { - context->Shutdown(); + wglReleasePbufferDCARB(static_cast<HPBUFFERARB>(pbuffer), dc); + wglDestroyPbufferARB(static_cast<HPBUFFERARB>(pbuffer)); return nullptr; } - return std::move(context); + std::unique_ptr<GLContextWGL> context = std::make_unique<GLContextWGL>(); + context->m_pbuffer_handle = pbuffer; + context->m_dc = dc; + context->m_rc = rc; + context->m_opengl_mode = m_opengl_mode; + context->m_is_shared = true; + return context; } -HGLRC cInterfaceWGL::CreateCoreContext(HDC dc, HGLRC share_context) +HGLRC GLContextWGL::CreateCoreContext(HDC dc, HGLRC share_context) { if (!wglCreateContextAttribsARB) { @@ -353,12 +371,7 @@ HGLRC cInterfaceWGL::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<std::pair<int, int>, 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<int, 5 * 2> attribs = {WGL_CONTEXT_PROFILE_MASK_ARB, @@ -402,8 +415,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,57 +475,23 @@ 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; -} - -// Close backend -void cInterfaceWGL::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<HPBUFFERARB>(m_pbuffer_handle), m_dc); - m_dc = nullptr; - - wglDestroyPbufferARB(static_cast<HPBUFFERARB>(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; - } - } + m_backbuffer_width = rcWindow.right - rcWindow.left; + m_backbuffer_height = rcWindow.bottom - rcWindow.top; } |
