768 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			768 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaPict.c,v 1.18 2003/04/23 18:35:34 eich Exp $
 | 
						|
 *
 | 
						|
 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
 | 
						|
 *
 | 
						|
 * Permission to use, copy, modify, distribute, and sell this software and its
 | 
						|
 * documentation for any purpose is hereby granted without fee, provided that
 | 
						|
 * the above copyright notice appear in all copies and that both that
 | 
						|
 * copyright notice and this permission notice appear in supporting
 | 
						|
 * documentation, and that the name of Keith Packard not be used in
 | 
						|
 * advertising or publicity pertaining to distribution of the software without
 | 
						|
 * specific, written prior permission.  Keith Packard makes no
 | 
						|
 * representations about the suitability of this software for any purpose.  It
 | 
						|
 * is provided "as is" without express or implied warranty.
 | 
						|
 *
 | 
						|
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
						|
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
						|
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
						|
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 | 
						|
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 | 
						|
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
						|
 * PERFORMANCE OF THIS SOFTWARE.
 | 
						|
 */
 | 
						|
 | 
						|
#include "misc.h"
 | 
						|
#include "xf86.h"
 | 
						|
#include "xf86_ansic.h"
 | 
						|
#include "xf86_OSproc.h"
 | 
						|
 | 
						|
#include <X11/X.h>
 | 
						|
#include "scrnintstr.h"
 | 
						|
#include "pixmapstr.h"
 | 
						|
#include "windowstr.h"
 | 
						|
#include "xf86str.h"
 | 
						|
#include "mi.h"
 | 
						|
#include "picturestr.h"
 | 
						|
#include "glyphstr.h"
 | 
						|
#include "picture.h"
 | 
						|
#include "mipict.h"
 | 
						|
#include "xaa.h"
 | 
						|
#include "xaalocal.h"
 | 
						|
#include "xaawrap.h"
 | 
						|
#include "xaacexp.h"
 | 
						|
#include "xf86fbman.h"
 | 
						|
#include "servermd.h"
 | 
						|
 | 
						|
Bool
 | 
						|
XAAGetPixelFromRGBA (
 | 
						|
    CARD32 *pixel,
 | 
						|
    CARD16 red,
 | 
						|
    CARD16 green,
 | 
						|
    CARD16 blue,
 | 
						|
    CARD16 alpha,
 | 
						|
    CARD32 format
 | 
						|
){
 | 
						|
    int rbits, bbits, gbits, abits;
 | 
						|
    int rshift, bshift, gshift, ashift;
 | 
						|
 | 
						|
    *pixel = 0;
 | 
						|
 | 
						|
    if(!PICT_FORMAT_COLOR(format))
 | 
						|
    	return FALSE;
 | 
						|
	
 | 
						|
    rbits = PICT_FORMAT_R(format);
 | 
						|
    gbits = PICT_FORMAT_G(format);
 | 
						|
    bbits = PICT_FORMAT_B(format);
 | 
						|
    abits = PICT_FORMAT_A(format);
 | 
						|
    
 | 
						|
    if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
 | 
						|
        bshift = 0;
 | 
						|
        gshift = bbits;
 | 
						|
	rshift = gshift + gbits;
 | 
						|
	ashift = rshift + rbits;
 | 
						|
    } else {  /* PICT_TYPE_ABGR */
 | 
						|
        rshift = 0;
 | 
						|
	gshift = rbits;
 | 
						|
	bshift = gshift + gbits;
 | 
						|
	ashift = bshift + bbits;
 | 
						|
    }
 | 
						|
    
 | 
						|
    *pixel |=  ( blue >> (16 - bbits)) << bshift;
 | 
						|
    *pixel |=  (  red >> (16 - rbits)) << rshift;
 | 
						|
    *pixel |=  (green >> (16 - gbits)) << gshift;
 | 
						|
    *pixel |=  (alpha >> (16 - abits)) << ashift;
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
Bool
 | 
						|
