📄 i810_dri.c
字号:
* instead of destination. My origin is upside down so the ydir cases * are reversed. * * KW: can you believe that this is called even when a 2d window moves? */static voidI810DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, RegionPtr prgnSrc, CARD32 index){ ScreenPtr pScreen = pParent->drawable.pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I810Ptr pI810 = I810PTR(pScrn); BoxPtr pboxTmp, pboxNext, pboxBase; DDXPointPtr pptTmp, pptNew2; int xdir, ydir; int screenwidth = pScrn->virtualX; int screenheight = pScrn->virtualY; BoxPtr pbox = REGION_RECTS(prgnSrc); int nbox = REGION_NUM_RECTS(prgnSrc); BoxPtr pboxNew1 = 0; BoxPtr pboxNew2 = 0; DDXPointPtr pptNew1 = 0; DDXPointPtr pptSrc = &ptOldOrg; int dx = pParent->drawable.x - ptOldOrg.x; int dy = pParent->drawable.y - ptOldOrg.y; /* If the copy will overlap in Y, reverse the order */ if (dy > 0) { ydir = -1; if (nbox > 1) { /* Keep ordering in each band, reverse order of bands */ pboxNew1 = (BoxPtr) ALLOCATE_LOCAL(sizeof(BoxRec) * nbox); if (!pboxNew1) return; pptNew1 = (DDXPointPtr) ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox); if (!pptNew1) { DEALLOCATE_LOCAL(pboxNew1); return; } pboxBase = pboxNext = pbox + nbox - 1; while (pboxBase >= pbox) { while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1)) pboxNext--; pboxTmp = pboxNext + 1; pptTmp = pptSrc + (pboxTmp - pbox); while (pboxTmp <= pboxBase) { *pboxNew1++ = *pboxTmp++; *pptNew1++ = *pptTmp++; } pboxBase = pboxNext; } pboxNew1 -= nbox; pbox = pboxNew1; pptNew1 -= nbox; pptSrc = pptNew1; } } else { /* No changes required */ ydir = 1; } /* If the regions will overlap in X, reverse the order */ if (dx > 0) { xdir = -1; if (nbox > 1) { /*reverse orderof rects in each band */ pboxNew2 = (BoxPtr) ALLOCATE_LOCAL(sizeof(BoxRec) * nbox); pptNew2 = (DDXPointPtr) ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox); if (!pboxNew2 || !pptNew2) { if (pptNew2) DEALLOCATE_LOCAL(pptNew2); if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2); if (pboxNew1) { DEALLOCATE_LOCAL(pptNew1); DEALLOCATE_LOCAL(pboxNew1); } return; } pboxBase = pboxNext = pbox; while (pboxBase < pbox + nbox) { while ((pboxNext < pbox + nbox) && (pboxNext->y1 == pboxBase->y1)) pboxNext++; pboxTmp = pboxNext; pptTmp = pptSrc + (pboxTmp - pbox); while (pboxTmp != pboxBase) { *pboxNew2++ = *--pboxTmp; *pptNew2++ = *--pptTmp; } pboxBase = pboxNext; } pboxNew2 -= nbox; pbox = pboxNew2; pptNew2 -= nbox; pptSrc = pptNew2; } } else { /* No changes are needed */ xdir = 1; } /* SelectBuffer isn't really a good concept for the i810. */ I810EmitFlush(pScrn); I810SetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, -1, -1); for (; nbox--; pbox++) { int x1 = pbox->x1; int y1 = pbox->y1; int destx = x1 + dx; int desty = y1 + dy; int w = pbox->x2 - x1 + 1; int h = pbox->y2 - y1 + 1; if (destx < 0) x1 -= destx, w += destx, destx = 0; if (desty < 0) y1 -= desty, h += desty, desty = 0; if (destx + w > screenwidth) w = screenwidth - destx; if (desty + h > screenheight) h = screenheight - desty; if (w <= 0) continue; if (h <= 0) continue; if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("MoveBuffers %d,%d %dx%d dx: %d dy: %d\n", x1, y1, w, h, dx, dy); I810SelectBuffer(pScrn, I810_SELECT_BACK); I810SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); I810SelectBuffer(pScrn, I810_SELECT_DEPTH); I810SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); } I810SelectBuffer(pScrn, I810_SELECT_FRONT); I810EmitFlush(pScrn); if (pboxNew2) { DEALLOCATE_LOCAL(pptNew2); DEALLOCATE_LOCAL(pboxNew2); } if (pboxNew1) { DEALLOCATE_LOCAL(pptNew1); DEALLOCATE_LOCAL(pboxNew1); } pI810->AccelInfoRec->NeedToSync = TRUE;}/* Fullscreen hooks. The DRI fullscreen mode can probably be removed as * it adds little or nothing above the mechanism below (and isn't widely * used). */static Bool I810DRIOpenFullScreen(ScreenPtr pScreen){ return TRUE;}static Bool I810DRICloseFullScreen(ScreenPtr pScreen){ return TRUE;}/* Use the miext/shadow module to maintain a list of dirty rectangles. * These are blitted to the back buffer to keep both buffers clean * during page-flipping when the 3d application isn't fullscreen. * * Unlike most use of the shadow code, both buffers are in video memory. * * An alternative to this would be to organize for all on-screen drawing * operations to be duplicated for the two buffers. That might be * faster, but seems like a lot more work... *//* This should be done *before* XAA syncs or fires its buffer. * Otherwise will have to fire it again??? */static void I810DRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox){ I810Ptr pI810 = I810PTR(pScrn); int i; I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); unsigned int br13; int cpp=2; /* Don't want to do this when no 3d is active and pages are * right-way-round */ if (!pSAREAPriv->pf_active && pSAREAPriv->pf_current_page == 0) return; br13 = (pI810->auxPitch) | (0xcc << 16); for (i = 0 ; i < num ; i++, pbox++) { unsigned int w = min(pbox->y2, pScrn->virtualY-1) - max(pbox->y1, 0) + 1; unsigned int h = min(pbox->x2, pScrn->virtualX-1) - max(pbox->x1, 0) + 1; unsigned int dst = max(pbox->x1, 0)*cpp + (max(pbox->y1, 0)*pI810->auxPitch); BEGIN_LP_RING(6); OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4); OUT_RING(br13); OUT_RING( (h<<16) | (w*cpp) ); OUT_RING(pI810->BackBuffer.Start + dst); OUT_RING(br13 & 0xffff); OUT_RING(dst); ADVANCE_LP_RING(); }}static void I810EnablePageFlip(ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I810Ptr pI810 = I810PTR(pScrn); I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); int cpp=2; pSAREAPriv->pf_enabled = pI810->allowPageFlip; pSAREAPriv->pf_active = 0; if (pI810->allowPageFlip) { unsigned int br13 = pI810->auxPitch | (0xcc << 16); BEGIN_LP_RING(6); OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4); OUT_RING(br13); OUT_RING((pScrn->virtualY << 16) | (pScrn->virtualX*cpp)); OUT_RING(pI810->BackBuffer.Start); OUT_RING(br13 & 0xFFFF); OUT_RING(0); ADVANCE_LP_RING(); pSAREAPriv->pf_active = 1; } }static void I810DisablePageFlip(ScreenPtr pScreen){ I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); pSAREAPriv->pf_active=0;}static void I810DRITransitionSingleToMulti3d(ScreenPtr pScreen){ /* Tell the clients not to pageflip. How? * -- Field in sarea, plus bumping the window counters. * -- DRM needs to cope with Front-to-Back swapbuffers. */ I810DisablePageFlip(pScreen);}static void I810DRITransitionMultiToSingle3d(ScreenPtr pScreen){ /* Let the remaining 3d app start page flipping again */ I810EnablePageFlip(pScreen);}static void I810DRITransitionTo3d(ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I810Ptr pI810 = I810PTR(pScrn); I810EnablePageFlip(pScreen); pI810->have3DWindows = 1;}static void I810DRITransitionTo2d(ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I810Ptr pI810 = I810PTR(pScrn); I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); /* Try flipping back to the front page if necessary */ if (pSAREAPriv->pf_current_page == 1) drmCommandNone(pI810->drmSubFD, DRM_I810_FLIP); /* Shut down shadowing if we've made it back to the front page */ if (pSAREAPriv->pf_current_page == 0) { I810DisablePageFlip(pScreen); } pI810->have3DWindows = 0;}BoolI810DRILeave(ScrnInfoPtr pScrn){ I810Ptr pI810 = I810PTR(pScrn); if (pI810->directRenderingEnabled) { if (pI810->dcacheHandle != 0) if (drmAgpUnbind(pI810->drmSubFD, pI810->dcacheHandle) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); return FALSE; } if (pI810->backHandle != 0) if (drmAgpUnbind(pI810->drmSubFD, pI810->backHandle) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); return FALSE; } if (pI810->zHandle != 0) if (drmAgpUnbind(pI810->drmSubFD, pI810->zHandle) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); return FALSE; } if (pI810->sysmemHandle != 0) if (drmAgpUnbind(pI810->drmSubFD, pI810->sysmemHandle) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); return FALSE; } if (pI810->xvmcHandle != 0) if (drmAgpUnbind(pI810->drmSubFD, pI810->xvmcHandle) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); return FALSE; } if (pI810->cursorHandle != 0) if (drmAgpUnbind(pI810->drmSubFD, pI810->cursorHandle) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); return FALSE; } if (pI810->cursorARGBHandle != 0) if (drmAgpUnbind(pI810->drmSubFD, pI810->cursorARGBHandle) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); return FALSE; } if (pI810->agpAcquired == TRUE) drmAgpRelease(pI810->drmSubFD); pI810->agpAcquired = FALSE; } return TRUE;}BoolI810DRIEnter(ScrnInfoPtr pScrn){ I810Ptr pI810 = I810PTR(pScrn); if (pI810->directRenderingEnabled) { if (pI810->agpAcquired == FALSE) drmAgpAcquire(pI810->drmSubFD); pI810->agpAcquired = TRUE; if (pI810->dcacheHandle != 0) if (drmAgpBind(pI810->drmSubFD, pI810->dcacheHandle, pI810->DepthOffset) != 0) return FALSE; if (pI810->backHandle != 0) if (drmAgpBind(pI810->drmSubFD, pI810->backHandle, pI810->BackOffset) != 0) return FALSE; if (pI810->zHandle != 0) if (drmAgpBind(pI810->drmSubFD, pI810->zHandle, pI810->DepthOffset) != 0) return FALSE; if (pI810->sysmemHandle != 0) if (drmAgpBind(pI810->drmSubFD, pI810->sysmemHandle, 0) != 0) return FALSE; if (pI810->xvmcHandle != 0) if (drmAgpBind(pI810->drmSubFD, pI810->xvmcHandle, pI810->MC.Start) != 0) return FALSE; if (pI810->cursorHandle != 0) if (drmAgpBind(pI810->drmSubFD, pI810->cursorHandle, pI810->CursorStart) != 0) return FALSE; if (pI810->cursorARGBHandle != 0) if (drmAgpBind(pI810->drmSubFD, pI810->cursorARGBHandle, pI810->CursorARGBStart) != 0) return FALSE; } return TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -