~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to hw/xfree86/xaa/xaaPict.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaPict.c,v 1.18 2003/04/23 18:35:34 eich Exp $
 
3
 *
 
4
 * Copyright Ā© 2000 Keith Packard, member of The XFree86 Project, Inc.
 
5
 *
 
6
 * Permission to use, copy, modify, distribute, and sell this software and its
 
7
 * documentation for any purpose is hereby granted without fee, provided that
 
8
 * the above copyright notice appear in all copies and that both that
 
9
 * copyright notice and this permission notice appear in supporting
 
10
 * documentation, and that the name of Keith Packard not be used in
 
11
 * advertising or publicity pertaining to distribution of the software without
 
12
 * specific, written prior permission.  Keith Packard makes no
 
13
 * representations about the suitability of this software for any purpose.  It
 
14
 * is provided "as is" without express or implied warranty.
 
15
 *
 
16
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
17
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 
18
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
19
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 
20
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 
21
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 
22
 * PERFORMANCE OF THIS SOFTWARE.
 
23
 */
 
24
 
 
25
#ifdef HAVE_XORG_CONFIG_H
 
26
#include <xorg-config.h>
 
27
#endif
 
28
 
 
29
#include "misc.h"
 
30
#include "xf86.h"
 
31
#include "xf86_ansic.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 {  /* PICT_TYPE_ABGR */
 
79
        rshift = 0;
 
80
        gshift = rbits;
 
81
        bshift = gshift + gbits;
 
82
        ashift = bshift + bbits;
 
83
    }
 
84
    
 
85
    *pixel |=  ( blue >> (16 - bbits)) << bshift;
 
86
    *pixel |=  (  red >> (16 - rbits)) << rshift;
 
87
    *pixel |=  (green >> (16 - gbits)) << gshift;
 
88
    *pixel |=  (alpha >> (16 - abits)) << ashift;
 
89
 
 
90
    return TRUE;
 
91
}
 
92
 
 
93
 
 
94
Bool
 
95
XAAGetRGBAFromPixel(
 
96
    CARD32 pixel,
 
97
    CARD16 *red,
 
98
    CARD16 *green,
 
99
    CARD16 *blue,
 
100
    CARD16 *alpha,
 
101
    CARD32 format
 
102
){
 
103
    int rbits, bbits, gbits, abits;
 
104
    int rshift, bshift, gshift, ashift;
 
105
    
 
106
    if(!PICT_FORMAT_COLOR(format))
 
107
        return FALSE;
 
108
        
 
109
    rbits = PICT_FORMAT_R(format);
 
110
    gbits = PICT_FORMAT_G(format);
 
111
    bbits = PICT_FORMAT_B(format);
 
112
    abits = PICT_FORMAT_A(format);
 
113
    
 
114
    if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
 
115
        bshift = 0;
 
116
        gshift = bbits;
 
117
        rshift = gshift + gbits;
 
118
        ashift = rshift + rbits;
 
119
    } else {  /* PICT_TYPE_ABGR */
 
120
        rshift = 0;
 
121
        gshift = rbits;
 
122
        bshift = gshift + gbits;
 
123
        ashift = bshift + bbits;
 
124
    }
 
125
 
 
126
    *red = ((pixel >> rshift ) & ((1 << rbits) - 1)) << (16 - rbits);
 
127
    while(rbits < 16) {
 
128
       *red |= *red >> rbits;
 
129
       rbits <<= 1;
 
130
    }
 
131
    
 
132
    *green = ((pixel >> gshift ) & ((1 << gbits) - 1)) << (16 - gbits);
 
133
    while(gbits < 16) {
 
134
       *green |= *green >> gbits;
 
135
       gbits <<= 1;
 
136
    }
 
137
        
 
138
    *blue = ((pixel >> bshift ) & ((1 << bbits) - 1)) << (16 - bbits);
 
