00001
00002
00003
#include "misc.h"
00004
#include "xf86.h"
00005
#include "xf86_ansic.h"
00006
#include "xf86_OSproc.h"
00007
#include "servermd.h"
00008
00009
#include "X.h"
00010
#include "scrnintstr.h"
00011
#include "mi.h"
00012
#include "pixmapstr.h"
00013
#include "xf86str.h"
00014
#include "xaa.h"
00015
#include "xaalocal.h"
00016
00017 void XAAMoveDWORDS_FixedBase(
00018
register CARD32* dest,
00019
register CARD32* src,
00020
register int dwords )
00021 {
00022
while(dwords & ~0x03) {
00023 *
dest = *
src;
00024 *
dest = *(
src + 1);
00025 *
dest = *(
src + 2);
00026 *
dest = *(
src + 3);
00027 dwords -= 4;
00028
src += 4;
00029 }
00030
00031
if(!dwords)
return;
00032 *
dest = *
src;
00033
if(dwords == 1)
return;
00034 *
dest = *(
src + 1);
00035
if(dwords == 2)
return;
00036 *
dest = *(
src + 2);
00037 }
00038
00039 void XAAMoveDWORDS(
00040
register CARD32* dest,
00041
register CARD32* src,
00042
register int dwords )
00043 {
00044
while(dwords & ~0x03) {
00045 *
dest = *
src;
00046 *(
dest + 1) = *(
src + 1);
00047 *(
dest + 2) = *(
src + 2);
00048 *(
dest + 3) = *(
src + 3);
00049
src += 4;
00050
dest += 4;
00051 dwords -= 4;
00052 }
00053
if(!dwords)
return;
00054 *
dest = *
src;
00055
if(dwords == 1)
return;
00056 *(
dest + 1) = *(
src + 1);
00057
if(dwords == 2)
return;
00058 *(
dest + 2) = *(
src + 2);
00059 }
00060
00061 void XAAMoveDWORDS_FixedSrc(
00062
register CARD32* dest,
00063
register CARD32* src,
00064
register int dwords )
00065 {
00066
while(dwords & ~0x03) {
00067 *
dest = *
src;
00068 *(
dest + 1) = *
src;
00069 *(
dest + 2) = *
src;
00070 *(
dest + 3) = *
src;
00071
dest += 4;
00072 dwords -= 4;
00073 }
00074
if(!dwords)
return;
00075 *
dest = *
src;
00076
if(dwords == 1)
return;
00077 *(
dest + 1) = *
src;
00078
if(dwords == 2)
return;
00079 *(
dest + 2) = *
src;
00080 }
00081
00082
static void
00083 XAAWritePixmap32To24(
00084
ScrnInfoPtr pScrn,
00085
int x,
int y,
int w,
int h,
00086
unsigned char *srcInit,
00087
int srcwidth,
00088
int rop,
00089
unsigned int planemask,
00090
int trans
00091 ){
00092
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(
pScrn);
00093
int count, dwords = ((
w * 3) + 3) >> 2;
00094 CARD32 *
src, *
dst;
00095
Bool PlusOne = FALSE;
00096
00097
if((infoRec->
ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) &&
00098 ((dwords *
h) & 0x01)) {
00099 PlusOne = TRUE;
00100 }
00101
00102 (*infoRec->
SetupForImageWrite)(
pScrn,
rop,
planemask, trans, 24, 24);
00103 (*infoRec->
SubsequentImageWriteRect)(
pScrn,
x,
y,
w,
h, 0);
00104
00105
if(dwords > infoRec->
ImageWriteRange) {
00106
dst = (CARD32*)infoRec->
ImageWriteBase;
00107
while(
h--) {
00108
src = (CARD32*)srcInit;
00109
count =
w;
00110
00111
while(
count >= 4) {
00112 *
dst = (
src[0] & 0x00ffffff) | (
src[1] << 24);
00113 *
dst = ((
src[1] >> 8) & 0x0000ffff) | (
src[2] << 16);
00114 *
dst = ((
src[2] >> 16) & 0x000000ff) | (
src[3] << 8);
00115
src += 4;
00116
count -= 4;
00117 }
00118
switch(
count) {
00119
case 0:
break;
00120
case 1: *
dst =
src[0];
00121
break;
00122
case 2: *
dst = (
src[0] & 0x00ffffff) | (
src[1] << 24);
00123 *
dst =
src[1] >> 8;
00124
break;
00125
default: *
dst = (
src[0] & 0x00ffffff) | (
src[1] << 24);
00126 *
dst = ((
src[1] >> 8) & 0x0000ffff) | (
src[2] << 16);
00127 *
dst =
src[2] >> 16;
00128
break;
00129 }
00130 srcInit += srcwidth;
00131 }
00132 }
else {
00133
while(
h--) {
00134
dst = (CARD32*)infoRec->
ImageWriteBase;
00135
src = (CARD32*)srcInit;
00136
count =
w;
00137
00138
while(
count >= 4) {
00139
dst[0] = (
src[0] & 0x00ffffff) | (
src[1] << 24);
00140
dst[1] = ((
src[1] >> 8) & 0x0000ffff) | (
src[2] << 16);
00141
dst[2] = ((
src[2] >> 16) & 0x000000ff) | (
src[3] << 8);
00142
dst += 3;
00143
src += 4;
00144
count -= 4;
00145 }
00146
switch(
count) {
00147
case 0:
break;
00148
case 1:
dst[0] =
src[0];
00149
break;
00150
case 2:
dst[0] = (
src[0] & 0x00ffffff) | (
src[1] << 24);
00151
dst[1] =
src[1] >> 8;
00152
break;
00153
default:
dst[0] = (
src[0] & 0x00ffffff) | (
src[1] << 24);
00154
dst[1] = ((
src[1] >> 8) & 0x0000ffff) | (
src[2] << 16);
00155
dst[2] =
src[2] >> 16;
00156
break;
00157 }
00158 srcInit += srcwidth;
00159 }
00160 }
00161
00162
if(PlusOne) {
00163 CARD32*
base = (CARD32*)infoRec->
ImageWriteBase;
00164 *
base = 0x00000000;
00165 }
00166
00167
if(infoRec->
ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
00168 (*infoRec->
Sync)(
pScrn);
00169
else SET_SYNC_FLAG(infoRec);
00170
00171 }
00172
00173
void
00174 XAAWritePixmap (
00175
ScrnInfoPtr pScrn,
00176
int x,
int y,
int w,
int h,
00177
unsigned char *src,
00178
int srcwidth,
00179
int rop,
00180
unsigned int planemask,
00181
int trans,
00182
int bpp,
int depth
00183 ){
00184
XAAInfoRecPtr infoRec;
00185
int dwords, skipleft, Bpp;
00186
Bool beCareful, PlusOne;
00187
00188
if((bpp == 32) && (
pScrn->bitsPerPixel == 24)) {
00189
XAAWritePixmap32To24(
pScrn,
x,
y,
w,
h,
src, srcwidth,
00190
rop,
planemask, trans);
00191
return;
00192 }
00193
00194 infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(
pScrn);
00195 beCareful = PlusOne = FALSE;
00196 Bpp = bpp >> 3;
00197
00198
if((skipleft = (
long)
src & 0x03L)) {
00199
if(!(infoRec->
ImageWriteFlags & LEFT_EDGE_CLIPPING)) {
00200 skipleft = 0;
00201 beCareful = TRUE;
00202
goto BAD_ALIGNMENT;
00203 }
00204
00205
if(Bpp == 3)
00206 skipleft = 4 - skipleft;
00207
else
00208 skipleft /= Bpp;
00209
00210
if((
x < skipleft) && !(infoRec->
ImageWriteFlags &
00211 LEFT_EDGE_CLIPPING_NEGATIVE_X)) {
00212 skipleft = 0;
00213 beCareful = TRUE;
00214
goto BAD_ALIGNMENT;
00215 }
00216
00217
x -= skipleft;
00218
w += skipleft;
00219
00220
if(Bpp == 3)
00221
src -= 3 * skipleft;
00222
else
00223
src = (
unsigned char*)((
long)
src & ~0x03L);
00224 }
00225
00226 BAD_ALIGNMENT:
00227
00228 dwords = ((
w * Bpp) + 3) >> 2;
00229
00230
if((infoRec->
ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) &&
00231 ((dwords *
h) & 0x01)) {
00232 PlusOne = TRUE;
00233 }
00234
00235
00236 (*infoRec->
SetupForImageWrite)(
pScrn,
rop,
planemask, trans, bpp,
depth);
00237 (*infoRec->
SubsequentImageWriteRect)(
pScrn,
x,
y,
w,
h, skipleft);
00238
00239
if(beCareful) {
00240
00241
00242
if(((
x * Bpp) + (dwords << 2)) > srcwidth)
h--;
00243
else beCareful = FALSE;
00244 }
00245
00246
if(dwords > infoRec->
ImageWriteRange) {
00247
while(
h--) {
00248
XAAMoveDWORDS_FixedBase((CARD32*)infoRec->
ImageWriteBase,
00249 (CARD32*)
src, dwords);
00250
src += srcwidth;
00251 }
00252
if(beCareful) {
00253
int shift = ((
long)
src & 0x03L) << 3;
00254
if(--dwords)
00255
XAAMoveDWORDS_FixedBase((CARD32*)infoRec->
ImageWriteBase,
00256 (CARD32*)
src, dwords);
00257
src = (
unsigned char*)((
long)(
src + (dwords << 2)) & ~0x03L);
00258 *((CARD32*)infoRec->
ImageWriteBase) = *((CARD32*)
src) >> shift;
00259 }
00260 }
else {
00261
if(srcwidth == (dwords << 2)) {
00262
int decrement = infoRec->
ImageWriteRange/dwords;
00263
00264
while(
h > decrement) {
00265
XAAMoveDWORDS((CARD32*)infoRec->
ImageWriteBase,
00266 (CARD32*)
src, dwords * decrement);
00267
src += (srcwidth * decrement);
00268
h -= decrement;
00269 }
00270
if(
h) {
00271
XAAMoveDWORDS((CARD32*)infoRec->
ImageWriteBase,
00272 (CARD32*)
src, dwords *
h);
00273
if(beCareful)
src += (srcwidth *
h);
00274 }
00275 }
else {
00276
while(
h--) {
00277
XAAMoveDWORDS((CARD32*)infoRec->
ImageWriteBase,
00278 (CARD32*)
src, dwords);
00279
src += srcwidth;
00280 }
00281 }
00282
00283
if(beCareful) {
00284
int shift = ((
long)
src & 0x03L) << 3;
00285
if(--dwords)
00286
XAAMoveDWORDS((CARD32*)infoRec->
ImageWriteBase,
00287 (CARD32*)
src, dwords);
00288
src = (
unsigned char*)((
long)(
src + (dwords << 2)) & ~0x03L);
00289
00290 ((CARD32*)infoRec->
ImageWriteBase)[dwords] =
00291 *((CARD32*)
src) >> shift;
00292 }
00293 }
00294
00295
if(PlusOne) {
00296 CARD32*
base = (CARD32*)infoRec->
ImageWriteBase;
00297 *
base = 0x00000000;
00298 }
00299
00300
if(infoRec->
ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
00301 (*infoRec->
Sync)(
pScrn);
00302
else SET_SYNC_FLAG(infoRec);
00303 }
00304
00305
00306
void
00307 XAAWritePixmapScanline (
00308
ScrnInfoPtr pScrn,
00309
int x,
int y,
int w,
int h,
00310
unsigned char *src,
00311
int srcwidth,
00312
int rop,
00313
unsigned int planemask,
00314
int trans,
00315
int bpp,
int depth
00316 ){
00317
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(
pScrn);
00318
int dwords, skipleft, bufferNo = 0, Bpp = bpp >> 3;
00319
Bool beCareful = FALSE;
00320 CARD32*
base;
00321
00322
if((skipleft = (
long)
src & 0x03L)) {
00323
if(!(infoRec->
ScanlineImageWriteFlags & LEFT_EDGE_CLIPPING)) {
00324 skipleft = 0;
00325 beCareful = TRUE;
00326
goto BAD_ALIGNMENT;
00327 }
00328
00329
if(Bpp == 3)
00330 skipleft = 4 - skipleft;
00331
else
00332 skipleft /= Bpp;
00333
00334
if((
x < skipleft) && !(infoRec->
ScanlineImageWriteFlags &
00335 LEFT_EDGE_CLIPPING_NEGATIVE_X)) {
00336 skipleft = 0;
00337 beCareful = TRUE;
00338
goto BAD_ALIGNMENT;
00339 }
00340
00341
x -= skipleft;
00342
w += skipleft;
00343
00344
if(Bpp == 3)
00345
src -= 3 * skipleft;
00346
else
00347
src = (
unsigned char*)((
long)
src & ~0x03L);
00348 }
00349
00350 BAD_ALIGNMENT:
00351
00352 dwords = ((
w * Bpp) + 3) >> 2;
00353
00354 (*infoRec->
SetupForScanlineImageWrite)(
00355
pScrn,
rop,
planemask, trans, bpp,
depth);
00356 (*infoRec->
SubsequentScanlineImageWriteRect)(
pScrn,
x,
y,
w,
h, skipleft);
00357
00358
if(beCareful) {
00359
00360
00361
if(((
x * Bpp) + (dwords << 2)) > srcwidth)
h--;
00362
else beCareful = FALSE;
00363 }
00364
00365
while(
h--) {
00366
base = (CARD32*)infoRec->
ScanlineImageWriteBuffers[bufferNo];
00367
XAAMoveDWORDS(
base, (CARD32*)
src, dwords);
00368 (*infoRec->
SubsequentImageWriteScanline)(
pScrn, bufferNo++);
00369
src += srcwidth;
00370
if(bufferNo >= infoRec->
NumScanlineImageWriteBuffers)
00371 bufferNo = 0;
00372 }
00373
00374
if(beCareful) {
00375
int shift = ((
long)
src & 0x03L) << 3;
00376
base = (CARD32*)infoRec->
ScanlineImageWriteBuffers[bufferNo];
00377
if(--dwords)
00378
XAAMoveDWORDS(
base,(CARD32*)
src, dwords);
00379
src = (
unsigned char*)((
long)(
src + (dwords << 2)) & ~0x03L);
00380
00381
base[dwords] = *((CARD32*)
src) >> shift;
00382 (*infoRec->
SubsequentImageWriteScanline)(
pScrn, bufferNo);
00383 }
00384
00385 SET_SYNC_FLAG(infoRec);
00386 }
00387
00388
00389
void
00390 XAAPutImage(
00391
DrawablePtr pDraw,
00392
GCPtr pGC,
00393
int depth,
00394
int x,
00395
int y,
00396
int w,
00397
int h,
00398
int leftPad,
00399
int format,
00400
char *pImage
00401 ){
00402
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
00403
int bpp = BitsPerPixel(
depth);
00404
Bool depthBug = FALSE;
00405
if(!
w || !
h)
return;
00406
00407
if(!REGION_NUM_RECTS(pGC->
pCompositeClip))
00408
return;
00409
00410 depthBug = XAA_DEPTH_BUG(pGC);
00411
00412
if(((
format == ZPixmap) && infoRec->
WritePixmap &&
00413 ((pDraw->
bitsPerPixel == bpp) ||
00414 ((pDraw->
bitsPerPixel == 24) && (bpp == 32) &&
00415 (infoRec->
WritePixmapFlags & CONVERT_32BPP_TO_24BPP))) &&
00416 CHECK_ROP(pGC,infoRec->
WritePixmapFlags) &&
00417 CHECK_ROPSRC(pGC,infoRec->
WritePixmapFlags) &&
00418 CHECK_PLANEMASK(pGC,infoRec->
WritePixmapFlags) &&
00419 CHECK_NO_GXCOPY(pGC,infoRec->
WritePixmapFlags)) ||
00420 ((
format == XYBitmap) && !depthBug && infoRec->
WriteBitmap &&
00421 CHECK_ROP(pGC,infoRec->
WriteBitmapFlags) &&
00422 CHECK_ROPSRC(pGC,infoRec->
WriteBitmapFlags) &&
00423 CHECK_PLANEMASK(pGC,infoRec->
WriteBitmapFlags) &&
00424 CHECK_COLORS(pGC,infoRec->
WriteBitmapFlags) &&
00425 !(infoRec->
WriteBitmapFlags & TRANSPARENCY_ONLY)) ||
00426 ((
format == XYPixmap) && !depthBug && infoRec->
WriteBitmap &&
00427 CHECK_ROP(pGC,infoRec->
WriteBitmapFlags) &&
00428 CHECK_ROPSRC(pGC,infoRec->
WriteBitmapFlags) &&
00429 !(infoRec->
WriteBitmapFlags & NO_PLANEMASK) &&
00430 !(infoRec->
WriteBitmapFlags & TRANSPARENCY_ONLY))){
00431
00432
int MaxBoxes = REGION_NUM_RECTS(pGC->
pCompositeClip);
00433
BoxPtr pbox, pClipBoxes;
00434
int nboxes, srcx, srcy, srcwidth;
00435 xRectangle TheRect;
00436
00437 TheRect.x = pDraw->
x +
x;
00438 TheRect.y = pDraw->
y +
y;
00439 TheRect.width =
w;
00440 TheRect.height =
h;
00441
00442
if(MaxBoxes > (infoRec->
PreAllocSize/
sizeof(
BoxRec))) {
00443 pClipBoxes =
xalloc(MaxBoxes *
sizeof(
BoxRec));
00444
if(!pClipBoxes)
return;
00445 }
else pClipBoxes = (
BoxPtr)infoRec->
PreAllocMem;
00446
00447 nboxes =
00448
XAAGetRectClipBoxes(pGC->
pCompositeClip, pClipBoxes, 1, &TheRect);
00449 pbox = pClipBoxes;
00450
00451
if(
format == XYBitmap) {
00452 srcwidth = BitmapBytePad(leftPad +
w);
00453
while(nboxes--) {
00454 srcx = pbox->
x1 - TheRect.x + leftPad;
00455 srcy = pbox->
y1 - TheRect.y;
00456 (*infoRec->
WriteBitmap)(infoRec->
pScrn, pbox->
x1, pbox->
y1,
00457 pbox->
x2 - pbox->
x1, pbox->
y2 - pbox->
y1,
00458 (
unsigned char*)pImage +
00459 (srcwidth * srcy) + ((srcx >> 5) << 2),
00460 srcwidth, srcx & 31, pGC->
fgPixel, pGC->
bgPixel,
00461 pGC->
alu, pGC->
planemask);
00462 pbox++;
00463 }
00464 }
else if(
format == ZPixmap) {
00465
int Bpp = bpp >> 3;
00466 srcwidth = PixmapBytePad(leftPad +
w,
depth);
00467
while(nboxes--) {
00468 srcx = pbox->
x1 - TheRect.x + leftPad;
00469 srcy = pbox->
y1 - TheRect.y;
00470 (*infoRec->
WritePixmap)(infoRec->
pScrn, pbox->
x1, pbox->
y1,
00471 pbox->
x2 - pbox->
x1, pbox->
y2 - pbox->
y1,
00472 (
unsigned char*)pImage +
00473 (srcwidth * srcy) + (srcx * Bpp),
00474 srcwidth, pGC->
alu, pGC->
planemask, -1,
00475 Bpp << 3,
depth);
00476 pbox++;
00477 }
00478 }
else {
00479
int depth = pGC->
depth;
00480
int numBox, increment;
00481
unsigned long i,
mask;
00482
BoxPtr pntBox;
00483
00484 srcwidth = BitmapBytePad(
w + leftPad);
00485 increment =
h * srcwidth;
00486
i = 1 << (
depth - 1);
00487
mask = ~0;
00488
00489
if((infoRec->
pScrn->
overlayFlags & OVERLAY_8_32_PLANAR) &&
00490 (pGC->
depth == 8)){
00491
i = 0x80000000;
mask = 0xff000000;
00492 }
00493
00494
for(;
i &
mask;
i >>= 1, pImage += increment) {
00495
if(
i & pGC->
planemask) {
00496 pntBox = pbox;
00497 numBox = nboxes;
00498
while(numBox--) {
00499 srcx = pntBox->
x1 - TheRect.x + leftPad;
00500 srcy = pntBox->
y1 - TheRect.y;
00501 (*infoRec->
WriteBitmap)(infoRec->
pScrn,
00502 pntBox->
x1, pntBox->
y1,
00503 pntBox->
x2 - pntBox->
x1,
00504 pntBox->
y2 - pntBox->
y1,
00505 (
unsigned char*)pImage +
00506 (srcwidth * srcy) + ((srcx >> 5) << 2),
00507 srcwidth, srcx & 31, ~0, 0, pGC->
alu,
i);
00508 pntBox++;
00509 }
00510 }
00511 }
00512
00513 }
00514
00515
if(pClipBoxes != (
BoxPtr)infoRec->
PreAllocMem)
00516
xfree(pClipBoxes);
00517 }
else
00518
XAAFallbackOps.
PutImage(pDraw, pGC,
depth,
x,
y,
w,
h, leftPad,
00519
format, pImage);
00520 }