XAAGetRGBAFromPixel(
 | 
						|
    CARD32 pixel,
 | 
						|
    CARD16 *red,
 | 
						|
    CARD16 *green,
 | 
						|
    CARD16 *blue,
 | 
						|
    CARD16 *alpha,
 | 
						|
    CARD32 format
 | 
						|
){
 | 
						|
    int rbits, bbits, gbits, abits;
 | 
						|
    int rshift, bshift, gshift, ashift;
 | 
						|
    
 | 
						|
    if(!PICT_FORMAT_COLOR(format))
 | 
						|
    	return FALSE;
 | 
						|
	
 | 
						|
    rbits = PICT_FORMAT_R(format);
 | 
						|
    gbits = PICT_FORMAT_G(format);
 | 
						|
    bbits = PICT_FORMAT_B(format);
 | 
						|
    abits = PICT_FORMAT_A(format);
 | 
						|
    
 | 
						|
    if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
 | 
						|
        bshift = 0;
 | 
						|
        gshift = bbits;
 | 
						|
	rshift = gshift + gbits;
 | 
						|
	ashift = rshift + rbits;
 | 
						|
    } else {  /* PICT_TYPE_ABGR */
 | 
						|
        rshift = 0;
 | 
						|
	gshift = rbits;
 | 
						|
	bshift = gshift + gbits;
 | 
						|
	ashift = bshift + bbits;
 | 
						|
    }
 | 
						|
 
 | 
						|
    *red = ((pixel >> rshift ) & ((1 << rbits) - 1)) << (16 - rbits);
 | 
						|
    while(rbits < 16) {
 | 
						|
       *red |= *red >> rbits;
 | 
						|
       rbits <<= 1;
 | 
						|
    }
 | 
						|
    
 | 
						|
    *green = ((pixel >> gshift ) & ((1 << gbits) - 1)) << (16 - gbits);
 | 
						|
    while(gbits < 16) {
 | 
						|
       *green |= *green >> gbits;
 | 
						|
       gbits <<= 1;
 | 
						|
    }
 | 
						|
        
 | 
						|
    *blue = ((pixel >> bshift ) & ((1 << bbits) - 1)) << (16 - bbits);
 | 
						|
    while(bbits < 16) {
 | 
						|
       *blue |= *blue >> bbits;
 | 
						|
       bbits <<= 1;
 | 
						|
    }  
 | 
						|
    
 | 
						|
    if(abits) {
 | 
						|
       *alpha = ((pixel >> ashift ) & ((1 << abits) - 1)) << (16 - abits);
 | 
						|
       while(abits < 16) {
 | 
						|
          *alpha |= *alpha >> abits;
 | 
						|
          abits <<= 1;
 | 
						|
       }     
 | 
						|
    } else *alpha = 0xffff;
 | 
						|
      
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/* 8:8:8 + PICT_a8 -> 8:8:8:8 texture */
 | 
						|
 | 
						|
void
 | 
						|
XAA_888_plus_PICT_a8_to_8888 (
 | 
						|
    CARD32 color,
 | 
						|
    CARD8  *alphaPtr,   /* in bytes */
 | 
						|
    int    alphaPitch,
 | 
						|
    CARD32  *dstPtr,
 | 
						|
    int    dstPitch,	/* in dwords */
 | 
						|
    int    width,
 | 
						|
    int    height
 | 
						|
){
 | 
						|
    int x;
 | 
						|
 | 
						|
    color &= 0x00ffffff;
 | 
						|
 | 
						|
    while(height--) {
 | 
						|
	for(x = 0; x < width; x++)
 | 
						|
	   dstPtr[x] = color | (alphaPtr[x] << 24);
 | 
						|
	dstPtr += dstPitch;
 | 
						|
	alphaPtr += alphaPitch;
 | 
						|
    } 
 | 
						|
}
 | 
						|
 | 
						|
#define DRAWABLE_IS_ON_CARD(pDraw) \
 | 
						|
    (pDraw->type == DRAWABLE_WINDOW || \
 | 
						|
     (pDraw->type == DRAWABLE_PIXMAP && IS_OFFSCREEN_PIXMAP(pDraw)))
 | 
						|
 | 
						|
Bool
 | 
						|