139
    while(bbits < 16) {
 
140
       *blue |= *blue >> bbits;
 
141
       bbits <<= 1;
 
142
    }  
 
143
    
 
144
    if(abits) {
 
145
       *alpha = ((pixel >> ashift ) & ((1 << abits) - 1)) << (16 - abits);
 
146
       while(abits < 16) {
 
147
          *alpha |= *alpha >> abits;
 
148
          abits <<= 1;
 
149
       }     
 
150
    } else *alpha = 0xffff;
 
151
      
 
152
    return TRUE;
 
153
}
 
154
 
 
155
/* 8:8:8 + PICT_a8 -> 8:8:8:8 texture */
 
156
 
 
157
void
 
158
XAA_888_plus_PICT_a8_to_8888 (
 
159
    CARD32 color,
 
160
    CARD8  *alphaPtr,   /* in bytes */
 
161
    int    alphaPitch,
 
162
    CARD32  *dstPtr,
 
163
    int    dstPitch,    /* in dwords */
 
164
    int    width,
 
165
    int    height
 
166
){
 
167
    int x;
 
168
 
 
169
    color &= 0x00ffffff;
 
170
 
 
171
    while(height--) {
 
172
        for(x = 0; x < width; x++)
 
173
           dstPtr[x] = color | (alphaPtr[x] << 24);
 
174
        dstPtr += dstPitch;
 
175
        alphaPtr += alphaPitch;
 
176
    } 
 
177
}
 
178
 
 
179
#define DRAWABLE_IS_ON_CARD(pDraw) \
 
180
    (pDraw->type == DRAWABLE_WINDOW || \
 
181
     (pDraw->type == DRAWABLE_PIXMAP && IS_OFFSCREEN_PIXMAP(pDraw)))
 
182
 
 
183
Bool
 
184
XAADoComposite (
 
185
    CARD8      op,
 
186
    PicturePtr pSrc,
 
187
    PicturePtr pMask,
 
188
    PicturePtr pDst,
 
189
    INT16      xSrc,
 
190
    INT16      ySrc,
 
191
    INT16      xMask,
 
192
    INT16      yMask,
 
193
    INT16      xDst,
 
194
    INT16      yDst,
 
195
    CARD16     width,
 
196
    CARD16     height
 
197
){
 
198
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
 
199
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
 
200
    RegionRec region;
 
201
    CARD32 *formats, *dstformats;
 
202
    int flags = 0;
 
203
    BoxPtr pbox;
 
204
    int nbox, w, h;
 
205
 
 
206
    if(!REGION_NUM_RECTS(pDst->pCompositeClip))
 
207
        return TRUE;
 
208
 
 
209
    if(!infoRec->pScrn->vtSema || !DRAWABLE_IS_ON_CARD(pDst->pDrawable))
 
210
        return FALSE;
 
211
 
 
212
    if(DRAWABLE_IS_ON_CARD(pSrc->pDrawable))
 
213
        return FALSE;
 
214
 
 
215
    if (pSrc->transform || (pMask && pMask->transform))
 
216
        return FALSE;
 
217
 
 
218
    if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap))
 
219
        return FALSE;
 
220
        
 
221
    xDst += pDst->pDrawable->x;
 
222
    yDst += pDst->pDrawable->y;
 
223
    xSrc += pSrc->pDrawable->x;
 
224
    ySrc += pSrc->pDrawable->y;
 
