Home | History | Annotate | Line # | Download | only in xaa
      1 
      2 #ifdef HAVE_XORG_CONFIG_H
      3 #include <xorg-config.h>
      4 #endif
      5 
      6 #include "misc.h"
      7 #include "xf86.h"
      8 #include "xf86_OSproc.h"
      9 
     10 #include <X11/X.h>
     11 #include "scrnintstr.h"
     12 #include "pixmapstr.h"
     13 #include "windowstr.h"
     14 #include "xf86str.h"
     15 #include "mi.h"
     16 #include "miline.h"
     17 #include "xaa.h"
     18 #include "xaalocal.h"
     19 #include "xaawrap.h"
     20 #include "xf86fbman.h"
     21 #include "servermd.h"
     22 #ifdef COMPOSITE
     23 #include "cw.h"
     24 #endif
     25 
     26 #define MAX_PREALLOC_MEM	65536	/* MUST be >= 1024 */
     27 
     28 #define MIN_OFFPIX_SIZE		(320*200)
     29 
     30 static Bool XAACloseScreen(int i, ScreenPtr pScreen);
     31 static void XAAGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
     32 			unsigned int format, unsigned long planemask,
     33 			char *pdstLine);
     34 static void XAAGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt,
     35 			int *pwidth, int nspans, char *pdstStart);
     36 static PixmapPtr XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth,
     37 				 unsigned usage_hint);
     38 static Bool XAADestroyPixmap(PixmapPtr pPixmap);
     39 static Bool XAAEnterVT (int index, int flags);
     40 static void XAALeaveVT (int index, int flags);
     41 static int  XAASetDGAMode(int index, int num, DGADevicePtr devRet);
     42 static void XAAEnableDisableFBAccess (int index, Bool enable);
     43 static Bool XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask);
     44 
     45 static DevPrivateKeyRec XAAScreenKeyRec;
     46 #define XAAScreenKey (&XAAScreenKeyRec)
     47 static DevPrivateKeyRec XAAGCKeyRec;
     48 #define XAAGCKey (&XAAGCKeyRec)
     49 static DevPrivateKeyRec XAAPixmapKeyRec;
     50 #define XAAPixmapKey (&XAAPixmapKeyRec)
     51 
     52 DevPrivateKey XAAGetScreenKey(void) {
     53     return XAAScreenKey;
     54 }
     55 
     56 DevPrivateKey XAAGetGCKey(void) {
     57     return XAAGCKey;
     58 }
     59 
     60 DevPrivateKey XAAGetPixmapKey(void) {
     61     return XAAPixmapKey;
     62 }
     63 
     64 /* temp kludge */
     65 static Bool SwitchedOut = FALSE;
     66 
     67 XAAInfoRecPtr
     68 XAACreateInfoRec(void)
     69 {
     70     XAAInfoRecPtr infoRec;
     71 
     72     infoRec = calloc(1, sizeof(XAAInfoRec));
     73     if(infoRec)
     74 	infoRec->CachePixelGranularity = -1;
     75 
     76     return infoRec;
     77 }
     78 
     79 void
     80 XAADestroyInfoRec(XAAInfoRecPtr infoRec)
     81 {
     82     if(!infoRec) return;
     83 
     84     if(infoRec->ClosePixmapCache)
     85 	(*infoRec->ClosePixmapCache)(infoRec->pScrn->pScreen);
     86 
     87     free(infoRec->PreAllocMem);
     88 
     89     free(infoRec->PixmapCachePrivate);
     90 
     91     free(infoRec);
     92 }
     93 
     94 
     95 Bool
     96 XAAInit(ScreenPtr pScreen, XAAInfoRecPtr infoRec)
     97 {
     98     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     99     XAAScreenPtr pScreenPriv;
    100     int i;
    101     PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
    102 
    103     /* Return successfully if no acceleration wanted */
    104     if (!infoRec)
    105 	return TRUE;
    106 
    107     if (!dixRegisterPrivateKey(&XAAGCKeyRec, PRIVATE_GC, sizeof(XAAGCRec)))
    108 	return FALSE;
    109 
    110     if (!dixRegisterPrivateKey(&XAAPixmapKeyRec, PRIVATE_PIXMAP, sizeof(XAAPixmapRec)))
    111 	return FALSE;
    112 
    113     if (!dixRegisterPrivateKey(&XAAScreenKeyRec, PRIVATE_SCREEN, 0))
    114 	return FALSE;
    115 
    116     if (!(pScreenPriv = malloc(sizeof(XAAScreenRec))))
    117 	return FALSE;
    118 
    119     dixSetPrivate(&pScreen->devPrivates, XAAScreenKey, pScreenPriv);
    120 
    121     if(!xf86FBManagerRunning(pScreen))
    122 	infoRec->Flags &= ~(PIXMAP_CACHE | OFFSCREEN_PIXMAPS);
    123     if(!(infoRec->Flags & LINEAR_FRAMEBUFFER))
    124 	infoRec->Flags &= ~OFFSCREEN_PIXMAPS;
    125 
    126     if(!infoRec->FullPlanemask) { /* for backwards compatibility */
    127 	infoRec->FullPlanemask =  (1 << pScrn->depth) - 1;
    128 	infoRec->FullPlanemasks[pScrn->depth - 1] = infoRec->FullPlanemask;
    129     }
    130 
    131     for(i = 0; i < 32; i++) {
    132 	if(!infoRec->FullPlanemasks[i]) /* keep any set by caller */
    133 	    infoRec->FullPlanemasks[i] = (1 << (i+1)) - 1;
    134     }
    135 
    136     if(!XAAInitAccel(pScreen, infoRec)) return FALSE;
    137     pScreenPriv->AccelInfoRec = infoRec;
    138     infoRec->ScratchGC.pScreen = pScreen;
    139 
    140 
    141     if(!infoRec->GetImage)
    142 	infoRec->GetImage = XAAGetImage;
    143     if(!infoRec->GetSpans)
    144 	infoRec->GetSpans = XAAGetSpans;
    145     if(!infoRec->CopyWindow)
    146 	infoRec->CopyWindow = XAACopyWindow;
    147 
    148     pScreenPriv->CreateGC = pScreen->CreateGC;
    149     pScreen->CreateGC = XAACreateGC;
    150     pScreenPriv->CloseScreen = pScreen->CloseScreen;
    151     pScreen->CloseScreen = XAACloseScreen;
    152     pScreenPriv->GetImage = pScreen->GetImage;
    153     pScreen->GetImage = infoRec->GetImage;
    154     pScreenPriv->GetSpans = pScreen->GetSpans;
    155     pScreen->GetSpans = infoRec->GetSpans;
    156     pScreenPriv->CopyWindow = pScreen->CopyWindow;
    157     pScreen->CopyWindow = infoRec->CopyWindow;
    158     pScreenPriv->CreatePixmap = pScreen->CreatePixmap;
    159     pScreen->CreatePixmap = XAACreatePixmap;
    160     pScreenPriv->DestroyPixmap = pScreen->DestroyPixmap;
    161     pScreen->DestroyPixmap = XAADestroyPixmap;
    162     pScreenPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
    163     pScreen->ChangeWindowAttributes = XAAChangeWindowAttributes;
    164 
    165     pScreenPriv->EnterVT = pScrn->EnterVT;
    166     pScrn->EnterVT = XAAEnterVT;
    167     pScreenPriv->LeaveVT = pScrn->LeaveVT;
    168     pScrn->LeaveVT = XAALeaveVT;
    169     pScreenPriv->SetDGAMode = pScrn->SetDGAMode;
    170     pScrn->SetDGAMode = XAASetDGAMode;
    171     pScreenPriv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess;
    172     pScrn->EnableDisableFBAccess = XAAEnableDisableFBAccess;
    173 
    174     pScreenPriv->WindowExposures = pScreen->WindowExposures;
    175     if (ps)
    176     {
    177 	pScreenPriv->Composite = ps->Composite;
    178 	ps->Composite = XAAComposite;
    179 	pScreenPriv->Glyphs = ps->Glyphs;
    180 	ps->Glyphs = XAAGlyphs;
    181     }
    182     if(pScrn->overlayFlags & OVERLAY_8_32_PLANAR)
    183         XAASetupOverlay8_32Planar(pScreen);
    184 
    185     infoRec->PreAllocMem = malloc(MAX_PREALLOC_MEM);
    186     if(infoRec->PreAllocMem)
    187     	infoRec->PreAllocSize = MAX_PREALLOC_MEM;
    188 
    189     if(infoRec->Flags & PIXMAP_CACHE)
    190 	xf86RegisterFreeBoxCallback(pScreen, infoRec->InitPixmapCache,
    191 						(pointer)infoRec);
    192 
    193     if(infoRec->Flags & MICROSOFT_ZERO_LINE_BIAS)
    194 	miSetZeroLineBias(pScreen, OCTANT1 | OCTANT2 | OCTANT3 | OCTANT4);
    195 
    196 #ifdef COMPOSITE
    197     /* Initialize the composite wrapper.  This needs to happen after the
    198      * wrapping above (so it comes before us), but before all other extensions,
    199      * so it doesn't confuse them. (particularly damage).
    200      */
    201     miInitializeCompositeWrapper(pScreen);
    202 #endif
    203 
    204     return TRUE;
    205 }
    206 
    207 
    208 
    209 static Bool
    210 XAACloseScreen (int i, ScreenPtr pScreen)
    211 {
    212     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    213     XAAScreenPtr pScreenPriv =
    214 	(XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey);
    215 
    216     pScrn->EnterVT = pScreenPriv->EnterVT;
    217     pScrn->LeaveVT = pScreenPriv->LeaveVT;
    218     pScrn->EnableDisableFBAccess = pScreenPriv->EnableDisableFBAccess;
    219 
    220     pScreen->CreateGC = pScreenPriv->CreateGC;
    221     pScreen->CloseScreen = pScreenPriv->CloseScreen;
    222     pScreen->GetImage = pScreenPriv->GetImage;
    223     pScreen->GetSpans = pScreenPriv->GetSpans;
    224     pScreen->CopyWindow = pScreenPriv->CopyWindow;
    225     pScreen->WindowExposures = pScreenPriv->WindowExposures;
    226     pScreen->CreatePixmap = pScreenPriv->CreatePixmap;
    227     pScreen->DestroyPixmap = pScreenPriv->DestroyPixmap;
    228     pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes;
    229 
    230     /* We leave it up to the client to free the XAAInfoRec */
    231 
    232     free((pointer) pScreenPriv);
    233 
    234     return (*pScreen->CloseScreen) (i, pScreen);
    235 }
    236 
    237 static void
    238 XAAGetImage (
    239     DrawablePtr pDraw,
    240     int	sx, int sy, int w, int h,
    241     unsigned int    format,
    242     unsigned long   planemask,
    243     char	    *pdstLine
    244 )
    245 {
    246     ScreenPtr pScreen = pDraw->pScreen;
    247     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    248     ScrnInfoPtr pScrn = infoRec->pScrn;
    249 
    250     if(pScrn->vtSema &&
    251 	((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw)))
    252     {
    253 	if(infoRec->ReadPixmap && (format == ZPixmap) &&
    254 	   ((planemask & infoRec->FullPlanemasks[pDraw->depth - 1]) ==
    255                            infoRec->FullPlanemasks[pDraw->depth - 1]) &&
    256 	   (pDraw->bitsPerPixel == BitsPerPixel(pDraw->depth)))
    257 	{
    258 	    (*infoRec->ReadPixmap)(pScrn,
    259 		   sx + pDraw->x, sy + pDraw->y, w, h,
    260 		   (unsigned char *)pdstLine,
    261 		   PixmapBytePad(w, pDraw->depth),
    262 		   pDraw->bitsPerPixel, pDraw->depth);
    263 	    return;
    264 	}
    265 	SYNC_CHECK(pDraw);
    266     }
    267 
    268     XAA_SCREEN_PROLOGUE (pScreen, GetImage);
    269     (*pScreen->GetImage) (pDraw, sx, sy, w, h, format, planemask, pdstLine);
    270     XAA_SCREEN_EPILOGUE (pScreen, GetImage, XAAGetImage);
    271 }
    272 
    273 static void
    274 XAAGetSpans (
    275     DrawablePtr pDraw,
    276     int		wMax,
    277     DDXPointPtr	ppt,
    278     int		*pwidth,
    279     int		nspans,
    280     char	*pdstStart
    281 )
    282 {
    283     ScreenPtr pScreen = pDraw->pScreen;
    284     XAA_SCREEN_PROLOGUE (pScreen, GetSpans);
    285     if(xf86Screens[pScreen->myNum]->vtSema &&
    286 	((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw))) {
    287 	SYNC_CHECK(pDraw);
    288     }
    289     (*pScreen->GetSpans) (pDraw, wMax, ppt, pwidth, nspans, pdstStart);
    290     XAA_SCREEN_EPILOGUE (pScreen, GetSpans, XAAGetSpans);
    291 }
    292 
    293 
    294 static int
    295 XAAPixmapBPP (ScreenPtr pScreen, int depth)
    296 {
    297     PixmapPtr	pPix;
    298     int		bpp;
    299     DestroyPixmapProcPtr    destroyPixmap;
    300 
    301     XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
    302     pPix = (*pScreen->CreatePixmap) (pScreen, 1, 1, depth,
    303 				     CREATE_PIXMAP_USAGE_SCRATCH);
    304     XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap);
    305     if (!pPix)
    306 	return 0;
    307     bpp = pPix->drawable.bitsPerPixel;
    308     destroyPixmap = pScreen->DestroyPixmap;
    309     XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap);
    310     (*pScreen->DestroyPixmap) (pPix);
    311     XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, destroyPixmap);
    312     return bpp;
    313 }
    314 
    315 static void
    316 XAAInitializeOffscreenDepths (ScreenPtr pScreen)
    317 {
    318     XAAInfoRecPtr   infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    319     ScrnInfoPtr	    pScrn = xf86Screens[pScreen->myNum];
    320     int		    d, dep;
    321 
    322     infoRec->offscreenDepthsInitialized = TRUE;
    323     infoRec->offscreenDepths = 0;
    324     if (infoRec->Flags & OFFSCREEN_PIXMAPS) {
    325 	for (d = 0; d < pScreen->numDepths; d++) {
    326 	    dep = pScreen->allowedDepths[d].depth;
    327 	    if (XAAPixmapBPP (pScreen, dep) == pScrn->bitsPerPixel)
    328 		infoRec->offscreenDepths |= (1 << (dep - 1));
    329 	}
    330     }
    331 }
    332 
    333 static PixmapPtr
    334 XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint)
    335 {
    336     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    337     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    338     XAAPixmapPtr pPriv;
    339     PixmapPtr pPix = NULL;
    340     int size = w * h;
    341 
    342     if (w > 32767 || h > 32767)
    343 	return NullPixmap;
    344 
    345     if (!infoRec->offscreenDepthsInitialized)
    346 	XAAInitializeOffscreenDepths (pScreen);
    347 
    348     if(pScrn->vtSema &&
    349 	(usage_hint != CREATE_PIXMAP_USAGE_GLYPH_PICTURE) &&
    350 	(infoRec->offscreenDepths & (1 << (depth - 1))) &&
    351 	(size >= MIN_OFFPIX_SIZE) && !SwitchedOut &&
    352 	(!infoRec->maxOffPixWidth || (w <= infoRec->maxOffPixWidth)) &&
    353 	(!infoRec->maxOffPixHeight || (h <= infoRec->maxOffPixHeight)) )
    354     {
    355         PixmapLinkPtr pLink;
    356 	PixmapPtr pScreenPix;
    357         FBAreaPtr area;
    358         int gran = 0;
    359 
    360 	switch(pScrn->bitsPerPixel) {
    361         case 24:
    362         case 8:  gran = 4;  break;
    363         case 16: gran = 2;  break;
    364         case 32: gran = 1;  break;
    365         default: break;
    366         }
    367 
    368         if(BITMAP_SCANLINE_PAD == 64)
    369            gran *= 2;
    370 
    371         if(!(area = xf86AllocateOffscreenArea(pScreen, w, h, gran, 0,
    372                                 XAARemoveAreaCallback, NULL))) {
    373 	    goto BAILOUT;
    374 	}
    375 
    376         if(!(pLink = malloc(sizeof(PixmapLink)))) {
    377             xf86FreeOffscreenArea(area);
    378 	    goto BAILOUT;
    379 	}
    380 
    381 	XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
    382 	pPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth, usage_hint);
    383 	XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap);
    384 
    385 	if (!pPix) {
    386 	    free(pLink);
    387             xf86FreeOffscreenArea(area);
    388 	    goto BAILOUT;
    389 	}
    390 
    391 	pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
    392 
    393 	pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
    394 	pPix->drawable.x = area->box.x1;
    395 	pPix->drawable.y = area->box.y1;
    396 	pPix->drawable.width = w;
    397 	pPix->drawable.height = h;
    398 	pPix->drawable.bitsPerPixel = pScrn->bitsPerPixel;
    399 	pPix->devKind = pScreenPix->devKind;
    400 	pPix->devPrivate.ptr = pScreenPix->devPrivate.ptr;
    401 	area->devPrivate.ptr = pPix;
    402 
    403 	pPriv->flags = OFFSCREEN;
    404 	pPriv->offscreenArea = area;
    405  	pPriv->freeData = FALSE;
    406 
    407 	pLink->next = infoRec->OffscreenPixmaps;
    408 	pLink->pPix = pPix;
    409 	infoRec->OffscreenPixmaps = pLink;
    410 	return pPix;
    411     }
    412 BAILOUT:
    413     XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
    414     pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth, usage_hint);
    415     XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap);
    416 
    417     if(pPix) {
    418        pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
    419        pPriv->flags = 0;
    420        pPriv->offscreenArea = NULL;
    421        pPriv->freeData = FALSE;
    422        if(!w || !h) /* either scratch or shared memory */
    423 	    pPriv->flags |= SHARED_PIXMAP;
    424     }
    425 
    426     return pPix;
    427 }
    428 
    429 static Bool
    430 XAADestroyPixmap(PixmapPtr pPix)
    431 {
    432     ScreenPtr pScreen = pPix->drawable.pScreen;
    433     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    434     XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
    435     Bool ret;
    436 
    437     if(pPix->refcnt == 1) {
    438         if(pPriv->flags & OFFSCREEN) {
    439 	    if(pPriv->flags & DGA_PIXMAP)
    440 	        free(pPriv->offscreenArea);
    441             else {
    442 	        FBAreaPtr area = pPriv->offscreenArea;
    443 		PixmapLinkPtr pLink = infoRec->OffscreenPixmaps;
    444 	        PixmapLinkPtr prev = NULL;
    445 
    446 		while(pLink->pPix != pPix) {
    447 		    prev = pLink;
    448 		    pLink = pLink->next;
    449 		}
    450 
    451 	        if(prev) prev->next = pLink->next;
    452 		else infoRec->OffscreenPixmaps = pLink->next;
    453 
    454 	        if(!area) area = pLink->area;
    455 
    456 	        xf86FreeOffscreenArea(area);
    457 	        pPriv->offscreenArea = NULL;
    458 	        free(pLink);
    459 	    }
    460         }
    461 
    462         if(pPriv->freeData) { /* pixmaps that were once in video ram */
    463 	    free(pPix->devPrivate.ptr);
    464 	    pPix->devPrivate.ptr = NULL;
    465 	}
    466     }
    467 
    468     XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap);
    469     ret = (*pScreen->DestroyPixmap) (pPix);
    470     XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, XAADestroyPixmap);
    471 
    472     return ret;
    473 }
    474 
    475 static Bool
    476 XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask)
    477 {
    478    ScreenPtr pScreen = pWin->drawable.pScreen;
    479    Bool ret;
    480 
    481    XAA_SCREEN_PROLOGUE (pScreen, ChangeWindowAttributes);
    482    ret = (*pScreen->ChangeWindowAttributes) (pWin, mask);
    483    XAA_SCREEN_EPILOGUE (pScreen, ChangeWindowAttributes, XAAChangeWindowAttributes);
    484 
    485    /* we have to assume that shared memory pixmaps are dirty
    486       because we can't wrap operations on them */
    487 
    488    if((mask & CWBackPixmap) && (pWin->backgroundState == BackgroundPixmap) &&
    489       PIXMAP_IS_SHARED(pWin->background.pixmap))
    490    {
    491         XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->background.pixmap);
    492 	pPixPriv->flags |= DIRTY;
    493    }
    494    if((mask & CWBorderPixmap) && !(pWin->borderIsPixel) &&
    495       PIXMAP_IS_SHARED(pWin->border.pixmap))
    496    {
    497         XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->border.pixmap);
    498         pPixPriv->flags |= DIRTY;
    499    }
    500 
    501    return ret;
    502 }
    503 
    504 
    505 
    506 /*  These two aren't really needed for anything */
    507 
    508 static Bool
    509 XAAEnterVT(int index, int flags)
    510 {
    511     ScrnInfoPtr pScrn = xf86Screens[index];
    512     Bool ret;
    513     ScreenPtr pScreen = screenInfo.screens[index];
    514     XAAScreenPtr pScreenPriv =
    515 	(XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey);
    516 
    517     pScrn->EnterVT = pScreenPriv->EnterVT;
    518     ret = ((*pScreenPriv->EnterVT)(index, flags));
    519     pScreenPriv->EnterVT = pScrn->EnterVT;
    520     pScrn->EnterVT = XAAEnterVT;
    521     return ret;
    522 }
    523 
    524 static void
    525 XAALeaveVT(int index, int flags)
    526 {
    527     ScrnInfoPtr pScrn = xf86Screens[index];
    528     ScreenPtr pScreen = screenInfo.screens[index];
    529     XAAScreenPtr pScreenPriv =
    530 	(XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey);
    531     XAAInfoRecPtr infoRec = pScreenPriv->AccelInfoRec;
    532 
    533     if(infoRec->NeedToSync) {
    534         (*infoRec->Sync)(infoRec->pScrn);
    535         infoRec->NeedToSync = FALSE;
    536     }
    537 
    538     pScrn->LeaveVT = pScreenPriv->LeaveVT;
    539     (*pScreenPriv->LeaveVT)(index, flags);
    540     pScreenPriv->LeaveVT = pScrn->LeaveVT;
    541     pScrn->LeaveVT = XAALeaveVT;
    542 }
    543 
    544 typedef struct {
    545    Bool UsingPixmapCache;
    546    Bool CanDoColor8x8;
    547    Bool CanDoMono8x8;
    548 } SavedCacheState, *SavedCacheStatePtr;
    549 
    550 static int
    551 XAASetDGAMode(int index, int num, DGADevicePtr devRet)
    552 {
    553     ScreenPtr pScreen = screenInfo.screens[index];
    554     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    555     XAAScreenPtr pScreenPriv =
    556 	(XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey);
    557     int ret;
    558 
    559     if (!num && infoRec->dgaSaves) { /* restore old pixmap cache state */
    560 	SavedCacheStatePtr state = (SavedCacheStatePtr)infoRec->dgaSaves;
    561 
    562 	infoRec->UsingPixmapCache = state->UsingPixmapCache;
    563 	infoRec->CanDoColor8x8 = state->CanDoColor8x8;
    564 	infoRec->CanDoMono8x8 = state->CanDoMono8x8;
    565 	free(infoRec->dgaSaves);
    566 	infoRec->dgaSaves = NULL;
    567     }
    568 
    569     ret = (*pScreenPriv->SetDGAMode)(index, num, devRet);
    570     if(ret != Success) return ret;
    571 
    572     if(num && devRet->pPix) {  /* accelerate this pixmap */
    573 	XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(devRet->pPix);
    574 	FBAreaPtr area;
    575 
    576 	if((area = malloc(sizeof(FBArea)))) {
    577 	    area->pScreen = pScreen;
    578 	    area->box.x1 = 0;
    579 	    area->box.x2 = 0;
    580 	    area->box.y1 = devRet->mode->pixmapWidth;
    581 	    area->box.y2 = devRet->mode->pixmapHeight;
    582 	    area->granularity = 0;
    583 	    area->MoveAreaCallback = 0;
    584 	    area->RemoveAreaCallback = 0;
    585 	    area->devPrivate.ptr = 0;
    586 
    587 	    pixPriv->flags |= OFFSCREEN | DGA_PIXMAP;
    588 	    pixPriv->offscreenArea = area;
    589 
    590 	    if(!infoRec->dgaSaves) { /* save pixmap cache state */
    591 		SavedCacheStatePtr state = malloc(sizeof(SavedCacheState));
    592 
    593 		state->UsingPixmapCache = infoRec->UsingPixmapCache;
    594 		state->CanDoColor8x8 = infoRec->CanDoColor8x8;
    595 		state->CanDoMono8x8 = infoRec->CanDoMono8x8;
    596 		infoRec->dgaSaves = (char*)state;
    597 
    598 		infoRec->UsingPixmapCache = FALSE;
    599 		if(infoRec->PixmapCacheFlags & CACHE_MONO_8x8)
    600 		    infoRec->CanDoMono8x8 = FALSE;
    601 		if(infoRec->PixmapCacheFlags & CACHE_COLOR_8x8)
    602 		    infoRec->CanDoColor8x8 = FALSE;
    603 	    }
    604 	}
    605     }
    606 
    607     return ret;
    608 }
    609 
    610 
    611 
    612 static void
    613 XAAEnableDisableFBAccess (int index, Bool enable)
    614 {
    615     ScreenPtr pScreen = screenInfo.screens[index];
    616     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    617     XAAScreenPtr pScreenPriv =
    618 	(XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey);
    619 
    620     if(!enable) {
    621 	if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps))
    622 	    XAAMoveOutOffscreenPixmaps(pScreen);
    623 	if(infoRec->Flags & PIXMAP_CACHE)
    624 	    XAAInvalidatePixmapCache(pScreen);
    625 	SwitchedOut = TRUE;
    626     }
    627 
    628     (*pScreenPriv->EnableDisableFBAccess)(index, enable);
    629 
    630     if(enable) {
    631 	if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps))
    632 	    XAAMoveInOffscreenPixmaps(pScreen);
    633 	SwitchedOut = FALSE;
    634     }
    635 }
    636