XAADoComposite (
 | 
						|
    CARD8      op,
 | 
						|
    PicturePtr pSrc,
 | 
						|
    PicturePtr pMask,
 | 
						|
    PicturePtr pDst,
 | 
						|
    INT16      xSrc,
 | 
						|
    INT16      ySrc,
 | 
						|
    INT16      xMask,
 | 
						|
    INT16      yMask,
 | 
						|
    INT16      xDst,
 | 
						|
    INT16      yDst,
 | 
						|
    CARD16     width,
 | 
						|
    CARD16     height
 | 
						|
){
 | 
						|
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
 | 
						|
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
 | 
						|
    RegionRec region;
 | 
						|
    CARD32 *formats, *dstformats;
 | 
						|
    int flags = 0;
 | 
						|
    BoxPtr pbox;
 | 
						|
    int nbox, w, h;
 | 
						|
 | 
						|
    if(!REGION_NUM_RECTS(pDst->pCompositeClip))
 | 
						|
        return TRUE;
 | 
						|
 | 
						|
    if(!infoRec->pScrn->vtSema || !DRAWABLE_IS_ON_CARD(pDst->pDrawable))
 | 
						|
	return FALSE;
 | 
						|
 | 
						|
    if(DRAWABLE_IS_ON_CARD(pSrc->pDrawable))
 | 
						|
	return FALSE;
 | 
						|
 | 
						|
    if (pSrc->transform || (pMask && pMask->transform))
 | 
						|
	return FALSE;
 | 
						|
 | 
						|
    if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap))
 | 
						|
	return FALSE;
 | 
						|
	
 | 
						|
    xDst += pDst->pDrawable->x;
 | 
						|
    yDst += pDst->pDrawable->y;
 | 
						|
    xSrc += pSrc->pDrawable->x;
 | 
						|
    ySrc += pSrc->pDrawable->y;
 | 
						|
 | 
						|
    if(pMask) {
 | 
						|
	if(pMask->componentAlpha)
 | 
						|
	    return FALSE;
 | 
						|
 
 | 
						|
	/* for now we only do it if there is a 1x1 (solid) source */
 | 
						|
 | 
						|
	if((pSrc->pDrawable->width == 1) && (pSrc->pDrawable->height == 1)) {
 | 
						|
	   CARD16 red, green, blue, alpha;
 | 
						|
           CARD32 pixel =
 | 
						|
                *((CARD32*)(((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr));
 | 
						|
 | 
						|
	   if(!XAAGetRGBAFromPixel(pixel,&red,&green,&blue,&alpha,pSrc->format))
 | 
						|
		return FALSE;
 | 
						|
 | 
						|
	   xMask += pMask->pDrawable->x;
 | 
						|
	   yMask += pMask->pDrawable->y;	
 | 
						|
		
 | 
						|
	   /* pull out color expandable operations here */
 | 
						|
	   if((pMask->format == PICT_a1) && (alpha == 0xffff) &&
 | 
						|
	       (op == PictOpOver) && infoRec->WriteBitmap && !pMask->repeat &&
 | 
						|
	       !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY) &&
 | 
						|
	       (!(infoRec->WriteBitmapFlags & RGB_EQUAL) || 
 | 
						|
	         ((red == green) && (green == blue))))
 | 
						|
	   {
 | 
						|
	        PixmapPtr pPix = (PixmapPtr)(pMask->pDrawable);
 | 
						|
		int skipleft;
 | 
						|
		        
 | 
						|
	  	if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
 | 
						|
                                   xSrc, ySrc, xMask, yMask, xDst, yDst,
 | 
						|
                                   width, height))
 | 
						|
		      return TRUE;
 | 
						|
		      
 | 
						|
	  	nbox = REGION_NUM_RECTS(®ion);
 | 
						|
	  	pbox = REGION_RECTS(®ion);   
 | 
						|
		
 | 
						|
	        if(!nbox)
 | 
						|
		    return TRUE;	
 | 
						|
		    
 | 
						|
	        XAAGetPixelFromRGBA(&pixel, red, green, blue, 0, pDst->format);
 | 
						|
		    
 | 
						|
	   	xMask -= xDst;
 | 
						|
	   	yMask -= yDst;
 | 
						|
 | 
						|
	   	while(nbox--) {
 | 
						|
		    skipleft = pbox->x1 + xMask;
 | 
						|
		    
 | 
						|
	            (*infoRec->WriteBitmap)(infoRec->pScrn,
 | 
						|
			        pbox->x1, pbox->y1, 
 | 
						|
			        pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
 | 
						|
			        (unsigned char*)(pPix->devPrivate.ptr) + 
 | 
						|
				  (pPix->devKind * (pbox->y1 + yMask)) + 
 | 
						|
			          ((skipleft >> 3) & ~3), pPix->devKind, 
 | 
						|
				skipleft & 31, pixel, -1, GXcopy, ~0);
 | 
						|
	            pbox++;
 | 
						|
	   	}
 | 
						|
				  
 | 
						|
		/* WriteBitmap sets the Sync flag */		  
 | 
						|
	        REGION_UNINIT(pScreen, ®ion);
 | 
						|
		return TRUE;
 | 
						|
	  }
 | 
						|
 | 
						|
	  formats = infoRec->CPUToScreenAlphaTextureFormats;
 | 
						|
	  dstformats = infoRec->CPUToScreenAlphaTextureDstFormats;
 | 
						|
	  if(!formats || !dstformats)
 | 
						|
		return FALSE;
 | 
						|
 | 
						|
	  w = pMask->pDrawable->width;
 | 
						|
	  h = pMask->pDrawable->height;
 | 
						|
 | 
						|
	  if(pMask->repeat) {
 | 
						|
	      if((infoRec->CPUToScreenAlphaTextureFlags & XAA_RENDER_NO_TILE) ||
 | 
						|
		   ((infoRec->CPUToScreenAlphaTextureFlags & 
 | 
						|
                                   XAA_RENDER_POWER_OF_2_TILE_ONLY) && 
 | 
						|
				((h & (h - 1)) || (w & (w - 1)))))
 | 
						|
	      {
 | 
						|
		 return FALSE;
 | 
						|
	      }
 | 
						|
	      flags |= XAA_RENDER_REPEAT;
 | 
						|
	  } 
 | 
						|
 | 
						|
	  if((alpha != 0xffff) &&
 | 
						|
              (infoRec->CPUToScreenAlphaTextureFlags & XAA_RENDER_NO_SRC_ALPHA))
 | 
						|
		return FALSE;
 | 
						|
 | 
						|
	  while(*formats != pMask->format) {
 | 
						|
		if(!(*formats)) return FALSE;
 | 
						|
		formats++;
 | 
						|
          }
 | 
						|
	  while(*dstformats != pDst->format) {
 | 
						|
		if(!(*dstformats))
 | 
						|
		    return FALSE;
 | 
						|
		dstformats++;
 | 
						|
          }
 | 
						|
 | 
						|
	  if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
 | 
						|
                                   xSrc, ySrc, xMask, yMask, xDst, yDst,
 | 
						|
                                   width, height))
 | 
						|
		return TRUE;
 | 
						|
 | 
						|
	  nbox = REGION_NUM_RECTS(®ion);
 | 
						|
	  pbox = REGION_RECTS(®ion);   
 | 
						|
	     
 | 
						|
	  if(!nbox) {
 | 
						|
                REGION_UNINIT(pScreen, ®ion);
 | 
						|
		return TRUE;
 | 
						|
	  }
 | 
						|
 | 
						|
	  if(!(infoRec->SetupForCPUToScreenAlphaTexture2)(infoRec->pScrn,
 | 
						|
			op, red, green, blue, alpha, pMask->format,
 | 
						|
			pDst->format,
 | 
						|
			((PixmapPtr)(pMask->pDrawable))->devPrivate.ptr,
 | 
						|
			((PixmapPtr)(pMask->pDrawable))->devKind, 
 | 
						|
			w, h, flags))
 | 
						|
	  {
 | 
						|
                REGION_UNINIT(pScreen, ®ion);
 | 
						|
		return FALSE;
 | 
						|
	  }
 | 
						|
 | 
						|
	   xMask -= xDst;
 | 
						|
	   yMask -= yDst;
 | 
						|
	
 | 
						|
	   while(nbox--) {
 | 
						|
	      (*infoRec->SubsequentCPUToScreenAlphaTexture)(infoRec->pScrn,
 | 
						|
			pbox->x1, pbox->y1, 
 | 
						|
			pbox->x1 + xMask, pbox->y1 + yMask,
 | 
						|
			pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
 | 
						|
	      pbox++;
 | 
						|
	   }
 | 
						|
 | 
						|
	   SET_SYNC_FLAG(infoRec);
 | 
						|
	   REGION_UNINIT(pScreen, ®ion);
 | 
						|
	   return TRUE;
 | 
						|
	}
 | 
						|
    } else {
 | 
						|
	formats = infoRec->CPUToScreenTextureFormats;
 | 
						|
	dstformats = infoRec->CPUToScreenTextureDstFormats;
 | 
						|
	if(!formats || !dstformats)
 | 
						|
	    return FALSE;
 | 
						|
 | 
						|
        w = pSrc->pDrawable->width;
 | 
						|
        h = pSrc->pDrawable->height;
 | 
						|
 | 
						|
        if(pSrc->repeat) {
 | 
						|
              if((infoRec->CPUToScreenTextureFlags & XAA_RENDER_NO_TILE) ||
 | 
						|
                   ((infoRec->CPUToScreenTextureFlags &
 | 
						|
                                   XAA_RENDER_POWER_OF_2_TILE_ONLY) &&
 | 
						|
                                ((h & (h - 1)) || (w & (w - 1)))))
 | 
						|
              {
 | 
						|
                 return FALSE;
 | 
						|
              }
 | 
						|
              flags |= XAA_RENDER_REPEAT;
 | 
						|
        }
 | 
						|
 | 
						|
	while(*formats != pSrc->format) {
 | 
						|
	    if(!(*formats)) return FALSE;
 | 
						|
	    formats++;
 | 
						|
	}
 | 
						|
	while(*dstformats != pDst->format) {
 | 
						|
	    if(!(*dstformats))
 | 
						|
		return FALSE;
 | 
						|
	    dstformats++;
 | 
						|
	}
 | 
						|
 | 
						|
	if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
 | 
						|
                                   xSrc, ySrc, xMask, yMask, xDst, yDst,
 | 
						|
                                   width, height))
 | 
						|
		return TRUE;
 | 
						|
 | 
						|
	nbox = REGION_NUM_RECTS(®ion);
 | 
						|
	pbox = REGION_RECTS(®ion);   
 | 
						|
	     
 | 
						|
        if(!nbox) {
 | 
						|
             REGION_UNINIT(pScreen, ®ion);
 | 
						|
             return TRUE;
 | 
						|
        }
 | 
						|
 | 
						|
	if(!(infoRec->SetupForCPUToScreenTexture2)(infoRec->pScrn,
 | 
						|
			op, pSrc->format, pDst->format, 
 | 
						|
			((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr,
 | 
						|
			((PixmapPtr)(pSrc->pDrawable))->devKind, 
 | 
						|
			w, h, flags))
 | 
						|
        {
 | 
						|
              REGION_UNINIT(pScreen, ®ion);
 | 
						|
              return FALSE;
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
	xSrc -= xDst;
 | 
						|
	ySrc -= yDst;
 | 
						|
	
 | 
						|
	while(nbox--) {
 | 
						|
	    (*infoRec->SubsequentCPUToScreenTexture)(infoRec->pScrn,
 | 
						|
			pbox->x1, pbox->y1, 
 | 
						|
			pbox->x1 + xSrc, pbox->y1 + ySrc,
 | 
						|
			pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
 | 
						|
	    pbox++;
 | 
						|
	 }
 | 
						|
 | 
						|
	SET_SYNC_FLAG(infoRec);
 | 
						|
	REGION_UNINIT(pScreen, ®ion);
 | 
						|
	return TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
XAACompositeSrcCopy (PicturePtr pSrc,
 | 
						|
		     PicturePtr pDst,
 | 
						|
		     INT16      xSrc,
 | 
						|
		     INT16      ySrc,
 | 
						|
		     INT16      xDst,
 | 
						|
		     INT16      yDst,
 | 
						|
		     CARD16     width,
 | 
						|
		     CARD16     height)
 | 
						|
{
 | 
						|
    ScreenPtr	pScreen = pDst->pDrawable->pScreen;
 | 
						|
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
 | 
						|
    int i, nbox;
 | 
						|
    int xoff, yoff;
 | 
						|
    BoxPtr pbox;
 | 
						|
    DDXPointPtr pptSrc;
 | 
						|
    RegionRec region;
 | 
						|
 | 
						|
    xDst += pDst->pDrawable->x;
 | 
						|
    yDst += pDst->pDrawable->y;
 | 
						|
    xSrc += pSrc->pDrawable->x;
 | 
						|
    ySrc += pSrc->pDrawable->y;
 | 
						|
 | 
						|
    if (!miComputeCompositeRegion (®ion, pSrc, NULL, pDst,
 | 
						|
				   xSrc, ySrc, 0, 0, xDst, yDst,
 | 
						|
				   width, height))
 | 
						|
	return;
 | 
						|
 | 
						|
    nbox = REGION_NUM_RECTS(®ion);
 | 
						|
    pbox = REGION_RECTS(®ion);   
 | 
						|
 | 
						|
    if(!nbox) {
 | 
						|
	REGION_UNINIT(pScreen, ®ion);
 | 
						|
	return;
 | 
						|
    }
 | 
						|
    pptSrc = ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
 | 
						|
    if (!pptSrc) {
 | 
						|
	REGION_UNINIT(pScreen, ®ion);
 | 
						|
	return;
 | 
						|
    }
 | 
						|
    xoff = xSrc - xDst;
 | 
						|
    yoff = ySrc - yDst;
 | 
						|
    for (i = 0; i < nbox; i++) {
 | 
						|
	pptSrc[i].x = pbox[i].x1 + xoff;
 | 
						|
	pptSrc[i].y = pbox[i].y1 + yoff; 
 | 
						|
    }
 | 
						|
 | 
						|
    infoRec->ScratchGC.planemask = ~0L;
 | 
						|
    infoRec->ScratchGC.alu = GXcopy;
 | 
						|
 | 
						|
    XAADoBitBlt(pSrc->pDrawable, pDst->pDrawable, &infoRec->ScratchGC, ®ion,
 | 
						|
		pptSrc);
 | 
						|
 | 
						|
    DEALLOCATE_LOCAL(pptSrc);
 | 
						|
    REGION_UNINIT(pScreen, ®ion);
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
XAAComposite (CARD8      op,
 | 
						|
	      PicturePtr pSrc,
 | 
						|
	      PicturePtr pMask,
 | 
						|
	      PicturePtr pDst,
 | 
						|
	      INT16      xSrc,
 | 
						|
	      INT16      ySrc,
 | 
						|
	      INT16      xMask,
 | 
						|
	      INT16      yMask,
 | 
						|
	      INT16      xDst,
 | 
						|
	      INT16      yDst,
 | 
						|
	      CARD16     width,
 | 
						|
	      CARD16     height)
 | 
						|
{
 | 
						|
    ScreenPtr	pScreen = pDst->pDrawable->pScreen;
 | 
						|
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
 | 
						|
    XAA_RENDER_PROLOGUE(pScreen, Composite);
 | 
						|
 | 
						|
    if((op == PictOpSrc) && !pMask && infoRec->pScrn->vtSema &&
 | 
						|
	infoRec->ScreenToScreenBitBlt &&
 | 
						|
        pSrc->pDrawable &&
 | 
						|
	DRAWABLE_IS_ON_CARD(pSrc->pDrawable) &&
 | 
						|
	DRAWABLE_IS_ON_CARD(pDst->pDrawable) &&
 | 
						|
	!pSrc->transform && !pSrc->repeat && (pSrc->format == pDst->format))
 | 
						|
    {
 | 
						|
	XAACompositeSrcCopy(pSrc, pDst, xSrc, ySrc, xDst, yDst, width, height);
 | 
						|
    } else if(!pSrc->pDrawable || (pMask && !pMask->pDrawable) ||
 | 
						|
              !infoRec->Composite ||
 | 
						|
              !(*infoRec->Composite)(op, pSrc, pMask, pDst,
 | 
						|
                                     xSrc, ySrc, xMask, yMask, xDst, yDst,
 | 
						|
                                     width, height))
 | 
						|
    {
 | 
						|
        if(infoRec->pScrn->vtSema &&
 | 
						|
           ((pSrc->pDrawable &&
 | 
						|
             (pSrc->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))) ||
 | 
						|
            pDst->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pDst->pDrawable))) {
 | 
						|
            SYNC_CHECK(pDst->pDrawable);
 | 
						|
        }
 | 
						|
        (*GetPictureScreen(pScreen)->Composite) (op,
 | 
						|
		       pSrc,
 | 
						|
		       pMask,
 | 
						|
		       pDst,
 | 
						|
		       xSrc,
 | 
						|
		       ySrc,
 | 
						|
		       xMask,
 | 
						|
		       yMask,
 | 
						|
		       xDst,
 | 
						|
		       yDst,
 | 
						|
		       width,
 | 
						|
		       height);    
 | 
						|
    }
 | 
						|
 | 
						|
    if(pDst->pDrawable->type == DRAWABLE_PIXMAP)
 | 
						|
	(XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDst->pDrawable)))->flags |= DIRTY;
 | 
						|
 | 
						|
    XAA_RENDER_EPILOGUE(pScreen, Composite, XAAComposite);
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
XAADoGlyphs (CARD8         op,
 | 
						|
	   PicturePtr    pSrc,
 | 
						|
	   PicturePtr    pDst,
 | 
						|
	   PictFormatPtr maskFormat,
 | 
						|
	   INT16         xSrc,
 | 
						|
	   INT16         ySrc,
 | 
						|
	   int           nlist,
 | 
						|
	   GlyphListPtr  list,
 | 
						|
	   GlyphPtr      *glyphs)
 | 
						|
{
 | 
						|
    ScreenPtr	pScreen = pDst->pDrawable->pScreen;
 | 
						|
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
 | 
						|
 | 
						|
    if(!REGION_NUM_RECTS(pDst->pCompositeClip))
 | 
						|
	return TRUE;
 | 
						|
 | 
						|
    if(!infoRec->pScrn->vtSema || 
 | 
						|
      ((pDst->pDrawable->type != DRAWABLE_WINDOW) &&
 | 
						|
	!IS_OFFSCREEN_PIXMAP(pDst->pDrawable)))
 | 
						|
	return FALSE;
 | 
						|
 | 
						|
    if((pSrc->pDrawable->type != DRAWABLE_PIXMAP) ||
 | 
						|
        IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))
 | 
						|
        return FALSE;
 | 
						|
 | 
						|
    if(maskFormat && (maskFormat->depth == 1) && 
 | 
						|
       (pSrc->pDrawable->width == 1) && (pSrc->pDrawable->height == 1) &&
 | 
						|
       (op == PictOpOver) && infoRec->WriteBitmap &&
 | 
						|
       !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY))
 | 
						|
    {
 | 
						|
	CARD16 red, green, blue, alpha;
 | 
						|
	CARD32 pixel =
 | 
						|
                *((CARD32*)(((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr));
 | 
						|
	CARD32 *bits, *pntr, *pnt;
 | 
						|
	int x, y, i, n, left, top, right, bottom, width, height, pitch;
 | 
						|
	int L, T, R, B, X, Y, h, w, dwords, row, column, nbox;
 | 
						|
	int leftEdge, rightEdge, topLine, botLine;
 | 
						|
	BoxPtr pbox;
 | 
						|
	GlyphPtr glyph;
 | 
						|
	
 | 
						|
	if(!XAAGetRGBAFromPixel(pixel,&red,&green,&blue,&alpha,pSrc->format))
 | 
						|
		return FALSE;
 | 
						|
 | 
						|
	if(alpha != 0xffff) return FALSE;
 | 
						|
 | 
						|
	XAAGetPixelFromRGBA(&pixel, red, green, blue, 0, pDst->format);
 | 
						|
 | 
						|
	if((infoRec->WriteBitmapFlags & RGB_EQUAL) && !((red == green) && (green == blue)))
 | 
						|
	   return FALSE;
 | 
						|
 | 
						|
	x = pDst->pDrawable->x;
 | 
						|
	y = pDst->pDrawable->y;
 | 
						|
 | 
						|
	while(nlist--) {
 | 
						|
	    x += list->xOff;
 | 
						|
	    y += list->yOff;
 | 
						|
	    left = right = X = x;
 | 
						|
	    top = bottom = Y = y;
 | 
						|
	    for(i = 0; i < list->len; i++) {
 | 
						|
		glyph = glyphs[i];
 | 
						|
 | 
						|
		L = X - glyph->info.x;
 | 
						|
		if(L < left) left = L;
 | 
						|
		R = L + glyph->info.width;
 | 
						|
		if(R > right) right = R;
 | 
						|
 | 
						|
		T = Y - glyph->info.y;
 | 
						|
		if(T < top) top = T;
 | 
						|
		B = T + glyph->info.height;
 | 
						|
		if(B > bottom) bottom = B;
 | 
						|
 | 
						|
		X += glyph->info.xOff;
 | 
						|
		Y += glyph->info.yOff;
 | 
						|
	    }
 | 
						|
 | 
						|
	    width = right - left;
 | 
						|
	    height = bottom - top;
 | 
						|
 | 
						|
	    if(width && height) {
 | 
						|
		pitch = (((width + 31) & ~31) >> 5) + 1;
 | 
						|
		pntr = (CARD32*)xalloc(sizeof(CARD32) * pitch * height);
 | 
						|
		if(!pntr) 
 | 
						|
		    return TRUE;
 | 
						|
		bzero(pntr, sizeof(CARD32) * pitch * height);
 | 
						|
		n = list->len;
 | 
						|
 | 
						|
		X = x; Y = y;
 | 
						|
		while(n--) {
 | 
						|
		    glyph = *glyphs++;
 | 
						|
		    h = glyph->info.height;
 | 
						|
		    w = glyph->info.width;
 | 
						|
		    if(h && w) {
 | 
						|
			row = y - top - glyph->info.y;
 | 
						|
			column = x - left - glyph->info.x;
 | 
						|
			pnt = pntr + (row * pitch) + (column >> 5);
 | 
						|
			column &= 31;
 | 
						|
			dwords = ((w + 31) >> 5) - 1;
 | 
						|
			bits = (CARD32*)(glyph + 1);
 | 
						|
			if(dwords) {
 | 
						|
			  while(h--) {
 | 
						|
			    for(i = 0; i <= dwords; i++) {
 | 
						|
				if(column) {
 | 
						|
				    pnt[i] |= SHIFT_L(*bits, column);
 | 
						|
				    pnt[i + 1] |= SHIFT_R(*bits, 32 - column);
 | 
						|
				} else
 | 
						|
				    pnt[i] |= *bits;
 | 
						|
 | 
						|
				if(i != dwords) bits++;
 | 
						|
			    }
 | 
						|
			    bits++;
 | 
						|
			    pnt += pitch;
 | 
						|
			  } 
 | 
						|
			} else {
 | 
						|
			  if(column) {
 | 
						|
			     while(h--) {
 | 
						|
				pnt[0] |= SHIFT_L(*bits, column);
 | 
						|
				pnt[0 + 1] |= SHIFT_R(*bits, 32 - column);
 | 
						|
				bits++;
 | 
						|
				pnt += pitch;
 | 
						|
			     }
 | 
						|
			  } else {
 | 
						|
			     while(h--) {
 | 
						|
				*pnt |= *bits++;
 | 
						|
				pnt += pitch;
 | 
						|
			     }			  
 | 
						|
			  }	  
 | 
						|
			}
 | 
						|
		    }
 | 
						|
		    x += glyph->info.xOff;
 | 
						|
		    y += glyph->info.yOff;
 | 
						|
		}
 | 
						|
		
 | 
						|
		nbox = REGION_NUM_RECTS(pDst->pCompositeClip);
 | 
						|
		pbox = REGION_RECTS(pDst->pCompositeClip);
 | 
						|
		
 | 
						|
		while(nbox && (top >= pbox->y2)) {
 | 
						|
		    pbox++; nbox--;
 | 
						|
		}
 | 
						|
		
 | 
						|
		while(nbox && (bottom > pbox->y1)) {		
 | 
						|
		    leftEdge = max(left, pbox->x1);
 | 
						|
		    rightEdge = min(right, pbox->x2);
 | 
						|
		    
 | 
						|
		    if(rightEdge > leftEdge) {
 | 
						|
		    	column = leftEdge - left;
 | 
						|
			topLine = max(top, pbox->y1);
 | 
						|
			botLine = min(bottom, pbox->y2);
 | 
						|
			h = botLine - topLine;
 | 
						|
			
 | 
						|
			if(h > 0) {
 | 
						|
			  (*infoRec->WriteBitmap)(infoRec->pScrn, 
 | 
						|
			  	leftEdge, topLine, rightEdge - leftEdge, h,
 | 
						|
				(unsigned char*)(pntr + 
 | 
						|
				  ((topLine - top) * pitch) + (column >> 5)),
 | 
						|
				pitch << 2, column & 31, pixel, -1, GXcopy, ~0);
 | 
						|
			}
 | 
						|
		    }	
 | 
						|
		    nbox--; pbox++;
 | 
						|
	   	}
 | 
						|
		xfree(pntr);
 | 
						|
	    } else {
 | 
						|
		x = X; y = Y;
 | 
						|
	    }
 | 
						|
	    list++;
 | 
						|
	}
 | 
						|
 | 
						|
	return TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
     * If it looks like we have a chance of being able to draw these
 | 
						|
     * glyphs with an accelerated Composite, do that now to avoid
 | 
						|
     * unneeded and costly syncs.
 | 
						|
     */
 | 
						|
    if(maskFormat) {
 | 
						|
        if(!infoRec->CPUToScreenAlphaTextureFormats)
 | 
						|
            return FALSE;
 | 
						|
    } else {
 | 
						|
        if(!infoRec->CPUToScreenTextureFormats)
 | 
						|
            return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}	   
 | 
						|
	 
 | 
						|
	
 | 
						|
void
 | 
						|
XAAGlyphs (CARD8         op,
 | 
						|
	   PicturePtr    pSrc,
 | 
						|
	   PicturePtr    pDst,
 | 
						|
	   PictFormatPtr maskFormat,
 | 
						|
	   INT16         xSrc,
 | 
						|
	   INT16         ySrc,
 | 
						|
	   int           nlist,
 | 
						|
	   GlyphListPtr  list,
 | 
						|
	   GlyphPtr      *glyphs)
 | 
						|
{
 | 
						|
    ScreenPtr	pScreen = pDst->pDrawable->pScreen;
 | 
						|
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
 | 
						|
    XAA_RENDER_PROLOGUE(pScreen, Glyphs);
 | 
						|
 | 
						|
    if(!pSrc->pDrawable || !infoRec->Glyphs ||
 | 
						|
       !(*infoRec->Glyphs)(op, pSrc, pDst, maskFormat,
 | 
						|
                           xSrc, ySrc, nlist, list, glyphs))
 | 
						|
    {
 | 
						|
        if(infoRec->pScrn->vtSema &&
 | 
						|
           ((pSrc->pDrawable &&
 | 
						|
             (pSrc->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))) ||
 | 
						|
            pDst->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pDst->pDrawable))) {
 | 
						|
            SYNC_CHECK(pDst->pDrawable);
 | 
						|
        }
 | 
						|
       (*GetPictureScreen(pScreen)->Glyphs) (op, pSrc, pDst, maskFormat,
 | 
						|
					  xSrc, ySrc, nlist, list, glyphs);
 | 
						|
    }
 | 
						|
 | 
						|
    if(pDst->pDrawable->type == DRAWABLE_PIXMAP)
 | 
						|
	(XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDst->pDrawable)))->flags |= DIRTY;
 | 
						|
 | 
						|
    XAA_RENDER_EPILOGUE(pScreen, Glyphs, XAAGlyphs);
 | 
						|
}
 |