summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpierre <pierre@pirsoft.de>2010-09-19 23:40:03 +0000
committerpierre <pierre@pirsoft.de>2010-09-19 23:40:03 +0000
commit6583a3f1e207cd0655a66fdddcfb8ed4e752c321 (patch)
tree253c7ce774dd22faba07e972f115071dc5c4c82a
parent236f75aac3e3fb09bbebdd1bc01c2191cdd7b029 (diff)
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
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp38
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h5
2 files changed, 27 insertions, 16 deletions
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp
index 8e571651c4..506127304b 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp
@@ -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
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h
index e87d557548..c0fb1a55f3 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h
+++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h
@@ -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;