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.

This commit is contained in:
Ben Anderson
2005-03-16 02:23:07 +00:00
parent 90a470ab4a
commit 18296126df
3 changed files with 73 additions and 55 deletions
@@ -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)),
@@ -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<XEvent> 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
}
/*
+22 -22
View File
@@ -7,18 +7,20 @@
#include "RageLog.h" // LOG
#include "RageDisplay.h" // RageDisplay
#include "RageThreads.h" // Don't make me list everything...
vector<long> 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<long>::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();
}
}