225
 
 
226
    if(pMask) {
 
227
        if(pMask->componentAlpha)
 
228
            return FALSE;
 
229
 
 
230
        /* for now we only do it if there is a 1x1 (solid) source */
 
231
 
 
232
        if((pSrc->pDrawable->width == 1) && (pSrc->pDrawable->height == 1)) {
 
233
           CARD16 red, green, blue, alpha;
 
234
           CARD32 pixel =
 
235
                *((CARD32*)(((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr));
 
236
 
 
237
           if(!XAAGetRGBAFromPixel(pixel,&red,&green,&blue,&alpha,pSrc->format))
 
238
                return FALSE;
 
239
 
 
240
           xMask += pMask->pDrawable->x;
 
241
           yMask += pMask->pDrawable->y;        
 
242
                
 
243
           /* pull out color expandable operations here */
 
244
           if((pMask->format == PICT_a1) && (alpha == 0xffff) &&
 
245
               (op == PictOpOver) && infoRec->WriteBitmap && !pMask->repeat &&
 
246
               !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY) &&
 
247
               (!(infoRec->WriteBitmapFlags & RGB_EQUAL) || 
 
248
                 ((red == green) && (green == blue))))
 
249
           {
 
250
                PixmapPtr pPix = (PixmapPtr)(pMask->pDrawable);
 
251
                int skipleft;
 
252
                        
 
253
                if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
 
254
                                   xSrc, ySrc, xMask, yMask, xDst, yDst,
 
255
                                   width, height))
 
256
                      return TRUE;
 
257
                      
 
258
                nbox = REGION_NUM_RECTS(&region);
 
259
                pbox = REGION_RECTS(&region);   
 
260
                
 
261
                if(!nbox)
 
262
                    return TRUE;        
 
263
                    
 
264
                XAAGetPixelFromRGBA(&pixel, red, green, blue, 0, pDst->format);
 
265
                    
 
266
                xMask -= xDst;
 
267
                yMask -= yDst;
 
268
 
 
269
                while(nbox--) {
 
270
                    skipleft = pbox->x1 + xMask;
 
271
                    
 
272
                    (*infoRec->WriteBitmap)(infoRec->pScrn,
 
273
                                pbox->x1, pbox->y1, 
 
274
                                pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
 
275
                                (unsigned char*)(pPix->devPrivate.ptr) + 
 
276
                                  (pPix->devKind * (pbox->y1 + yMask)) + 
 
277
                                  ((skipleft >> 3) & ~3), pPix->devKind, 
 
278
                                skipleft & 31, pixel, -1, GXcopy, ~0);
 
279
                    pbox++;
 
280
                }
 
281
                                  
 
282
                /* WriteBitmap sets the Sync flag */              
 
283
                REGION_UNINIT(pScreen, &region);
 
284
                return TRUE;
 
285
          }
 
286
 
 
287
          formats = infoRec->CPUToScreenAlphaTextureFormats;
 
288
          dstformats = infoRec->CPUToScreenAlphaTextureDstFormats;
 
289
          if(!formats || !dstformats)
 
290
                return FALSE;
 
291
 
 
292
          w = pMask->pDrawable->width;
 
293
          h = pMask->pDrawable->height;
 
294
 
 
295
          if(pMask->repeat) {
 
296
              if((infoRec->CPUToScreenAlphaTextureFlags & XAA_RENDER_NO_TILE) ||
 
297
                   ((infoRec->CPUToScreenAlphaTextureFlags & 
 
298
                                   XAA_RENDER_POWER_OF_2_TILE_ONLY) && 
 
299
                                ((h & (h - 1)) || (w & (w - 1)))))
 
300
              {
 
301
                 return FALSE;
 
302
              }
 
303
              flags |= XAA_RENDER_REPEAT;
 
304
          } 
 
305
 
 
306
          if((alpha != 0xffff) &&
 
307
              (infoRec->CPUToScreenAlphaTextureFlags & XAA_RENDER_NO_SRC_ALPHA))
 
308
                return FALSE;
 
309
 
 
310
          while(*formats != pMask->format) {
 
311
                if(!(*formats)) return FALSE;
 
312
                formats++;
 
313
          }
 
314
          while(*dstformats != pDst->format) {
 
315
                if(!(*dstformats))
 
316
                    return FALSE;
 
317
                dstformats++;
 
318
          }
 
319
 
 
320
          if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
 
321
                                   xSrc, ySrc, xMask, yMask, xDst, yDst,
 
322
                                   width, height))
 
