From 1c94119ae26b94a60bb2c2b33494ed43c3b8a52f Mon Sep 17 00:00:00 2001 From: marha Date: Sun, 16 May 2010 20:50:58 +0000 Subject: svn merge -r588:HEAD ^/branches/released . --- xorg-server/hw/xfree86/xaa/xaaInit.c | 1248 +++++++++++++++++----------------- 1 file changed, 624 insertions(+), 624 deletions(-) (limited to 'xorg-server/hw/xfree86/xaa/xaaInit.c') diff --git a/xorg-server/hw/xfree86/xaa/xaaInit.c b/xorg-server/hw/xfree86/xaa/xaaInit.c index 7d4583dc2..58efb6a82 100644 --- a/xorg-server/hw/xfree86/xaa/xaaInit.c +++ b/xorg-server/hw/xfree86/xaa/xaaInit.c @@ -1,624 +1,624 @@ - -#ifdef HAVE_XORG_CONFIG_H -#include -#endif - -#include "misc.h" -#include "xf86.h" -#include "xf86_OSproc.h" - -#include -#include "scrnintstr.h" -#include "pixmapstr.h" -#include "windowstr.h" -#include "xf86str.h" -#include "mi.h" -#include "miline.h" -#include "xaa.h" -#include "xaalocal.h" -#include "xaawrap.h" -#include "xf86fbman.h" -#include "servermd.h" -#ifdef COMPOSITE -#include "cw.h" -#endif - -#define MAX_PREALLOC_MEM 65536 /* MUST be >= 1024 */ - -#define MIN_OFFPIX_SIZE (320*200) - -static Bool XAACloseScreen(int i, ScreenPtr pScreen); -static void XAAGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, - unsigned int format, unsigned long planemask, - char *pdstLine); -static void XAAGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, - int *pwidth, int nspans, char *pdstStart); -static PixmapPtr XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth, - unsigned usage_hint); -static Bool XAADestroyPixmap(PixmapPtr pPixmap); -static Bool XAAEnterVT (int index, int flags); -static void XAALeaveVT (int index, int flags); -static int XAASetDGAMode(int index, int num, DGADevicePtr devRet); -static void XAAEnableDisableFBAccess (int index, Bool enable); -static Bool XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask); - -static int XAAScreenKeyIndex; -static DevPrivateKey XAAScreenKey = &XAAScreenKeyIndex; -static int XAAGCKeyIndex; -static DevPrivateKey XAAGCKey = &XAAGCKeyIndex; -static int XAAPixmapKeyIndex; -static DevPrivateKey XAAPixmapKey = &XAAPixmapKeyIndex; - -DevPrivateKey XAAGetScreenKey(void) { - return XAAScreenKey; -} - -DevPrivateKey XAAGetGCKey(void) { - return XAAGCKey; -} - -DevPrivateKey XAAGetPixmapKey(void) { - return XAAPixmapKey; -} - -/* temp kludge */ -static Bool SwitchedOut = FALSE; - -XAAInfoRecPtr -XAACreateInfoRec(void) -{ - XAAInfoRecPtr infoRec; - - infoRec = xcalloc(1, sizeof(XAAInfoRec)); - if(infoRec) - infoRec->CachePixelGranularity = -1; - - return infoRec; -} - -void -XAADestroyInfoRec(XAAInfoRecPtr infoRec) -{ - if(!infoRec) return; - - if(infoRec->ClosePixmapCache) - (*infoRec->ClosePixmapCache)(infoRec->pScrn->pScreen); - - if(infoRec->PreAllocMem) - xfree(infoRec->PreAllocMem); - - if(infoRec->PixmapCachePrivate) - xfree(infoRec->PixmapCachePrivate); - - xfree(infoRec); -} - - -Bool -XAAInit(ScreenPtr pScreen, XAAInfoRecPtr infoRec) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - XAAScreenPtr pScreenPriv; - int i; - PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); - - /* Return successfully if no acceleration wanted */ - if (!infoRec) - return TRUE; - - if (!dixRequestPrivate(XAAGCKey, sizeof(XAAGCRec))) - return FALSE; - - if (!dixRequestPrivate(XAAPixmapKey, sizeof(XAAPixmapRec))) - return FALSE; - - if (!(pScreenPriv = xalloc(sizeof(XAAScreenRec)))) - return FALSE; - - dixSetPrivate(&pScreen->devPrivates, XAAScreenKey, pScreenPriv); - - if(!xf86FBManagerRunning(pScreen)) - infoRec->Flags &= ~(PIXMAP_CACHE | OFFSCREEN_PIXMAPS); - if(!(infoRec->Flags & LINEAR_FRAMEBUFFER)) - infoRec->Flags &= ~OFFSCREEN_PIXMAPS; - - if(!infoRec->FullPlanemask) { /* for backwards compatibility */ - infoRec->FullPlanemask = (1 << pScrn->depth) - 1; - infoRec->FullPlanemasks[pScrn->depth - 1] = infoRec->FullPlanemask; - } - - for(i = 0; i < 32; i++) { - if(!infoRec->FullPlanemasks[i]) /* keep any set by caller */ - infoRec->FullPlanemasks[i] = (1 << (i+1)) - 1; - } - - if(!XAAInitAccel(pScreen, infoRec)) return FALSE; - pScreenPriv->AccelInfoRec = infoRec; - infoRec->ScratchGC.pScreen = pScreen; - - - if(!infoRec->GetImage) - infoRec->GetImage = XAAGetImage; - if(!infoRec->GetSpans) - infoRec->GetSpans = XAAGetSpans; - if(!infoRec->CopyWindow) - infoRec->CopyWindow = XAACopyWindow; - - pScreenPriv->CreateGC = pScreen->CreateGC; - pScreen->CreateGC = XAACreateGC; - pScreenPriv->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = XAACloseScreen; - pScreenPriv->GetImage = pScreen->GetImage; - pScreen->GetImage = infoRec->GetImage; - pScreenPriv->GetSpans = pScreen->GetSpans; - pScreen->GetSpans = infoRec->GetSpans; - pScreenPriv->CopyWindow = pScreen->CopyWindow; - pScreen->CopyWindow = infoRec->CopyWindow; - pScreenPriv->CreatePixmap = pScreen->CreatePixmap; - pScreen->CreatePixmap = XAACreatePixmap; - pScreenPriv->DestroyPixmap = pScreen->DestroyPixmap; - pScreen->DestroyPixmap = XAADestroyPixmap; - pScreenPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes; - pScreen->ChangeWindowAttributes = XAAChangeWindowAttributes; - - pScreenPriv->EnterVT = pScrn->EnterVT; - pScrn->EnterVT = XAAEnterVT; - pScreenPriv->LeaveVT = pScrn->LeaveVT; - pScrn->LeaveVT = XAALeaveVT; - pScreenPriv->SetDGAMode = pScrn->SetDGAMode; - pScrn->SetDGAMode = XAASetDGAMode; - pScreenPriv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess; - pScrn->EnableDisableFBAccess = XAAEnableDisableFBAccess; - - pScreenPriv->WindowExposures = pScreen->WindowExposures; - if (ps) - { - pScreenPriv->Composite = ps->Composite; - ps->Composite = XAAComposite; - pScreenPriv->Glyphs = ps->Glyphs; - ps->Glyphs = XAAGlyphs; - } - if(pScrn->overlayFlags & OVERLAY_8_32_PLANAR) - XAASetupOverlay8_32Planar(pScreen); - - infoRec->PreAllocMem = xalloc(MAX_PREALLOC_MEM); - if(infoRec->PreAllocMem) - infoRec->PreAllocSize = MAX_PREALLOC_MEM; - - if(infoRec->Flags & PIXMAP_CACHE) - xf86RegisterFreeBoxCallback(pScreen, infoRec->InitPixmapCache, - (pointer)infoRec); - - if(infoRec->Flags & MICROSOFT_ZERO_LINE_BIAS) - miSetZeroLineBias(pScreen, OCTANT1 | OCTANT2 | OCTANT3 | OCTANT4); - -#ifdef COMPOSITE - /* Initialize the composite wrapper. This needs to happen after the - * wrapping above (so it comes before us), but before all other extensions, - * so it doesn't confuse them. (particularly damage). - */ - miInitializeCompositeWrapper(pScreen); -#endif - - return TRUE; -} - - - -static Bool -XAACloseScreen (int i, ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - XAAScreenPtr pScreenPriv = - (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); - - pScrn->EnterVT = pScreenPriv->EnterVT; - pScrn->LeaveVT = pScreenPriv->LeaveVT; - pScrn->EnableDisableFBAccess = pScreenPriv->EnableDisableFBAccess; - - pScreen->CreateGC = pScreenPriv->CreateGC; - pScreen->CloseScreen = pScreenPriv->CloseScreen; - pScreen->GetImage = pScreenPriv->GetImage; - pScreen->GetSpans = pScreenPriv->GetSpans; - pScreen->CopyWindow = pScreenPriv->CopyWindow; - pScreen->WindowExposures = pScreenPriv->WindowExposures; - pScreen->CreatePixmap = pScreenPriv->CreatePixmap; - pScreen->DestroyPixmap = pScreenPriv->DestroyPixmap; - pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes; - - /* We leave it up to the client to free the XAAInfoRec */ - - xfree ((pointer) pScreenPriv); - - return (*pScreen->CloseScreen) (i, pScreen); -} - -static void -XAAGetImage ( - DrawablePtr pDraw, - int sx, int sy, int w, int h, - unsigned int format, - unsigned long planemask, - char *pdstLine -) -{ - ScreenPtr pScreen = pDraw->pScreen; - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); - ScrnInfoPtr pScrn = infoRec->pScrn; - - if(pScrn->vtSema && - ((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw))) - { - if(infoRec->ReadPixmap && (format == ZPixmap) && - ((planemask & infoRec->FullPlanemasks[pDraw->depth - 1]) == - infoRec->FullPlanemasks[pDraw->depth - 1]) && - (pDraw->bitsPerPixel == BitsPerPixel(pDraw->depth))) - { - (*infoRec->ReadPixmap)(pScrn, - sx + pDraw->x, sy + pDraw->y, w, h, - (unsigned char *)pdstLine, - PixmapBytePad(w, pDraw->depth), - pDraw->bitsPerPixel, pDraw->depth); - return; - } - SYNC_CHECK(pDraw); - } - - XAA_SCREEN_PROLOGUE (pScreen, GetImage); - (*pScreen->GetImage) (pDraw, sx, sy, w, h, format, planemask, pdstLine); - XAA_SCREEN_EPILOGUE (pScreen, GetImage, XAAGetImage); -} - -static void -XAAGetSpans ( - DrawablePtr pDraw, - int wMax, - DDXPointPtr ppt, - int *pwidth, - int nspans, - char *pdstStart -) -{ - ScreenPtr pScreen = pDraw->pScreen; - XAA_SCREEN_PROLOGUE (pScreen, GetSpans); - if(xf86Screens[pScreen->myNum]->vtSema && - ((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw))) { - SYNC_CHECK(pDraw); - } - (*pScreen->GetSpans) (pDraw, wMax, ppt, pwidth, nspans, pdstStart); - XAA_SCREEN_EPILOGUE (pScreen, GetSpans, XAAGetSpans); -} - - -static int -XAAPixmapBPP (ScreenPtr pScreen, int depth) -{ - PixmapPtr pPix; - int bpp; - DestroyPixmapProcPtr destroyPixmap; - - XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap); - pPix = (*pScreen->CreatePixmap) (pScreen, 1, 1, depth, - CREATE_PIXMAP_USAGE_SCRATCH); - XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap); - if (!pPix) - return 0; - bpp = pPix->drawable.bitsPerPixel; - destroyPixmap = pScreen->DestroyPixmap; - XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap); - (*pScreen->DestroyPixmap) (pPix); - XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, destroyPixmap); - return bpp; -} - -static void -XAAInitializeOffscreenDepths (ScreenPtr pScreen) -{ - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - int d, dep; - - infoRec->offscreenDepthsInitialized = TRUE; - infoRec->offscreenDepths = 0; - if (infoRec->Flags & OFFSCREEN_PIXMAPS) { - for (d = 0; d < pScreen->numDepths; d++) { - dep = pScreen->allowedDepths[d].depth; - if (XAAPixmapBPP (pScreen, dep) == pScrn->bitsPerPixel) - infoRec->offscreenDepths |= (1 << (dep - 1)); - } - } -} - -static PixmapPtr -XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint) -{ - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - XAAPixmapPtr pPriv; - PixmapPtr pPix = NULL; - int size = w * h; - - if (w > 32767 || h > 32767) - return NullPixmap; - - if (!infoRec->offscreenDepthsInitialized) - XAAInitializeOffscreenDepths (pScreen); - - if(pScrn->vtSema && - (usage_hint != CREATE_PIXMAP_USAGE_GLYPH_PICTURE) && - (infoRec->offscreenDepths & (1 << (depth - 1))) && - (size >= MIN_OFFPIX_SIZE) && !SwitchedOut && - (!infoRec->maxOffPixWidth || (w <= infoRec->maxOffPixWidth)) && - (!infoRec->maxOffPixHeight || (h <= infoRec->maxOffPixHeight)) ) - { - PixmapLinkPtr pLink; - PixmapPtr pScreenPix; - FBAreaPtr area; - int gran = 0; - - switch(pScrn->bitsPerPixel) { - case 24: - case 8: gran = 4; break; - case 16: gran = 2; break; - case 32: gran = 1; break; - default: break; - } - - if(BITMAP_SCANLINE_PAD == 64) - gran *= 2; - - if(!(area = xf86AllocateOffscreenArea(pScreen, w, h, gran, 0, - XAARemoveAreaCallback, NULL))) { - goto BAILOUT; - } - - if(!(pLink = xalloc(sizeof(PixmapLink)))) { - xf86FreeOffscreenArea(area); - goto BAILOUT; - } - - XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap); - pPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth, usage_hint); - XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap); - - if (!pPix) { - xfree (pLink); - xf86FreeOffscreenArea(area); - goto BAILOUT; - } - - pScreenPix = (*pScreen->GetScreenPixmap)(pScreen); - - pPriv = XAA_GET_PIXMAP_PRIVATE(pPix); - pPix->drawable.x = area->box.x1; - pPix->drawable.y = area->box.y1; - pPix->drawable.width = w; - pPix->drawable.height = h; - pPix->drawable.bitsPerPixel = pScrn->bitsPerPixel; - pPix->devKind = pScreenPix->devKind; - pPix->devPrivate.ptr = pScreenPix->devPrivate.ptr; - area->devPrivate.ptr = pPix; - - pPriv->flags = OFFSCREEN; - pPriv->offscreenArea = area; - pPriv->freeData = FALSE; - - pLink->next = infoRec->OffscreenPixmaps; - pLink->pPix = pPix; - infoRec->OffscreenPixmaps = pLink; - return pPix; - } -BAILOUT: - XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap); - pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth, usage_hint); - XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap); - - if(pPix) { - pPriv = XAA_GET_PIXMAP_PRIVATE(pPix); - pPriv->flags = 0; - pPriv->offscreenArea = NULL; - pPriv->freeData = FALSE; - if(!w || !h) /* either scratch or shared memory */ - pPriv->flags |= SHARED_PIXMAP; - } - - return pPix; -} - -static Bool -XAADestroyPixmap(PixmapPtr pPix) -{ - ScreenPtr pScreen = pPix->drawable.pScreen; - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); - XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix); - Bool ret; - - if(pPix->refcnt == 1) { - if(pPriv->flags & OFFSCREEN) { - if(pPriv->flags & DGA_PIXMAP) - xfree(pPriv->offscreenArea); - else { - FBAreaPtr area = pPriv->offscreenArea; - PixmapLinkPtr pLink = infoRec->OffscreenPixmaps; - PixmapLinkPtr prev = NULL; - - while(pLink->pPix != pPix) { - prev = pLink; - pLink = pLink->next; - } - - if(prev) prev->next = pLink->next; - else infoRec->OffscreenPixmaps = pLink->next; - - if(!area) area = pLink->area; - - xf86FreeOffscreenArea(area); - pPriv->offscreenArea = NULL; - xfree(pLink); - } - } - - if(pPriv->freeData) { /* pixmaps that were once in video ram */ - xfree(pPix->devPrivate.ptr); - pPix->devPrivate.ptr = NULL; - } - } - - XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap); - ret = (*pScreen->DestroyPixmap) (pPix); - XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, XAADestroyPixmap); - - return ret; -} - -static Bool -XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - Bool ret; - - XAA_SCREEN_PROLOGUE (pScreen, ChangeWindowAttributes); - ret = (*pScreen->ChangeWindowAttributes) (pWin, mask); - XAA_SCREEN_EPILOGUE (pScreen, ChangeWindowAttributes, XAAChangeWindowAttributes); - - /* we have to assume that shared memory pixmaps are dirty - because we can't wrap operations on them */ - - if((mask & CWBackPixmap) && (pWin->backgroundState == BackgroundPixmap) && - PIXMAP_IS_SHARED(pWin->background.pixmap)) - { - XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->background.pixmap); - pPixPriv->flags |= DIRTY; - } - if((mask & CWBorderPixmap) && !(pWin->borderIsPixel) && - PIXMAP_IS_SHARED(pWin->border.pixmap)) - { - XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->border.pixmap); - pPixPriv->flags |= DIRTY; - } - - return ret; -} - - - -/* These two aren't really needed for anything */ - -static Bool -XAAEnterVT(int index, int flags) -{ - ScreenPtr pScreen = screenInfo.screens[index]; - XAAScreenPtr pScreenPriv = - (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); - - return((*pScreenPriv->EnterVT)(index, flags)); -} - -static void -XAALeaveVT(int index, int flags) -{ - ScreenPtr pScreen = screenInfo.screens[index]; - XAAScreenPtr pScreenPriv = - (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); - XAAInfoRecPtr infoRec = pScreenPriv->AccelInfoRec; - - if(infoRec->NeedToSync) { - (*infoRec->Sync)(infoRec->pScrn); - infoRec->NeedToSync = FALSE; - } - - (*pScreenPriv->LeaveVT)(index, flags); -} - -typedef struct { - Bool UsingPixmapCache; - Bool CanDoColor8x8; - Bool CanDoMono8x8; -} SavedCacheState, *SavedCacheStatePtr; - -static int -XAASetDGAMode(int index, int num, DGADevicePtr devRet) -{ - ScreenPtr pScreen = screenInfo.screens[index]; - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); - XAAScreenPtr pScreenPriv = - (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); - int ret; - - if (!num && infoRec->dgaSaves) { /* restore old pixmap cache state */ - SavedCacheStatePtr state = (SavedCacheStatePtr)infoRec->dgaSaves; - - infoRec->UsingPixmapCache = state->UsingPixmapCache; - infoRec->CanDoColor8x8 = state->CanDoColor8x8; - infoRec->CanDoMono8x8 = state->CanDoMono8x8; - xfree(infoRec->dgaSaves); - infoRec->dgaSaves = NULL; - } - - ret = (*pScreenPriv->SetDGAMode)(index, num, devRet); - if(ret != Success) return ret; - - if(num && devRet->pPix) { /* accelerate this pixmap */ - XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(devRet->pPix); - FBAreaPtr area; - - if((area = xalloc(sizeof(FBArea)))) { - area->pScreen = pScreen; - area->box.x1 = 0; - area->box.x2 = 0; - area->box.y1 = devRet->mode->pixmapWidth; - area->box.y2 = devRet->mode->pixmapHeight; - area->granularity = 0; - area->MoveAreaCallback = 0; - area->RemoveAreaCallback = 0; - area->devPrivate.ptr = 0; - - pixPriv->flags |= OFFSCREEN | DGA_PIXMAP; - pixPriv->offscreenArea = area; - - if(!infoRec->dgaSaves) { /* save pixmap cache state */ - SavedCacheStatePtr state = xalloc(sizeof(SavedCacheState)); - - state->UsingPixmapCache = infoRec->UsingPixmapCache; - state->CanDoColor8x8 = infoRec->CanDoColor8x8; - state->CanDoMono8x8 = infoRec->CanDoMono8x8; - infoRec->dgaSaves = (char*)state; - - infoRec->UsingPixmapCache = FALSE; - if(infoRec->PixmapCacheFlags & CACHE_MONO_8x8) - infoRec->CanDoMono8x8 = FALSE; - if(infoRec->PixmapCacheFlags & CACHE_COLOR_8x8) - infoRec->CanDoColor8x8 = FALSE; - } - } - } - - return ret; -} - - - -static void -XAAEnableDisableFBAccess (int index, Bool enable) -{ - ScreenPtr pScreen = screenInfo.screens[index]; - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); - XAAScreenPtr pScreenPriv = - (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); - - if(!enable) { - if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps)) - XAAMoveOutOffscreenPixmaps(pScreen); - if(infoRec->Flags & PIXMAP_CACHE) - XAAInvalidatePixmapCache(pScreen); - SwitchedOut = TRUE; - } - - (*pScreenPriv->EnableDisableFBAccess)(index, enable); - - if(enable) { - if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps)) - XAAMoveInOffscreenPixmaps(pScreen); - SwitchedOut = FALSE; - } -} + +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#include "misc.h" +#include "xf86.h" +#include "xf86_OSproc.h" + +#include +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "xf86str.h" +#include "mi.h" +#include "miline.h" +#include "xaa.h" +#include "xaalocal.h" +#include "xaawrap.h" +#include "xf86fbman.h" +#include "servermd.h" +#ifdef COMPOSITE +#include "cw.h" +#endif + +#define MAX_PREALLOC_MEM 65536 /* MUST be >= 1024 */ + +#define MIN_OFFPIX_SIZE (320*200) + +static Bool XAACloseScreen(int i, ScreenPtr pScreen); +static void XAAGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, + unsigned int format, unsigned long planemask, + char *pdstLine); +static void XAAGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, + int *pwidth, int nspans, char *pdstStart); +static PixmapPtr XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth, + unsigned usage_hint); +static Bool XAADestroyPixmap(PixmapPtr pPixmap); +static Bool XAAEnterVT (int index, int flags); +static void XAALeaveVT (int index, int flags); +static int XAASetDGAMode(int index, int num, DGADevicePtr devRet); +static void XAAEnableDisableFBAccess (int index, Bool enable); +static Bool XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask); + +static int XAAScreenKeyIndex; +static DevPrivateKey XAAScreenKey = &XAAScreenKeyIndex; +static int XAAGCKeyIndex; +static DevPrivateKey XAAGCKey = &XAAGCKeyIndex; +static int XAAPixmapKeyIndex; +static DevPrivateKey XAAPixmapKey = &XAAPixmapKeyIndex; + +DevPrivateKey XAAGetScreenKey(void) { + return XAAScreenKey; +} + +DevPrivateKey XAAGetGCKey(void) { + return XAAGCKey; +} + +DevPrivateKey XAAGetPixmapKey(void) { + return XAAPixmapKey; +} + +/* temp kludge */ +static Bool SwitchedOut = FALSE; + +XAAInfoRecPtr +XAACreateInfoRec(void) +{ + XAAInfoRecPtr infoRec; + + infoRec = calloc(1, sizeof(XAAInfoRec)); + if(infoRec) + infoRec->CachePixelGranularity = -1; + + return infoRec; +} + +void +XAADestroyInfoRec(XAAInfoRecPtr infoRec) +{ + if(!infoRec) return; + + if(infoRec->ClosePixmapCache) + (*infoRec->ClosePixmapCache)(infoRec->pScrn->pScreen); + + if(infoRec->PreAllocMem) + free(infoRec->PreAllocMem); + + if(infoRec->PixmapCachePrivate) + free(infoRec->PixmapCachePrivate); + + free(infoRec); +} + + +Bool +XAAInit(ScreenPtr pScreen, XAAInfoRecPtr infoRec) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + XAAScreenPtr pScreenPriv; + int i; + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + + /* Return successfully if no acceleration wanted */ + if (!infoRec) + return TRUE; + + if (!dixRequestPrivate(XAAGCKey, sizeof(XAAGCRec))) + return FALSE; + + if (!dixRequestPrivate(XAAPixmapKey, sizeof(XAAPixmapRec))) + return FALSE; + + if (!(pScreenPriv = malloc(sizeof(XAAScreenRec)))) + return FALSE; + + dixSetPrivate(&pScreen->devPrivates, XAAScreenKey, pScreenPriv); + + if(!xf86FBManagerRunning(pScreen)) + infoRec->Flags &= ~(PIXMAP_CACHE | OFFSCREEN_PIXMAPS); + if(!(infoRec->Flags & LINEAR_FRAMEBUFFER)) + infoRec->Flags &= ~OFFSCREEN_PIXMAPS; + + if(!infoRec->FullPlanemask) { /* for backwards compatibility */ + infoRec->FullPlanemask = (1 << pScrn->depth) - 1; + infoRec->FullPlanemasks[pScrn->depth - 1] = infoRec->FullPlanemask; + } + + for(i = 0; i < 32; i++) { + if(!infoRec->FullPlanemasks[i]) /* keep any set by caller */ + infoRec->FullPlanemasks[i] = (1 << (i+1)) - 1; + } + + if(!XAAInitAccel(pScreen, infoRec)) return FALSE; + pScreenPriv->AccelInfoRec = infoRec; + infoRec->ScratchGC.pScreen = pScreen; + + + if(!infoRec->GetImage) + infoRec->GetImage = XAAGetImage; + if(!infoRec->GetSpans) + infoRec->GetSpans = XAAGetSpans; + if(!infoRec->CopyWindow) + infoRec->CopyWindow = XAACopyWindow; + + pScreenPriv->CreateGC = pScreen->CreateGC; + pScreen->CreateGC = XAACreateGC; + pScreenPriv->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = XAACloseScreen; + pScreenPriv->GetImage = pScreen->GetImage; + pScreen->GetImage = infoRec->GetImage; + pScreenPriv->GetSpans = pScreen->GetSpans; + pScreen->GetSpans = infoRec->GetSpans; + pScreenPriv->CopyWindow = pScreen->CopyWindow; + pScreen->CopyWindow = infoRec->CopyWindow; + pScreenPriv->CreatePixmap = pScreen->CreatePixmap; + pScreen->CreatePixmap = XAACreatePixmap; + pScreenPriv->DestroyPixmap = pScreen->DestroyPixmap; + pScreen->DestroyPixmap = XAADestroyPixmap; + pScreenPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes; + pScreen->ChangeWindowAttributes = XAAChangeWindowAttributes; + + pScreenPriv->EnterVT = pScrn->EnterVT; + pScrn->EnterVT = XAAEnterVT; + pScreenPriv->LeaveVT = pScrn->LeaveVT; + pScrn->LeaveVT = XAALeaveVT; + pScreenPriv->SetDGAMode = pScrn->SetDGAMode; + pScrn->SetDGAMode = XAASetDGAMode; + pScreenPriv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess; + pScrn->EnableDisableFBAccess = XAAEnableDisableFBAccess; + + pScreenPriv->WindowExposures = pScreen->WindowExposures; + if (ps) + { + pScreenPriv->Composite = ps->Composite; + ps->Composite = XAAComposite; + pScreenPriv->Glyphs = ps->Glyphs; + ps->Glyphs = XAAGlyphs; + } + if(pScrn->overlayFlags & OVERLAY_8_32_PLANAR) + XAASetupOverlay8_32Planar(pScreen); + + infoRec->PreAllocMem = malloc(MAX_PREALLOC_MEM); + if(infoRec->PreAllocMem) + infoRec->PreAllocSize = MAX_PREALLOC_MEM; + + if(infoRec->Flags & PIXMAP_CACHE) + xf86RegisterFreeBoxCallback(pScreen, infoRec->InitPixmapCache, + (pointer)infoRec); + + if(infoRec->Flags & MICROSOFT_ZERO_LINE_BIAS) + miSetZeroLineBias(pScreen, OCTANT1 | OCTANT2 | OCTANT3 | OCTANT4); + +#ifdef COMPOSITE + /* Initialize the composite wrapper. This needs to happen after the + * wrapping above (so it comes before us), but before all other extensions, + * so it doesn't confuse them. (particularly damage). + */ + miInitializeCompositeWrapper(pScreen); +#endif + + return TRUE; +} + + + +static Bool +XAACloseScreen (int i, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + XAAScreenPtr pScreenPriv = + (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); + + pScrn->EnterVT = pScreenPriv->EnterVT; + pScrn->LeaveVT = pScreenPriv->LeaveVT; + pScrn->EnableDisableFBAccess = pScreenPriv->EnableDisableFBAccess; + + pScreen->CreateGC = pScreenPriv->CreateGC; + pScreen->CloseScreen = pScreenPriv->CloseScreen; + pScreen->GetImage = pScreenPriv->GetImage; + pScreen->GetSpans = pScreenPriv->GetSpans; + pScreen->CopyWindow = pScreenPriv->CopyWindow; + pScreen->WindowExposures = pScreenPriv->WindowExposures; + pScreen->CreatePixmap = pScreenPriv->CreatePixmap; + pScreen->DestroyPixmap = pScreenPriv->DestroyPixmap; + pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes; + + /* We leave it up to the client to free the XAAInfoRec */ + + free((pointer) pScreenPriv); + + return (*pScreen->CloseScreen) (i, pScreen); +} + +static void +XAAGetImage ( + DrawablePtr pDraw, + int sx, int sy, int w, int h, + unsigned int format, + unsigned long planemask, + char *pdstLine +) +{ + ScreenPtr pScreen = pDraw->pScreen; + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); + ScrnInfoPtr pScrn = infoRec->pScrn; + + if(pScrn->vtSema && + ((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw))) + { + if(infoRec->ReadPixmap && (format == ZPixmap) && + ((planemask & infoRec->FullPlanemasks[pDraw->depth - 1]) == + infoRec->FullPlanemasks[pDraw->depth - 1]) && + (pDraw->bitsPerPixel == BitsPerPixel(pDraw->depth))) + { + (*infoRec->ReadPixmap)(pScrn, + sx + pDraw->x, sy + pDraw->y, w, h, + (unsigned char *)pdstLine, + PixmapBytePad(w, pDraw->depth), + pDraw->bitsPerPixel, pDraw->depth); + return; + } + SYNC_CHECK(pDraw); + } + + XAA_SCREEN_PROLOGUE (pScreen, GetImage); + (*pScreen->GetImage) (pDraw, sx, sy, w, h, format, planemask, pdstLine); + XAA_SCREEN_EPILOGUE (pScreen, GetImage, XAAGetImage); +} + +static void +XAAGetSpans ( + DrawablePtr pDraw, + int wMax, + DDXPointPtr ppt, + int *pwidth, + int nspans, + char *pdstStart +) +{ + ScreenPtr pScreen = pDraw->pScreen; + XAA_SCREEN_PROLOGUE (pScreen, GetSpans); + if(xf86Screens[pScreen->myNum]->vtSema && + ((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw))) { + SYNC_CHECK(pDraw); + } + (*pScreen->GetSpans) (pDraw, wMax, ppt, pwidth, nspans, pdstStart); + XAA_SCREEN_EPILOGUE (pScreen, GetSpans, XAAGetSpans); +} + + +static int +XAAPixmapBPP (ScreenPtr pScreen, int depth) +{ + PixmapPtr pPix; + int bpp; + DestroyPixmapProcPtr destroyPixmap; + + XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap); + pPix = (*pScreen->CreatePixmap) (pScreen, 1, 1, depth, + CREATE_PIXMAP_USAGE_SCRATCH); + XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap); + if (!pPix) + return 0; + bpp = pPix->drawable.bitsPerPixel; + destroyPixmap = pScreen->DestroyPixmap; + XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap); + (*pScreen->DestroyPixmap) (pPix); + XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, destroyPixmap); + return bpp; +} + +static void +XAAInitializeOffscreenDepths (ScreenPtr pScreen) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + int d, dep; + + infoRec->offscreenDepthsInitialized = TRUE; + infoRec->offscreenDepths = 0; + if (infoRec->Flags & OFFSCREEN_PIXMAPS) { + for (d = 0; d < pScreen->numDepths; d++) { + dep = pScreen->allowedDepths[d].depth; + if (XAAPixmapBPP (pScreen, dep) == pScrn->bitsPerPixel) + infoRec->offscreenDepths |= (1 << (dep - 1)); + } + } +} + +static PixmapPtr +XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + XAAPixmapPtr pPriv; + PixmapPtr pPix = NULL; + int size = w * h; + + if (w > 32767 || h > 32767) + return NullPixmap; + + if (!infoRec->offscreenDepthsInitialized) + XAAInitializeOffscreenDepths (pScreen); + + if(pScrn->vtSema && + (usage_hint != CREATE_PIXMAP_USAGE_GLYPH_PICTURE) && + (infoRec->offscreenDepths & (1 << (depth - 1))) && + (size >= MIN_OFFPIX_SIZE) && !SwitchedOut && + (!infoRec->maxOffPixWidth || (w <= infoRec->maxOffPixWidth)) && + (!infoRec->maxOffPixHeight || (h <= infoRec->maxOffPixHeight)) ) + { + PixmapLinkPtr pLink; + PixmapPtr pScreenPix; + FBAreaPtr area; + int gran = 0; + + switch(pScrn->bitsPerPixel) { + case 24: + case 8: gran = 4; break; + case 16: gran = 2; break; + case 32: gran = 1; break; + default: break; + } + + if(BITMAP_SCANLINE_PAD == 64) + gran *= 2; + + if(!(area = xf86AllocateOffscreenArea(pScreen, w, h, gran, 0, + XAARemoveAreaCallback, NULL))) { + goto BAILOUT; + } + + if(!(pLink = malloc(sizeof(PixmapLink)))) { + xf86FreeOffscreenArea(area); + goto BAILOUT; + } + + XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap); + pPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth, usage_hint); + XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap); + + if (!pPix) { + free(pLink); + xf86FreeOffscreenArea(area); + goto BAILOUT; + } + + pScreenPix = (*pScreen->GetScreenPixmap)(pScreen); + + pPriv = XAA_GET_PIXMAP_PRIVATE(pPix); + pPix->drawable.x = area->box.x1; + pPix->drawable.y = area->box.y1; + pPix->drawable.width = w; + pPix->drawable.height = h; + pPix->drawable.bitsPerPixel = pScrn->bitsPerPixel; + pPix->devKind = pScreenPix->devKind; + pPix->devPrivate.ptr = pScreenPix->devPrivate.ptr; + area->devPrivate.ptr = pPix; + + pPriv->flags = OFFSCREEN; + pPriv->offscreenArea = area; + pPriv->freeData = FALSE; + + pLink->next = infoRec->OffscreenPixmaps; + pLink->pPix = pPix; + infoRec->OffscreenPixmaps = pLink; + return pPix; + } +BAILOUT: + XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap); + pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth, usage_hint); + XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap); + + if(pPix) { + pPriv = XAA_GET_PIXMAP_PRIVATE(pPix); + pPriv->flags = 0; + pPriv->offscreenArea = NULL; + pPriv->freeData = FALSE; + if(!w || !h) /* either scratch or shared memory */ + pPriv->flags |= SHARED_PIXMAP; + } + + return pPix; +} + +static Bool +XAADestroyPixmap(PixmapPtr pPix) +{ + ScreenPtr pScreen = pPix->drawable.pScreen; + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); + XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix); + Bool ret; + + if(pPix->refcnt == 1) { + if(pPriv->flags & OFFSCREEN) { + if(pPriv->flags & DGA_PIXMAP) + free(pPriv->offscreenArea); + else { + FBAreaPtr area = pPriv->offscreenArea; + PixmapLinkPtr pLink = infoRec->OffscreenPixmaps; + PixmapLinkPtr prev = NULL; + + while(pLink->pPix != pPix) { + prev = pLink; + pLink = pLink->next; + } + + if(prev) prev->next = pLink->next; + else infoRec->OffscreenPixmaps = pLink->next; + + if(!area) area = pLink->area; + + xf86FreeOffscreenArea(area); + pPriv->offscreenArea = NULL; + free(pLink); + } + } + + if(pPriv->freeData) { /* pixmaps that were once in video ram */ + free(pPix->devPrivate.ptr); + pPix->devPrivate.ptr = NULL; + } + } + + XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap); + ret = (*pScreen->DestroyPixmap) (pPix); + XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, XAADestroyPixmap); + + return ret; +} + +static Bool +XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + Bool ret; + + XAA_SCREEN_PROLOGUE (pScreen, ChangeWindowAttributes); + ret = (*pScreen->ChangeWindowAttributes) (pWin, mask); + XAA_SCREEN_EPILOGUE (pScreen, ChangeWindowAttributes, XAAChangeWindowAttributes); + + /* we have to assume that shared memory pixmaps are dirty + because we can't wrap operations on them */ + + if((mask & CWBackPixmap) && (pWin->backgroundState == BackgroundPixmap) && + PIXMAP_IS_SHARED(pWin->background.pixmap)) + { + XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->background.pixmap); + pPixPriv->flags |= DIRTY; + } + if((mask & CWBorderPixmap) && !(pWin->borderIsPixel) && + PIXMAP_IS_SHARED(pWin->border.pixmap)) + { + XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->border.pixmap); + pPixPriv->flags |= DIRTY; + } + + return ret; +} + + + +/* These two aren't really needed for anything */ + +static Bool +XAAEnterVT(int index, int flags) +{ + ScreenPtr pScreen = screenInfo.screens[index]; + XAAScreenPtr pScreenPriv = + (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); + + return((*pScreenPriv->EnterVT)(index, flags)); +} + +static void +XAALeaveVT(int index, int flags) +{ + ScreenPtr pScreen = screenInfo.screens[index]; + XAAScreenPtr pScreenPriv = + (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); + XAAInfoRecPtr infoRec = pScreenPriv->AccelInfoRec; + + if(infoRec->NeedToSync) { + (*infoRec->Sync)(infoRec->pScrn); + infoRec->NeedToSync = FALSE; + } + + (*pScreenPriv->LeaveVT)(index, flags); +} + +typedef struct { + Bool UsingPixmapCache; + Bool CanDoColor8x8; + Bool CanDoMono8x8; +} SavedCacheState, *SavedCacheStatePtr; + +static int +XAASetDGAMode(int index, int num, DGADevicePtr devRet) +{ + ScreenPtr pScreen = screenInfo.screens[index]; + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); + XAAScreenPtr pScreenPriv = + (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); + int ret; + + if (!num && infoRec->dgaSaves) { /* restore old pixmap cache state */ + SavedCacheStatePtr state = (SavedCacheStatePtr)infoRec->dgaSaves; + + infoRec->UsingPixmapCache = state->UsingPixmapCache; + infoRec->CanDoColor8x8 = state->CanDoColor8x8; + infoRec->CanDoMono8x8 = state->CanDoMono8x8; + free(infoRec->dgaSaves); + infoRec->dgaSaves = NULL; + } + + ret = (*pScreenPriv->SetDGAMode)(index, num, devRet); + if(ret != Success) return ret; + + if(num && devRet->pPix) { /* accelerate this pixmap */ + XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(devRet->pPix); + FBAreaPtr area; + + if((area = malloc(sizeof(FBArea)))) { + area->pScreen = pScreen; + area->box.x1 = 0; + area->box.x2 = 0; + area->box.y1 = devRet->mode->pixmapWidth; + area->box.y2 = devRet->mode->pixmapHeight; + area->granularity = 0; + area->MoveAreaCallback = 0; + area->RemoveAreaCallback = 0; + area->devPrivate.ptr = 0; + + pixPriv->flags |= OFFSCREEN | DGA_PIXMAP; + pixPriv->offscreenArea = area; + + if(!infoRec->dgaSaves) { /* save pixmap cache state */ + SavedCacheStatePtr state = malloc(sizeof(SavedCacheState)); + + state->UsingPixmapCache = infoRec->UsingPixmapCache; + state->CanDoColor8x8 = infoRec->CanDoColor8x8; + state->CanDoMono8x8 = infoRec->CanDoMono8x8; + infoRec->dgaSaves = (char*)state; + + infoRec->UsingPixmapCache = FALSE; + if(infoRec->PixmapCacheFlags & CACHE_MONO_8x8) + infoRec->CanDoMono8x8 = FALSE; + if(infoRec->PixmapCacheFlags & CACHE_COLOR_8x8) + infoRec->CanDoColor8x8 = FALSE; + } + } + } + + return ret; +} + + + +static void +XAAEnableDisableFBAccess (int index, Bool enable) +{ + ScreenPtr pScreen = screenInfo.screens[index]; + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); + XAAScreenPtr pScreenPriv = + (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); + + if(!enable) { + if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps)) + XAAMoveOutOffscreenPixmaps(pScreen); + if(infoRec->Flags & PIXMAP_CACHE) + XAAInvalidatePixmapCache(pScreen); + SwitchedOut = TRUE; + } + + (*pScreenPriv->EnableDisableFBAccess)(index, enable); + + if(enable) { + if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps)) + XAAMoveInOffscreenPixmaps(pScreen); + SwitchedOut = FALSE; + } +} -- cgit v1.2.3