diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2008-06-15 00:17:34 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2008-06-15 00:17:34 +0000 |
commit | 86fc487fbc0e5e6f7146a43099dc7ce1791c84f0 (patch) | |
tree | 86479ce8d7fc54c515b1aac90f960401587caef0 /xserver/GL/glx | |
parent | f629cb662c6469d23587f9dffc2352a8b6505b7b (diff) |
Update to xserver 1.4.2. Tested by landry@, ckuethe@, jsing@ mbalmer@.
Diffstat (limited to 'xserver/GL/glx')
-rw-r--r-- | xserver/GL/glx/glxdri.c | 338 |
1 files changed, 246 insertions, 92 deletions
diff --git a/xserver/GL/glx/glxdri.c b/xserver/GL/glx/glxdri.c index 170662c7e..09abca3f9 100644 --- a/xserver/GL/glx/glxdri.c +++ b/xserver/GL/glx/glxdri.c @@ -76,6 +76,11 @@ struct __GLXDRIscreen { xf86EnterVTProc *enterVT; xf86LeaveVTProc *leaveVT; + DRITexOffsetStartProcPtr texOffsetStart; + DRITexOffsetFinishProcPtr texOffsetFinish; + __GLXpixmap* texOffsetOverride[16]; + GLuint lastTexOffsetOverride; + unsigned char glx_enable_bits[__GLX_EXT_BYTES]; }; @@ -125,30 +130,75 @@ struct __GLXDRIdrawable { static const char CREATE_NEW_SCREEN_FUNC[] = "__driCreateNewScreen_" STRINGIFY (INTERNAL_VERSION); -/* The DRI driver entry point version wasn't bumped when the - * copySubBuffer functionality was added to the DRI drivers, but the - * functionality is still conditional on the value of the - * internal_api_version passed to __driCreateNewScreen. However, the - * screen constructor doesn't fail for a DRI driver that's older than - * the passed in version number, so there's no way we can know for - * sure that we can actually use the copySubBuffer functionality. But - * since the earliest (and at this point only) released mesa version - * (6.5) that uses the 20050727 entry point does have copySubBuffer, - * we'll just settle for that. We still have to pass in a higher to - * the screen constructor to enable the functionality. - */ -#define COPY_SUB_BUFFER_INTERNAL_VERSION 20060314 static void -__glXDRIleaveServer(void) +__glXDRIleaveServer(GLboolean rendering) { - DRIBlockHandler(NULL, NULL, NULL); + int i; + + for (i = 0; rendering && i < screenInfo.numScreens; i++) { + __GLXDRIscreen * const screen = + (__GLXDRIscreen *) __glXgetActiveScreen(i); + GLuint lastOverride = screen->lastTexOffsetOverride; + + if (lastOverride) { + __GLXpixmap **texOffsetOverride = screen->texOffsetOverride; + int j; + + for (j = 0; j < lastOverride; j++) { + __GLXpixmap *pGlxPix = texOffsetOverride[j]; + + if (pGlxPix && pGlxPix->texname) { + pGlxPix->offset = + screen->texOffsetStart((PixmapPtr)pGlxPix->pDraw); + } + } + } + } + + DRIBlockHandler(NULL, NULL, NULL); + + for (i = 0; rendering && i < screenInfo.numScreens; i++) { + __GLXDRIscreen * const screen = + (__GLXDRIscreen *) __glXgetActiveScreen(i); + GLuint lastOverride = screen->lastTexOffsetOverride; + + if (lastOverride) { + __GLXpixmap **texOffsetOverride = screen->texOffsetOverride; + int j; + + for (j = 0; j < lastOverride; j++) { + __GLXpixmap *pGlxPix = texOffsetOverride[j]; + + if (pGlxPix && pGlxPix->texname) { + screen->driScreen.setTexOffset(pGlxPix->pDRICtx, + pGlxPix->texname, + pGlxPix->offset, + pGlxPix->pDraw->depth, + ((PixmapPtr)pGlxPix->pDraw)-> + devKind); + } + } + } + } } static void -__glXDRIenterServer(void) +__glXDRIenterServer(GLboolean rendering) { - DRIWakeupHandler(NULL, 0, NULL); + int i; + + for (i = 0; rendering && i < screenInfo.numScreens; i++) { + __GLXDRIscreen * const screen = + (__GLXDRIscreen *) __glXgetActiveScreen(i); + + if (screen->lastTexOffsetOverride) { + CALL_Flush(GET_DISPATCH(), ()); + break; + } + } + + DRIWakeupHandler(NULL, 0, NULL); } /** @@ -289,19 +339,6 @@ __glXDRIcontextForceCurrent(__GLXcontext *baseContext) &context->driContext); } -static int -glxCountBits(int word) -{ - int ret = 0; - - while (word) { - ret += (word & 1); - word >>= 1; - } - - return ret; -} - static void glxFillAlphaChannel (PixmapPtr pixmap, int x, int y, int width, int height) { @@ -335,19 +372,68 @@ __glXDRIbindTexImage(__GLXcontext *baseContext, int buffer, __GLXpixmap *glxPixmap) { - RegionPtr pRegion; + RegionPtr pRegion = NULL; PixmapPtr pixmap; - int bpp; - GLenum target, format, type; + int bpp, override = 0; + GLenum format, type; + ScreenPtr pScreen = glxPixmap->pScreen; + __GLXDRIscreen * const screen = + (__GLXDRIscreen *) __glXgetActiveScreen(pScreen->myNum); pixmap = (PixmapPtr) glxPixmap->pDraw; + + if (screen->texOffsetStart && screen->driScreen.setTexOffset) { + __GLXpixmap **texOffsetOverride = screen->texOffsetOverride; + int i, firstEmpty = 16, texname; + + for (i = 0; i < 16; i++) { + if (texOffsetOverride[i] == glxPixmap) + goto alreadyin; + + if (firstEmpty == 16 && !texOffsetOverride[i]) + firstEmpty = i; + } + + if (firstEmpty == 16) { + ErrorF("%s: Failed to register texture offset override\n", __func__); + goto nooverride; + } + + if (firstEmpty >= screen->lastTexOffsetOverride) + screen->lastTexOffsetOverride = firstEmpty + 1; + + texOffsetOverride[firstEmpty] = glxPixmap; + +alreadyin: + override = 1; + + glxPixmap->pDRICtx = &((__GLXDRIcontext*)baseContext)->driContext; + + CALL_GetIntegerv(GET_DISPATCH(), (glxPixmap->target == GL_TEXTURE_2D ? + GL_TEXTURE_BINDING_2D : + GL_TEXTURE_BINDING_RECTANGLE_NV, + &texname)); + + if (texname == glxPixmap->texname) + return Success; + + glxPixmap->texname = texname; + + screen->driScreen.setTexOffset(glxPixmap->pDRICtx, texname, 0, + pixmap->drawable.depth, pixmap->devKind); + } +nooverride: + if (!glxPixmap->pDamage) { - glxPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone, - TRUE, glxPixmap->pScreen, NULL); - if (!glxPixmap->pDamage) - return BadAlloc; + if (!override) { + glxPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone, + TRUE, pScreen, NULL); + if (!glxPixmap->pDamage) + return BadAlloc; + + DamageRegister ((DrawablePtr) pixmap, glxPixmap->pDamage); + } - DamageRegister ((DrawablePtr) pixmap, glxPixmap->pDamage); pRegion = NULL; } else { pRegion = DamageRegion(glxPixmap->pDamage); @@ -360,30 +446,22 @@ __glXDRIbindTexImage(__GLXcontext *baseContext, bpp = 4; format = GL_BGRA; type = -#if X_BYTE_ORDER == X_LITTLE_ENDIAN - GL_UNSIGNED_BYTE; -#else - GL_UNSIGNED_INT_8_8_8_8_REV; +#if X_BYTE_ORDER == X_BIG_ENDIAN + !override ? GL_UNSIGNED_INT_8_8_8_8_REV : #endif + GL_UNSIGNED_BYTE; } else { bpp = 2; format = GL_RGB; type = GL_UNSIGNED_SHORT_5_6_5; } - if (!(glxCountBits(pixmap->drawable.width) == 1 && - glxCountBits(pixmap->drawable.height) == 1) - /* || strstr(CALL_GetString(GL_EXTENSIONS, - "GL_ARB_texture_non_power_of_two")) */) - target = GL_TEXTURE_RECTANGLE_ARB; - else - target = GL_TEXTURE_2D; - CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH, pixmap->devKind / bpp) ); + if (pRegion == NULL) { - if (pixmap->drawable.depth == 24) + if (!override && pixmap->drawable.depth == 24) glxFillAlphaChannel(pixmap, pixmap->drawable.x, pixmap->drawable.y, @@ -396,7 +474,7 @@ __glXDRIbindTexImage(__GLXcontext *baseContext, pixmap->drawable.y) ); CALL_TexImage2D( GET_DISPATCH(), - (target, + (glxPixmap->target, 0, bpp == 4 ? 4 : 3, pixmap->drawable.width, @@ -404,8 +482,8 @@ __glXDRIbindTexImage(__GLXcontext *baseContext, 0, format, type, - pixmap->devPrivate.ptr) ); - } else { + override ? NULL : pixmap->devPrivate.ptr) ); + } else if (!override) { int i, numRects; BoxPtr p; @@ -426,7 +504,7 @@ __glXDRIbindTexImage(__GLXcontext *baseContext, pixmap->drawable.y + p[i].y1) ); CALL_TexSubImage2D( GET_DISPATCH(), - (target, + (glxPixmap->target, 0, p[i].x1, p[i].y1, p[i].x2 - p[i].x1, p[i].y2 - p[i].y1, @@ -436,7 +514,8 @@ __glXDRIbindTexImage(__GLXcontext *baseContext, } } - DamageEmpty(glxPixmap->pDamage); + if (!override) + DamageEmpty(glxPixmap->pDamage); return Success; } @@ -446,6 +525,40 @@ __glXDRIreleaseTexImage(__GLXcontext *baseContext, int buffer, __GLXpixmap *pixmap) { + ScreenPtr pScreen = pixmap->pScreen; + __GLXDRIscreen * const screen = + (__GLXDRIscreen *) __glXgetActiveScreen(pScreen->myNum); + GLuint lastOverride = screen->lastTexOffsetOverride; + + if (lastOverride) { + __GLXpixmap **texOffsetOverride = screen->texOffsetOverride; + int i; + + for (i = 0; i < lastOverride; i++) { + if (texOffsetOverride[i] == pixmap) { + if (screen->texOffsetFinish) + screen->texOffsetFinish((PixmapPtr)pixmap->pDraw); + + texOffsetOverride[i] = NULL; + + if (i + 1 == lastOverride) { + lastOverride = 0; + + while (i--) { + if (texOffsetOverride[i]) { + lastOverride = i + 1; + break; + } + } + + screen->lastTexOffsetOverride = lastOverride; + + break; + } + } + } + } + return Success; } @@ -485,6 +598,9 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, else sharePrivate = NULL; + if (baseShareContext && baseShareContext->isDirect) + return NULL; + context = xalloc(sizeof *context); if (context == NULL) return NULL; @@ -495,6 +611,7 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, context->base.loseCurrent = __glXDRIcontextLoseCurrent; context->base.copy = __glXDRIcontextCopy; context->base.forceCurrent = __glXDRIcontextForceCurrent; + context->base.pScreen = screen->base.pScreen; context->base.textureFromPixmap = &__glXDRItextureFromPixmap; @@ -503,6 +620,11 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, 0, /* render type */ sharePrivate, &context->driContext); + + if (!context->driContext.private) { + xfree(context); + return NULL; + } context->driContext.mode = modes; @@ -637,9 +759,16 @@ static __DRIscreen *findScreen(__DRInativeDisplay *dpy, int scrn) static GLboolean windowExists(__DRInativeDisplay *dpy, __DRIid draw) { - WindowPtr pWin = (WindowPtr) LookupIDByType(draw, RT_WINDOW); - - return pWin == NULL ? GL_FALSE : GL_TRUE; + DrawablePtr pDrawable = (DrawablePtr) LookupIDByType(draw, RT_WINDOW); + int unused; + drm_clip_rect_t *pRects; + + return pDrawable ? DRIGetDrawableInfo(pDrawable->pScreen, pDrawable, + (unsigned*)&unused, (unsigned*)&unused, + &unused, &unused, &unused, &unused, + &unused, &pRects, &unused, &unused, + &unused, &pRects) + : GL_FALSE; } static GLboolean createContext(__DRInativeDisplay *dpy, int screen, @@ -665,9 +794,9 @@ static GLboolean createContext(__DRInativeDisplay *dpy, int screen, fakeID = FakeClientID(0); *(XID *) contextID = fakeID; - __glXDRIenterServer(); + __glXDRIenterServer(GL_FALSE); retval = DRICreateContext(pScreen, visual, fakeID, hw_context); - __glXDRIleaveServer(); + __glXDRIleaveServer(GL_FALSE); return retval; } @@ -676,9 +805,9 @@ static GLboolean destroyContext(__DRInativeDisplay *dpy, int screen, { GLboolean retval; - __glXDRIenterServer(); + __glXDRIenterServer(GL_FALSE); retval = DRIDestroyContext(screenInfo.screens[screen], context); - __glXDRIleaveServer(); + __glXDRIleaveServer(GL_FALSE); return retval; } @@ -693,12 +822,10 @@ createDrawable(__DRInativeDisplay *dpy, int screen, if (!pDrawable) return GL_FALSE; - __glXDRIenterServer(); - retval = DRICreateDrawable(screenInfo.screens[screen], - drawable, - pDrawable, - hHWDrawable); - __glXDRIleaveServer(); + __glXDRIenterServer(GL_FALSE); + retval = DRICreateDrawable(screenInfo.screens[screen], __pGlxClient, + pDrawable, hHWDrawable); + __glXDRIleaveServer(GL_FALSE); return retval; } @@ -712,11 +839,10 @@ destroyDrawable(__DRInativeDisplay *dpy, int screen, __DRIid drawable) if (!pDrawable) return GL_FALSE; - __glXDRIenterServer(); - retval = DRIDestroyDrawable(screenInfo.screens[screen], - drawable, - pDrawable); - __glXDRIleaveServer(); + __glXDRIenterServer(GL_FALSE); + retval = DRIDestroyDrawable(screenInfo.screens[screen], __pGlxClient, + pDrawable); + __glXDRIleaveServer(GL_FALSE); return retval; } @@ -753,20 +879,44 @@ getDrawableInfo(__DRInativeDisplay *dpy, int screen, return GL_FALSE; } - __glXDRIenterServer(); + __glXDRIenterServer(GL_FALSE); retval = DRIGetDrawableInfo(screenInfo.screens[screen], pDrawable, index, stamp, x, y, width, height, numClipRects, &pClipRects, backX, backY, numBackClipRects, &pBackClipRects); - __glXDRIleaveServer(); + __glXDRIleaveServer(GL_FALSE); if (*numClipRects > 0) { size = sizeof (drm_clip_rect_t) * *numClipRects; *ppClipRects = xalloc (size); - if (*ppClipRects != NULL) - memcpy (*ppClipRects, pClipRects, size); + + /* Clip cliprects to screen dimensions (redirected windows) */ + if (*ppClipRects != NULL) { + ScreenPtr pScreen = screenInfo.screens[screen]; + int i, j; + + for (i = 0, j = 0; i < *numClipRects; i++) { + (*ppClipRects)[j].x1 = max(pClipRects[i].x1, 0); + (*ppClipRects)[j].y1 = max(pClipRects[i].y1, 0); + (*ppClipRects)[j].x2 = min(pClipRects[i].x2, pScreen->width); + (*ppClipRects)[j].y2 = min(pClipRects[i].y2, pScreen->height); + + if ((*ppClipRects)[j].x1 < (*ppClipRects)[j].x2 && + (*ppClipRects)[j].y1 < (*ppClipRects)[j].y2) { + j++; + } + } + + if (*numClipRects != j) { + *numClipRects = j; + *ppClipRects = xrealloc (*ppClipRects, + sizeof (drm_clip_rect_t) * + *numClipRects); + } + } else + *numClipRects = 0; } else { *ppClipRects = NULL; @@ -782,7 +932,7 @@ getDrawableInfo(__DRInativeDisplay *dpy, int screen, *ppBackClipRects = NULL; } - return GL_TRUE; + return retval; } static int @@ -831,9 +981,12 @@ glxDRIEnterVT (int index, int flags) LogMessage(X_INFO, "AIGLX: Resuming AIGLX clients after VT switch\n"); + if (!(*screen->enterVT) (index, flags)) + return FALSE; + glxResumeClients(); - return (*screen->enterVT) (index, flags); + return TRUE; } static void @@ -861,9 +1014,10 @@ __glXDRIscreenProbe(ScreenPtr pScreen) __DRIframebuffer framebuffer; int fd = -1; int status; - int api_ver = COPY_SUB_BUFFER_INTERNAL_VERSION; + int api_ver = 20070121; drm_magic_t magic; drmVersionPtr version; + int newlyopened; char *driverName; drm_handle_t hFB; int junk; @@ -875,13 +1029,10 @@ __glXDRIscreenProbe(ScreenPtr pScreen) size_t buffer_size; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable")) { - LogMessage(X_ERROR, "AIGLX: DRI module not loaded\n"); - return NULL; - } - - if (!DRIQueryDirectRenderingCapable(pScreen, &isCapable) || !isCapable) { - LogMessage(X_ERROR, + if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") || + !DRIQueryDirectRenderingCapable(pScreen, &isCapable) || + !isCapable) { + LogMessage(X_INFO, "AIGLX: Screen %d is not DRI capable\n", pScreen->myNum); return NULL; } @@ -914,10 +1065,10 @@ __glXDRIscreenProbe(ScreenPtr pScreen) goto handle_error; } - fd = drmOpen(NULL, BusID); + fd = drmOpenOnce(NULL, BusID, &newlyopened); if (fd < 0) { - LogMessage(X_ERROR, "AIGLX error: drmOpen failed (%s)\n", + LogMessage(X_ERROR, "AIGLX error: drmOpenOnce failed (%s)\n", strerror(-fd)); goto handle_error; } @@ -940,7 +1091,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen) drm_version.patch = -1; } - if (!DRIAuthConnection(pScreen, magic)) { + if (newlyopened && !DRIAuthConnection(pScreen, magic)) { LogMessage(X_ERROR, "AIGLX error: DRIAuthConnection failed\n"); goto handle_error; } @@ -1042,6 +1193,9 @@ __glXDRIscreenProbe(ScreenPtr pScreen) goto handle_error; } + DRIGetTexOffsetFuncs(pScreen, &screen->texOffsetStart, + &screen->texOffsetFinish); + __glXScreenInit(&screen->base, pScreen); buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL); @@ -1082,7 +1236,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen) xfree(dev_priv); if (fd >= 0) - drmClose(fd); + drmCloseOnce(fd); DRICloseConnection(pScreen); |