323
                return TRUE;
 
324
 
 
325
          nbox = REGION_NUM_RECTS(&region);
 
326
          pbox = REGION_RECTS(&region);   
 
327
             
 
328
          if(!nbox) {
 
329
                REGION_UNINIT(pScreen, &region);
 
330
                return TRUE;
 
331
          }
 
332
 
 
333
          if(!(infoRec->SetupForCPUToScreenAlphaTexture2)(infoRec->pScrn,
 
334
                        op, red, green, blue, alpha, pMask->format,
 
335
                        pDst->format,
 
336
                        ((PixmapPtr)(pMask->pDrawable))->devPrivate.ptr,
 
337
                        ((PixmapPtr)(pMask->pDrawable))->devKind, 
 
338
                        w, h, flags))
 
339
          {
 
340
                REGION_UNINIT(pScreen, &region);
 
341
                return FALSE;
 
342
          }
 
343
 
 
344
           xMask -= xDst;
 
345
           yMask -= yDst;
 
346
        
 
347
           while(nbox--) {
 
348
              (*infoRec->SubsequentCPUToScreenAlphaTexture)(infoRec->pScrn,
 
349
                        pbox->x1, pbox->y1, 
 
350
                        pbox->x1 + xMask, pbox->y1 + yMask,
 
351
                        pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
 
352
              pbox++;
 
353
           }
 
354
 
 
355
           SET_SYNC_FLAG(infoRec);
 
356
           REGION_UNINIT(pScreen, &region);
 
357
           return TRUE;
 
358
        }
 
359
    } else {
 
360
        formats = infoRec->CPUToScreenTextureFormats;
 
361
        dstformats = infoRec->CPUToScreenTextureDstFormats;
 
362
        if(!formats || !dstformats)
 
363
            return FALSE;
 
364
 
 
365
        w = pSrc->pDrawable->width;
 
366
        h = pSrc->pDrawable->height;
 
367
 
 
368
        if(pSrc->repeat) {
 
369
              if((infoRec->CPUToScreenTextureFlags & XAA_RENDER_NO_TILE) ||
 
370
                   ((infoRec->CPUToScreenTextureFlags &
 
371
                                   XAA_RENDER_POWER_OF_2_TILE_ONLY) &&
 
372
                                ((h & (h - 1)) || (w & (w - 1)))))
 
373
              {
 
374
                 return FALSE;
 
375
              }
 
376
              flags |= XAA_RENDER_REPEAT;
 
377
        }
 
378
 
 
379
        while(*formats != pSrc->format) {
 
380
            if(!(*formats)) return FALSE;
 
381
            formats++;
 
382
        }
 
383
        while(*dstformats != pDst->format) {
 
384
            if(!(*dstformats))
 
385
                return FALSE;
 
386
            dstformats++;
 
387
        }
 
388
 
 
389
        if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
 
390
                                   xSrc, ySrc, xMask, yMask, xDst, yDst,
 
391
                                   width, height))
 
392
                return TRUE;
 
393
 
 
394
        nbox = REGION_NUM_RECTS(&region);
 
395
        pbox = REGION_RECTS(&region);   
 
396
             
 
397
        if(!nbox) {
 
398
             REGION_UNINIT(pScreen, &region);
 
399
             return TRUE;
 
400
        }
 
