GLContext: Combine shared context initialization and creation

This commit is contained in:
Stenzek 2018-10-03 23:03:30 +10:00
parent dcdd02d646
commit 4b8d1c2b42
10 changed files with 68 additions and 109 deletions

View File

@ -30,11 +30,6 @@ bool GLContext::Initialize(void* display_handle, void* window_handle, bool stere
return false; return false;
} }
bool GLContext::Initialize(GLContext* main_context)
{
return false;
}
bool GLContext::IsHeadless() const bool GLContext::IsHeadless() const
{ {
return true; return true;

View File

@ -50,7 +50,6 @@ public:
protected: protected:
virtual bool Initialize(void* display_handle, void* window_handle, bool stereo, bool core); virtual bool Initialize(void* display_handle, void* window_handle, bool stereo, bool core);
virtual bool Initialize(GLContext* main_context);
Mode m_opengl_mode = Mode::Detect; Mode m_opengl_mode = Mode::Detect;

View File

@ -32,7 +32,6 @@ public:
protected: protected:
bool Initialize(void* display_handle, void* window_handle, bool stereo, bool core) override; bool Initialize(void* display_handle, void* window_handle, bool stereo, bool core) override;
bool Initialize(GLContext* main_context) override;
NSView* m_view = nullptr; NSView* m_view = nullptr;
NSOpenGLContext* m_context = nullptr; NSOpenGLContext* m_context = nullptr;

View File

@ -86,28 +86,21 @@ bool GLContextAGL::Initialize(void* display_handle, void* window_handle, bool st
return AttachContextToView(m_context, m_view, &m_backbuffer_width, &m_backbuffer_height); return AttachContextToView(m_context, m_view, &m_backbuffer_width, &m_backbuffer_height);
} }
bool GLContextAGL::Initialize(GLContext* main_context)
{
GLContextAGL* agl_context = static_cast<GLContextAGL*>(main_context);
NSOpenGLPixelFormat* pixel_format = agl_context->m_pixel_format;
NSOpenGLContext* share_context = agl_context->m_context;
m_context = [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:share_context];
if (m_context == nil)
{
ERROR_LOG(VIDEO, "failed to create shared context");
return false;
}
return true;
}
std::unique_ptr<GLContext> GLContextAGL::CreateSharedContext() std::unique_ptr<GLContext> GLContextAGL::CreateSharedContext()
{ {
std::unique_ptr<GLContextAGL> context = std::make_unique<GLContextAGL>(); NSOpenGLContext* new_agl_context =
if (!context->Initialize(this)) [[NSOpenGLContext alloc] initWithFormat:m_pixel_format shareContext:m_context];
if (new_agl_context == nil)
{
ERROR_LOG(VIDEO, "failed to create shared context");
return nullptr; return nullptr;
return context; }
std::unique_ptr<GLContextAGL> new_context = std::make_unique<GLContextAGL>();
new_context->m_context = new_agl_context;
new_context->m_pixel_format = m_pixel_format;
[new_context->m_pixel_format retain];
return new_context;
} }
bool GLContextAGL::MakeCurrent() bool GLContextAGL::MakeCurrent()

View File

@ -289,43 +289,31 @@ bool GLContextEGL::Initialize(void* display_handle, void* window_handle, bool st
std::unique_ptr<GLContext> GLContextEGL::CreateSharedContext() std::unique_ptr<GLContext> GLContextEGL::CreateSharedContext()
{ {
std::unique_ptr<GLContextEGL> context = std::make_unique<GLContextEGL>(); eglBindAPI(m_opengl_mode == Mode::OpenGL ? EGL_OPENGL_API : EGL_OPENGL_ES_API);
if (!context->Initialize(this)) EGLContext new_egl_context =
return nullptr; eglCreateContext(m_egl_display, m_config, m_egl_context, m_attribs.data());
return context; if (!new_egl_context)
}
bool GLContextEGL::Initialize(GLContext* main_context)
{
GLContextEGL* egl_context = static_cast<GLContextEGL*>(main_context);
m_opengl_mode = egl_context->m_opengl_mode;
m_host_display = egl_context->m_host_display;
m_egl_display = egl_context->m_egl_display;
m_is_core_context = egl_context->m_is_core_context;
m_config = egl_context->m_config;
m_supports_surfaceless = egl_context->m_supports_surfaceless;
m_is_shared = true;
if (egl_context->GetMode() == Mode::OpenGL)
eglBindAPI(EGL_OPENGL_API);
else
eglBindAPI(EGL_OPENGL_ES_API);
m_egl_context = eglCreateContext(m_egl_display, m_config, egl_context->m_egl_context,
egl_context->m_attribs.data());
if (!m_egl_context)
{ {
INFO_LOG(VIDEO, "Error: eglCreateContext failed 0x%04x", eglGetError()); INFO_LOG(VIDEO, "Error: eglCreateContext failed 0x%04x", eglGetError());
return false; return nullptr;
} }
if (!CreateWindowSurface()) std::unique_ptr<GLContextEGL> new_context = std::make_unique<GLContextEGL>();
new_context->m_opengl_mode = m_opengl_mode;
new_context->m_egl_context = new_egl_context;
new_context->m_host_display = m_host_display;
new_context->m_egl_display = m_egl_display;
new_context->m_is_core_context = m_is_core_context;
new_context->m_config = m_config;
new_context->m_supports_surfaceless = m_supports_surfaceless;
new_context->m_is_shared = true;
if (!new_context->CreateWindowSurface())
{ {
ERROR_LOG(VIDEO, "Error: CreateWindowSurface failed 0x%04x", eglGetError()); ERROR_LOG(VIDEO, "Error: CreateWindowSurface failed 0x%04x", eglGetError());
return false; return nullptr;
} }
return true;
return new_context;
} }
bool GLContextEGL::CreateWindowSurface() bool GLContextEGL::CreateWindowSurface()

View File

@ -36,7 +36,6 @@ protected:
virtual EGLNativeWindowType GetEGLNativeWindow(EGLConfig config); virtual EGLNativeWindowType GetEGLNativeWindow(EGLConfig config);
bool Initialize(void* display_handle, void* window_handle, bool stereo, bool core) override; bool Initialize(void* display_handle, void* window_handle, bool stereo, bool core) override;
bool Initialize(GLContext* main_context) override;
bool CreateWindowSurface(); bool CreateWindowSurface();
void DestroyWindowSurface(); void DestroyWindowSurface();

View File

@ -30,6 +30,11 @@ static int ctxErrorHandler(Display* dpy, XErrorEvent* ev)
return 0; return 0;
} }
bool GLContextGLX::IsHeadless() const
{
return m_render_window == nullptr;
}
void GLContextGLX::SwapInterval(int Interval) void GLContextGLX::SwapInterval(int Interval)
{ {
if (!m_drawable) if (!m_drawable)
@ -200,50 +205,38 @@ bool GLContextGLX::Initialize(void* display_handle, void* window_handle, bool st
return true; return true;
} }
bool GLContextGLX::Initialize(GLContext* main_context) std::unique_ptr<GLContext> GLContextGLX::CreateSharedContext()
{ {
GLContextGLX* glx_context = static_cast<GLContextGLX*>(main_context);
m_opengl_mode = glx_context->m_opengl_mode;
m_supports_pbuffer = glx_context->m_supports_pbuffer;
m_display = glx_context->m_display;
m_fbconfig = glx_context->m_fbconfig;
s_glxError = false; s_glxError = false;
XErrorHandler oldHandler = XSetErrorHandler(&ctxErrorHandler); XErrorHandler oldHandler = XSetErrorHandler(&ctxErrorHandler);
m_context = glXCreateContextAttribs(m_display, m_fbconfig, glx_context->m_context, True, GLXContext new_glx_context =
&glx_context->m_attribs[0]); glXCreateContextAttribs(m_display, m_fbconfig, m_context, True, &m_attribs[0]);
XSync(m_display, False); XSync(m_display, False);
if (!m_context || s_glxError) if (!new_glx_context || s_glxError)
{ {
ERROR_LOG(VIDEO, "Unable to create GL context."); ERROR_LOG(VIDEO, "Unable to create GL context.");
XSetErrorHandler(oldHandler); XSetErrorHandler(oldHandler);
return false; return nullptr;
} }
if (m_supports_pbuffer && !CreateWindowSurface(None)) std::unique_ptr<GLContextGLX> new_context = std::make_unique<GLContextGLX>();
new_context->m_context = new_glx_context;
new_context->m_opengl_mode = m_opengl_mode;
new_context->m_supports_pbuffer = m_supports_pbuffer;
new_context->m_display = m_display;
new_context->m_fbconfig = m_fbconfig;
if (m_supports_pbuffer && !new_context->CreateWindowSurface(None))
{ {
ERROR_LOG(VIDEO, "Error: CreateWindowSurface failed\n"); ERROR_LOG(VIDEO, "Error: CreateWindowSurface failed");
XSetErrorHandler(oldHandler); XSetErrorHandler(oldHandler);
return false; return nullptr;
} }
XSetErrorHandler(oldHandler); XSetErrorHandler(oldHandler);
return true; return new_context;
}
bool GLContextGLX::IsHeadless() const
{
return m_render_window == nullptr;
}
std::unique_ptr<GLContext> GLContextGLX::CreateSharedContext()
{
std::unique_ptr<GLContextGLX> context = std::make_unique<GLContextGLX>();
if (!context->Initialize(this))
return nullptr;
return context;
} }
bool GLContextGLX::CreateWindowSurface(Window window_handle) bool GLContextGLX::CreateWindowSurface(Window window_handle)

View File

@ -33,7 +33,6 @@ public:
protected: protected:
bool Initialize(void* display_handle, void* window_handle, bool stereo, bool core) override; bool Initialize(void* display_handle, void* window_handle, bool stereo, bool core) override;
bool Initialize(GLContext* main_context) override;
Display* m_display = nullptr; Display* m_display = nullptr;
std::unique_ptr<GLX11Window> m_render_window; std::unique_ptr<GLX11Window> m_render_window;

View File

@ -306,34 +306,29 @@ bool GLContextWGL::Initialize(void* display_handle, void* window_handle, bool st
return true; return true;
} }
bool GLContextWGL::Initialize(GLContext* main_context)
{
GLContextWGL* wgl_main_context = static_cast<GLContextWGL*>(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;
}
std::unique_ptr<GLContext> GLContextWGL::CreateSharedContext() std::unique_ptr<GLContext> GLContextWGL::CreateSharedContext()
{ {
std::unique_ptr<GLContextWGL> context = std::make_unique<GLContextWGL>(); // WGL does not support surfaceless contexts, so we use a 1x1 pbuffer instead.
if (!context->Initialize(this)) HANDLE pbuffer;
HDC dc;
if (!CreatePBuffer(m_dc, 1, 1, &pbuffer, &dc))
return nullptr;
HGLRC rc = CreateCoreContext(dc, m_rc);
if (!rc)
{ {
context->Shutdown(); wglReleasePbufferDCARB(static_cast<HPBUFFERARB>(pbuffer), dc);
wglDestroyPbufferARB(static_cast<HPBUFFERARB>(pbuffer));
return nullptr; 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_core_context = m_is_core_context;
return context;
} }
HGLRC GLContextWGL::CreateCoreContext(HDC dc, HGLRC share_context) HGLRC GLContextWGL::CreateCoreContext(HDC dc, HGLRC share_context)

View File

@ -28,7 +28,6 @@ public:
protected: protected:
bool Initialize(void* display_handle, void* window_handle, bool stereo, bool core) override; bool Initialize(void* display_handle, void* window_handle, bool stereo, bool core) override;
bool Initialize(GLContext* main_context) override;
static HGLRC CreateCoreContext(HDC dc, HGLRC share_context); static HGLRC CreateCoreContext(HDC dc, HGLRC share_context);
static bool CreatePBuffer(HDC onscreen_dc, int width, int height, HANDLE* pbuffer_handle, static bool CreatePBuffer(HDC onscreen_dc, int width, int height, HANDLE* pbuffer_handle,