From 18296126dfd7f88d1cc831f392b03fcb94230d93 Mon Sep 17 00:00:00 2001 From: Ben Anderson Date: Wed, 16 Mar 2005 02:23:07 +0000 Subject: [PATCH] Do things a little closer to the way SDL does them (but not much), magical hack that fixes performance issues for X11 on some (all?) systems, use variables instead of functions for Dpy and Win in X11Helper, a couple formatting tweaks. --- .../arch/InputHandler/InputHandler_X11.cpp | 9 ++- .../LowLevelWindow/LowLevelWindow_X11.cpp | 75 +++++++++++-------- stepmania/src/archutils/Unix/X11Helper.cpp | 44 +++++------ 3 files changed, 73 insertions(+), 55 deletions(-) diff --git a/stepmania/src/arch/InputHandler/InputHandler_X11.cpp b/stepmania/src/arch/InputHandler/InputHandler_X11.cpp index 39cb82b697..605001b917 100644 --- a/stepmania/src/arch/InputHandler/InputHandler_X11.cpp +++ b/stepmania/src/arch/InputHandler/InputHandler_X11.cpp @@ -126,9 +126,12 @@ void InputHandler_X11::Update(float fDeltaTime) Display *display = X11Helper::Dpy(); Window window = X11Helper::Win(); XEvent event; - if (window) - while(XCheckTypedWindowEvent(display, window, KeyPress, &event) - || XCheckTypedWindowEvent(display, window, KeyRelease, &event) ) + + if (X11Helper::Win) + while(XCheckTypedWindowEvent(X11Helper::Dpy, + X11Helper::Win, KeyPress, &event) + || XCheckTypedWindowEvent(X11Helper::Dpy, + X11Helper::Win, KeyRelease, &event) ) { LOG->Trace("key: sym %i, key %i, state %i", XLookupKeysym(&event.xkey,0), XSymToKeySym(XLookupKeysym(&event.xkey,0)), diff --git a/stepmania/src/arch/LowLevelWindow/LowLevelWindow_X11.cpp b/stepmania/src/arch/LowLevelWindow/LowLevelWindow_X11.cpp index f5e8a1e7a5..b19bc66c3f 100644 --- a/stepmania/src/arch/LowLevelWindow/LowLevelWindow_X11.cpp +++ b/stepmania/src/arch/LowLevelWindow/LowLevelWindow_X11.cpp @@ -21,7 +21,7 @@ LowLevelWindow_X11::LowLevelWindow_X11() { RageException::Throw("Failed to establish a connection with the X server."); } - g_X11Display = X11Helper::Dpy(); + g_X11Display = X11Helper::Dpy; } LowLevelWindow_X11::~LowLevelWindow_X11() @@ -39,15 +39,12 @@ void *LowLevelWindow_X11::GetProcAddress(CString s) CString LowLevelWindow_X11::TryVideoMode(RageDisplay::VideoModeParams p, bool &bNewDeviceOut) { - int i; - int bpppc; // Bits per pixel per channel - int visAttribs[11]; - XVisualInfo *xvi; - XEvent ev; XSizeHints hints; - GLXContext ctxt; + XEvent ev; stack otherEvs; + int i; + // XXX: LLW_SDL allows the window to be resized. Do we really want to? hints.flags = PMinSize | PMaxSize | PBaseSize; hints.min_width = hints.max_width = hints.base_width = p.width; @@ -57,39 +54,53 @@ CString LowLevelWindow_X11::TryVideoMode(RageDisplay::VideoModeParams p, bool &b if(!windowIsOpen || p.bpp != CurrentParams.bpp) { + int visAttribs[32]; + XVisualInfo *xvi; + GLXContext ctxt; + // Different depth, or we didn't make a window before. New context. bNewDeviceOut = true; - - bpppc = (int) ceil(p.bpp / 4.0); - visAttribs[0] = GLX_RGBA; - visAttribs[1] = GLX_DOUBLEBUFFER; - visAttribs[2] = GLX_RED_SIZE; visAttribs[3] = bpppc; - visAttribs[4] = GLX_GREEN_SIZE; visAttribs[5] = bpppc; - visAttribs[6] = GLX_BLUE_SIZE; visAttribs[7] = bpppc; - visAttribs[8] = GLX_ALPHA_SIZE; visAttribs[9] = p.bpp - - (bpppc * 3); - // Alpha gets however many bits are left... - visAttribs[10] = None; + i = 0; + ASSERT(p.bpp == 16 || p.bpp == 32); + if(p.bpp == 32) + { + visAttribs[i++] = GLX_RED_SIZE; visAttribs[i++] = 8; + visAttribs[i++] = GLX_GREEN_SIZE; visAttribs[i++] = 8; + visAttribs[i++] = GLX_BLUE_SIZE; visAttribs[i++] = 8; + } + else + { + visAttribs[i++] = GLX_RED_SIZE; visAttribs[i++] = 5; + visAttribs[i++] = GLX_GREEN_SIZE; visAttribs[i++] = 6; + visAttribs[i++] = GLX_BLUE_SIZE; visAttribs[i++] = 5; + } - xvi = glXChooseVisual(X11Helper::Dpy(), - DefaultScreen(X11Helper::Dpy() ), visAttribs); + visAttribs[i++] = GLX_DEPTH_SIZE; visAttribs[i++] = 16; + visAttribs[i++] = GLX_RGBA; + visAttribs[i++] = GLX_DOUBLEBUFFER; + + visAttribs[i++] = None; + + xvi = glXChooseVisual(X11Helper::Dpy, + DefaultScreen(X11Helper::Dpy), visAttribs); if(!xvi) { return "No visual available for that depth."; } - if(!X11Helper::MakeWindow(xvi->screen, xvi->depth, xvi->visual, - p.width, p.height) ) + // Taking a hint from SDL. + + if(!X11Helper::MakeWindow(xvi->screen, xvi->depth, xvi->visual) ) { return "Failed to create the window."; } windowIsOpen = true; - ctxt = glXCreateContext(X11Helper::Dpy(), xvi, NULL, True); + ctxt = glXCreateContext(X11Helper::Dpy, xvi, NULL, True); - glXMakeCurrent(X11Helper::Dpy(), X11Helper::Win(), ctxt); + glXMakeCurrent(X11Helper::Dpy, X11Helper::Win, ctxt); } else @@ -99,12 +110,12 @@ CString LowLevelWindow_X11::TryVideoMode(RageDisplay::VideoModeParams p, bool &b bNewDeviceOut = false; // Remap the window to work around possible buggy WMs and/or // X servers - XUnmapWindow(X11Helper::Dpy(), X11Helper::Win() ); + XUnmapWindow(X11Helper::Dpy, X11Helper::Win); } - XSetWMNormalHints(X11Helper::Dpy(), X11Helper::Win(), &hints); + XSetWMNormalHints(X11Helper::Dpy, X11Helper::Win, &hints); - XMapWindow(X11Helper::Dpy(), X11Helper::Win() ); + XMapWindow(X11Helper::Dpy, X11Helper::Win); // HACK: Wait for the MapNotify event, without spinning and // eating CPU unnecessarily, and without smothering other @@ -113,7 +124,7 @@ CString LowLevelWindow_X11::TryVideoMode(RageDisplay::VideoModeParams p, bool &b // after MapNotify arrives. while(true) { - XNextEvent(X11Helper::Dpy(), &ev); + XNextEvent(X11Helper::Dpy, &ev); if(ev.type == MapNotify) { break; @@ -125,7 +136,7 @@ CString LowLevelWindow_X11::TryVideoMode(RageDisplay::VideoModeParams p, bool &b } while(!otherEvs.empty() ) { - XPutBackEvent(X11Helper::Dpy(), &otherEvs.top() ); + XPutBackEvent(X11Helper::Dpy, &otherEvs.top() ); otherEvs.pop(); } @@ -138,7 +149,11 @@ CString LowLevelWindow_X11::TryVideoMode(RageDisplay::VideoModeParams p, bool &b void LowLevelWindow_X11::SwapBuffers() { - glXSwapBuffers(X11Helper::Dpy(), X11Helper::Win() ); + glXSwapBuffers(X11Helper::Dpy, X11Helper::Win); + // XXX HACK: I added this sleep on a strange hunch while trying to find + // the source of crippling performance issues, and suddenly + // those performance issues simply stopped... + usleep(10000); // Allows up to ~100fps } /* diff --git a/stepmania/src/archutils/Unix/X11Helper.cpp b/stepmania/src/archutils/Unix/X11Helper.cpp index 3309f52475..f6572b0e83 100644 --- a/stepmania/src/archutils/Unix/X11Helper.cpp +++ b/stepmania/src/archutils/Unix/X11Helper.cpp @@ -7,18 +7,20 @@ #include "RageLog.h" // LOG #include "RageDisplay.h" // RageDisplay +#include "RageThreads.h" // Don't make me list everything... vector pMasks; // Currently open masks -Display *pDpy = NULL; // Running X connection bool pHaveWin = false; // Do we have a window? -Window pWin; // Current window unsigned short int pCt = 0; // Number of subsystems // using the X connection +Display *X11Helper::Dpy = NULL; +Window X11Helper::Win; + int protoErrorCallback(Display *d, XErrorEvent *err) { - char errText[1024]; - XGetErrorText(d, err->error_code, errText, 1024); + char errText[512]; + XGetErrorText(d, err->error_code, errText, 512); LOG->Warn("X11 Protocol error %s (%d) has occurred, caused by request %d,%d, resource ID %d", errText, err->error_code, err->request_code, err->minor_code, err->resourceid); @@ -32,11 +34,14 @@ int protoFatalCallback(Display *d) bool X11Helper::Go() { + int i; + if(pCt == 0) { - pDpy = XOpenDisplay(0); - if(pDpy == NULL) { return false; } + Dpy = XOpenDisplay(0); + if(Dpy == NULL) { return false; } + XSetIOErrorHandler(&protoFatalCallback); XSetErrorHandler(&protoErrorCallback); } pCt++; @@ -44,21 +49,13 @@ bool X11Helper::Go() return true; } -Display *X11Helper::Dpy() -{ - return pDpy; -} - -Window& X11Helper::Win() -{ - return pWin; -} - static bool pApplyMasks() { unsigned int i; long finalMask; + LOG->Trace("X11Helper: Reapplying event masks."); + i = 0; while(i < pMasks.size() ) { @@ -66,7 +63,10 @@ static bool pApplyMasks() i++; } - if(XSelectInput(pDpy, pWin, finalMask) == 0) { return false; } + if(XSelectInput(X11Helper::Dpy, X11Helper::Win, finalMask) == 0) { return false; } + + // Sync, so that the event mask applies now. + XSync(X11Helper::Dpy, false); return true; } @@ -114,9 +114,9 @@ bool X11Helper::MakeWindow(int screenNum, int depth, Visual *visual, int width, { vector::iterator i; - if(pDpy == NULL) { return false; } + if(pCt == 0) { return false; } - if(pHaveWin) { XDestroyWindow(pDpy, pWin); pHaveWin = false; } + if(pHaveWin) { XDestroyWindow(Dpy, Win); pHaveWin = false; } XSetWindowAttributes winAttribs; @@ -131,10 +131,10 @@ bool X11Helper::MakeWindow(int screenNum, int depth, Visual *visual, int width, // XXX: Error catching/handling? - winAttribs.colormap = XCreateColormap(pDpy, RootWindow(pDpy, screenNum), + winAttribs.colormap = XCreateColormap(Dpy, RootWindow(Dpy, screenNum), visual, AllocNone); - pWin = XCreateWindow(pDpy, RootWindow(pDpy, screenNum), 0, 0, width, + Win = XCreateWindow(Dpy, RootWindow(Dpy, screenNum), 0, 0, width, height, 0, depth, InputOutput, visual, CWBorderPixel | CWColormap | CWEventMask, &winAttribs); @@ -149,7 +149,7 @@ void X11Helper::Stop() if(pCt == 0) { - XCloseDisplay(pDpy); + XCloseDisplay(Dpy); pMasks.clear(); } }