GLContext: Combine shared context initialization and creation
This commit is contained in:
parent
dcdd02d646
commit
4b8d1c2b42
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue