1706f2543Smrg/* 2706f2543Smrg * 3706f2543Smrg * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. 4706f2543Smrg * 5706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its 6706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that 7706f2543Smrg * the above copyright notice appear in all copies and that both that 8706f2543Smrg * copyright notice and this permission notice appear in supporting 9706f2543Smrg * documentation, and that the name of Keith Packard not be used in 10706f2543Smrg * advertising or publicity pertaining to distribution of the software without 11706f2543Smrg * specific, written prior permission. Keith Packard makes no 12706f2543Smrg * representations about the suitability of this software for any purpose. It 13706f2543Smrg * is provided "as is" without express or implied warranty. 14706f2543Smrg * 15706f2543Smrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17706f2543Smrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21706f2543Smrg * PERFORMANCE OF THIS SOFTWARE. 22706f2543Smrg */ 23706f2543Smrg 24706f2543Smrg#ifdef HAVE_XORG_CONFIG_H 25706f2543Smrg#include <xorg-config.h> 26706f2543Smrg#endif 27706f2543Smrg 28706f2543Smrg#include <string.h> 29706f2543Smrg 30706f2543Smrg#include "misc.h" 31706f2543Smrg#include "xf86.h" 32706f2543Smrg#include "xf86_OSproc.h" 33706f2543Smrg 34706f2543Smrg#include <X11/X.h> 35706f2543Smrg#include "scrnintstr.h" 36706f2543Smrg#include "pixmapstr.h" 37706f2543Smrg#include "windowstr.h" 38706f2543Smrg#include "xf86str.h" 39706f2543Smrg#include "mi.h" 40706f2543Smrg#include "picturestr.h" 41706f2543Smrg#include "glyphstr.h" 42706f2543Smrg#include "picture.h" 43706f2543Smrg#include "mipict.h" 44706f2543Smrg#include "xaa.h" 45706f2543Smrg#include "xaalocal.h" 46706f2543Smrg#include "xaawrap.h" 47706f2543Smrg#include "xaacexp.h" 48706f2543Smrg#include "xf86fbman.h" 49706f2543Smrg#include "servermd.h" 50706f2543Smrg 51706f2543SmrgBool 52706f2543SmrgXAAGetPixelFromRGBA ( 53706f2543Smrg CARD32 *pixel, 54706f2543Smrg CARD16 red, 55706f2543Smrg CARD16 green, 56706f2543Smrg CARD16 blue, 57706f2543Smrg CARD16 alpha, 58706f2543Smrg CARD32 format 59706f2543Smrg){ 60706f2543Smrg int rbits, bbits, gbits, abits; 61706f2543Smrg int rshift, bshift, gshift, ashift; 62706f2543Smrg 63706f2543Smrg *pixel = 0; 64706f2543Smrg 65706f2543Smrg if(!PICT_FORMAT_COLOR(format)) 66706f2543Smrg return FALSE; 67706f2543Smrg 68706f2543Smrg rbits = PICT_FORMAT_R(format); 69706f2543Smrg gbits = PICT_FORMAT_G(format); 70706f2543Smrg bbits = PICT_FORMAT_B(format); 71706f2543Smrg abits = PICT_FORMAT_A(format); 72706f2543Smrg 73706f2543Smrg if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) { 74706f2543Smrg bshift = 0; 75706f2543Smrg gshift = bbits; 76706f2543Smrg rshift = gshift + gbits; 77706f2543Smrg ashift = rshift + rbits; 78706f2543Smrg } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) { 79706f2543Smrg rshift = 0; 80706f2543Smrg gshift = rbits; 81706f2543Smrg bshift = gshift + gbits; 82706f2543Smrg ashift = bshift + bbits; 83706f2543Smrg } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) { 84706f2543Smrg bshift = PICT_FORMAT_BPP(format) - bbits; 85706f2543Smrg gshift = bshift - gbits; 86706f2543Smrg rshift = gshift - rbits; 87706f2543Smrg ashift = 0; 88706f2543Smrg } else 89706f2543Smrg return FALSE; 90706f2543Smrg 91706f2543Smrg *pixel |= ( blue >> (16 - bbits)) << bshift; 92706f2543Smrg *pixel |= ( red >> (16 - rbits)) << rshift; 93706f2543Smrg *pixel |= (green >> (16 - gbits)) << gshift; 94706f2543Smrg *pixel |= (alpha >> (16 - abits)) << ashift; 95706f2543Smrg 96706f2543Smrg return TRUE; 97706f2543Smrg} 98706f2543Smrg 99706f2543Smrg 100706f2543SmrgBool 101706f2543SmrgXAAGetRGBAFromPixel( 102706f2543Smrg CARD32 pixel, 103706f2543Smrg CARD16 *red, 104706f2543Smrg CARD16 *green, 105706f2543Smrg CARD16 *blue, 106706f2543Smrg CARD16 *alpha, 107706f2543Smrg CARD32 format 108706f2543Smrg){ 109706f2543Smrg int rbits, bbits, gbits, abits; 110706f2543Smrg int rshift, bshift, gshift, ashift; 111706f2543Smrg 112706f2543Smrg if(!PICT_FORMAT_COLOR(format)) 113706f2543Smrg return FALSE; 114706f2543Smrg 115706f2543Smrg rbits = PICT_FORMAT_R(format); 116706f2543Smrg gbits = PICT_FORMAT_G(format); 117706f2543Smrg bbits = PICT_FORMAT_B(format); 118706f2543Smrg abits = PICT_FORMAT_A(format); 119706f2543Smrg 120706f2543Smrg if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) { 121706f2543Smrg bshift = 0; 122706f2543Smrg gshift = bbits; 123706f2543Smrg rshift = gshift + gbits; 124706f2543Smrg ashift = rshift + rbits; 125706f2543Smrg } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) { 126706f2543Smrg rshift = 0; 127706f2543Smrg gshift = rbits; 128706f2543Smrg bshift = gshift + gbits; 129706f2543Smrg ashift = bshift + bbits; 130706f2543Smrg } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) { 131706f2543Smrg bshift = PICT_FORMAT_BPP(format) - bbits; 132706f2543Smrg gshift = bshift - gbits; 133706f2543Smrg rshift = gshift - rbits; 134706f2543Smrg ashift = 0; 135706f2543Smrg } else 136706f2543Smrg return FALSE; 137706f2543Smrg 138706f2543Smrg *red = ((pixel >> rshift ) & ((1 << rbits) - 1)) << (16 - rbits); 139706f2543Smrg while(rbits < 16) { 140706f2543Smrg *red |= *red >> rbits; 141706f2543Smrg rbits <<= 1; 142706f2543Smrg } 143706f2543Smrg 144706f2543Smrg *green = ((pixel >> gshift ) & ((1 << gbits) - 1)) << (16 - gbits); 145706f2543Smrg while(gbits < 16) { 146706f2543Smrg *green |= *green >> gbits; 147706f2543Smrg gbits <<= 1; 148706f2543Smrg } 149706f2543Smrg 150706f2543Smrg *blue = ((pixel >> bshift ) & ((1 << bbits) - 1)) << (16 - bbits); 151706f2543Smrg while(bbits < 16) { 152706f2543Smrg *blue |= *blue >> bbits; 153706f2543Smrg bbits <<= 1; 154706f2543Smrg } 155706f2543Smrg 156706f2543Smrg if(abits) { 157706f2543Smrg *alpha = ((pixel >> ashift ) & ((1 << abits) - 1)) << (16 - abits); 158706f2543Smrg while(abits < 16) { 159706f2543Smrg *alpha |= *alpha >> abits; 160706f2543Smrg abits <<= 1; 161706f2543Smrg } 162706f2543Smrg } else *alpha = 0xffff; 163706f2543Smrg 164706f2543Smrg return TRUE; 165706f2543Smrg} 166706f2543Smrg 167706f2543Smrg/* 8:8:8 + PICT_a8 -> 8:8:8:8 texture */ 168706f2543Smrg 169706f2543Smrgvoid 170706f2543SmrgXAA_888_plus_PICT_a8_to_8888 ( 171706f2543Smrg CARD32 color, 172706f2543Smrg CARD8 *alphaPtr, /* in bytes */ 173706f2543Smrg int alphaPitch, 174706f2543Smrg CARD32 *dstPtr, 175706f2543Smrg int dstPitch, /* in dwords */ 176706f2543Smrg int width, 177706f2543Smrg int height 178706f2543Smrg){ 179706f2543Smrg int x; 180706f2543Smrg 181706f2543Smrg color &= 0x00ffffff; 182706f2543Smrg 183706f2543Smrg while(height--) { 184706f2543Smrg for(x = 0; x < width; x++) 185706f2543Smrg dstPtr[x] = color | (alphaPtr[x] << 24); 186706f2543Smrg dstPtr += dstPitch; 187706f2543Smrg alphaPtr += alphaPitch; 188706f2543Smrg } 189706f2543Smrg} 190706f2543Smrg 191706f2543Smrg#define DRAWABLE_IS_ON_CARD(pDraw) \ 192706f2543Smrg (pDraw->type == DRAWABLE_WINDOW || \ 193706f2543Smrg (pDraw->type == DRAWABLE_PIXMAP && IS_OFFSCREEN_PIXMAP(pDraw))) 194706f2543Smrg 195706f2543SmrgBool 196706f2543SmrgXAADoComposite ( 197706f2543Smrg CARD8 op, 198706f2543Smrg PicturePtr pSrc, 199706f2543Smrg PicturePtr pMask, 200706f2543Smrg PicturePtr pDst, 201706f2543Smrg INT16 xSrc, 202706f2543Smrg INT16 ySrc, 203706f2543Smrg INT16 xMask, 204706f2543Smrg INT16 yMask, 205706f2543Smrg INT16 xDst, 206706f2543Smrg INT16 yDst, 207706f2543Smrg CARD16 width, 208706f2543Smrg CARD16 height 209706f2543Smrg){ 210706f2543Smrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 211706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 212706f2543Smrg RegionRec region; 213706f2543Smrg CARD32 *formats, *dstformats; 214706f2543Smrg int flags = 0; 215706f2543Smrg BoxPtr pbox; 216706f2543Smrg int nbox, w, h; 217706f2543Smrg 218706f2543Smrg if(!RegionNumRects(pDst->pCompositeClip)) 219706f2543Smrg return TRUE; 220706f2543Smrg 221706f2543Smrg if(!infoRec->pScrn->vtSema || !DRAWABLE_IS_ON_CARD(pDst->pDrawable)) 222706f2543Smrg return FALSE; 223706f2543Smrg 224706f2543Smrg if(DRAWABLE_IS_ON_CARD(pSrc->pDrawable)) 225706f2543Smrg return FALSE; 226706f2543Smrg 227706f2543Smrg if (pSrc->transform || (pMask && pMask->transform)) 228706f2543Smrg return FALSE; 229706f2543Smrg 230706f2543Smrg if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap)) 231706f2543Smrg return FALSE; 232706f2543Smrg 233706f2543Smrg if ((pSrc->repeat && pSrc->repeatType != RepeatNormal) || 234706f2543Smrg (pMask && pMask->repeat && pMask->repeatType != RepeatNormal)) 235706f2543Smrg { 236706f2543Smrg return FALSE; 237706f2543Smrg } 238706f2543Smrg 239706f2543Smrg xDst += pDst->pDrawable->x; 240706f2543Smrg yDst += pDst->pDrawable->y; 241706f2543Smrg xSrc += pSrc->pDrawable->x; 242706f2543Smrg ySrc += pSrc->pDrawable->y; 243706f2543Smrg 244706f2543Smrg if(pMask) { 245706f2543Smrg if(pMask->componentAlpha) 246706f2543Smrg return FALSE; 247706f2543Smrg 248706f2543Smrg /* for now we only do it if there is a 1x1 (solid) source */ 249706f2543Smrg 250706f2543Smrg if((pSrc->pDrawable->width == 1) && (pSrc->pDrawable->height == 1)) { 251706f2543Smrg CARD16 red, green, blue, alpha; 252706f2543Smrg CARD32 pixel = 253706f2543Smrg *((CARD32*)(((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr)); 254706f2543Smrg 255706f2543Smrg if(!XAAGetRGBAFromPixel(pixel,&red,&green,&blue,&alpha,pSrc->format)) 256706f2543Smrg return FALSE; 257706f2543Smrg 258706f2543Smrg xMask += pMask->pDrawable->x; 259706f2543Smrg yMask += pMask->pDrawable->y; 260706f2543Smrg 261706f2543Smrg /* pull out color expandable operations here */ 262706f2543Smrg if((pMask->format == PICT_a1) && (alpha == 0xffff) && 263706f2543Smrg (op == PictOpOver) && infoRec->WriteBitmap && !pMask->repeat && 264706f2543Smrg !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY) && 265706f2543Smrg (!(infoRec->WriteBitmapFlags & RGB_EQUAL) || 266706f2543Smrg ((red == green) && (green == blue)))) 267706f2543Smrg { 268706f2543Smrg PixmapPtr pPix = (PixmapPtr)(pMask->pDrawable); 269706f2543Smrg int skipleft; 270706f2543Smrg 271706f2543Smrg if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, 272706f2543Smrg xSrc, ySrc, xMask, yMask, xDst, yDst, 273706f2543Smrg width, height)) 274706f2543Smrg return TRUE; 275706f2543Smrg 276706f2543Smrg nbox = RegionNumRects(®ion); 277706f2543Smrg pbox = RegionRects(®ion); 278706f2543Smrg 279706f2543Smrg if(!nbox) 280706f2543Smrg return TRUE; 281706f2543Smrg 282706f2543Smrg XAAGetPixelFromRGBA(&pixel, red, green, blue, 0, pDst->format); 283706f2543Smrg 284706f2543Smrg xMask -= xDst; 285706f2543Smrg yMask -= yDst; 286706f2543Smrg 287706f2543Smrg while(nbox--) { 288706f2543Smrg skipleft = pbox->x1 + xMask; 289706f2543Smrg 290706f2543Smrg (*infoRec->WriteBitmap)(infoRec->pScrn, 291706f2543Smrg pbox->x1, pbox->y1, 292706f2543Smrg pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, 293706f2543Smrg (unsigned char*)(pPix->devPrivate.ptr) + 294706f2543Smrg (pPix->devKind * (pbox->y1 + yMask)) + 295706f2543Smrg ((skipleft >> 3) & ~3), pPix->devKind, 296706f2543Smrg skipleft & 31, pixel, -1, GXcopy, ~0); 297706f2543Smrg pbox++; 298706f2543Smrg } 299706f2543Smrg 300706f2543Smrg /* WriteBitmap sets the Sync flag */ 301706f2543Smrg RegionUninit(®ion); 302706f2543Smrg return TRUE; 303706f2543Smrg } 304706f2543Smrg 305706f2543Smrg formats = infoRec->CPUToScreenAlphaTextureFormats; 306706f2543Smrg dstformats = infoRec->CPUToScreenAlphaTextureDstFormats; 307706f2543Smrg if(!formats || !dstformats) 308706f2543Smrg return FALSE; 309706f2543Smrg 310706f2543Smrg w = pMask->pDrawable->width; 311706f2543Smrg h = pMask->pDrawable->height; 312706f2543Smrg 313706f2543Smrg if(pMask->repeat) { 314706f2543Smrg if((infoRec->CPUToScreenAlphaTextureFlags & XAA_RENDER_NO_TILE) || 315706f2543Smrg ((infoRec->CPUToScreenAlphaTextureFlags & 316706f2543Smrg XAA_RENDER_POWER_OF_2_TILE_ONLY) && 317706f2543Smrg ((h & (h - 1)) || (w & (w - 1))))) 318706f2543Smrg { 319706f2543Smrg return FALSE; 320706f2543Smrg } 321706f2543Smrg flags |= XAA_RENDER_REPEAT; 322706f2543Smrg } 323706f2543Smrg 324706f2543Smrg if((alpha != 0xffff) && 325706f2543Smrg (infoRec->CPUToScreenAlphaTextureFlags & XAA_RENDER_NO_SRC_ALPHA)) 326706f2543Smrg return FALSE; 327706f2543Smrg 328706f2543Smrg while(*formats != pMask->format) { 329706f2543Smrg if(!(*formats)) return FALSE; 330706f2543Smrg formats++; 331706f2543Smrg } 332706f2543Smrg while(*dstformats != pDst->format) { 333706f2543Smrg if(!(*dstformats)) 334706f2543Smrg return FALSE; 335706f2543Smrg dstformats++; 336706f2543Smrg } 337706f2543Smrg 338706f2543Smrg if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, 339706f2543Smrg xSrc, ySrc, xMask, yMask, xDst, yDst, 340706f2543Smrg width, height)) 341706f2543Smrg return TRUE; 342706f2543Smrg 343706f2543Smrg nbox = RegionNumRects(®ion); 344706f2543Smrg pbox = RegionRects(®ion); 345706f2543Smrg 346706f2543Smrg if(!nbox) { 347706f2543Smrg RegionUninit(®ion); 348706f2543Smrg return TRUE; 349706f2543Smrg } 350706f2543Smrg 351706f2543Smrg if(!(infoRec->SetupForCPUToScreenAlphaTexture2)(infoRec->pScrn, 352706f2543Smrg op, red, green, blue, alpha, pMask->format, 353706f2543Smrg pDst->format, 354706f2543Smrg ((PixmapPtr)(pMask->pDrawable))->devPrivate.ptr, 355706f2543Smrg ((PixmapPtr)(pMask->pDrawable))->devKind, 356706f2543Smrg w, h, flags)) 357706f2543Smrg { 358706f2543Smrg RegionUninit(®ion); 359706f2543Smrg return FALSE; 360706f2543Smrg } 361706f2543Smrg 362706f2543Smrg xMask -= xDst; 363706f2543Smrg yMask -= yDst; 364706f2543Smrg 365706f2543Smrg while(nbox--) { 366706f2543Smrg (*infoRec->SubsequentCPUToScreenAlphaTexture)(infoRec->pScrn, 367706f2543Smrg pbox->x1, pbox->y1, 368706f2543Smrg pbox->x1 + xMask, pbox->y1 + yMask, 369706f2543Smrg pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); 370706f2543Smrg pbox++; 371706f2543Smrg } 372706f2543Smrg 373706f2543Smrg SET_SYNC_FLAG(infoRec); 374706f2543Smrg RegionUninit(®ion); 375706f2543Smrg return TRUE; 376706f2543Smrg } 377706f2543Smrg } else { 378706f2543Smrg formats = infoRec->CPUToScreenTextureFormats; 379706f2543Smrg dstformats = infoRec->CPUToScreenTextureDstFormats; 380706f2543Smrg if(!formats || !dstformats) 381706f2543Smrg return FALSE; 382706f2543Smrg 383706f2543Smrg w = pSrc->pDrawable->width; 384706f2543Smrg h = pSrc->pDrawable->height; 385706f2543Smrg 386706f2543Smrg if(pSrc->repeat) { 387706f2543Smrg if((infoRec->CPUToScreenTextureFlags & XAA_RENDER_NO_TILE) || 388706f2543Smrg ((infoRec->CPUToScreenTextureFlags & 389706f2543Smrg XAA_RENDER_POWER_OF_2_TILE_ONLY) && 390706f2543Smrg ((h & (h - 1)) || (w & (w - 1))))) 391706f2543Smrg { 392706f2543Smrg return FALSE; 393706f2543Smrg } 394706f2543Smrg flags |= XAA_RENDER_REPEAT; 395706f2543Smrg } 396706f2543Smrg 397706f2543Smrg while(*formats != pSrc->format) { 398706f2543Smrg if(!(*formats)) return FALSE; 399706f2543Smrg formats++; 400706f2543Smrg } 401706f2543Smrg while(*dstformats != pDst->format) { 402706f2543Smrg if(!(*dstformats)) 403706f2543Smrg return FALSE; 404706f2543Smrg dstformats++; 405706f2543Smrg } 406706f2543Smrg 407706f2543Smrg if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, 408706f2543Smrg xSrc, ySrc, xMask, yMask, xDst, yDst, 409706f2543Smrg width, height)) 410706f2543Smrg return TRUE; 411706f2543Smrg 412706f2543Smrg nbox = RegionNumRects(®ion); 413706f2543Smrg pbox = RegionRects(®ion); 414706f2543Smrg 415706f2543Smrg if(!nbox) { 416706f2543Smrg RegionUninit(®ion); 417706f2543Smrg return TRUE; 418706f2543Smrg } 419706f2543Smrg 420706f2543Smrg if(!(infoRec->SetupForCPUToScreenTexture2)(infoRec->pScrn, 421706f2543Smrg op, pSrc->format, pDst->format, 422706f2543Smrg ((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr, 423706f2543Smrg ((PixmapPtr)(pSrc->pDrawable))->devKind, 424706f2543Smrg w, h, flags)) 425706f2543Smrg { 426706f2543Smrg RegionUninit(®ion); 427706f2543Smrg return FALSE; 428706f2543Smrg } 429706f2543Smrg 430706f2543Smrg 431706f2543Smrg xSrc -= xDst; 432706f2543Smrg ySrc -= yDst; 433706f2543Smrg 434706f2543Smrg while(nbox--) { 435706f2543Smrg (*infoRec->SubsequentCPUToScreenTexture)(infoRec->pScrn, 436706f2543Smrg pbox->x1, pbox->y1, 437706f2543Smrg pbox->x1 + xSrc, pbox->y1 + ySrc, 438706f2543Smrg pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); 439706f2543Smrg pbox++; 440706f2543Smrg } 441706f2543Smrg 442706f2543Smrg SET_SYNC_FLAG(infoRec); 443706f2543Smrg RegionUninit(®ion); 444706f2543Smrg return TRUE; 445706f2543Smrg } 446706f2543Smrg 447706f2543Smrg 448706f2543Smrg return FALSE; 449706f2543Smrg} 450706f2543Smrg 451706f2543Smrgstatic void 452706f2543SmrgXAACompositeSrcCopy (PicturePtr pSrc, 453706f2543Smrg PicturePtr pDst, 454706f2543Smrg INT16 xSrc, 455706f2543Smrg INT16 ySrc, 456706f2543Smrg INT16 xDst, 457706f2543Smrg INT16 yDst, 458706f2543Smrg CARD16 width, 459706f2543Smrg CARD16 height) 460706f2543Smrg{ 461706f2543Smrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 462706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 463706f2543Smrg int i, nbox; 464706f2543Smrg int xoff, yoff; 465706f2543Smrg BoxPtr pbox; 466706f2543Smrg DDXPointPtr pptSrc; 467706f2543Smrg RegionRec region; 468706f2543Smrg 469706f2543Smrg xDst += pDst->pDrawable->x; 470706f2543Smrg yDst += pDst->pDrawable->y; 471706f2543Smrg xSrc += pSrc->pDrawable->x; 472706f2543Smrg ySrc += pSrc->pDrawable->y; 473706f2543Smrg 474706f2543Smrg if (!miComputeCompositeRegion (®ion, pSrc, NULL, pDst, 475706f2543Smrg xSrc, ySrc, 0, 0, xDst, yDst, 476706f2543Smrg width, height)) 477706f2543Smrg return; 478706f2543Smrg 479706f2543Smrg nbox = RegionNumRects(®ion); 480706f2543Smrg pbox = RegionRects(®ion); 481706f2543Smrg 482706f2543Smrg if(!nbox) { 483706f2543Smrg RegionUninit(®ion); 484706f2543Smrg return; 485706f2543Smrg } 486706f2543Smrg pptSrc = malloc(sizeof(DDXPointRec) * nbox); 487706f2543Smrg if (!pptSrc) { 488706f2543Smrg RegionUninit(®ion); 489706f2543Smrg return; 490706f2543Smrg } 491706f2543Smrg xoff = xSrc - xDst; 492706f2543Smrg yoff = ySrc - yDst; 493706f2543Smrg for (i = 0; i < nbox; i++) { 494706f2543Smrg pptSrc[i].x = pbox[i].x1 + xoff; 495706f2543Smrg pptSrc[i].y = pbox[i].y1 + yoff; 496706f2543Smrg } 497706f2543Smrg 498706f2543Smrg infoRec->ScratchGC.planemask = ~0L; 499706f2543Smrg infoRec->ScratchGC.alu = GXcopy; 500706f2543Smrg 501706f2543Smrg XAADoBitBlt(pSrc->pDrawable, pDst->pDrawable, &infoRec->ScratchGC, ®ion, 502706f2543Smrg pptSrc); 503706f2543Smrg 504706f2543Smrg free(pptSrc); 505706f2543Smrg RegionUninit(®ion); 506706f2543Smrg return; 507706f2543Smrg} 508706f2543Smrg 509706f2543Smrgvoid 510706f2543SmrgXAAComposite (CARD8 op, 511706f2543Smrg PicturePtr pSrc, 512706f2543Smrg PicturePtr pMask, 513706f2543Smrg PicturePtr pDst, 514706f2543Smrg INT16 xSrc, 515706f2543Smrg INT16 ySrc, 516706f2543Smrg INT16 xMask, 517706f2543Smrg INT16 yMask, 518706f2543Smrg INT16 xDst, 519706f2543Smrg INT16 yDst, 520706f2543Smrg CARD16 width, 521706f2543Smrg CARD16 height) 522706f2543Smrg{ 523706f2543Smrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 524706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 525706f2543Smrg XAA_RENDER_PROLOGUE(pScreen, Composite); 526706f2543Smrg 527706f2543Smrg if(!pMask && infoRec->pScrn->vtSema && 528706f2543Smrg infoRec->ScreenToScreenBitBlt && 529706f2543Smrg pSrc->pDrawable && 530706f2543Smrg DRAWABLE_IS_ON_CARD(pSrc->pDrawable) && 531706f2543Smrg DRAWABLE_IS_ON_CARD(pDst->pDrawable) && 532706f2543Smrg !pSrc->transform && 533706f2543Smrg (!pSrc->repeat || (xSrc >= 0 && ySrc >= 0 && 534706f2543Smrg xSrc+width<=pSrc->pDrawable->width && 535706f2543Smrg ySrc+height<=pSrc->pDrawable->height)) && 536706f2543Smrg ((op == PictOpSrc && 537706f2543Smrg ((pSrc->format==pDst->format) || 538706f2543Smrg (pSrc->format==PICT_a8r8g8b8 && pDst->format==PICT_x8r8g8b8) || 539706f2543Smrg (pSrc->format==PICT_a8b8g8r8 && pDst->format==PICT_x8b8g8r8))) || 540706f2543Smrg (op == PictOpOver && !pSrc->alphaMap && !pDst->alphaMap && 541706f2543Smrg pSrc->format==pDst->format && 542706f2543Smrg (pSrc->format==PICT_x8r8g8b8 || pSrc->format==PICT_x8b8g8r8)))) 543706f2543Smrg { 544706f2543Smrg XAACompositeSrcCopy(pSrc, pDst, xSrc, ySrc, xDst, yDst, width, height); 545706f2543Smrg } else if(!pSrc->pDrawable || (pMask && !pMask->pDrawable) || 546706f2543Smrg !infoRec->Composite || 547706f2543Smrg !(*infoRec->Composite)(op, pSrc, pMask, pDst, 548706f2543Smrg xSrc, ySrc, xMask, yMask, xDst, yDst, 549706f2543Smrg width, height)) 550706f2543Smrg { 551706f2543Smrg if(infoRec->pScrn->vtSema && 552706f2543Smrg ((pSrc->pDrawable && 553706f2543Smrg (pSrc->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))) || 554706f2543Smrg pDst->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pDst->pDrawable))) { 555706f2543Smrg SYNC_CHECK(pDst->pDrawable); 556706f2543Smrg } 557706f2543Smrg (*GetPictureScreen(pScreen)->Composite) (op, 558706f2543Smrg pSrc, 559706f2543Smrg pMask, 560706f2543Smrg pDst, 561706f2543Smrg xSrc, 562706f2543Smrg ySrc, 563706f2543Smrg xMask, 564706f2543Smrg yMask, 565706f2543Smrg xDst, 566706f2543Smrg yDst, 567706f2543Smrg width, 568706f2543Smrg height); 569706f2543Smrg } 570706f2543Smrg 571706f2543Smrg if(pDst->pDrawable->type == DRAWABLE_PIXMAP) 572706f2543Smrg (XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDst->pDrawable)))->flags |= DIRTY; 573706f2543Smrg 574706f2543Smrg XAA_RENDER_EPILOGUE(pScreen, Composite, XAAComposite); 575706f2543Smrg} 576706f2543Smrg 577706f2543SmrgBool 578706f2543SmrgXAADoGlyphs (CARD8 op, 579706f2543Smrg PicturePtr pSrc, 580706f2543Smrg PicturePtr pDst, 581706f2543Smrg PictFormatPtr maskFormat, 582706f2543Smrg INT16 xSrc, 583706f2543Smrg INT16 ySrc, 584706f2543Smrg int nlist, 585706f2543Smrg GlyphListPtr list, 586706f2543Smrg GlyphPtr *glyphs) 587706f2543Smrg{ 588706f2543Smrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 589706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 590706f2543Smrg 591706f2543Smrg if(!RegionNumRects(pDst->pCompositeClip)) 592706f2543Smrg return TRUE; 593706f2543Smrg 594706f2543Smrg if(!infoRec->pScrn->vtSema || 595706f2543Smrg ((pDst->pDrawable->type != DRAWABLE_WINDOW) && 596706f2543Smrg !IS_OFFSCREEN_PIXMAP(pDst->pDrawable))) 597706f2543Smrg return FALSE; 598706f2543Smrg 599706f2543Smrg if((pSrc->pDrawable->type != DRAWABLE_PIXMAP) || 600706f2543Smrg IS_OFFSCREEN_PIXMAP(pSrc->pDrawable)) 601706f2543Smrg return FALSE; 602706f2543Smrg 603706f2543Smrg /* 604706f2543Smrg * If it looks like we have a chance of being able to draw these 605706f2543Smrg * glyphs with an accelerated Composite, do that now to avoid 606706f2543Smrg * unneeded and costly syncs. 607706f2543Smrg */ 608706f2543Smrg if(maskFormat) { 609706f2543Smrg if(!infoRec->CPUToScreenAlphaTextureFormats) 610706f2543Smrg return FALSE; 611706f2543Smrg } else { 612706f2543Smrg if(!infoRec->CPUToScreenTextureFormats) 613706f2543Smrg return FALSE; 614706f2543Smrg } 615706f2543Smrg 616706f2543Smrg miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); 617706f2543Smrg 618706f2543Smrg return TRUE; 619706f2543Smrg} 620706f2543Smrg 621706f2543Smrg 622706f2543Smrgvoid 623706f2543SmrgXAAGlyphs (CARD8 op, 624706f2543Smrg PicturePtr pSrc, 625706f2543Smrg PicturePtr pDst, 626706f2543Smrg PictFormatPtr maskFormat, 627706f2543Smrg INT16 xSrc, 628706f2543Smrg INT16 ySrc, 629706f2543Smrg int nlist, 630706f2543Smrg GlyphListPtr list, 631706f2543Smrg GlyphPtr *glyphs) 632706f2543Smrg{ 633706f2543Smrg ScreenPtr pScreen = pDst->pDrawable->pScreen; 634706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 635706f2543Smrg XAA_RENDER_PROLOGUE(pScreen, Glyphs); 636706f2543Smrg 637706f2543Smrg if(!pSrc->pDrawable || !infoRec->Glyphs || 638706f2543Smrg !(*infoRec->Glyphs)(op, pSrc, pDst, maskFormat, 639706f2543Smrg xSrc, ySrc, nlist, list, glyphs)) 640706f2543Smrg { 641706f2543Smrg if(infoRec->pScrn->vtSema && 642706f2543Smrg ((pSrc->pDrawable && 643706f2543Smrg (pSrc->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))) || 644706f2543Smrg pDst->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pDst->pDrawable))) { 645706f2543Smrg SYNC_CHECK(pDst->pDrawable); 646706f2543Smrg } 647706f2543Smrg (*GetPictureScreen(pScreen)->Glyphs) (op, pSrc, pDst, maskFormat, 648706f2543Smrg xSrc, ySrc, nlist, list, glyphs); 649706f2543Smrg } 650706f2543Smrg 651706f2543Smrg if(pDst->pDrawable->type == DRAWABLE_PIXMAP) 652706f2543Smrg (XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDst->pDrawable)))->flags |= DIRTY; 653706f2543Smrg 654706f2543Smrg XAA_RENDER_EPILOGUE(pScreen, Glyphs, XAAGlyphs); 655706f2543Smrg} 656