401
 
 
402
        if(!(infoRec->SetupForCPUToScreenTexture2)(infoRec->pScrn,
 
403
                        op, pSrc->format, pDst->format, 
 
404
                        ((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr,
 
405
                        ((PixmapPtr)(pSrc->pDrawable))->devKind, 
 
406
                        w, h, flags))
 
407
        {
 
408
              REGION_UNINIT(pScreen, &region);
 
409
              return FALSE;
 
410
        }
 
411
 
 
412
 
 
413
        xSrc -= xDst;
 
414
        ySrc -= yDst;
 
415
        
 
416
        while(nbox--) {
 
417
            (*infoRec->SubsequentCPUToScreenTexture)(infoRec->pScrn,
 
418
                        pbox->x1, pbox->y1, 
 
419
                        pbox->x1 + xSrc, pbox->y1 + ySrc,
 
420
                        pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
 
421
            pbox++;
 
422
         }
 
423
 
 
424
        SET_SYNC_FLAG(infoRec);
 
425
        REGION_UNINIT(pScreen, &region);
 
426
        return TRUE;
 
427
    }
 
428
 
 
429
 
 
430
    return FALSE;
 
431
}
 
432
 
 
433
static void
 
434
XAACompositeSrcCopy (PicturePtr pSrc,
 
435
                     PicturePtr pDst,
 
436
                     INT16      xSrc,
 
437
                     INT16      ySrc,
 
438
                     INT16      xDst,
 
439
                     INT16      yDst,
 
440
                     CARD16     width,
 
441
                     CARD16     height)
 
442
{
 
443
    ScreenPtr   pScreen = pDst->pDrawable->pScreen;
 
444
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
 
445
    int i, nbox;
 
446
    int xoff, yoff;
 
447
    BoxPtr pbox;
 
448
    DDXPointPtr pptSrc;
 
449
    RegionRec region;
 
450
 
 
451
    xDst += pDst->pDrawable->x;
 
452
    yDst += pDst->pDrawable->y;
 
453
    xSrc += pSrc->pDrawable->x;
 
454
    ySrc += pSrc->pDrawable->y;
 
455
 
 
456
    if (!miComputeCompositeRegion (&region, pSrc, NULL, pDst,
 
457
                                   xSrc, ySrc, 0, 0, xDst, yDst,
 
458
                                   width, height))
 
459
        return;
 
460
 
 
461
    nbox = REGION_NUM_RECTS(&region);
 
462
    pbox = REGION_RECTS(&region);   
 
463
 
 
464
    if(!nbox) {
 
465
        REGION_UNINIT(pScreen, &region);
 
466
        return;
 
467
    }
 
468
    pptSrc = ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
 
469
    if (!pptSrc) {
 
470
        REGION_UNINIT(pScreen, &region);
 
471
        return;
 
472
    }
 
473
    xoff = xSrc - xDst;
 
474
    yoff = ySrc - yDst;
 
475
    for (i = 0; i < nbox; i++) {
 
476
        pptSrc[i].x = pbox[i].x1 + xoff;
 
477
        pptSrc[i].y = pbox[i].y1 + yoff; 
 
478
    }
 
479
 
 
480
    infoRec->ScratchGC.planemask = ~0L;
 
481
    infoRec->ScratchGC.alu = GXcopy;
 
482
 
 
483
    XAADoBitBlt(pSrc->pDrawable, pDst->pDrawable, &infoRec->ScratchGC, &region,
 
484
                pptSrc);
 
485
 
 
486
    DEALLOCATE_LOCAL(pptSrc);
 
487
    REGION_UNINIT(pScreen, &region);
 
488
    return;
 
489
}
 
490
 
 
491
void
 
492
XAAComposite (CARD8      op,
 
493
              PicturePtr pSrc,
 
494
              PicturePtr pMask,
 
495
              PicturePtr pDst,
 
496
              INT16      xSrc,
 
497
              INT16      ySrc,
 
498
              INT16      xMask,
 
499
              INT16      yMask,
 
500
              INT16      xDst,
 
501
              INT16      yDst,
 
502
              CARD16     width,
 
503
              CARD16     height)
 
504
{
 
505
    ScreenPtr   pScreen = pDst->pDrawable->pScreen;
 
506
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
 
507
    XAA_RENDER_PROLOGUE(pScreen, Composite);
 
508
 
 
509
    if((op == PictOpSrc) && !pMask && infoRec->pScrn->vtSema &&
 
510
        infoRec->ScreenToScreenBitBlt &&
 
511
        pSrc->pDrawable &&
 
512
        DRAWABLE_IS_ON_CARD(pSrc->pDrawable) &&
 
513
        DRAWABLE_IS_ON_CARD(pDst->pDrawable) &&
 
514
        !pSrc->transform && !pSrc->repeat && (pSrc->format == pDst->format))
 
515
    {
 
516
        XAACompositeSrcCopy(pSrc, pDst, xSrc, ySrc, xDst, yDst, width, height);
 
517
    } else if(!pSrc->pDrawable || (pMask && !pMask->pDrawable) ||
 
518
              !infoRec->Composite ||
 
519
              !(*infoRec->Composite)(op, pSrc, pMask, pDst,
 
520
                                     xSrc, ySrc, xMask, yMask, xDst, yDst,
 
521
                                     width, height))
 
522
    {
 
523
        if(infoRec->pScrn->vtSema &&
 
524
           ((pSrc->pDrawable &&
 
525
             (pSrc->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))) ||
 
526
            pDst->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pDst->pDrawable))) {
 
527
            SYNC_CHECK(pDst->pDrawable);
 
528
        }
 
529
        (*GetPictureScreen(pScreen)->Composite) (op,
 
530
                       pSrc,
 
531
                       pMask,
 
532
                       pDst,
 
533
                       xSrc,
 
534
                       ySrc,
 
535
                       xMask,
 
536
                       yMask,
 
537
                       xDst,
 
538
                       yDst,
 
539
                       width,
 
540
                       height);    
 
541
    }
 
