mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-10 08:09:26 +01:00
Plugin_VideoOGL: X11: Add another display connection to keep the two threads from
eating each others events. Manifests itself in GPU thread waiting forever for a reply in GL library code(and thus a frozen emulation). Most of the time, this can be resolved by creating more events (clicking, changing focus), but sometimes it stays stuck. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6218 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
236f75aac3
commit
6583a3f1e2
@ -112,22 +112,28 @@ void CreateXWindow (void)
|
||||
{
|
||||
Atom wmProtocols[1];
|
||||
|
||||
// use evdpy to create the window, so that connection gets the events
|
||||
// the colormap needs to be created on the same display, because it
|
||||
// is a client side structure, as well as wmProtocols(or so it seems)
|
||||
// GLWin.win is a xserver global window handle, so it can be used by both
|
||||
// display connections
|
||||
|
||||
// Setup window attributes
|
||||
GLWin.attr.colormap = XCreateColormap(GLWin.dpy,
|
||||
GLWin.attr.colormap = XCreateColormap(GLWin.evdpy,
|
||||
GLWin.parent, GLWin.vi->visual, AllocNone);
|
||||
GLWin.attr.event_mask = KeyPressMask | StructureNotifyMask | FocusChangeMask;
|
||||
GLWin.attr.background_pixel = BlackPixel(GLWin.dpy, GLWin.screen);
|
||||
GLWin.attr.background_pixel = BlackPixel(GLWin.evdpy, GLWin.screen);
|
||||
GLWin.attr.border_pixel = 0;
|
||||
|
||||
// Create the window
|
||||
GLWin.win = XCreateWindow(GLWin.dpy, GLWin.parent,
|
||||
GLWin.win = XCreateWindow(GLWin.evdpy, GLWin.parent,
|
||||
GLWin.x, GLWin.y, GLWin.width, GLWin.height, 0, GLWin.vi->depth, InputOutput, GLWin.vi->visual,
|
||||
CWBorderPixel | CWBackPixel | CWColormap | CWEventMask, &GLWin.attr);
|
||||
wmProtocols[0] = XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", True);
|
||||
XSetWMProtocols(GLWin.dpy, GLWin.win, wmProtocols, 1);
|
||||
XSetStandardProperties(GLWin.dpy, GLWin.win, "GPU", "GPU", None, NULL, 0, NULL);
|
||||
XMapRaised(GLWin.dpy, GLWin.win);
|
||||
XSync(GLWin.dpy, True);
|
||||
wmProtocols[0] = XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", True);
|
||||
XSetWMProtocols(GLWin.evdpy, GLWin.win, wmProtocols, 1);
|
||||
XSetStandardProperties(GLWin.evdpy, GLWin.win, "GPU", "GPU", None, NULL, 0, NULL);
|
||||
XMapRaised(GLWin.evdpy, GLWin.win);
|
||||
XSync(GLWin.evdpy, True);
|
||||
|
||||
GLWin.xEventThread = new Common::Thread(XEventThread, NULL);
|
||||
}
|
||||
@ -136,10 +142,10 @@ void DestroyXWindow(void)
|
||||
{
|
||||
XUnmapWindow(GLWin.dpy, GLWin.win);
|
||||
GLWin.win = 0;
|
||||
XFreeColormap(GLWin.dpy, GLWin.attr.colormap);
|
||||
if (GLWin.xEventThread)
|
||||
GLWin.xEventThread->WaitForDeath();
|
||||
GLWin.xEventThread = NULL;
|
||||
XFreeColormap(GLWin.evdpy, GLWin.attr.colormap);
|
||||
}
|
||||
|
||||
THREAD_RETURN XEventThread(void *pArg)
|
||||
@ -148,8 +154,8 @@ THREAD_RETURN XEventThread(void *pArg)
|
||||
{
|
||||
XEvent event;
|
||||
KeySym key;
|
||||
for (int num_events = XPending(GLWin.dpy); num_events > 0; num_events--) {
|
||||
XNextEvent(GLWin.dpy, &event);
|
||||
for (int num_events = XPending(GLWin.evdpy); num_events > 0; num_events--) {
|
||||
XNextEvent(GLWin.evdpy, &event);
|
||||
switch(event.type) {
|
||||
case KeyPress:
|
||||
key = XLookupKeysym((XKeyEvent*)&event, 0);
|
||||
@ -202,16 +208,16 @@ THREAD_RETURN XEventThread(void *pArg)
|
||||
case ConfigureNotify:
|
||||
Window winDummy;
|
||||
unsigned int borderDummy, depthDummy;
|
||||
XGetGeometry(GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y,
|
||||
XGetGeometry(GLWin.evdpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y,
|
||||
&GLWin.width, &GLWin.height, &borderDummy, &depthDummy);
|
||||
s_backbuffer_width = GLWin.width;
|
||||
s_backbuffer_height = GLWin.height;
|
||||
break;
|
||||
case ClientMessage:
|
||||
if ((unsigned long) event.xclient.data.l[0] == XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", False))
|
||||
if ((unsigned long) event.xclient.data.l[0] == XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", False))
|
||||
g_VideoInitialize.pCoreMessage(WM_USER_STOP);
|
||||
if ((unsigned long) event.xclient.data.l[0] == XInternAtom(GLWin.dpy, "RESIZE", False))
|
||||
XMoveResizeWindow(GLWin.dpy, GLWin.win, event.xclient.data.l[1],
|
||||
if ((unsigned long) event.xclient.data.l[0] == XInternAtom(GLWin.evdpy, "RESIZE", False))
|
||||
XMoveResizeWindow(GLWin.evdpy, GLWin.win, event.xclient.data.l[1],
|
||||
event.xclient.data.l[2], event.xclient.data.l[3], event.xclient.data.l[4]);
|
||||
break;
|
||||
default:
|
||||
@ -343,6 +349,7 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
|
||||
None };
|
||||
|
||||
GLWin.dpy = XOpenDisplay(0);
|
||||
GLWin.evdpy = XOpenDisplay(0);
|
||||
GLWin.parent = (Window)g_VideoInitialize.pWindowHandle;
|
||||
GLWin.screen = DefaultScreen(GLWin.dpy);
|
||||
if (GLWin.parent == 0)
|
||||
@ -492,6 +499,7 @@ void OpenGL_Shutdown()
|
||||
{
|
||||
glXDestroyContext(GLWin.dpy, GLWin.ctx);
|
||||
XCloseDisplay(GLWin.dpy);
|
||||
XCloseDisplay(GLWin.evdpy);
|
||||
GLWin.ctx = NULL;
|
||||
}
|
||||
#endif
|
||||
|
@ -78,7 +78,10 @@ typedef struct {
|
||||
int screen;
|
||||
Window win;
|
||||
Window parent;
|
||||
Display *dpy;
|
||||
// dpy (mainly) used for glx stuff, evdpy for window events etc.
|
||||
// used to keep the two threads from eating each others events
|
||||
// evdpy is to be used by XEventThread only (when it is running)
|
||||
Display *dpy, *evdpy;
|
||||
XVisualInfo *vi;
|
||||
GLXContext ctx;
|
||||
XSetWindowAttributes attr;
|
||||
|
Loading…
x
Reference in New Issue
Block a user