GLContext: Use host connection

This also removes the need for a sleeping event thread.
This commit is contained in:
Stenzek 2018-10-03 23:03:19 +10:00
parent 1d827a5223
commit 9c57a98723
18 changed files with 68 additions and 97 deletions

View File

@ -27,7 +27,7 @@ std::unique_ptr<GLContext> g_main_gl_context;
GLContext::~GLContext() = default; GLContext::~GLContext() = default;
bool GLContext::Initialize(void* window_handle, bool stereo, bool core) bool GLContext::Initialize(void* display_handle, void* window_handle, bool stereo, bool core)
{ {
return false; return false;
} }
@ -37,12 +37,6 @@ bool GLContext::Initialize(GLContext* main_context)
return false; return false;
} }
void GLContext::SetBackBufferDimensions(u32 w, u32 h)
{
m_backbuffer_width = w;
m_backbuffer_height = h;
}
bool GLContext::IsHeadless() const bool GLContext::IsHeadless() const
{ {
return true; return true;
@ -88,7 +82,8 @@ void* GLContext::GetFuncAddress(const std::string& name)
return nullptr; return nullptr;
} }
std::unique_ptr<GLContext> GLContext::Create(void* window_handle, bool stereo, bool core) std::unique_ptr<GLContext> GLContext::Create(void* display_handle, void* window_handle, bool stereo,
bool core)
{ {
std::unique_ptr<GLContext> context; std::unique_ptr<GLContext> context;
#if defined(__APPLE__) #if defined(__APPLE__)
@ -108,7 +103,7 @@ std::unique_ptr<GLContext> GLContext::Create(void* window_handle, bool stereo, b
#else #else
return nullptr; return nullptr;
#endif #endif
if (!context->Initialize(window_handle, stereo, core)) if (!context->Initialize(display_handle, window_handle, stereo, core))
return nullptr; return nullptr;
return context; return context;

View File

@ -26,7 +26,6 @@ public:
u32 GetBackBufferWidth() { return m_backbuffer_width; } u32 GetBackBufferWidth() { return m_backbuffer_width; }
u32 GetBackBufferHeight() { return m_backbuffer_height; } u32 GetBackBufferHeight() { return m_backbuffer_height; }
void SetBackBufferDimensions(u32 w, u32 h);
virtual bool IsHeadless() const; virtual bool IsHeadless() const;
@ -45,11 +44,11 @@ public:
virtual void* GetFuncAddress(const std::string& name); virtual void* GetFuncAddress(const std::string& name);
// Creates an instance of GLInterface specific to the platform we are running on. // Creates an instance of GLInterface specific to the platform we are running on.
static std::unique_ptr<GLContext> Create(void* window_handle, bool stereo = false, static std::unique_ptr<GLContext> Create(void* display_handle, void* window_handle,
bool core = true); bool stereo = false, bool core = true);
protected: protected:
virtual bool Initialize(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); virtual bool Initialize(GLContext* main_context);
Mode m_opengl_mode = Mode::Detect; Mode m_opengl_mode = Mode::Detect;

View File

@ -31,7 +31,7 @@ public:
void SwapInterval(int interval) override; void SwapInterval(int interval) override;
protected: protected:
bool Initialize(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 Initialize(GLContext* main_context) override;
NSView* m_view = nullptr; NSView* m_view = nullptr;

View File

@ -55,7 +55,7 @@ void GLContextAGL::Swap()
// Create rendering window. // Create rendering window.
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() // Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
bool GLContextAGL::Initialize(void* window_handle, bool stereo, bool core) bool GLContextAGL::Initialize(void* display_handle, void* window_handle, bool stereo, bool core)
{ {
NSOpenGLPixelFormatAttribute attr[] = { NSOpenGLPixelFormatAttribute attr[] = {
NSOpenGLPFADoubleBuffer, NSOpenGLPFADoubleBuffer,

View File

@ -152,15 +152,16 @@ EGLNativeWindowType GLContextEGL::GetEGLNativeWindow(EGLConfig config)
// Create rendering window. // Create rendering window.
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() // Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
bool GLContextEGL::Initialize(void* window_handle, bool stereo, bool core) bool GLContextEGL::Initialize(void* display_handle, void* window_handle, bool stereo, bool core)
{ {
const bool has_handle = !!window_handle; const bool has_handle = !!window_handle;
EGLint egl_major, egl_minor; EGLint egl_major, egl_minor;
bool supports_core_profile = false; bool supports_core_profile = false;
m_egl_display = OpenEGLDisplay(); m_host_display = display_handle;
m_host_window = window_handle; m_host_window = window_handle;
m_egl_display = OpenEGLDisplay();
m_is_core_context = core; m_is_core_context = core;
if (!m_egl_display) if (!m_egl_display)
@ -299,6 +300,7 @@ bool GLContextEGL::Initialize(GLContext* main_context)
GLContextEGL* egl_context = static_cast<GLContextEGL*>(main_context); GLContextEGL* egl_context = static_cast<GLContextEGL*>(main_context);
m_opengl_mode = egl_context->m_opengl_mode; 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_egl_display = egl_context->m_egl_display;
m_is_core_context = egl_context->m_is_core_context; m_is_core_context = egl_context->m_is_core_context;
m_config = egl_context->m_config; m_config = egl_context->m_config;

View File

@ -35,13 +35,14 @@ protected:
virtual EGLDisplay OpenEGLDisplay(); virtual EGLDisplay OpenEGLDisplay();
virtual EGLNativeWindowType GetEGLNativeWindow(EGLConfig config); virtual EGLNativeWindowType GetEGLNativeWindow(EGLConfig config);
bool Initialize(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 Initialize(GLContext* main_context) override;
bool CreateWindowSurface(); bool CreateWindowSurface();
void DestroyWindowSurface(); void DestroyWindowSurface();
void DetectMode(bool has_handle); void DetectMode(bool has_handle);
void* m_host_display = nullptr;
void* m_host_window = nullptr; void* m_host_window = nullptr;
EGLConfig m_config; EGLConfig m_config;

View File

@ -3,20 +3,19 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "Common/GL/GLInterface/EGLX11.h" #include "Common/GL/GLInterface/EGLX11.h"
#include "Common/Logging/Log.h"
GLContextEGLX11::~GLContextEGLX11() GLContextEGLX11::~GLContextEGLX11() = default;
void GLContextEGLX11::Update()
{ {
if (m_display) m_render_window->UpdateDimensions();
XCloseDisplay(m_display); m_backbuffer_width = m_render_window->GetWidth();
m_backbuffer_height = m_render_window->GetHeight();
} }
EGLDisplay GLContextEGLX11::OpenEGLDisplay() EGLDisplay GLContextEGLX11::OpenEGLDisplay()
{ {
if (!m_display) return eglGetDisplay(static_cast<Display*>(m_host_display));
m_display = XOpenDisplay(nullptr);
return eglGetDisplay(m_display);
} }
EGLNativeWindowType GLContextEGLX11::GetEGLNativeWindow(EGLConfig config) EGLNativeWindowType GLContextEGLX11::GetEGLNativeWindow(EGLConfig config)
@ -28,16 +27,18 @@ EGLNativeWindowType GLContextEGLX11::GetEGLNativeWindow(EGLConfig config)
visTemplate.visualid = vid; visTemplate.visualid = vid;
int nVisuals; int nVisuals;
XVisualInfo* vi = XGetVisualInfo(m_display, VisualIDMask, &visTemplate, &nVisuals); XVisualInfo* vi =
XGetVisualInfo(static_cast<Display*>(m_host_display), VisualIDMask, &visTemplate, &nVisuals);
if (m_x_window) if (m_render_window)
m_x_window.reset(); m_render_window.reset();
m_x_window = GLX11Window::Create(m_display, reinterpret_cast<Window>(m_host_window), vi); m_render_window = GLX11Window::Create(static_cast<Display*>(m_host_display),
m_backbuffer_width = m_x_window->GetWidth(); reinterpret_cast<Window>(m_host_window), vi);
m_backbuffer_height = m_x_window->GetHeight(); m_backbuffer_width = m_render_window->GetWidth();
m_backbuffer_height = m_render_window->GetHeight();
XFree(vi); XFree(vi);
return reinterpret_cast<EGLNativeWindowType>(m_x_window->GetWindow()); return reinterpret_cast<EGLNativeWindowType>(m_render_window->GetWindow());
} }

View File

@ -14,10 +14,11 @@ class GLContextEGLX11 : public GLContextEGL
public: public:
~GLContextEGLX11() override; ~GLContextEGLX11() override;
void Update() override;
protected: protected:
EGLDisplay OpenEGLDisplay() override; EGLDisplay OpenEGLDisplay() override;
EGLNativeWindowType GetEGLNativeWindow(EGLConfig config) override; EGLNativeWindowType GetEGLNativeWindow(EGLConfig config) override;
Display* m_display = nullptr; std::unique_ptr<GLX11Window> m_render_window;
std::unique_ptr<GLX11Window> m_x_window;
}; };

View File

@ -56,9 +56,9 @@ void GLContextGLX::Swap()
// Create rendering window. // Create rendering window.
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() // Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
bool GLContextGLX::Initialize(void* window_handle, bool stereo, bool core) bool GLContextGLX::Initialize(void* display_handle, void* window_handle, bool stereo, bool core)
{ {
m_display = XOpenDisplay(nullptr); m_display = static_cast<Display*>(display_handle);
int screen = DefaultScreen(m_display); int screen = DefaultScreen(m_display);
// checking glx version // checking glx version
@ -298,16 +298,12 @@ void GLContextGLX::Shutdown()
{ {
DestroyWindowSurface(); DestroyWindowSurface();
if (m_context) if (m_context)
{
glXDestroyContext(m_display, m_context); glXDestroyContext(m_display, m_context);
}
// Don't close the display connection if we are a shared context.
// Saves doing reference counting on this object, and the main context will always void GLContextGLX::Update()
// be shut down last anyway. {
if (m_render_window) m_render_window->UpdateDimensions();
{ m_backbuffer_width = m_render_window->GetWidth();
XCloseDisplay(m_display); m_backbuffer_height = m_render_window->GetHeight();
m_context = nullptr;
}
}
} }

View File

@ -24,13 +24,15 @@ public:
bool MakeCurrent() override; bool MakeCurrent() override;
bool ClearCurrent() override; bool ClearCurrent() override;
void Update() override;
void SwapInterval(int Interval) override; void SwapInterval(int Interval) override;
void Swap() override; void Swap() override;
void* GetFuncAddress(const std::string& name) override; void* GetFuncAddress(const std::string& name) override;
protected: protected:
bool Initialize(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 Initialize(GLContext* main_context) override;
Display* m_display = nullptr; Display* m_display = nullptr;

View File

@ -190,7 +190,7 @@ void* GLContextWGL::GetFuncAddress(const std::string& name)
// Create rendering window. // Create rendering window.
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() // Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
bool GLContextWGL::Initialize(void* window_handle, bool stereo, bool core) bool GLContextWGL::Initialize(void* display_handle, void* window_handle, bool stereo, bool core)
{ {
if (!window_handle) if (!window_handle)
return false; return false;

View File

@ -27,7 +27,7 @@ public:
void* GetFuncAddress(const std::string& name) override; void* GetFuncAddress(const std::string& name) override;
protected: protected:
bool Initialize(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 Initialize(GLContext* main_context) override;
static HGLRC CreateCoreContext(HDC dc, HGLRC share_context); static HGLRC CreateCoreContext(HDC dc, HGLRC share_context);

View File

@ -4,27 +4,30 @@
#include "Common/GL/GLX11Window.h" #include "Common/GL/GLX11Window.h"
#include "Common/GL/GLContext.h" #include "Common/GL/GLContext.h"
#include "Common/Thread.h"
GLX11Window::GLX11Window(Display* display, Window parent_window, Colormap color_map, Window window, GLX11Window::GLX11Window(Display* display, Window parent_window, Colormap color_map, Window window,
int width, int height) int width, int height)
: m_display(display), m_parent_window(parent_window), m_color_map(color_map), m_window(window), : m_display(display), m_parent_window(parent_window), m_color_map(color_map), m_window(window),
m_width(width), m_height(height), m_width(width), m_height(height)
m_event_thread(std::thread(&GLX11Window::XEventThread, this))
{ {
} }
GLX11Window::~GLX11Window() GLX11Window::~GLX11Window()
{ {
Window window = m_window; XUnmapWindow(m_display, m_window);
m_window = None; XDestroyWindow(m_display, m_window);
if (m_event_thread.joinable())
m_event_thread.join();
XUnmapWindow(m_display, window);
XDestroyWindow(m_display, window);
XFreeColormap(m_display, m_color_map); XFreeColormap(m_display, m_color_map);
} }
void GLX11Window::UpdateDimensions()
{
XWindowAttributes attribs;
XGetWindowAttributes(m_display, m_parent_window, &attribs);
XResizeWindow(m_display, m_window, attribs.width, attribs.height);
m_width = attribs.width;
m_height = attribs.height;
}
std::unique_ptr<GLX11Window> GLX11Window::Create(Display* display, Window parent_window, std::unique_ptr<GLX11Window> GLX11Window::Create(Display* display, Window parent_window,
XVisualInfo* vi) XVisualInfo* vi)
{ {
@ -48,30 +51,3 @@ std::unique_ptr<GLX11Window> GLX11Window::Create(Display* display, Window parent
return std::make_unique<GLX11Window>(display, parent_window, color_map, window, return std::make_unique<GLX11Window>(display, parent_window, color_map, window,
parent_attribs.width, parent_attribs.height); parent_attribs.width, parent_attribs.height);
} }
void GLX11Window::XEventThread()
{
// There's a potential race here on m_window. But this thread will disappear soon.
while (m_window)
{
XEvent event;
for (int num_events = XPending(m_display); num_events > 0; num_events--)
{
XNextEvent(m_display, &event);
switch (event.type)
{
case ConfigureNotify:
{
m_width = event.xconfigure.width;
m_height = event.xconfigure.height;
XResizeWindow(m_display, m_window, m_width, m_height);
g_main_gl_context->SetBackBufferDimensions(m_width, m_height);
}
break;
default:
break;
}
}
Common::SleepCurrentThread(20);
}
}

View File

@ -23,12 +23,12 @@ public:
int GetWidth() const { return m_width; } int GetWidth() const { return m_width; }
int GetHeight() const { return m_height; } int GetHeight() const { return m_height; }
void UpdateDimensions();
static std::unique_ptr<GLX11Window> Create(Display* display, Window parent_window, static std::unique_ptr<GLX11Window> Create(Display* display, Window parent_window,
XVisualInfo* vi); XVisualInfo* vi);
private: private:
void XEventThread();
Display* m_display; Display* m_display;
Window m_parent_window; Window m_parent_window;
Colormap m_color_map; Colormap m_color_map;
@ -36,6 +36,4 @@ private:
int m_width; int m_width;
int m_height; int m_height;
std::thread m_event_thread;
}; };

View File

@ -161,8 +161,8 @@ bool VideoBackend::Initialize(void* display_handle, void* window_handle)
{ {
InitializeShared(); InitializeShared();
g_main_gl_context = g_main_gl_context = GLContext::Create(display_handle, window_handle,
GLContext::Create(window_handle, g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer); g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer);
if (!g_main_gl_context) if (!g_main_gl_context)
return false; return false;

View File

@ -13,9 +13,9 @@
std::unique_ptr<SWOGLWindow> SWOGLWindow::s_instance; std::unique_ptr<SWOGLWindow> SWOGLWindow::s_instance;
void SWOGLWindow::Init(void* window_handle) void SWOGLWindow::Init(void* display_handle, void* window_handle)
{ {
g_main_gl_context = GLContext::Create(window_handle); g_main_gl_context = GLContext::Create(display_handle, window_handle);
if (!g_main_gl_context) if (!g_main_gl_context)
{ {
ERROR_LOG(VIDEO, "GLInterface::Create failed."); ERROR_LOG(VIDEO, "GLInterface::Create failed.");

View File

@ -16,7 +16,7 @@ class AbstractTexture;
class SWOGLWindow class SWOGLWindow
{ {
public: public:
static void Init(void* window_handle); static void Init(void* display_handle, void* window_handle);
static void Shutdown(); static void Shutdown();
void Prepare(); void Prepare();

View File

@ -82,7 +82,7 @@ bool VideoSoftware::Initialize(void* display_handle, void* window_handle)
{ {
InitializeShared(); InitializeShared();
SWOGLWindow::Init(window_handle); SWOGLWindow::Init(display_handle, window_handle);
Clipper::Init(); Clipper::Init();
Rasterizer::Init(); Rasterizer::Init();