542
 
 
543
    if(pDst->pDrawable->type == DRAWABLE_PIXMAP)
 
544
        (XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDst->pDrawable)))->flags |= DIRTY;
 
545
 
 
546
    XAA_RENDER_EPILOGUE(pScreen, Composite, XAAComposite);
 
547
}
 
548
 
 
549
Bool
 
550
XAADoGlyphs (CARD8         op,
 
551
           PicturePtr    pSrc,
 
552
           PicturePtr    pDst,
 
553
           PictFormatPtr maskFormat,
 
554
           INT16         xSrc,
 
555
           INT16         ySrc,
 
556
           int           nlist,
 
557
           GlyphListPtr  list,
 
558
           GlyphPtr      *glyphs)
 
559
{
 
560
    ScreenPtr   pScreen = pDst->pDrawable->pScreen;
 
561
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
 
562
 
 
563
    if(!REGION_NUM_RECTS(pDst->pCompositeClip))
 
564
        return TRUE;
 
565
 
 
566
    if(!infoRec->pScrn->vtSema || 
 
567
      ((pDst->pDrawable->type != DRAWABLE_WINDOW) &&
 
568
        !IS_OFFSCREEN_PIXMAP(pDst->pDrawable)))
 
569
        return FALSE;
 
570
 
 
571
    if((pSrc->pDrawable->type != DRAWABLE_PIXMAP) ||
 
572
        IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))
 
573
        return FALSE;
 
574
 
 
575
    if(maskFormat && (maskFormat->depth == 1) && 
 
576
       (pSrc->pDrawable->width == 1) && (pSrc->pDrawable->height == 1) &&
 
577
       (op == PictOpOver) && infoRec->WriteBitmap &&
 
578
       !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY))
 
