Swapping.

This commit is contained in:
Ben Vanik
2014-12-24 22:35:03 -08:00
parent fa0dfa4dce
commit f438ae1bfd
11 changed files with 380 additions and 127 deletions

View File

@@ -9,13 +9,18 @@
#include <xenia/gpu/gl4/gl_context.h>
#include <mutex>
#include <poly/assert.h>
#include <poly/logging.h>
#include <xenia/gpu/gl4/gl4_gpu-private.h>
namespace xe {
namespace gpu {
namespace gl4 {
static std::recursive_mutex global_gl_mutex_;
thread_local GLEWContext* tls_glew_context_ = nullptr;
thread_local WGLEWContext* tls_wglew_context_ = nullptr;
extern "C" GLEWContext* glewGetContext() { return tls_glew_context_; }
@@ -110,24 +115,31 @@ bool GLContext::Initialize(HWND hwnd) {
// Clearing errors.
}
ClearCurrent();
return true;
}
std::unique_ptr<GLContext> GLContext::CreateShared() {
assert_not_null(glrc_);
int context_flags = 0;
HGLRC new_glrc = nullptr;
{
GLContextLock context_lock(this);
int context_flags = 0;
#if DEBUG
context_flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
#endif // DEBUG
int attrib_list[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 4, //
WGL_CONTEXT_MINOR_VERSION_ARB, 5, //
WGL_CONTEXT_FLAGS_ARB, context_flags, //
0};
auto new_glrc = wglCreateContextAttribsARB(dc_, glrc_, attrib_list);
if (!new_glrc) {
PLOGE("Could not create shared context");
return nullptr;
context_flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
#endif // DEBUG
int attrib_list[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 4, //
WGL_CONTEXT_MINOR_VERSION_ARB, 5, //
WGL_CONTEXT_FLAGS_ARB, context_flags, //
0};
new_glrc = wglCreateContextAttribsARB(dc_, glrc_, attrib_list);
if (!new_glrc) {
PLOGE("Could not create shared context");
return nullptr;
}
}
auto new_context = std::make_unique<GLContext>(hwnd_, new_glrc);
@@ -138,26 +150,31 @@ std::unique_ptr<GLContext> GLContext::CreateShared() {
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
new_context->ClearCurrent();
PLOGE("Unable to initialize GLEW");
return nullptr;
}
if (wglewInit() != GLEW_OK) {
new_context->ClearCurrent();
PLOGE("Unable to initialize WGLEW");
return nullptr;
}
new_context->ClearCurrent();
MakeCurrent();
while (glGetError()) {
// Clearing errors.
}
return new_context;
}
bool GLContext::MakeCurrent() {
if (FLAGS_thread_safe_gl) {
global_gl_mutex_.lock();
}
if (!wglMakeCurrent(dc_, glrc_)) {
if (FLAGS_thread_safe_gl) {
global_gl_mutex_.unlock();
}
PLOGE("Unable to make GL context current");
return false;
}
tls_glew_context_ = &glew_context_;
@@ -169,6 +186,10 @@ void GLContext::ClearCurrent() {
wglMakeCurrent(nullptr, nullptr);
tls_glew_context_ = nullptr;
tls_wglew_context_ = nullptr;
if (FLAGS_thread_safe_gl) {
global_gl_mutex_.unlock();
}
}
} // namespace gl4