summaryrefslogtreecommitdiff
path: root/Source/Core/Common/GL/GLInterface/WGL.cpp
diff options
context:
space:
mode:
authorStenzek <stenzek@users.noreply.github.com>2018-10-24 14:51:21 +1100
committerGitHub <noreply@github.com>2018-10-24 14:51:21 +1100
commitc4d1e4adffcd380cc87b841069ce2fe8b62d7b60 (patch)
treec61a0a07c14ccc3c1f7247bdcc82927a82c145bb /Source/Core/Common/GL/GLInterface/WGL.cpp
parent9c9d598ec006527bc47aea306e5171d03c12c5f5 (diff)
parent2c6d96433c322b50470705d43005fd6308506d49 (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.cpp169
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;
}