Moving graphics context creation around to hide actual creation.

Makes it easier to support APIs that don't have a concept of sharing.
This commit is contained in:
Ben Vanik
2015-11-10 17:38:57 -08:00
parent d8fa54ffc4
commit 6c95ca1cdb
16 changed files with 234 additions and 97 deletions

View File

@@ -58,24 +58,20 @@ void FatalGLError(std::string error) {
"of supported GPUs.");
}
std::unique_ptr<GLContext> GLContext::Create(Window* target_window,
std::unique_ptr<GLContext> GLContext::Create(GraphicsProvider* provider,
Window* target_window,
GLContext* share_context) {
auto context = std::unique_ptr<GLContext>(new GLContext(target_window));
if (!context->Initialize(target_window, share_context)) {
auto context =
std::unique_ptr<GLContext>(new GLContext(provider, target_window));
if (!context->Initialize(share_context)) {
return nullptr;
}
context->AssertExtensionsPresent();
return context;
}
GLContext::GLContext(Window* target_window) : GraphicsContext(target_window) {
glew_context_.reset(new GLEWContext());
wglew_context_.reset(new WGLEWContext());
}
GLContext::GLContext(Window* target_window, HGLRC glrc)
: GraphicsContext(target_window), glrc_(glrc) {
dc_ = GetDC(HWND(target_window_->native_handle()));
GLContext::GLContext(GraphicsProvider* provider, Window* target_window)
: GraphicsContext(provider, target_window) {
glew_context_.reset(new GLEWContext());
wglew_context_.reset(new WGLEWContext());
}
@@ -93,8 +89,7 @@ GLContext::~GLContext() {
}
}
bool GLContext::Initialize(Window* target_window, GLContext* share_context) {
target_window_ = target_window;
bool GLContext::Initialize(GLContext* share_context) {
dc_ = GetDC(HWND(target_window_->native_handle()));
PIXELFORMATDESCRIPTOR pfd = {0};
@@ -193,12 +188,13 @@ bool GLContext::Initialize(Window* target_window, GLContext* share_context) {
return true;
}
std::unique_ptr<GraphicsContext> GLContext::CreateShared() {
assert_not_null(glrc_);
std::unique_ptr<GLContext> GLContext::CreateOffscreen(
GraphicsProvider* provider, GLContext* parent_context) {
assert_not_null(parent_context->glrc_);
HGLRC new_glrc = nullptr;
{
GraphicsContextLock context_lock(this);
GraphicsContextLock context_lock(parent_context);
int context_flags = 0;
if (FLAGS_gl_debug) {
@@ -214,15 +210,19 @@ std::unique_ptr<GraphicsContext> GLContext::CreateShared() {
WGL_CONTEXT_PROFILE_MASK_ARB,
WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
0};
new_glrc = wglCreateContextAttribsARB(dc_, glrc_, attrib_list);
new_glrc = wglCreateContextAttribsARB(parent_context->dc_,
parent_context->glrc_, attrib_list);
if (!new_glrc) {
FatalGLError("Could not create shared context.");
return nullptr;
}
}
auto new_context =
std::unique_ptr<GLContext>(new GLContext(target_window_, new_glrc));
auto new_context = std::unique_ptr<GLContext>(
new GLContext(provider, parent_context->target_window_));
new_context->glrc_ = new_glrc;
new_context->dc_ =
GetDC(HWND(parent_context->target_window_->native_handle()));
if (!new_context->MakeCurrent()) {
FatalGLError("Could not make new GL context current.");
return nullptr;
@@ -244,18 +244,16 @@ std::unique_ptr<GraphicsContext> GLContext::CreateShared() {
return nullptr;
}
SetupDebugging();
new_context->SetupDebugging();
if (!new_context->blitter_.Initialize()) {
FatalGLError("Unable to initialize blitter on shared context.");
return nullptr;
}
new_context->immediate_drawer_ = std::make_unique<GLImmediateDrawer>(this);
new_context->ClearCurrent();
return std::unique_ptr<GraphicsContext>(new_context.release());
return new_context;
}
void GLContext::AssertExtensionsPresent() {

View File

@@ -29,18 +29,14 @@ namespace ui {
namespace gl {
class GLImmediateDrawer;
class GLProvider;
class GLContext : public GraphicsContext {
public:
static std::unique_ptr<GLContext> Create(Window* target_window,
GLContext* share_context = nullptr);
~GLContext() override;
HDC dc() const { return dc_; }
std::unique_ptr<GraphicsContext> CreateShared() override;
ImmediateDrawer* immediate_drawer() override;
bool is_current() override;
@@ -53,10 +49,18 @@ class GLContext : public GraphicsContext {
Blitter* blitter() { return &blitter_; }
private:
explicit GLContext(Window* target_window);
GLContext(Window* target_window, HGLRC glrc);
friend class GLProvider;
bool Initialize(Window* target_window, GLContext* share_context);
static std::unique_ptr<GLContext> Create(GraphicsProvider* provider,
Window* target_window,
GLContext* share_context = nullptr);
static std::unique_ptr<GLContext> CreateOffscreen(GraphicsProvider* provider,
GLContext* parent_context);
private:
GLContext(GraphicsProvider* provider, Window* target_window);
bool Initialize(GLContext* share_context);
void AssertExtensionsPresent();
void SetupDebugging();

View File

@@ -0,0 +1,49 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2015 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/ui/gl/gl_provider.h"
#include "xenia/ui/gl/gl_context.h"
#include "xenia/ui/window.h"
namespace xe {
namespace ui {
namespace gl {
std::unique_ptr<GraphicsProvider> GLProvider::Create(Window* main_window) {
std::unique_ptr<GLProvider> provider(new GLProvider(main_window));
//
return std::unique_ptr<GraphicsProvider>(provider.release());
}
GLProvider::GLProvider(Window* main_window) : GraphicsProvider(main_window) {}
GLProvider::~GLProvider() = default;
std::unique_ptr<GraphicsContext> GLProvider::CreateContext(
Window* target_window) {
auto share_context = main_window_->context();
return std::unique_ptr<GraphicsContext>(
GLContext::Create(this, target_window,
static_cast<GLContext*>(share_context))
.release());
}
std::unique_ptr<GraphicsContext> GLProvider::CreateOffscreenContext() {
auto share_context = main_window_->context();
return std::unique_ptr<GraphicsContext>(
GLContext::CreateOffscreen(this, static_cast<GLContext*>(share_context))
.release());
}
} // namespace gl
} // namespace ui
} // namespace xe

View File

@@ -0,0 +1,40 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2015 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_UI_GL_GL_PROVIDER_H_
#define XENIA_UI_GL_GL_PROVIDER_H_
#include <memory>
#include "xenia/ui/graphics_provider.h"
namespace xe {
namespace ui {
namespace gl {
class GLProvider : public GraphicsProvider {
public:
~GLProvider() override;
static std::unique_ptr<GraphicsProvider> Create(Window* main_window);
std::unique_ptr<GraphicsContext> CreateContext(
Window* target_window) override;
std::unique_ptr<GraphicsContext> CreateOffscreenContext() override;
protected:
explicit GLProvider(Window* main_window);
};
} // namespace gl
} // namespace ui
} // namespace xe
#endif // XENIA_UI_GL_GL_PROVIDER_H_

View File

@@ -11,7 +11,7 @@
#include <vector>
#include "xenia/base/main.h"
#include "xenia/ui/gl/gl_context.h"
#include "xenia/ui/gl/gl_provider.h"
#include "xenia/ui/window.h"
namespace xe {
@@ -19,8 +19,8 @@ namespace ui {
int window_demo_main(const std::vector<std::wstring>& args);
std::unique_ptr<GraphicsContext> CreateDemoContext(Window* window) {
return xe::ui::gl::GLContext::Create(window);
std::unique_ptr<GraphicsProvider> CreateDemoGraphicsProvider(Window* window) {
return xe::ui::gl::GLProvider::Create(window);
}
} // namespace ui