Home | History | Annotate | Line # | Download | only in xaa
      1 /*
      2  *
      3  * Copyright  2000 Keith Packard, member of The XFree86 Project, Inc.
      4  *
      5  * Permission to use, copy, modify, distribute, and sell this software and its
      6  * documentation for any purpose is hereby granted without fee, provided that
      7  * the above copyright notice appear in all copies and that both that
      8  * copyright notice and this permission notice appear in supporting
      9  * documentation, and that the name of Keith Packard not be used in
     10  * advertising or publicity pertaining to distribution of the software without
     11  * specific, written prior permission.  Keith Packard makes no
     12  * representations about the suitability of this software for any purpose.  It
     13  * is provided "as is" without express or implied warranty.
     14  *
     15  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     17  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     19  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     20  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     21  * PERFORMANCE OF THIS SOFTWARE.
     22  */
     23 
     24 #ifdef HAVE_XORG_CONFIG_H
     25 #include <xorg-config.h>
     26 #endif
     27 
     28 #include <string.h>
     29 
     30 #include "misc.h"
     31 #include "xf86.h"
     32 #include "xf86_OSproc.h"
     33 
     34 #include <X11/X.h>
     35 #include "scrnintstr.h"
     36 #include "pixmapstr.h"
     37 #include "windowstr.h"
     38 #include "xf86str.h"
     39 #include "mi.h"
     40 #include "picturestr.h"
     41 #include "glyphstr.h"
     42 #include "picture.h"
     43 #include "mipict.h"
     44 #include "xaa.h"
     45 #include "xaalocal.h"
     46 #include "xaawrap.h"
     47 #include "xaacexp.h"
     48 #include "xf86fbman.h"
     49 #include "servermd.h"
     50 
     51 Bool
     52 XAAGetPixelFromRGBA (
     53     CARD32 *pixel,
     54     CARD16 red,
     55     CARD16 green,
     56     CARD16 blue,
     57     CARD16 alpha,
     58     CARD32 format
     59 ){
     60     int rbits, bbits, gbits, abits;
     61     int rshift, bshift, gshift, ashift;
     62 
     63     *pixel = 0;
     64 
     65     if(!PICT_FORMAT_COLOR(format))
     66     	return FALSE;
     67 
     68     rbits = PICT_FORMAT_R(format);
     69     gbits = PICT_FORMAT_G(format);
     70     bbits = PICT_FORMAT_B(format);
     71     abits = PICT_FORMAT_A(format);
     72 
     73     if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
     74         bshift = 0;
     75         gshift = bbits;
     76 	rshift = gshift + gbits;
     77 	ashift = rshift + rbits;
     78     } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
     79         rshift = 0;
     80 	gshift = rbits;
     81 	bshift = gshift + gbits;
     82 	ashift = bshift + bbits;
     83     } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
     84 	bshift = PICT_FORMAT_BPP(format) - bbits;
     85 	gshift = bshift - gbits;
     86 	rshift = gshift - rbits;
     87 	ashift = 0;
     88     } else
     89 	return FALSE;
     90 
     91     *pixel |=  ( blue >> (16 - bbits)) << bshift;
     92     *pixel |=  (  red >> (16 - rbits)) << rshift;
     93     *pixel |=  (green >> (16 - gbits)) << gshift;
     94     *pixel |=  (alpha >> (16 - abits)) << ashift;
     95 
     96     return TRUE;
     97 }
     98 
     99 
    100 Bool
    101 XAAGetRGBAFromPixel(
    102     CARD32 pixel,
    103     CARD16 *red,
    104     CARD16 *green,
    105     CARD16 *blue,
    106     CARD16 *alpha,
    107     CARD32 format
    108 ){
    109     int rbits, bbits, gbits, abits;
    110     int rshift, bshift, gshift, ashift;
    111 
    112     if(!PICT_FORMAT_COLOR(format))
    113     	return FALSE;
    114 
    115     rbits = PICT_FORMAT_R(format);
    116     gbits = PICT_FORMAT_G(format);
    117     bbits = PICT_FORMAT_B(format);
    118     abits = PICT_FORMAT_A(format);
    119 
    120     if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
    121         bshift = 0;
    122         gshift = bbits;
    123 	rshift = gshift + gbits;
    124 	ashift = rshift + rbits;
    125     } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
    126         rshift = 0;
    127 	gshift = rbits;
    128 	bshift = gshift + gbits;
    129 	ashift = bshift + bbits;
    130     } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
    131 	bshift = PICT_FORMAT_BPP(format) - bbits;
    132 	gshift = bshift - gbits;
    133 	rshift = gshift - rbits;
    134 	ashift = 0;
    135     } else
    136 	return FALSE;
    137 
    138     *red = ((pixel >> rshift ) & ((1 << rbits) - 1)) << (16 - rbits);
    139     while(rbits < 16) {
    140        *red |= *red >> rbits;
    141        rbits <<= 1;
    142     }
    143 
    144     *green = ((pixel >> gshift ) & ((1 << gbits) - 1)) << (16 - gbits);
    145     while(gbits < 16) {
    146        *green |= *green >> gbits;
    147        gbits <<= 1;
    148     }
    149 
    150     *blue = ((pixel >> bshift ) & ((1 << bbits) - 1)) << (16 - bbits);
    151     while(bbits < 16) {
    152        *blue |= *blue >> bbits;
    153        bbits <<= 1;
    154     }
    155 
    156     if(abits) {
    157        *alpha = ((pixel >> ashift ) & ((1 << abits) - 1)) << (16 - abits);
    158        while(abits < 16) {
    159           *alpha |= *alpha >> abits;
    160           abits <<= 1;
    161        }
    162     } else *alpha = 0xffff;
    163 
    164     return TRUE;
    165 }
    166 
    167 /* 8:8:8 + PICT_a8 -> 8:8:8:8 texture */
    168 
    169 void
    170 XAA_888_plus_PICT_a8_to_8888 (
    171     CARD32 color,
    172     CARD8  *alphaPtr,   /* in bytes */
    173     int    alphaPitch,
    174     CARD32  *dstPtr,
    175     int    dstPitch,	/* in dwords */
    176     int    width,
    177     int    height
    178 ){
    179     int x;
    180 
    181     color &= 0x00ffffff;
    182 
    183     while(height--) {
    184 	for(x = 0; x < width; x++)
    185 	   dstPtr[x] = color | (alphaPtr[x] << 24);
    186 	dstPtr += dstPitch;
    187 	alphaPtr += alphaPitch;
    188     }
    189 }
    190 
    191 #define DRAWABLE_IS_ON_CARD(pDraw) \
    192     (pDraw->type == DRAWABLE_WINDOW || \
    193      (pDraw->type == DRAWABLE_PIXMAP && IS_OFFSCREEN_PIXMAP(pDraw)))
    194 
    195 Bool
    196 XAADoComposite (
    197     CARD8      op,
    198     PicturePtr pSrc,
    199     PicturePtr pMask,
    200     PicturePtr pDst,
    201     INT16      xSrc,
    202     INT16      ySrc,
    203     INT16      xMask,
    204     INT16      yMask,
    205     INT16      xDst,
    206     INT16      yDst,
    207     CARD16     width,
    208     CARD16     height
    209 ){
    210     ScreenPtr pScreen = pDst->pDrawable->pScreen;
    211     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    212     RegionRec region;
    213     CARD32 *formats, *dstformats;
    214     int flags = 0;
    215     BoxPtr pbox;
    216     int nbox, w, h;
    217 
    218     if(!RegionNumRects(pDst->pCompositeClip))
    219         return TRUE;
    220 
    221     if(!infoRec->pScrn->vtSema || !DRAWABLE_IS_ON_CARD(pDst->pDrawable))
    222 	return FALSE;
    223 
    224     if(DRAWABLE_IS_ON_CARD(pSrc->pDrawable))
    225 	return FALSE;
    226 
    227     if (pSrc->transform || (pMask && pMask->transform))
    228 	return FALSE;
    229 
    230     if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap))
    231 	return FALSE;
    232 
    233     if ((pSrc->repeat && pSrc->repeatType != RepeatNormal) ||
    234 	(pMask && pMask->repeat && pMask->repeatType != RepeatNormal))
    235     {
    236 	return FALSE;
    237     }
    238 
    239     xDst += pDst->pDrawable->x;
    240     yDst += pDst->pDrawable->y;
    241     xSrc += pSrc->pDrawable->x;
    242     ySrc += pSrc->pDrawable->y;
    243 
    244     if(pMask) {
    245 	if(pMask->componentAlpha)
    246 	    return FALSE;
    247 
    248 	/* for now we only do it if there is a 1x1 (solid) source */
    249 
    250 	if((pSrc->pDrawable->width == 1) && (pSrc->pDrawable->height == 1)) {
    251 	   CARD16 red, green, blue, alpha;
    252            CARD32 pixel =
    253                 *((CARD32*)(((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr));
    254 
    255 	   if(!XAAGetRGBAFromPixel(pixel,&red,&green,&blue,&alpha,pSrc->format))
    256 		return FALSE;
    257 
    258 	   xMask += pMask->pDrawable->x;
    259 	   yMask += pMask->pDrawable->y;
    260 
    261 	   /* pull out color expandable operations here */
    262 	   if((pMask->format == PICT_a1) && (alpha == 0xffff) &&
    263 	       (op == PictOpOver) && infoRec->WriteBitmap && !pMask->repeat &&
    264 	       !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY) &&
    265 	       (!(infoRec->WriteBitmapFlags & RGB_EQUAL) ||
    266 	         ((red == green) && (green == blue))))
    267 	   {
    268 	        PixmapPtr pPix = (PixmapPtr)(pMask->pDrawable);
    269 		int skipleft;
    270 
    271 	  	if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
    272                                    xSrc, ySrc, xMask, yMask, xDst, yDst,
    273                                    width, height))
    274 		      return TRUE;
    275 
    276 		nbox = RegionNumRects(&region);
    277 		pbox = RegionRects(&region);
    278 
    279 	        if(!nbox)
    280 		    return TRUE;
    281 
    282 	        XAAGetPixelFromRGBA(&pixel, red, green, blue, 0, pDst->format);
    283 
    284 	   	xMask -= xDst;
    285 	   	yMask -= yDst;
    286 
    287 	   	while(nbox--) {
    288 		    skipleft = pbox->x1 + xMask;
    289 
    290 	            (*infoRec->WriteBitmap)(infoRec->pScrn,
    291 			        pbox->x1, pbox->y1,
    292 			        pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
    293 			        (unsigned char*)(pPix->devPrivate.ptr) +
    294 				  (pPix->devKind * (pbox->y1 + yMask)) +
    295 			          ((skipleft >> 3) & ~3), pPix->devKind,
    296 				skipleft & 31, pixel, -1, GXcopy, ~0);
    297 	            pbox++;
    298 	   	}
    299 
    300 		/* WriteBitmap sets the Sync flag */
    301 	        RegionUninit(&region);
    302 		return TRUE;
    303 	  }
    304 
    305 	  formats = infoRec->CPUToScreenAlphaTextureFormats;
    306 	  dstformats = infoRec->CPUToScreenAlphaTextureDstFormats;
    307 	  if(!formats || !dstformats)
    308 		return FALSE;
    309 
    310 	  w = pMask->pDrawable->width;
    311 	  h = pMask->pDrawable->height;
    312 
    313 	  if(pMask->repeat) {
    314 	      if((infoRec->CPUToScreenAlphaTextureFlags & XAA_RENDER_NO_TILE) ||
    315 		   ((infoRec->CPUToScreenAlphaTextureFlags &
    316                                    XAA_RENDER_POWER_OF_2_TILE_ONLY) &&
    317 				((h & (h - 1)) || (w & (w - 1)))))
    318 	      {
    319 		 return FALSE;
    320 	      }
    321 	      flags |= XAA_RENDER_REPEAT;
    322 	  }
    323 
    324 	  if((alpha != 0xffff) &&
    325               (infoRec->CPUToScreenAlphaTextureFlags & XAA_RENDER_NO_SRC_ALPHA))
    326 		return FALSE;
    327 
    328 	  while(*formats != pMask->format) {
    329 		if(!(*formats)) return FALSE;
    330 		formats++;
    331           }
    332 	  while(*dstformats != pDst->format) {
    333 		if(!(*dstformats))
    334 		    return FALSE;
    335 		dstformats++;
    336           }
    337 
    338 	  if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
    339                                    xSrc, ySrc, xMask, yMask, xDst, yDst,
    340                                    width, height))
    341 		return TRUE;
    342 
    343 	  nbox = RegionNumRects(&region);
    344 	  pbox = RegionRects(&region);
    345 
    346 	  if(!nbox) {
    347                 RegionUninit(&region);
    348 		return TRUE;
    349 	  }
    350 
    351 	  if(!(infoRec->SetupForCPUToScreenAlphaTexture2)(infoRec->pScrn,
    352 			op, red, green, blue, alpha, pMask->format,
    353 			pDst->format,
    354 			((PixmapPtr)(pMask->pDrawable))->devPrivate.ptr,
    355 			((PixmapPtr)(pMask->pDrawable))->devKind,
    356 			w, h, flags))
    357 	  {
    358                 RegionUninit(&region);
    359 		return FALSE;
    360 	  }
    361 
    362 	   xMask -= xDst;
    363 	   yMask -= yDst;
    364 
    365 	   while(nbox--) {
    366 	      (*infoRec->SubsequentCPUToScreenAlphaTexture)(infoRec->pScrn,
    367 			pbox->x1, pbox->y1,
    368 			pbox->x1 + xMask, pbox->y1 + yMask,
    369 			pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
    370 	      pbox++;
    371 	   }
    372 
    373 	   SET_SYNC_FLAG(infoRec);
    374 	   RegionUninit(&region);
    375 	   return TRUE;
    376 	}
    377     } else {
    378 	formats = infoRec->CPUToScreenTextureFormats;
    379 	dstformats = infoRec->CPUToScreenTextureDstFormats;
    380 	if(!formats || !dstformats)
    381 	    return FALSE;
    382 
    383         w = pSrc->pDrawable->width;
    384         h = pSrc->pDrawable->height;
    385 
    386         if(pSrc->repeat) {
    387               if((infoRec->CPUToScreenTextureFlags & XAA_RENDER_NO_TILE) ||
    388                    ((infoRec->CPUToScreenTextureFlags &
    389                                    XAA_RENDER_POWER_OF_2_TILE_ONLY) &&
    390                                 ((h & (h - 1)) || (w & (w - 1)))))
    391               {
    392                  return FALSE;
    393               }
    394               flags |= XAA_RENDER_REPEAT;
    395         }
    396 
    397 	while(*formats != pSrc->format) {
    398 	    if(!(*formats)) return FALSE;
    399 	    formats++;
    400 	}
    401 	while(*dstformats != pDst->format) {
    402 	    if(!(*dstformats))
    403 		return FALSE;
    404 	    dstformats++;
    405 	}
    406 
    407 	if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
    408                                    xSrc, ySrc, xMask, yMask, xDst, yDst,
    409                                    width, height))
    410 		return TRUE;
    411 
    412 	nbox = RegionNumRects(&region);
    413 	pbox = RegionRects(&region);
    414 
    415         if(!nbox) {
    416              RegionUninit(&region);
    417              return TRUE;
    418         }
    419 
    420 	if(!(infoRec->SetupForCPUToScreenTexture2)(infoRec->pScrn,
    421 			op, pSrc->format, pDst->format,
    422 			((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr,
    423 			((PixmapPtr)(pSrc->pDrawable))->devKind,
    424 			w, h, flags))
    425         {
    426               RegionUninit(&region);
    427               return FALSE;
    428         }
    429 
    430 
    431 	xSrc -= xDst;
    432 	ySrc -= yDst;
    433 
    434 	while(nbox--) {
    435 	    (*infoRec->SubsequentCPUToScreenTexture)(infoRec->pScrn,
    436 			pbox->x1, pbox->y1,
    437 			pbox->x1 + xSrc, pbox->y1 + ySrc,
    438 			pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
    439 	    pbox++;
    440 	 }
    441 
    442 	SET_SYNC_FLAG(infoRec);
    443 	RegionUninit(&region);
    444 	return TRUE;
    445     }
    446 
    447 
    448     return FALSE;
    449 }
    450 
    451 static void
    452 XAACompositeSrcCopy (PicturePtr pSrc,
    453 		     PicturePtr pDst,
    454 		     INT16      xSrc,
    455 		     INT16      ySrc,
    456 		     INT16      xDst,
    457 		     INT16      yDst,
    458 		     CARD16     width,
    459 		     CARD16     height)
    460 {
    461     ScreenPtr	pScreen = pDst->pDrawable->pScreen;
    462     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    463     int i, nbox;
    464     int xoff, yoff;
    465     BoxPtr pbox;
    466     DDXPointPtr pptSrc;
    467     RegionRec region;
    468 
    469     xDst += pDst->pDrawable->x;
    470     yDst += pDst->pDrawable->y;
    471     xSrc += pSrc->pDrawable->x;
    472     ySrc += pSrc->pDrawable->y;
    473 
    474     if (!miComputeCompositeRegion (&region, pSrc, NULL, pDst,
    475 				   xSrc, ySrc, 0, 0, xDst, yDst,
    476 				   width, height))
    477 	return;
    478 
    479     nbox = RegionNumRects(&region);
    480     pbox = RegionRects(&region);
    481 
    482     if(!nbox) {
    483 	RegionUninit(&region);
    484 	return;
    485     }
    486     pptSrc = malloc(sizeof(DDXPointRec) * nbox);
    487     if (!pptSrc) {
    488 	RegionUninit(&region);
    489 	return;
    490     }
    491     xoff = xSrc - xDst;
    492     yoff = ySrc - yDst;
    493     for (i = 0; i < nbox; i++) {
    494 	pptSrc[i].x = pbox[i].x1 + xoff;
    495 	pptSrc[i].y = pbox[i].y1 + yoff;
    496     }
    497 
    498     infoRec->ScratchGC.planemask = ~0L;
    499     infoRec->ScratchGC.alu = GXcopy;
    500 
    501     XAADoBitBlt(pSrc->pDrawable, pDst->pDrawable, &infoRec->ScratchGC, &region,
    502 		pptSrc);
    503 
    504     free(pptSrc);
    505     RegionUninit(&region);
    506     return;
    507 }
    508 
    509 void
    510 XAAComposite (CARD8      op,
    511 	      PicturePtr pSrc,
    512 	      PicturePtr pMask,
    513 	      PicturePtr pDst,
    514 	      INT16      xSrc,
    515 	      INT16      ySrc,
    516 	      INT16      xMask,
    517 	      INT16      yMask,
    518 	      INT16      xDst,
    519 	      INT16      yDst,
    520 	      CARD16     width,
    521 	      CARD16     height)
    522 {
    523     ScreenPtr	pScreen = pDst->pDrawable->pScreen;
    524     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    525     XAA_RENDER_PROLOGUE(pScreen, Composite);
    526 
    527     if(!pMask && infoRec->pScrn->vtSema &&
    528        infoRec->ScreenToScreenBitBlt &&
    529        pSrc->pDrawable &&
    530        DRAWABLE_IS_ON_CARD(pSrc->pDrawable) &&
    531        DRAWABLE_IS_ON_CARD(pDst->pDrawable) &&
    532        !pSrc->transform &&
    533        (!pSrc->repeat || (xSrc >= 0 && ySrc >= 0 &&
    534 			  xSrc+width<=pSrc->pDrawable->width &&
    535 			  ySrc+height<=pSrc->pDrawable->height)) &&
    536        ((op == PictOpSrc &&
    537 	 ((pSrc->format==pDst->format) ||
    538 	  (pSrc->format==PICT_a8r8g8b8 && pDst->format==PICT_x8r8g8b8) ||
    539 	  (pSrc->format==PICT_a8b8g8r8 && pDst->format==PICT_x8b8g8r8))) ||
    540 	(op == PictOpOver && !pSrc->alphaMap && !pDst->alphaMap &&
    541 	 pSrc->format==pDst->format &&
    542 	 (pSrc->format==PICT_x8r8g8b8 || pSrc->format==PICT_x8b8g8r8))))
    543     {
    544 	XAACompositeSrcCopy(pSrc, pDst, xSrc, ySrc, xDst, yDst, width, height);
    545     } else if(!pSrc->pDrawable || (pMask && !pMask->pDrawable) ||
    546               !infoRec->Composite ||
    547               !(*infoRec->Composite)(op, pSrc, pMask, pDst,
    548                                      xSrc, ySrc, xMask, yMask, xDst, yDst,
    549                                      width, height))
    550     {
    551         if(infoRec->pScrn->vtSema &&
    552            ((pSrc->pDrawable &&
    553              (pSrc->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))) ||
    554             pDst->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pDst->pDrawable))) {
    555             SYNC_CHECK(pDst->pDrawable);
    556         }
    557         (*GetPictureScreen(pScreen)->Composite) (op,
    558 		       pSrc,
    559 		       pMask,
    560 		       pDst,
    561 		       xSrc,
    562 		       ySrc,
    563 		       xMask,
    564 		       yMask,
    565 		       xDst,
    566 		       yDst,
    567 		       width,
    568 		       height);
    569     }
    570 
    571     if(pDst->pDrawable->type == DRAWABLE_PIXMAP)
    572 	(XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDst->pDrawable)))->flags |= DIRTY;
    573 
    574     XAA_RENDER_EPILOGUE(pScreen, Composite, XAAComposite);
    575 }
    576 
    577 Bool
    578 XAADoGlyphs (CARD8         op,
    579 	   PicturePtr    pSrc,
    580 	   PicturePtr    pDst,
    581 	   PictFormatPtr maskFormat,
    582 	   INT16         xSrc,
    583 	   INT16         ySrc,
    584 	   int           nlist,
    585 	   GlyphListPtr  list,
    586 	   GlyphPtr      *glyphs)
    587 {
    588     ScreenPtr	pScreen = pDst->pDrawable->pScreen;
    589     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    590 
    591     if(!RegionNumRects(pDst->pCompositeClip))
    592 	return TRUE;
    593 
    594     if(!infoRec->pScrn->vtSema ||
    595       ((pDst->pDrawable->type != DRAWABLE_WINDOW) &&
    596 	!IS_OFFSCREEN_PIXMAP(pDst->pDrawable)))
    597 	return FALSE;
    598 
    599     if((pSrc->pDrawable->type != DRAWABLE_PIXMAP) ||
    600         IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))
    601         return FALSE;
    602 
    603     /*
    604      * If it looks like we have a chance of being able to draw these
    605      * glyphs with an accelerated Composite, do that now to avoid
    606      * unneeded and costly syncs.
    607      */
    608     if(maskFormat) {
    609         if(!infoRec->CPUToScreenAlphaTextureFormats)
    610             return FALSE;
    611     } else {
    612         if(!infoRec->CPUToScreenTextureFormats)
    613             return FALSE;
    614     }
    615 
    616     miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
    617 
    618     return TRUE;
    619 }
    620 
    621 
    622 void
    623 XAAGlyphs (CARD8         op,
    624 	   PicturePtr    pSrc,
    625 	   PicturePtr    pDst,
    626 	   PictFormatPtr maskFormat,
    627 	   INT16         xSrc,
    628 	   INT16         ySrc,
    629 	   int           nlist,
    630 	   GlyphListPtr  list,
    631 	   GlyphPtr      *glyphs)
    632 {
    633     ScreenPtr	pScreen = pDst->pDrawable->pScreen;
    634     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    635     XAA_RENDER_PROLOGUE(pScreen, Glyphs);
    636 
    637     if(!pSrc->pDrawable || !infoRec->Glyphs ||
    638        !(*infoRec->Glyphs)(op, pSrc, pDst, maskFormat,
    639                            xSrc, ySrc, nlist, list, glyphs))
    640     {
    641         if(infoRec->pScrn->vtSema &&
    642            ((pSrc->pDrawable &&
    643              (pSrc->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))) ||
    644             pDst->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pDst->pDrawable))) {
    645             SYNC_CHECK(pDst->pDrawable);
    646         }
    647        (*GetPictureScreen(pScreen)->Glyphs) (op, pSrc, pDst, maskFormat,
    648 					  xSrc, ySrc, nlist, list, glyphs);
    649     }
    650 
    651     if(pDst->pDrawable->type == DRAWABLE_PIXMAP)
    652 	(XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDst->pDrawable)))->flags |= DIRTY;
    653 
    654     XAA_RENDER_EPILOGUE(pScreen, Glyphs, XAAGlyphs);
    655 }
    656