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:
pierre 2010-09-19 23:40:03 +00:00
parent 236f75aac3
commit 6583a3f1e2
2 changed files with 27 additions and 16 deletions

View File

@ -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

View File

@ -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;