? xorg/cscope.files ? xorg/cscope.out ? xorg/cfb/compiler.h ? xorg/cfb24/.deps ? xorg/cfb24/.libs ? xorg/cfb24/Makefile ? xorg/cfb24/Makefile.in ? xorg/cfb24/cfb8lineCO.c ? xorg/cfb24/cfb8lineCO.lo ? xorg/cfb24/cfb8lineCP.c ? xorg/cfb24/cfb8lineCP.lo ? xorg/cfb24/cfb8lineG.c ? xorg/cfb24/cfb8lineG.lo ? xorg/cfb24/cfb8lineX.c ? xorg/cfb24/cfb8lineX.lo ? xorg/cfb24/cfb8segC.c ? xorg/cfb24/cfb8segC.lo ? xorg/cfb24/cfb8segCS.c ? xorg/cfb24/cfb8segCS.lo ? xorg/cfb24/cfb8segX.c ? xorg/cfb24/cfb8segX.lo ? xorg/cfb24/cfb8setG.c ? xorg/cfb24/cfb8setG.lo ? xorg/cfb24/cfballpriv.lo ? xorg/cfb24/cfbbitblt.lo ? xorg/cfb24/cfbbltC.c ? xorg/cfb24/cfbbltC.lo ? xorg/cfb24/cfbbltG.c ? xorg/cfb24/cfbbltG.lo ? xorg/cfb24/cfbbltO.c ? xorg/cfb24/cfbbltO.lo ? xorg/cfb24/cfbbltX.c ? xorg/cfb24/cfbbltX.lo ? xorg/cfb24/cfbbres.lo ? xorg/cfb24/cfbbresd.lo ? xorg/cfb24/cfbbstore.lo ? xorg/cfb24/cfbcmap.lo ? xorg/cfb24/cfbcppl.lo ? xorg/cfb24/cfbfillarcC.c ? xorg/cfb24/cfbfillarcC.lo ? xorg/cfb24/cfbfillarcG.c ? xorg/cfb24/cfbfillarcG.lo ? xorg/cfb24/cfbfillrct.lo ? xorg/cfb24/cfbfillsp.lo ? xorg/cfb24/cfbgc.lo ? xorg/cfb24/cfbgetsp.lo ? xorg/cfb24/cfbglblt8.lo ? xorg/cfb24/cfbhrzvert.lo ? xorg/cfb24/cfbigblt8.lo ? xorg/cfb24/cfbimage.lo ? xorg/cfb24/cfbline.lo ? xorg/cfb24/cfbmskbits.lo ? xorg/cfb24/cfbpixmap.lo ? xorg/cfb24/cfbply1rctC.c ? xorg/cfb24/cfbply1rctC.lo ? xorg/cfb24/cfbply1rctG.c ? xorg/cfb24/cfbply1rctG.lo ? xorg/cfb24/cfbpntwin.lo ? xorg/cfb24/cfbpolypnt.loT ? xorg/cfb24/cfbrrop.lo ? xorg/cfb24/cfbscrinit.lo ? xorg/cfb24/cfbseg.c ? xorg/cfb24/cfbseg.lo ? xorg/cfb24/cfbsetsp.lo ? xorg/cfb24/cfbsolidC.c ? xorg/cfb24/cfbsolidC.lo ? xorg/cfb24/cfbsolidG.c ? xorg/cfb24/cfbsolidG.lo ? xorg/cfb24/cfbsolidX.c ? xorg/cfb24/cfbsolidX.lo ? xorg/cfb24/cfbtegblt.lo ? xorg/cfb24/cfbtile32C.c ? xorg/cfb24/cfbtile32C.lo ? xorg/cfb24/cfbtile32G.c ? xorg/cfb24/cfbtile32G.lo ? xorg/cfb24/cfbtileoddC.c ? xorg/cfb24/cfbtileoddC.lo ? xorg/cfb24/cfbtileoddG.c ? xorg/cfb24/cfbtileoddG.lo ? xorg/cfb24/cfbwindow.lo ? xorg/cfb24/cfbzerarcC.c ? xorg/cfb24/cfbzerarcC.lo ? xorg/cfb24/cfbzerarcG.c ? xorg/cfb24/cfbzerarcG.lo ? xorg/cfb24/cfbzerarcX.c ? xorg/cfb24/cfbzerarcX.lo ? xorg/cfb24/libcfb24.la ? xorg/doc/Xserver.1x ? xorg/exa/Doxyfile ? xorg/exa/html ? xorg/exa/latex ? xorg/hw/dmx/Xdmx.1x ? xorg/hw/dmx/config/dmxtodmx.1x ? xorg/hw/dmx/config/vdltodmx.1x ? xorg/hw/dmx/config/xdmxconfig.1x ? xorg/hw/xfree86/xf8_32wid/.deps ? xorg/hw/xfree86/xf8_32wid/.libs ? xorg/hw/xfree86/xf8_32wid/Makefile ? xorg/hw/xfree86/xf8_32wid/Makefile.in ? xorg/hw/xfree86/xf8_32wid/cfb8_32widmodule.lo ? xorg/hw/xfree86/xf8_32wid/cfbscrinit.lo ? xorg/hw/xfree86/xf8_32wid/cfbwid.lo ? xorg/hw/xfree86/xf8_32wid/cfbwindow.lo ? xorg/hw/xfree86/xf8_32wid/libxf8_32wid.la ? xorg/ilbm/Makefile ? xorg/ilbm/Makefile.in ? xorg/iplan2p4/Makefile ? xorg/iplan2p4/Makefile.in Index: xorg/hw/xfree86/os-support/drm/xf86drm.c =================================================================== RCS file: /cvs/xorg/xserver/xorg/hw/xfree86/os-support/drm/xf86drm.c,v retrieving revision 1.2 diff -u -r1.2 xf86drm.c --- xorg/hw/xfree86/os-support/drm/xf86drm.c 10 Feb 2006 22:00:25 -0000 1.2 +++ xorg/hw/xfree86/os-support/drm/xf86drm.c 7 Feb 2007 03:58:58 -0000 @@ -528,6 +528,128 @@ return -1; } +/* + * DRM based VBLANK support + * + * We add a new system counter called "VBLANK" if the underlying DRM driver we + * just opened supports vblank. + * + * FIXME: multihead? one counter per head? + */ +#define _SYNC_SERVER +#include +#include +static void *drmVBlankCounter; +static XSyncValue curVBlankCount; +static XSyncValue *nextVBlankCount; + +/* + * Increment the Xsync VBLANK counter and request another signal. + * + * Note that we can't call SyncChangeCounter here to fire the triggers + * since we don't know where the server was interrupted (it could have + * been while updating the trigger list or something). + */ +static void drmVBlankSigHandler(int fd, void *oldctx, void *newctx) +{ + XSyncValue add; + drmVBlank vbl; + int ovf; + + /* Get the current count in case we missed any events */ + vbl.request.type = DRM_VBLANK_RELATIVE; + vbl.request.sequence = 0; + drmWaitVBlank(fd, &vbl); + XSyncIntToValue(&add, vbl.request.sequence); + XSyncValueAdd(&curVBlankCount, curVBlankCount, add, &ovf); + + /* Setup for the next vblank event */ + vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_SIGNAL; + vbl.request.sequence = 1; + vbl.request.signal = SIGIO; + drmWaitVBlank(fd, &vbl); +} + +/* + * Nothing to do here. + */ +static void drmVBlankBlockHandler(void *env, struct timeval **wt, + void *LastSelectMask) +{ + return; +} + +/* + * The XSync architecture is vulnerable to laggy wakeup handling since the + * signal handler can't call SyncChangeCounter by itself (no locking means + * the triggers called by SyncChangeCounter might change from underneath it). + * That means we could get to this point long after the VBLANK actually + * occurred, which probably isn't what the client wanted. + */ +static void drmVBlankWakeupHandler(void *env, int rc, void *LastSelectMask) +{ + /* Fire the triggers if we have a waiter and their time has come */ + if (nextVBlankCount && XSyncValueGreaterOrEqual(curVBlankCount, + *nextVBlankCount)) + SyncChangeCounter(drmVBlankCounter, curVBlankCount); +} + +/* + * Just return the current value of the VBLANK counter. + */ +static void drmVBlankQueryValue(void *pCounter, CARD64 *pValue_return) +{ + *pValue_return = curVBlankCount; +} + +/* + * Setup a notification request. + */ +static void drmVBlankBracketValues(void *pCounter, CARD64 *pbracket_less, + CARD64 *pbracket_greater) +{ + if (!nextVBlankCount && pbracket_greater) + RegisterBlockAndWakeupHandlers(drmVBlankBlockHandler, + drmVBlankWakeupHandler, + NULL); + else if (nextVBlankCount && !pbracket_greater) + RemoveBlockAndWakeupHandlers(drmVBlankBlockHandler, + drmVBlankWakeupHandler, + NULL); + nextVBlankCount = pbracket_greater; +} + +/* + * Setup VBLANK support if possible + * + * Setup the DRM VBLANK SIGIO handler then try requesting a VBLANK interrupt. + * If the driver supports it, create the XSync counter and continue on our + * merry way. + */ +static void SyncInitDrmVBlank(int fd) +{ + XSyncValue start, res; + drmVBlank vbl; + int ret; + + drmInstallSIGIOHandler(fd, drmVBlankSigHandler); + vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_SIGNAL; + vbl.request.sequence = 1; /* next event */ + vbl.request.signal = SIGIO; + if ((ret = drmWaitVBlank(fd, &vbl))) { + ErrorF("[drm] failed to regsister vblank handler: %s\n", + strerror(-ret)); + drmRemoveSIGIOHandler(fd); + return; + } + + XSyncIntToValue(&start, 0); + XSyncIntToValue(&res, 1); + drmVBlankCounter = SyncCreateSystemCounter("VBLANK", start, res, + XSyncCounterNeverDecreases, + drmVBlankQueryValue, + drmVBlankBracketValues); +} /** * Open the DRM device. @@ -546,6 +668,8 @@ */ int drmOpen(const char *name, const char *busid) { + int fd = -1; + #ifdef XFree86Server if (!drmAvailable() && name != NULL) { /* try to load the kernel */ @@ -557,16 +681,15 @@ } #endif - if (busid) { - int fd; - + if (busid) fd = drmOpenByBusid(busid); - if (fd >= 0) - return fd; - } - if (name) - return drmOpenByName(name); - return -1; + if (fd < 0 && name) + fd = drmOpenByName(name); + if (fd < 0) + return -1; + + SyncInitDrmVBlank(fd); + return fd; }