579
    {
 
580
        CARD16 red, green, blue, alpha;
 
581
        CARD32 pixel =
 
582
                *((CARD32*)(((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr));
 
583
        CARD32 *bits, *pntr, *pnt;
 
584
        int x, y, i, n, left, top, right, bottom, width, height, pitch;
 
585
        int L, T, R, B, X, Y, h, w, dwords, row, column, nbox;
 
586
        int leftEdge, rightEdge, topLine, botLine;
 
587
        BoxPtr pbox;
 
588
        GlyphPtr glyph;
 
589
        
 
590
        if(!XAAGetRGBAFromPixel(pixel,&red,&green,&blue,&alpha,pSrc->format))
 
591
                return FALSE;
 
592
 
 
593
        if(alpha != 0xffff) return FALSE;
 
594
 
 
595
        XAAGetPixelFromRGBA(&pixel, red, green, blue, 0, pDst->format);
 
596
 
 
597
        if((infoRec->WriteBitmapFlags & RGB_EQUAL) && !((red == green) && (green == blue)))
 
598
           return FALSE;
 
599
 
 
600
        x = pDst->pDrawable->x;
 
601
        y = pDst->pDrawable->y;
 
602
 
 
603
        while(nlist--) {
 
604
            x += list->xOff;
 
605
            y += list->yOff;
 
606
            left = right = X = x;
 
607
            top = bottom = Y = y;
 
608
            for(i = 0; i < list->len; i++) {
 
609
                glyph = glyphs[i];
 
610
 
 
611
                L = X - glyph->info.x;
 
612
                if(L < left) left = L;
 
613
                R = L + glyph->info.width;
 
614
                if(R > right) right = R;
 
615
 
 
616
                T = Y - glyph->info.y;
 
617
                if(T < top) top = T;
 
618
                B = T + glyph->info.height;
 
619
                if(B > bottom) bottom = B;
 
620
 
 
621
                X += glyph->info.xOff;
 
622
                Y += glyph->info.yOff;
 
623
            }
 
624
 
 
625
            width = right - left;
 
626
            height = bottom - top;
 
627
 
 
628
            if(width && height) {
 
629
                pitch = (((width + 31) & ~31) >> 5) + 1;
 
630
                pntr = (CARD32*)xalloc(sizeof(CARD32) * pitch * height);
 
631
                if(!pntr) 
 
632
                    return TRUE;
 
633
                bzero(pntr, sizeof(CARD32) * pitch * height);
 
634
                n = list->len;
 
635
 
 
636
                X = x; Y = y;
 
637
                while(n--) {
 
638
                    glyph = *glyphs++;
 
639
                    h = glyph->info.height;
 
640
                    w = glyph->info.width;
 
641
                    if(h && w) {
 
642
                        row = y - top - glyph->info.y;
 
643
                        column = x - left - glyph->info.x;
 
644
                        pnt = pntr + (row * pitch) + (column >> 5);
 
645
                        column &= 31;
 
646
                        dwords = ((w + 31) >> 5) - 1;
 
647
                        bits = (CARD32*)(glyph + 1);
 
648
                        if(dwords) {
 
649
                          while(h--) {
 
650
                            for(i = 0; i <= dwords; i++) {
 
651
                                if(column) {
 
652
                                    pnt[i] |= SHIFT_L(*bits, column);
 
653
                                    pnt[i + 1] |= SHIFT_R(*bits, 32 - column);
 
654
                                } else
 
655
                                    pnt[i] |= *bits;
 
656
 
 
657
                                if(i != dwords) bits++;
 
658
                            }
 
659
                            bits++;
 
660
                            pnt += pitch;
 
661
                          } 
 
662
                        } else {
 
663
                          if(column) {
 
664
                             while(h--) {
 
665
                                pnt[0] |= SHIFT_L(*bits, column);
 
666
                                pnt[0 + 1] |= SHIFT_R(*bits, 32 - column);
 
667
                                bits++;
 
668
                                pnt += pitch;
 
669
                             }
 
670
                          } else {
 
671
                             while(h--) {
 
672
                                *pnt |= *bits++;
 
673
                                pnt += pitch;
 
674
                             }                    
 
675
                          }       
 
676
                        }
 
677
                    }
 
678
                    x += glyph->info.xOff;
 
679
                    y += glyph->info.yOff;
 
680
                }
 
681
                
 
682
                nbox = REGION_NUM_RECTS(pDst->pCompositeClip);
 
683
                pbox = REGION_RECTS(pDst->pCompositeClip);
 
684
                
 
685
                while(nbox && (top >= pbox->y2)) {
 
686
                    pbox++; nbox--;
 
687
                }
 
688
                
 
689
                while(nbox && (bottom > pbox->y1)) {            
 
690
                    leftEdge = max(left, pbox->x1);
 
691
                    rightEdge = min(right, pbox->x2);
 
692
                    
 
693
                    if(rightEdge > leftEdge) {
 
694
                        column = leftEdge - left;
 
695
                        topLine = max(top, pbox->y1);
 
696
                        botLine = min(bottom, pbox->y2);
 
697
                        h = botLine - topLine;
 
698
                        
 
699
                        if(h > 0) {
 
700
                          (*infoRec->WriteBitmap)(infoRec->pScrn, 
 
701
                                leftEdge, topLine, rightEdge - leftEdge, h,
 
702
                                (unsigned char*)(pntr + 
 
703
                                  ((topLine - top) * pitch) + (column >> 5)),
 
704
                                pitch << 2, column & 31, pixel, -1, GXcopy, ~0);
 
705
                        }
 
706
                    }   
 
707
                    nbox--; pbox++;
 
708
                }
 
709
                xfree(pntr);
 
710
            } else {
 
711
                x = X; y = Y;
 
712
            }
 
713
            list++;
 
714
        }
 
715
 
 
716
        return TRUE;
 
717
    }
 
718
 
 
719
    /*
 
720
     * If it looks like we have a chance of being able to draw these
 
721
     * glyphs with an accelerated Composite, do that now to avoid
 
722
     * unneeded and costly syncs.
 
723
     */
 
724
    if(maskFormat) {
 
725
        if(!infoRec->CPUToScreenAlphaTextureFormats)
 
726
            return FALSE;
 
727
    } else {
 
728
        if(!infoRec->CPUToScreenTextureFormats)
 
729
            return FALSE;
 
730
    }
 
731
 
 
732
    miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
 
733
 
 
734
    return TRUE;
 
735
}          
 
736
         
 
737
        
 
738
void
 
739
XAAGlyphs (CARD8         op,
 
740
           PicturePtr    pSrc,
 
741
           PicturePtr    pDst,
 
742
           PictFormatPtr maskFormat,
 
743
           INT16         xSrc,
 
744
           INT16         ySrc,
 
745
           int           nlist,
 
746
           GlyphListPtr  list,
 
747
           GlyphPtr      *glyphs)
 
748
{
 
749
    ScreenPtr   pScreen = pDst->pDrawable->pScreen;
 
750
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
 
751
    XAA_RENDER_PROLOGUE(pScreen, Glyphs);
 
752
 
 
753
    if(!pSrc->pDrawable || !infoRec->Glyphs ||
 
754
       !(*infoRec->Glyphs)(op, pSrc, pDst, maskFormat,
 
755
                           xSrc, ySrc, nlist, list, glyphs))
 
756
    {
 
757
        if(infoRec->pScrn->vtSema &&
 
758
           ((pSrc->pDrawable &&
 
759
             (pSrc->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))) ||
 
760
            pDst->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pDst->pDrawable))) {
 
761
            SYNC_CHECK(pDst->pDrawable);
 
762
        }
 
763
       (*GetPictureScreen(pScreen)->Glyphs) (op, pSrc, pDst, maskFormat,
 
764
                                          xSrc, ySrc, nlist, list, glyphs);
 
765
    }
 
766
 
 
767
    if(pDst->pDrawable->type == DRAWABLE_PIXMAP)
 
768
        (XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDst->pDrawable)))->flags |= DIRTY;
 
769
 
 
770
    XAA_RENDER_EPILOGUE(pScreen, Glyphs, XAAGlyphs);
 
771
}