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

« back to all changes in this revision

Viewing changes to hw/xfree86/xaa/xaaPCache.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
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaPCache.c,v 1.32tsi Exp $ */
 
2
 
 
3
#ifdef HAVE_XORG_CONFIG_H
 
4
#include <xorg-config.h>
 
5
#endif
 
6
 
 
7
#include "misc.h"
 
8
#include "xf86.h"
 
9
#include "xf86_ansic.h"
 
10
#include "xf86_OSproc.h"
 
11
 
 
12
#include <X11/X.h>
 
13
#include "scrnintstr.h"
 
14
#include "gc.h"
 
15
#include "mi.h"
 
16
#include "pixmapstr.h"
 
17
#include "windowstr.h"
 
18
#include "regionstr.h"
 
19
#include "servermd.h"
 
20
#include "xf86str.h"
 
21
#include "xaa.h"
 
22
#include "xaacexp.h"
 
23
#include "xaalocal.h"
 
24
#include "xaawrap.h"
 
25
 
 
26
#define MAX_COLOR       32
 
27
#define MAX_MONO        32
 
28
#define MAX_8           32
 
29
#define MAX_128         32
 
30
#define MAX_256         32
 
31
#define MAX_512         16
 
32
 
 
33
static int CacheInitIndex = -1;
 
34
#define CACHEINIT(p) ((p)->privates[CacheInitIndex].val)
 
35
        
 
36
 
 
37
typedef struct _CacheLink {
 
38
   int x;
 
39
   int y;
 
40
   int w;
 
41
   int h;
 
42
   struct _CacheLink *next;
 
43
} CacheLink, *CacheLinkPtr;
 
44
 
 
45
 
 
46
static void
 
47
TransferList(CacheLinkPtr list, XAACacheInfoPtr array, int num)
 
48
{
 
49
   while(num--) {
 
50
        array->x = list->x;
 
51
        array->y = list->y;
 
52
        array->w = list->w;
 
53
        array->h = list->h;
 
54
        array->serialNumber = 0;
 
55
        array->fg = array->bg = -1;
 
56
        list = list->next;
 
57
        array++;
 
58
  }
 
59
}
 
60
 
 
61
 
 
62
 
 
63
static CacheLinkPtr 
 
64
Enlist(CacheLinkPtr link, int x, int y, int w, int h)
 
65
{
 
66
    CacheLinkPtr newLink;
 
67
 
 
68
    newLink = xalloc(sizeof(CacheLink));
 
69
    newLink->next = link;
 
70
    newLink->x = x; newLink->y = y;
 
71
    newLink->w = w; newLink->h = h;     
 
72
    return newLink;
 
73
}
 
74
 
 
75
 
 
76
 
 
77
static CacheLinkPtr
 
78
Delist(CacheLinkPtr link) {
 
79
    CacheLinkPtr ret = NULL;
 
80
 
 
81
    if(link) {
 
82
        ret = link->next;
 
83
        xfree(link);
 
84
    }    
 
85
    return ret;
 
86
}
 
87
 
 
88
 
 
89
 
 
90
static void
 
91
FreeList(CacheLinkPtr link) {
 
92
    CacheLinkPtr tmp;
 
93
 
 
94
    while(link) {
 
95
        tmp = link;
 
96
        link = link->next;
 
97
        xfree(tmp);
 
98
    }
 
99
}
 
100
 
 
101
 
 
102
 
 
103
static CacheLinkPtr
 
104
QuadLinks(CacheLinkPtr big, CacheLinkPtr little) 
 
105
{
 
106
    /* CAUTION: This doesn't free big */
 
107
    int w1, w2, h1, h2;
 
108
 
 
109
    while(big) {
 
110
        w1 = big->w >> 1;       
 
111
        w2 = big->w - w1;
 
112
        h1 = big->h >> 1;       
 
113
        h2 = big->h - h1;
 
114
 
 
115
        little = Enlist(little, big->x, big->y, w1, h1);
 
116
        little = Enlist(little, big->x + w1, big->y, w2, h1);
 
117
        little = Enlist(little, big->x, big->y + h1, w1, h2);
 
118
        little = Enlist(little, big->x + w1, big->y + h1, w2, h2);
 
119
 
 
120
        big = big->next;
 
121
    }     
 
122
    return little;
 
123
}
 
124
 
 
125
 
 
126
static void
 
127
SubdivideList(CacheLinkPtr *large, CacheLinkPtr *small)
 
128
{
 
129
   CacheLinkPtr big = *large;
 
130
   CacheLinkPtr little = *small;
 
131
   int size = big->w >> 1;
 
132
 
 
133
   little = Enlist(little, big->x, big->y, size, size);
 
134
   little = Enlist(little, big->x + size, big->y, size, size);
 
135
   little = Enlist(little, big->x, big->y + size, size, size);
 
136
   little = Enlist(little, big->x + size, big->y + size, size, size);
 
137
   *small = little;
 
138
   big = Delist(big);
 
139
   *large = big;
 
140
}
 
141
 
 
142
static void
 
143
FreePixmapCachePrivate(XAAPixmapCachePrivatePtr pPriv)
 
144
{
 
145
    if(!pPriv) return;
 
146
 
 
147
    if(pPriv->Info512)
 
148
        xfree(pPriv->Info512);
 
149
    if(pPriv->Info256)
 
150
        xfree(pPriv->Info256);
 
151
    if(pPriv->Info128)
 
152
        xfree(pPriv->Info128);
 
153
    if(pPriv->InfoColor)
 
154
        xfree(pPriv->InfoColor);
 
155
    if(pPriv->InfoMono)
 
156
        xfree(pPriv->InfoMono);
 
157
    if(pPriv->InfoPartial)
 
158
        xfree(pPriv->InfoPartial);
 
159
     
 
160
    xfree(pPriv);
 
161
}
 
162
 
 
163
void
 
164
XAAClosePixmapCache(ScreenPtr pScreen)
 
165
{
 
166
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
 
167
  
 
168
   if(infoRec->PixmapCachePrivate)
 
169
        FreePixmapCachePrivate(
 
170
                (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate);
 
171
 
 
172
   infoRec->PixmapCachePrivate = NULL;
 
173
}
 
174
 
 
175
 
 
176
 
 
177
static CacheLinkPtr
 
178
ThinOutPartials(
 
179
   CacheLinkPtr ListPartial, 
 
180
   int *num, int *maxw, int *maxh
 
181
) { 
 
182
/* This guy's job is to get at least 4 big slots out of a list of fragments */
 
183
 
 
184
   CacheLinkPtr List64, List32, List16, List8, pCur, next, ListKeepers;
 
185
   int Num64, Num32, Num16, Num8, NumKeepers;
 
186
   int w, h;
 
187
 
 
188
   List64 = List32 = List16 = List8 = ListKeepers = NULL;
 
189
   Num64 = Num32 = Num16 = Num8 = NumKeepers = 0;
 
190
   w = h = 0;
 
191
 
 
192
   /* We sort partials by how large a square tile they can cache.
 
193
        If a partial can't store a 64x64, 32x32, 16x16 or 8x8 tile,
 
194
        we free it.  */
 
195
 
 
196
   pCur = ListPartial;
 
197
   while(pCur) {
 
198
        next = pCur->next;
 
199
        if((pCur->w >= 64) && (pCur->h >= 64)) {
 
200
            pCur->next = List64; List64 = pCur;
 
201
            Num64++;
 
202
        } else
 
203
        if((pCur->w >= 32) && (pCur->h >= 32)) {
 
204
            pCur->next = List32; List32 = pCur;
 
205
            Num32++;
 
206
        } else
 
207
        if((pCur->w >= 16) && (pCur->h >= 16)) {
 
208
            pCur->next = List16; List16 = pCur;
 
209
            Num16++;
 
210
        } else
 
211
        if((pCur->w >= 8) && (pCur->h >= 8)) {
 
212
            pCur->next = List8; List8 = pCur;
 
213
            Num8++;
 
214
        } else {
 
215
           xfree(pCur);
 
216
        }
 
217
 
 
218
        pCur = next;
 
219
   }
 
220
 
 
221
   /* We save all the tiles from the largest bin that we can get
 
222
        at least 4 of.  If there are too few of a bigger slot, we
 
223
        cut it in fourths to make smaller slots. */
 
224
 
 
225
   if(Num64 >= 4) {
 
226
        ListKeepers = List64; List64 = NULL;
 
227
        NumKeepers = Num64;
 
228
        goto GOT_EM;
 
229
   } else if(Num64) {
 
230
        List32 = QuadLinks(List64, List32);
 
231
        Num32 += Num64 * 4;
 
232
        Num64 = 0;
 
233
   }
 
234
 
 
235
   if(Num32 >= 4) {
 
236
        ListKeepers = List32; List32 = NULL;
 
237
        NumKeepers = Num32;
 
238
        goto GOT_EM;
 
239
   } else if(Num32) {
 
240
        List16 = QuadLinks(List32, List16);
 
241
        Num16 += Num32 * 4;
 
242
        Num32 = 0;
 
243
   }
 
244
 
 
245
   if(Num16 >= 4) {
 
246
        ListKeepers = List16; List16 = NULL;
 
247
        NumKeepers = Num16;
 
248
        goto GOT_EM;
 
249
   } else if(Num16) {
 
250
        List8 = QuadLinks(List16, List8);
 
251
        Num8 += Num16 * 4;
 
252
        Num16 = 0;
 
253
   }
 
254
 
 
255
   if(Num8 >= 4) {
 
256
        ListKeepers = List8; List8 = NULL;
 
257
        NumKeepers = Num8;
 
258
        goto GOT_EM;
 
259
   } 
 
260
 
 
261
GOT_EM:
 
262
 
 
263
   /* Free the ones we aren't using */
 
264
        
 
265
   if(List64) FreeList(List64);
 
266
   if(List32) FreeList(List32);
 
267
   if(List16) FreeList(List16);
 
268
   if(List8) FreeList(List8);
 
269
 
 
270
  
 
271
   /* Enlarge the slots if we can */
 
272
 
 
273
   if(ListKeepers) {
 
274
        CacheLinkPtr pLink = ListKeepers;
 
275
        w = h = 128;
 
276
        
 
277
        while(pLink) {
 
278
           if(pLink->w < w) w = pLink->w;
 
279
           if(pLink->h < h) h = pLink->h;
 
280
           pLink = pLink->next;
 
281
        }
 
282
   } 
 
283
 
 
284
   *maxw = w;
 
285
   *maxh = h;
 
286
   *num = NumKeepers;
 
287
   return ListKeepers;
 
288
}
 
289
 
 
290
static void
 
291
ConvertColorToMono(
 
292
   CacheLinkPtr *ColorList, 
 
293
   int ColorW, int ColorH,
 
294
   CacheLinkPtr *MonoList, 
 
295
   int MonoW, int MonoH
 
296
){
 
297
   int x, y, w;
 
298
 
 
299
   x = (*ColorList)->x; y = (*ColorList)->y;
 
300
   *ColorList = Delist(*ColorList);
 
301
  
 
302
   while(ColorH) {
 
303
        ColorH -= MonoH;
 
304
        for(w = 0; w <= (ColorW - MonoW); w += MonoW)
 
305
             *MonoList = Enlist(*MonoList, x + w, y + ColorH, MonoW, MonoH);
 
306
   }   
 
307
}
 
308
 
 
309
static void
 
310
ConvertAllPartialsTo8x8(
 
311
   int *NumMono, int *NumColor,
 
312
   CacheLinkPtr ListPartial,
 
313
   CacheLinkPtr *ListMono,
 
314
   CacheLinkPtr *ListColor,
 
315
   XAAInfoRecPtr infoRec 
 
316
){
 
317
/* This guy extracts as many 8x8 slots as it can out of fragments */
 
318
 
 
319
   int ColorH = infoRec->CacheHeightColor8x8Pattern;
 
320
   int ColorW = infoRec->CacheWidthColor8x8Pattern;
 
321
   int MonoH = infoRec->CacheHeightMono8x8Pattern;
 
322
   int MonoW = infoRec->CacheWidthMono8x8Pattern;
 
323
   int x, y, w, Height, Width;
 
324
   Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
 
325
   Bool DoMono  = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
 
326
   CacheLinkPtr pLink = ListPartial;
 
327
   CacheLinkPtr MonoList = *ListMono, ColorList = *ListColor;
 
328
 
 
329
   if(DoColor && DoMono) { 
 
330
        /* we assume color patterns take more space than color ones */
 
331
        if(MonoH > ColorH) ColorH = MonoH;
 
332
        if(MonoW > ColorW) ColorW = MonoW;
 
333
   }
 
334
 
 
335
   /* Break up the area into as many Color and Mono slots as we can */
 
336
 
 
337
   while(pLink) {
 
338
        Height = pLink->h;
 
339
        Width = pLink->w;
 
340
        x = pLink->x;
 
341
        y = pLink->y;
 
342
 
 
343
        if(DoColor) {
 
344
           while(Height >= ColorH) {            
 
345
                Height -= ColorH;
 
346
                for(w = 0; w <= (Width - ColorW); w += ColorW) {
 
347
                    ColorList = Enlist(
 
348
                        ColorList, x + w, y + Height, ColorW, ColorH);
 
349
                    (*NumColor)++;
 
350
                }
 
351
           }
 
352
        }
 
353
 
 
354
        if(DoMono && (Height >= MonoH)) {
 
355
           while(Height >= MonoH) {             
 
356
                Height -= MonoH;
 
357
                for(w = 0; w <= (Width - MonoW); w += MonoW) {
 
358
                    MonoList = Enlist(
 
359
                        MonoList, x + w, y + Height, MonoW, MonoH);
 
360
                    (*NumMono)++;
 
361
                }
 
362
           }
 
363
        }
 
364
 
 
365
        pLink = pLink->next;
 
366
   }
 
367
 
 
368
 
 
369
   *ListMono = MonoList;
 
370
   *ListColor = ColorList;
 
371
   FreeList(ListPartial);
 
372
}
 
373
 
 
374
 
 
375
static CacheLinkPtr
 
376
ExtractOneThatFits(CacheLinkPtr *initList, int w, int h)
 
377
{
 
378
     CacheLinkPtr list = *initList;
 
379
     CacheLinkPtr prev = NULL;
 
380
 
 
381
     while(list) { 
 
382
        if((list->w >= w) && (list->h >= h)) 
 
383
            break;
 
384
        prev = list;
 
385
        list = list->next;
 
386
     }
 
387
 
 
388
     if(list) {
 
389
        if(prev) 
 
390
           prev->next = list->next;
 
391
        else
 
392
           *initList = list->next;
 
393
 
 
394
        list->next = NULL;
 
395
     }
 
396
 
 
397
     return list;     
 
398
}
 
399
 
 
400
 
 
401
static CacheLinkPtr
 
402
ConvertSomePartialsTo8x8(
 
403
   int *NumMono, int *NumColor, int *NumPartial,
 
404
   CacheLinkPtr ListPartial,
 
405
   CacheLinkPtr *ListMono,
 
406
   CacheLinkPtr *ListColor,
 
407
   int *maxw, int *maxh,
 
408
   XAAInfoRecPtr infoRec 
 
409
){
 
410
/* This guy tries to get 4 of each type of 8x8 slot requested out of
 
411
   a list of fragments all while trying to retain some big fragments
 
412
   for the cache blits */
 
413
 
 
414
   int ColorH = infoRec->CacheHeightColor8x8Pattern;
 
415
   int ColorW = infoRec->CacheWidthColor8x8Pattern;
 
416
   int MonoH = infoRec->CacheHeightMono8x8Pattern;
 
417
   int MonoW = infoRec->CacheWidthMono8x8Pattern;
 
418
   Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
 
419
   Bool DoMono  = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
 
420
   CacheLinkPtr List64, List32, List16, List8, pCur, next, ListKeepers;
 
421
   CacheLinkPtr MonoList = *ListMono, ColorList = *ListColor;
 
422
   int Num64, Num32, Num16, Num8, NumKeepers;
 
423
   int w, h, Width, Height;
 
424
   int MonosPerColor = 1;
 
425
 
 
426
   if(DoColor && DoMono) { 
 
427
        /* we assume color patterns take more space than color ones */
 
428
        if(MonoH > ColorH) ColorH = MonoH;
 
429
        if(MonoW > ColorW) ColorW = MonoW;
 
430
        MonosPerColor = (ColorH/MonoH) * (ColorW/MonoW);
 
431
   }
 
432
 
 
433
   List64 = List32 = List16 = List8 = ListKeepers = MonoList = ColorList = NULL;
 
434
   Num64 = Num32 = Num16 = Num8 = NumKeepers = 0;
 
435
   Width = Height = 0;
 
436
 
 
437
   /* We sort partials by how large a square tile they can cache.
 
438
      We make 8x8 patterns from the leftovers if we can. */
 
439
 
 
440
   pCur = ListPartial;
 
441
   while(pCur) {
 
442
        next = pCur->next;
 
443
        if((pCur->w >= 64) && (pCur->h >= 64)) {
 
444
            pCur->next = List64; List64 = pCur;
 
445
            Num64++;
 
446
        } else
 
447
        if((pCur->w >= 32) && (pCur->h >= 32)) {
 
448
            pCur->next = List32; List32 = pCur;
 
449
            Num32++;
 
450
        } else
 
451
        if((pCur->w >= 16) && (pCur->h >= 16)) {
 
452
            pCur->next = List16; List16 = pCur;
 
453
            Num16++;
 
454
        } else
 
455
        if((pCur->w >= 8) && (pCur->h >= 8)) {
 
456
            pCur->next = List8; List8 = pCur;
 
457
            Num8++;
 
458
        } else {
 
459
           h = pCur->h;
 
460
           if(DoColor && (pCur->w >= ColorW) && (h >= ColorH)) {
 
461
                while(h >= ColorH) {
 
462
                    h -= ColorH;
 
463
                    for(w = 0; w <= (pCur->w - ColorW); w += ColorW) {
 
464
                        ColorList = Enlist( ColorList,
 
465
                            pCur->x + w, pCur->y + h, ColorW, ColorH);
 
466
                        (*NumColor)++;
 
467
                    }   
 
468
                }
 
469
           }    
 
470
           if(DoMono && (pCur->w >= MonoW) && (h >= MonoH)) {
 
471
                while(h >= MonoH) {
 
472
                    h -= MonoH;
 
473
                    for(w = 0; w <= (pCur->w - MonoW); w += MonoW) {
 
474
                        MonoList = Enlist( MonoList,
 
475
                            pCur->x + w, pCur->y + h, MonoW, MonoH);
 
476
                        (*NumMono)++;
 
477
                    }   
 
478
                }
 
479
           }    
 
480
           xfree(pCur);
 
481
        }
 
482
 
 
483
        pCur = next;
 
484
   }
 
485
 
 
486
   /* Try to extract at least 4 of each type of 8x8 slot that we need */
 
487
 
 
488
   if(DoColor) {
 
489
        CacheLinkPtr theOne;
 
490
        while(*NumColor < 4) {
 
491
            theOne = NULL;
 
492
            if(Num8) {
 
493
                if((theOne = ExtractOneThatFits(&List8, ColorW, ColorH))) 
 
494
                        Num8--;
 
495
            }
 
496
            if(Num16 && !theOne) { 
 
497
                if((theOne = ExtractOneThatFits(&List16, ColorW, ColorH))) 
 
498
                        Num16--;
 
499
            }
 
500
            if(Num32 && !theOne) {
 
501
                if((theOne = ExtractOneThatFits(&List32, ColorW, ColorH)))
 
502
                        Num32--;
 
503
            }
 
504
            if(Num64 && !theOne) {
 
505
                if((theOne = ExtractOneThatFits(&List64, ColorW, ColorH)))
 
506
                        Num64--;
 
507
            }
 
508
 
 
509
            if(!theOne) break;
 
510
 
 
511
                
 
512
            ConvertAllPartialsTo8x8(NumMono, NumColor, theOne, 
 
513
                        &MonoList, &ColorList, infoRec);
 
514
 
 
515
            if(DoMono) {
 
516
                while(*NumColor && (*NumMono < 4)) {
 
517
                     ConvertColorToMono(&ColorList, ColorW, ColorH,
 
518
                                &MonoList, MonoW, MonoH);
 
519
                      (*NumColor)--; *NumMono += MonosPerColor;
 
520
                }
 
521
            }
 
522
        }
 
523
   }
 
524
 
 
525
   if(DoMono) {
 
526
        CacheLinkPtr theOne;
 
527
        while(*NumMono < 4) {
 
528
            theOne = NULL;
 
529
            if(Num8) {
 
530
                if((theOne = ExtractOneThatFits(&List8, MonoW, MonoH))) 
 
531
                        Num8--;
 
532
            }
 
533
            if(Num16 && !theOne) { 
 
534
                if((theOne = ExtractOneThatFits(&List16, MonoW, MonoH))) 
 
535
                        Num16--;
 
536
            }
 
537
            if(Num32 && !theOne) {
 
538
                if((theOne = ExtractOneThatFits(&List32, MonoW, MonoH)))
 
539
                        Num32--;
 
540
            }
 
541
            if(Num64 && !theOne) {
 
542
                if((theOne = ExtractOneThatFits(&List64, MonoW, MonoH)))
 
543
                        Num64--;
 
544
            }
 
545
 
 
546
            if(!theOne) break;
 
547
                
 
548
            ConvertAllPartialsTo8x8(NumMono, NumColor, theOne, 
 
549
                        &MonoList, &ColorList, infoRec);
 
550
        }
 
551
   }
 
552
 
 
553
   /* We save all the tiles from the largest bin that we can get
 
554
        at least 4 of.  If there are too few of a bigger slot, we
 
555
        cut it in fourths to make smaller slots. */
 
556
 
 
557
   if(Num64 >= 4) {
 
558
        ListKeepers = List64; List64 = NULL;
 
559
        NumKeepers = Num64;
 
560
        goto GOT_EM;
 
561
   } else if(Num64) {
 
562
        List32 = QuadLinks(List64, List32);
 
563
        Num32 += Num64 * 4;
 
564
        Num64 = 0;
 
565
   }
 
566
 
 
567
   if(Num32 >= 4) {
 
568
        ListKeepers = List32; List32 = NULL;
 
569
        NumKeepers = Num32;
 
570
        goto GOT_EM;
 
571
   } else if(Num32) {
 
572
        List16 = QuadLinks(List32, List16);
 
573
        Num16 += Num32 * 4;
 
574
        Num32 = 0;
 
575
   }
 
576
 
 
577
   if(Num16 >= 4) {
 
578
        ListKeepers = List16; List16 = NULL;
 
579
        NumKeepers = Num16;
 
580
        goto GOT_EM;
 
581
   } else if(Num16) {
 
582
        List8 = QuadLinks(List16, List8);
 
583
        Num8 += Num16 * 4;
 
584
        Num16 = 0;
 
585
   }
 
586
 
 
587
   if(Num8 >= 4) {
 
588
        ListKeepers = List8; List8 = NULL;
 
589
        NumKeepers = Num8;
 
590
        goto GOT_EM;
 
591
   } 
 
592
 
 
593
GOT_EM:
 
594
 
 
595
   /* Free the ones we aren't using */
 
596
        
 
597
   if(List64) 
 
598
        ConvertAllPartialsTo8x8(NumMono, NumColor, List64, 
 
599
                        &MonoList, &ColorList, infoRec);
 
600
   if(List32) 
 
601
        ConvertAllPartialsTo8x8(NumMono, NumColor, List32, 
 
602
                        &MonoList, &ColorList, infoRec);
 
603
   if(List16) 
 
604
        ConvertAllPartialsTo8x8(NumMono, NumColor, List16, 
 
605
                        &MonoList, &ColorList, infoRec);
 
606
   if(List8) 
 
607
        ConvertAllPartialsTo8x8(NumMono, NumColor, List8, 
 
608
                        &MonoList, &ColorList, infoRec);
 
609
 
 
610
 
 
611
   /* Enlarge the slots if we can */
 
612
 
 
613
   if(ListKeepers) {
 
614
        CacheLinkPtr pLink = ListKeepers;
 
615
        Width = Height = 128;
 
616
        
 
617
        while(pLink) {
 
618
           if(pLink->w < Width) Width = pLink->w;
 
619
           if(pLink->h < Height) Height = pLink->h;
 
620
           pLink = pLink->next;
 
621
        }
 
622
   } 
 
623
 
 
624
   *ListMono = MonoList;
 
625
   *ListColor = ColorList;
 
626
   *maxw = Width;
 
627
   *maxh = Height;
 
628
   *NumPartial = NumKeepers;
 
629
   return ListKeepers;
 
630
}
 
631
 
 
632
 
 
633
void 
 
634
XAAInitPixmapCache(     
 
635
    ScreenPtr pScreen, 
 
636
    RegionPtr areas,
 
637
    pointer data
 
638
) {
 
639
   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
 
640
   XAAInfoRecPtr infoRec = (XAAInfoRecPtr)data;
 
641
   XAAPixmapCachePrivatePtr pCachePriv;
 
642
   BoxPtr pBox = REGION_RECTS(areas);
 
643
   int nBox = REGION_NUM_RECTS(areas);
 
644
   int Num512, Num256, Num128, NumPartial, NumColor, NumMono;
 
645
   int Target512, Target256;
 
646
   CacheLinkPtr List512, List256, List128, ListPartial, ListColor, ListMono;
 
647
   int x, y, w, h, ntotal, granularity, width, height, i;
 
648
   int MaxPartialWidth, MaxPartialHeight;
 
649
 
 
650
   infoRec->MaxCacheableTileWidth = 0;
 
651
   infoRec->MaxCacheableTileHeight = 0;
 
652
   infoRec->MaxCacheableStippleHeight = 0;
 
653
   infoRec->MaxCacheableStippleWidth = 0;
 
654
   infoRec->UsingPixmapCache = FALSE;
 
655
 
 
656
 
 
657
   if(!nBox || !pBox || !(infoRec->Flags & PIXMAP_CACHE))
 
658
        return;
 
659
 
 
660
   /* Allocate a persistent per-screen init flag to control messages */
 
661
   if (CacheInitIndex < 0)
 
662
        CacheInitIndex = xf86AllocateScrnInfoPrivateIndex();
 
663
 
 
664
   /* free the old private data if it exists */
 
665
   if(infoRec->PixmapCachePrivate) {
 
666
        FreePixmapCachePrivate(
 
667
                (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate);
 
668
        infoRec->PixmapCachePrivate = NULL;
 
669
   }
 
670
 
 
671
   Num512 = Num256 = Num128 = NumPartial = NumMono = NumColor = 0;
 
672
   List512 = List256 = List128 = ListPartial = ListMono = ListColor = NULL;
 
673
   granularity = infoRec->CachePixelGranularity;
 
674
   if(granularity <= 1) granularity = 0;
 
675
 
 
676
   /* go through the boxes and break it into as many pieces as we can fit */
 
677
 
 
678
   while(nBox--) {
 
679
        x = pBox->x1;
 
680
        if(granularity) {
 
681
            int tmp = x % granularity;
 
682
            if(tmp) x += (granularity - tmp);
 
683
        }
 
684
        width = pBox->x2 - x;
 
685
        if(width <= 0) {pBox++; continue;}
 
686
 
 
687
        y = pBox->y1;
 
688
        height = pBox->y2 - y;
 
689
 
 
690
        for(h = 0; h <= (height - 512); h += 512) {
 
691
            for(w = 0; w <= (width - 512); w += 512) {
 
692
                List512 = Enlist(List512, x + w, y + h, 512, 512);
 
693
                Num512++;       
 
694
            }
 
695
            for(; w <= (width - 256); w += 256) {
 
696
                List256 = Enlist(List256, x + w, y + h, 256, 256);
 
697
                List256 = Enlist(List256, x + w, y + h + 256, 256, 256);
 
698
                Num256 += 2;
 
699
            }
 
700
            for(; w <= (width - 128); w += 128) {
 
701
                List128 = Enlist(List128, x + w, y + h, 128, 128);
 
702
                List128 = Enlist(List128, x + w, y + h + 128, 128, 128);
 
703
                List128 = Enlist(List128, x + w, y + h + 256, 128, 128);
 
704
                List128 = Enlist(List128, x + w, y + h + 384, 128, 128);
 
705
                Num128 += 4;
 
706
            }
 
707
            if(w < width) {
 
708
                int d = width - w;
 
709
                ListPartial = Enlist(ListPartial, x + w, y + h, d, 128);
 
710
                ListPartial = Enlist(ListPartial, x + w, y + h + 128, d, 128);
 
711
                ListPartial = Enlist(ListPartial, x + w, y + h + 256, d, 128);
 
712
                ListPartial = Enlist(ListPartial, x + w, y + h + 384, d, 128);
 
713
                NumPartial += 4;
 
714
            }
 
715
        }
 
716
        for(; h <= (height - 256); h += 256) {
 
717
            for(w = 0; w <= (width - 256); w += 256) {
 
718
                List256 = Enlist(List256, x + w, y + h, 256, 256);
 
719
                Num256++;
 
720
            }
 
721
            for(; w <= (width - 128); w += 128) {
 
722
                List128 = Enlist(List128, x + w, y + h, 128, 128);
 
723
                List128 = Enlist(List128, x + w, y + h + 128, 128, 128);
 
724
                Num128 += 2;
 
725
            }
 
726
            if(w < width) {
 
727
                int d = width - w;
 
728
                ListPartial = Enlist(ListPartial, x + w, y + h, d, 128);
 
729
                ListPartial = Enlist(ListPartial, x + w, y + h + 128, d, 128);
 
730
                NumPartial += 2;
 
731
            }
 
732
        }
 
733
        for(; h <= (height - 128); h += 128) {
 
734
            for(w = 0; w <= (width - 128); w += 128) {
 
735
                List128 = Enlist(List128, x + w, y + h, 128, 128);
 
736
                Num128++;
 
737
            }
 
738
            if(w < width) {
 
739
                ListPartial = Enlist(
 
740
                        ListPartial, x + w, y + h, width - w, 128);
 
741
                NumPartial++;
 
742
            }
 
743
        }
 
744
        if(h < height) {
 
745
            int d = height - h;
 
746
            for(w = 0; w <= (width - 128); w += 128) {
 
747
                ListPartial = Enlist(ListPartial, x + w, y + h, 128, d);
 
748
                NumPartial++;
 
749
            }
 
750
            if(w < width) {
 
751
                ListPartial = Enlist(ListPartial, x + w, y + h, width - w, d);
 
752
                NumPartial++;
 
753
            }
 
754
        }
 
755
        pBox++;
 
756
   }
 
757
 
 
758
 
 
759
/* 
 
760
   by this point we've carved the space into as many 512x512, 256x256
 
761
        and 128x128 blocks as we could fit.  We will then break larger
 
762
        blocks into smaller ones if we need to.  The rules are as follows:
 
763
 
 
764
     512x512 -
 
765
        1) Don't take up more than half the memory.
 
766
        2) Don't bother if you can't get at least four.
 
767
        3) Don't make more than MAX_512.
 
768
        4) Don't have any of there are no 256x256s.
 
769
 
 
770
     256x256 -
 
771
        1) Don't take up more than a quarter of the memory enless there
 
772
                aren't any 512x512s.  Then we can take up to half.
 
773
        2) Don't bother if you can't get at least four.
 
774
        3) Don't make more than MAX_256.
 
775
 
 
776
     128x128 -
 
777
        1) Don't make more than MAX_128.
 
778
 
 
779
     We don't bother with the partial blocks unless we can use them
 
780
     for 8x8 pattern fills or we are short on larger blocks.
 
781
 
 
782
*/
 
783
 
 
784
    ntotal = Num128 + (Num256<<2) + (Num512<<4);   
 
785
        
 
786
    Target512 = ntotal >> 5;
 
787
    if(Target512 < 4) Target512 = 0;
 
788
    if(!Target512) Target256 = ntotal >> 3;
 
789
    else Target256 = ntotal >> 4;
 
790
    if(Target256 < 4) Target256 = 0;
 
791
 
 
792
    if(Num512 && Num256 < 4) {
 
793
        while(Num512 && Num256 < Target256) {
 
794
           SubdivideList(&List512, &List256);
 
795
           Num256 += 4; Num512--;
 
796
        }
 
797
    }
 
798
 
 
799
    if(!Num512) { /* no room */
 
800
    } else if((Num512 < 4) || (!Target512)) {
 
801
        while(Num512) {
 
802
           SubdivideList(&List512, &List256);
 
803
           Num256 += 4; Num512--;
 
804
        }
 
805
    } else if((Num512 > MAX_512) || (Num512 > Target512)){
 
806
        while(Num512 > MAX_512) {
 
807
           SubdivideList(&List512, &List256);
 
808
           Num256 += 4; Num512--;
 
809
        }
 
810
        while(Num512 > Target512) {
 
811
            if(Num256 < MAX_256) {
 
812
                SubdivideList(&List512, &List256);
 
813
                Num256 += 4; Num512--;
 
814
            } else break;
 
815
        }
 
816
    }
 
817
 
 
818
    if(!Num256) { /* no room */
 
819
    } else if((Num256 < 4) || (!Target256)) {
 
820
        while(Num256) {
 
821
           SubdivideList(&List256, &List128);
 
822
           Num128 += 4; Num256--;
 
823
        }
 
824
    } else if((Num256 > MAX_256) || (Num256 > Target256)) {
 
825
        while(Num256 > MAX_256) {
 
826
           SubdivideList(&List256, &List128);
 
827
           Num128 += 4; Num256--;
 
828
        }
 
829
        while(Num256 > Target256) {
 
830
            if(Num128 < MAX_128) {
 
831
                SubdivideList(&List256, &List128);
 
832
                Num128 += 4; Num256--;
 
833
            } else break;
 
834
        }
 
835
    } 
 
836
 
 
837
    if(Num128 && ((Num128 < 4) || (Num128 > MAX_128))) {
 
838
        CacheLinkPtr next;
 
839
        int max = (Num128 > MAX_128) ? MAX_128 : 0;
 
840
 
 
841
        /*
 
842
         * Note: next is set in this way to work around a code generation
 
843
         * bug in gcc 2.7.2.3.
 
844
         */
 
845
        next = List128->next;
 
846
        while(Num128 > max) {
 
847
           List128->next = ListPartial; 
 
848
           ListPartial = List128;
 
849
           if((List128 = next))
 
850
                next = List128->next;
 
851
           NumPartial++; Num128--;
 
852
        }
 
853
    }
 
854
 
 
855
    MaxPartialHeight = MaxPartialWidth = 0;
 
856
 
 
857
    /* at this point we have as many 512x512 and 256x256 slots as we
 
858
        want but may have an excess of 128x128 slots.  We still need
 
859
        to find out if we need 8x8 slots.  We take these from the
 
860
        partials if we have them.  Otherwise, we break some 128x128's */
 
861
 
 
862
    if(!(infoRec->PixmapCacheFlags & (CACHE_MONO_8x8 | CACHE_COLOR_8x8))) {
 
863
        if(NumPartial) {
 
864
            if(Num128) { /* don't bother with partials */
 
865
                FreeList(ListPartial);  
 
866
                NumPartial = 0; ListPartial = NULL;
 
867
            } else {
 
868
           /* We have no big slots.  Weed out the unusable partials */
 
869
                ListPartial = ThinOutPartials(ListPartial, &NumPartial,
 
870
                        &MaxPartialWidth, &MaxPartialHeight);
 
871
            }
 
872
        }
 
873
    } else {
 
874
        int MonosPerColor = 1;
 
875
        int ColorH = infoRec->CacheHeightColor8x8Pattern;
 
876
        int ColorW = infoRec->CacheWidthColor8x8Pattern;
 
877
        int MonoH = infoRec->CacheHeightMono8x8Pattern;
 
878
        int MonoW = infoRec->CacheWidthMono8x8Pattern;
 
879
        Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
 
880
        Bool DoMono  = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
 
881
 
 
882
        if(DoColor) infoRec->CanDoColor8x8 = FALSE;
 
883
        if(DoMono) infoRec->CanDoMono8x8 = FALSE;
 
884
        
 
885
        if(DoColor && DoMono) { 
 
886
            /* we assume color patterns take more space than color ones */
 
887
            if(MonoH > ColorH) ColorH = MonoH;
 
888
            if(MonoW > ColorW) ColorW = MonoW;
 
889
            MonosPerColor = (ColorH/MonoH) * (ColorW/MonoW);
 
890
        }
 
891
 
 
892
        if(Num128) {
 
893
            if(NumPartial) { /* use all for 8x8 slots */
 
894
                ConvertAllPartialsTo8x8(&NumMono, &NumColor, 
 
895
                        ListPartial, &ListMono, &ListColor, infoRec);
 
896
                NumPartial = 0; ListPartial = NULL;
 
897
            } 
 
898
 
 
899
                /* Get some 8x8 slots from the 128 slots */
 
900
            while((Num128 > 4) && 
 
901
                      ((NumMono < MAX_MONO) && (NumColor < MAX_COLOR))) {
 
902
                CacheLinkPtr tmp = NULL;
 
903
 
 
904
                tmp = Enlist(tmp, List128->x, List128->y, 
 
905
                                        List128->w, List128->h);
 
906
                List128 = Delist(List128);
 
907
                Num128--;
 
908
 
 
909
                ConvertAllPartialsTo8x8(&NumMono, &NumColor, 
 
910
                                tmp, &ListMono, &ListColor, infoRec);
 
911
            }
 
912
        } else if(NumPartial) {
 
913
        /* We have share partials between 8x8 slots and tiles. */
 
914
            ListPartial = ConvertSomePartialsTo8x8(&NumMono, &NumColor,         
 
915
                        &NumPartial, ListPartial, &ListMono, &ListColor, 
 
916
                        &MaxPartialWidth, &MaxPartialHeight, infoRec);
 
917
        }
 
918
 
 
919
        
 
920
        if(DoMono && DoColor) {
 
921
            if(NumColor && ((NumColor > MAX_COLOR) || (NumColor < 4))) {
 
922
                int max = (NumColor > MAX_COLOR) ? MAX_COLOR : 0;
 
923
 
 
924
                while(NumColor > max) {
 
925
                    ConvertColorToMono(&ListColor, ColorW, ColorH,
 
926
                                        &ListMono, MonoW, MonoH);
 
927
                    NumColor--; NumMono += MonosPerColor;
 
928
                }
 
929
            }
 
930
 
 
931
            /* favor Mono slots over Color ones */
 
932
            while((NumColor > 4) && (NumMono < MAX_MONO)) {
 
933
                ConvertColorToMono(&ListColor, ColorW, ColorH,
 
934
                                &ListMono, MonoW, MonoH);
 
935
                NumColor--; NumMono += MonosPerColor;
 
936
            }
 
937
        }
 
938
 
 
939
        if(NumMono && ((NumMono > MAX_MONO) || (NumMono < 4))) {
 
940
            int max = (NumMono > MAX_MONO) ? MAX_MONO : 0;
 
941
 
 
942
            while(NumMono > max) {
 
943
                ListMono = Delist(ListMono);
 
944
                NumMono--;
 
945
            }
 
946
        }
 
947
        if(NumColor && ((NumColor > MAX_COLOR) || (NumColor < 4))) {
 
948
            int max = (NumColor > MAX_COLOR) ? MAX_COLOR : 0;
 
949
 
 
950
            while(NumColor > max) {
 
951
                ListColor = Delist(ListColor);
 
952
                NumColor--;
 
953
            }
 
954
        }
 
955
    }
 
956
 
 
957
 
 
958
    pCachePriv = xcalloc(1,sizeof(XAAPixmapCachePrivate));
 
959
    if(!pCachePriv) {
 
960
        if(Num512) FreeList(List512);
 
961
        if(Num256) FreeList(List256);
 
962
        if(Num128) FreeList(List128);
 
963
        if(NumPartial) FreeList(ListPartial);
 
964
        if(NumColor) FreeList(ListColor);
 
965
        if(NumMono) FreeList(ListMono);
 
966
        return;
 
967
    }
 
968
 
 
969
    infoRec->PixmapCachePrivate = (char*)pCachePriv;
 
970
 
 
971
    if(Num512) {
 
972
        pCachePriv->Info512 = xcalloc(Num512,sizeof(XAACacheInfoRec));
 
973
        if(!pCachePriv->Info512) Num512 = 0;
 
974
        if(Num512) TransferList(List512, pCachePriv->Info512, Num512);
 
975
        FreeList(List512);
 
976
        pCachePriv->Num512x512 = Num512;
 
977
    }
 
978
    if(Num256) {
 
979
        pCachePriv->Info256 = xcalloc(Num256, sizeof(XAACacheInfoRec));
 
980
        if(!pCachePriv->Info256) Num256 = 0;
 
981
        if(Num256) TransferList(List256, pCachePriv->Info256, Num256);
 
982
        FreeList(List256);
 
983
        pCachePriv->Num256x256 = Num256;
 
984
    }
 
985
    if(Num128) {
 
986
        pCachePriv->Info128 = xcalloc(Num128, sizeof(XAACacheInfoRec));
 
987
        if(!pCachePriv->Info128) Num128 = 0;
 
988
        if(Num128) TransferList(List128, pCachePriv->Info128, Num128);
 
989
        FreeList(List128);
 
990
        pCachePriv->Num128x128 = Num128;
 
991
    }
 
992
 
 
993
    if(NumPartial) {
 
994
        pCachePriv->InfoPartial = xcalloc(NumPartial, sizeof(XAACacheInfoRec));
 
995
        if(!pCachePriv->InfoPartial) NumPartial = 0;
 
996
        if(NumPartial) 
 
997
            TransferList(ListPartial, pCachePriv->InfoPartial, NumPartial);
 
998
        FreeList(ListPartial);
 
999
        pCachePriv->NumPartial = NumPartial;
 
1000
    }
 
1001
 
 
1002
    if(NumColor) {
 
1003
        pCachePriv->InfoColor = xcalloc(NumColor, sizeof(XAACacheInfoRec));
 
1004
        if(!pCachePriv->InfoColor) NumColor = 0;
 
1005
        if(NumColor) TransferList(ListColor, pCachePriv->InfoColor, NumColor);
 
1006
        FreeList(ListColor);
 
1007
        pCachePriv->NumColor = NumColor;
 
1008
    }
 
1009
 
 
1010
    if(NumMono) {
 
1011
        pCachePriv->InfoMono = xcalloc(NumMono, sizeof(XAACacheInfoRec));
 
1012
        if(!pCachePriv->InfoMono) NumMono = 0;
 
1013
        if(NumMono) TransferList(ListMono, pCachePriv->InfoMono, NumMono);
 
1014
        FreeList(ListMono);
 
1015
        pCachePriv->NumMono = NumMono;
 
1016
    }
 
1017
 
 
1018
 
 
1019
    if(NumPartial) {
 
1020
        infoRec->MaxCacheableTileWidth = MaxPartialWidth;
 
1021
        infoRec->MaxCacheableTileHeight = MaxPartialHeight;
 
1022
    }
 
1023
    if(Num128) 
 
1024
        infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 128;
 
1025
    if(Num256) 
 
1026
        infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 256;
 
1027
    if(Num512) 
 
1028
        infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 512;
 
1029
 
 
1030
     
 
1031
    infoRec->MaxCacheableStippleHeight = infoRec->MaxCacheableTileHeight;
 
1032
    infoRec->MaxCacheableStippleWidth = 
 
1033
                infoRec->MaxCacheableTileWidth * pScrn->bitsPerPixel;
 
1034
    if(infoRec->ScreenToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP) 
 
1035
        infoRec->MaxCacheableStippleWidth /= 3;
 
1036
 
 
1037
    if(NumMono)  {
 
1038
        if(!(infoRec->Mono8x8PatternFillFlags & 
 
1039
                (HARDWARE_PATTERN_PROGRAMMED_ORIGIN | 
 
1040
                 HARDWARE_PATTERN_PROGRAMMED_BITS))) {
 
1041
            int numPerLine = 
 
1042
                  infoRec->CacheWidthMono8x8Pattern/infoRec->MonoPatternPitch;
 
1043
 
 
1044
            for(i = 0; i < 64; i++) { 
 
1045
                pCachePriv->MonoOffsets[i].y = i/numPerLine;
 
1046
                pCachePriv->MonoOffsets[i].x = (i % numPerLine) *
 
1047
                                        infoRec->MonoPatternPitch;
 
1048
            }
 
1049
        }
 
1050
        infoRec->CanDoMono8x8 = TRUE;
 
1051
    }
 
1052
    if(NumColor) {
 
1053
        if(!(infoRec->Color8x8PatternFillFlags & 
 
1054
                                HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) {
 
1055
 
 
1056
           for(i = 0; i < 64; i++) { 
 
1057
                pCachePriv->ColorOffsets[i].y = i & 0x07;
 
1058
                pCachePriv->ColorOffsets[i].x = i & ~0x07;
 
1059
           }
 
1060
        }
 
1061
        infoRec->CanDoColor8x8 = TRUE;
 
1062
    }
 
1063
 
 
1064
    if(!CACHEINIT(pScrn)) {
 
1065
        xf86ErrorF("\tSetting up tile and stipple cache:\n");
 
1066
        if(NumPartial) 
 
1067
           xf86ErrorF("\t\t%i %ix%i slots\n", 
 
1068
                NumPartial, MaxPartialWidth, MaxPartialHeight);
 
1069
        if(Num128) xf86ErrorF("\t\t%i 128x128 slots\n", Num128);
 
1070
        if(Num256) xf86ErrorF("\t\t%i 256x256 slots\n", Num256);
 
1071
        if(Num512) xf86ErrorF("\t\t%i 512x512 slots\n", Num512);
 
1072
        if(NumColor) xf86ErrorF("\t\t%i 8x8 color pattern slots\n", NumColor);
 
1073
        if(NumMono) xf86ErrorF("\t\t%i 8x8 color expansion slots\n", NumMono);
 
1074
    } 
 
1075
 
 
1076
    if(!(NumPartial | Num128 | Num256 | Num512 | NumColor | NumMono)) {
 
1077
        if(!CACHEINIT(pScrn))
 
1078
           xf86ErrorF("\t\tNot enough video memory for pixmap cache\n");
 
1079
    } else infoRec->UsingPixmapCache = TRUE;
 
1080
 
 
1081
    CACHEINIT(pScrn) = 1;
 
1082
}
 
1083
 
 
1084
#if X_BYTE_ORDER == X_BIG_ENDIAN
 
1085
static CARD32 StippleMasks[4] = {
 
1086
   0x80808080,
 
1087
   0xC0C0C0C0,
 
1088
   0x00000000,
 
1089
   0xF0F0F0F0
 
1090
};
 
1091
#else
 
1092
static CARD32 StippleMasks[4] = {
 
1093
   0x01010101,
 
1094
   0x03030303,
 
1095
   0x00000000,
 
1096
   0x0F0F0F0F
 
1097
};
 
1098
#endif
 
1099
 
 
1100
Bool
 
1101
XAACheckStippleReducibility(PixmapPtr pPixmap)
 
1102
{
 
1103
    XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
 
1104
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_DRAWABLE(&pPixmap->drawable);
 
1105
    CARD32 *IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
 
1106
    int w = pPixmap->drawable.width;
 
1107
    int h = pPixmap->drawable.height;
 
1108
    int i;
 
1109
    CARD32 bits[8];
 
1110
    CARD32 mask = SHIFT_R(0xFFFFFFFF,24);
 
1111
 
 
1112
    pPriv->flags |= REDUCIBILITY_CHECKED | REDUCIBLE_TO_2_COLOR;
 
1113
    pPriv->flags &= ~REDUCIBLE_TO_8x8;
 
1114
 
 
1115
    if((w > 32) || (h > 32) || (w & (w - 1)) || (h & (h - 1))) 
 
1116
        return FALSE;
 
1117
 
 
1118
    i = (h > 8) ? 8 : h;
 
1119
 
 
1120
    switch(w) {
 
1121
    case 32:
 
1122
        while(i--) {
 
1123
           bits[i] = IntPtr[i] & mask;
 
1124
            if( (bits[i] != SHIFT_R((IntPtr[i] & SHIFT_L(mask, 8)), 8)) ||
 
1125
                (bits[i] != SHIFT_R((IntPtr[i] & SHIFT_L(mask,16)),16)) ||
 
1126
                (bits[i] != SHIFT_R((IntPtr[i] & SHIFT_L(mask,24)),24)))
 
1127
                return FALSE; 
 
1128
        }
 
1129
        break;
 
1130
    case 16:
 
1131
        while(i--) {
 
1132
           bits[i] = IntPtr[i] & mask;
 
1133
            if(bits[i] != ((IntPtr[i] & SHIFT_R(SHIFT_L(mask,8),8))))
 
1134
                return FALSE; 
 
1135
        }
 
1136
        break;
 
1137
    default: 
 
1138
        while(i--)
 
1139
           bits[i] = IntPtr[i] & mask;
 
1140
        break;
 
1141
    }    
 
1142
 
 
1143
    switch(h) {
 
1144
        case 32: 
 
1145
            if( (IntPtr[8]  != IntPtr[16]) || (IntPtr[9]  != IntPtr[17]) ||
 
1146
                (IntPtr[10] != IntPtr[18]) || (IntPtr[11] != IntPtr[19]) ||
 
1147
                (IntPtr[12] != IntPtr[20]) || (IntPtr[13] != IntPtr[21]) ||
 
1148
                (IntPtr[14] != IntPtr[22]) || (IntPtr[15] != IntPtr[23]) ||
 
1149
                (IntPtr[16] != IntPtr[24]) || (IntPtr[17] != IntPtr[25]) ||
 
1150
                (IntPtr[18] != IntPtr[26]) || (IntPtr[19] != IntPtr[27]) ||
 
1151
                (IntPtr[20] != IntPtr[28]) || (IntPtr[21] != IntPtr[29]) ||
 
1152
                (IntPtr[22] != IntPtr[30]) || (IntPtr[23] != IntPtr[31]))
 
1153
                return FALSE;
 
1154
            /* fall through */
 
1155
        case 16:
 
1156
            if( (IntPtr[0] != IntPtr[8])  || (IntPtr[1] != IntPtr[9])  ||
 
1157
                (IntPtr[2] != IntPtr[10]) || (IntPtr[3] != IntPtr[11]) ||
 
1158
                (IntPtr[4] != IntPtr[12]) || (IntPtr[5] != IntPtr[13]) ||
 
1159
                (IntPtr[6] != IntPtr[14]) || (IntPtr[7] != IntPtr[15]))
 
1160
                return FALSE;
 
1161
        case 8: break;
 
1162
        case 1: bits[1] = bits[0];
 
1163
        case 2: bits[2] = bits[0];      bits[3] = bits[1];
 
1164
        case 4: bits[4] = bits[0];      bits[5] = bits[1];
 
1165
                bits[6] = bits[2];      bits[7] = bits[3];
 
1166
                break;
 
1167
    }
 
1168
        
 
1169
    pPriv->flags |= REDUCIBLE_TO_8x8;
 
1170
 
 
1171
    pPriv->pattern0 = bits[0] | SHIFT_L(bits[1],8) | SHIFT_L(bits[2],16) | SHIFT_L(bits[3],24);
 
1172
    pPriv->pattern1 = bits[4] | SHIFT_L(bits[5],8) | SHIFT_L(bits[6],16) | SHIFT_L(bits[7],24);
 
1173
 
 
1174
    if(w < 8) {
 
1175
        pPriv->pattern0 &= StippleMasks[w - 1];
 
1176
        pPriv->pattern1 &= StippleMasks[w - 1];
 
1177
 
 
1178
        switch(w) {
 
1179
        case 1: pPriv->pattern0 |= SHIFT_L(pPriv->pattern0,1);
 
1180
                pPriv->pattern1 |= SHIFT_L(pPriv->pattern1,1);
 
1181
        case 2: pPriv->pattern0 |= SHIFT_L(pPriv->pattern0,2);
 
1182
                pPriv->pattern1 |= SHIFT_L(pPriv->pattern1,2);
 
1183
        case 4: pPriv->pattern0 |= SHIFT_L(pPriv->pattern0,4);
 
1184
                pPriv->pattern1 |= SHIFT_L(pPriv->pattern1,4);
 
1185
        }
 
1186
    }
 
1187
 
 
1188
    if(infoRec->Mono8x8PatternFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
 
1189
        pPriv->pattern0 = SWAP_BITS_IN_BYTES(pPriv->pattern0);
 
1190
        pPriv->pattern1 = SWAP_BITS_IN_BYTES(pPriv->pattern1);
 
1191
    }
 
1192
 
 
1193
 
 
1194
    return TRUE;
 
1195
}
 
1196
 
 
1197
 
 
1198
Bool
 
1199
XAACheckTileReducibility(PixmapPtr pPixmap, Bool checkMono)
 
1200
{
 
1201
    XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
 
1202
    CARD32 *IntPtr;
 
1203
    int w = pPixmap->drawable.width;
 
1204
    int h = pPixmap->drawable.height;
 
1205
    int pitch = pPixmap->devKind >> 2;
 
1206
    int dwords, i, j;
 
1207
 
 
1208
    pPriv->flags |= REDUCIBILITY_CHECKED;
 
1209
    pPriv->flags &= ~(REDUCIBILITY_CHECKED | REDUCIBLE_TO_2_COLOR);
 
1210
 
 
1211
    if((w > 32) || (h > 32) || (w & (w - 1)) || (h & (h - 1))) 
 
1212
        return FALSE;
 
1213
 
 
1214
    dwords = ((w * pPixmap->drawable.bitsPerPixel) + 31) >> 5;
 
1215
    i = (h > 8) ? 8 : h;
 
1216
 
 
1217
 
 
1218
    if(w > 8) {
 
1219
        IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
 
1220
        switch(pPixmap->drawable.bitsPerPixel) {
 
1221
        case 8:
 
1222
            while(i--) {
 
1223
                for(j = 2; j < dwords; j++)
 
1224
                    if(IntPtr[j] != IntPtr[j & 0x01])
 
1225
                        return FALSE;
 
1226
                IntPtr += pitch;
 
1227
             }
 
1228
             break;
 
1229
        case 16:
 
1230
            while(i--) {
 
1231
                for(j = 4; j < dwords; j++)
 
1232
                    if(IntPtr[j] != IntPtr[j & 0x03])
 
1233
                        return FALSE;
 
1234
                IntPtr += pitch;
 
1235
             }
 
1236
             break;
 
1237
        case 24:
 
1238
            while(i--) {
 
1239
                for(j = 6; j < dwords; j++)
 
1240
                    if(IntPtr[j] != IntPtr[j % 6])
 
1241
                        return FALSE;
 
1242
                IntPtr += pitch;
 
1243
             }
 
1244
             break;
 
1245
        case 32:
 
1246
            while(i--) {
 
1247
                for(j = 8; j < dwords; j++)
 
1248
                    if(IntPtr[j] != IntPtr[j & 0x07])
 
1249
                        return FALSE;
 
1250
                IntPtr += pitch;
 
1251
             }
 
1252
             break;
 
1253
        default:  return FALSE;
 
1254
        }
 
1255
 
 
1256
    }
 
1257
 
 
1258
 
 
1259
    if(h == 32) {
 
1260
        CARD32 *IntPtr2, *IntPtr3, *IntPtr4;
 
1261
        i = 8;
 
1262
        IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
 
1263
        IntPtr2 = IntPtr + (pitch << 3);
 
1264
        IntPtr3 = IntPtr2 + (pitch << 3);
 
1265
        IntPtr4 = IntPtr3 + (pitch << 3);
 
1266
        while(i--) {
 
1267
            for(j = 0; j < dwords; j++)
 
1268
                if((IntPtr[j] != IntPtr2[j]) || (IntPtr[j] != IntPtr3[j]) ||
 
1269
                    (IntPtr[j] != IntPtr4[j]))
 
1270
                        return FALSE;
 
1271
            IntPtr += pitch;
 
1272
            IntPtr2 += pitch;
 
1273
            IntPtr3 += pitch;
 
1274
            IntPtr4 += pitch;
 
1275
        }
 
1276
    } else if (h == 16) {
 
1277
        CARD32 *IntPtr2;
 
1278
        i = 8;
 
1279
        IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
 
1280
        IntPtr2 = IntPtr + (pitch << 3);
 
1281
        while(i--) {
 
1282
            for(j = 0; j < dwords; j++)
 
1283
                if(IntPtr[j] != IntPtr2[j])
 
1284
                        return FALSE;
 
1285
            IntPtr += pitch;
 
1286
            IntPtr2 += pitch;
 
1287
        }
 
1288
    }
 
1289
        
 
1290
    pPriv->flags |= REDUCIBLE_TO_8x8;
 
1291
 
 
1292
    if(checkMono) {
 
1293
        XAAInfoRecPtr infoRec = 
 
1294
                GET_XAAINFORECPTR_FROM_DRAWABLE(&pPixmap->drawable);
 
1295
        unsigned char bits[8];
 
1296
        int fg, bg = -1, x, y;
 
1297
 
 
1298
        i = (h > 8) ? 8 : h;
 
1299
        j = (w > 8) ? 8 : w;
 
1300
 
 
1301
        if(pPixmap->drawable.bitsPerPixel == 8) {
 
1302
            unsigned char *srcp = pPixmap->devPrivate.ptr;
 
1303
            fg = srcp[0];
 
1304
            pitch = pPixmap->devKind;
 
1305
            for(y = 0; y < i; y++) {
 
1306
                bits[y] = 0;
 
1307
                for(x = 0; x < j; x++) {
 
1308
                   if(srcp[x] != fg) {
 
1309
                        if(bg == -1) bg = srcp[x];
 
1310
                        else if(bg != srcp[x]) return TRUE;
 
1311
                   } else bits[y] |= 1 << x;
 
1312
                }
 
1313
                srcp += pitch;
 
1314
            }
 
1315
        } else if(pPixmap->drawable.bitsPerPixel == 16) {
 
1316
            unsigned short *srcp = (unsigned short*)pPixmap->devPrivate.ptr;
 
1317
            fg = srcp[0];
 
1318
            pitch = pPixmap->devKind >> 1;
 
1319
            for(y = 0; y < i; y++) {
 
1320
                bits[y] = 0;
 
1321
                for(x = 0; x < j; x++) {
 
1322
                   if(srcp[x] != fg) {
 
1323
                        if(bg == -1) bg = srcp[x];
 
1324
                        else if(bg != srcp[x]) return TRUE;
 
1325
                   } else bits[y] |= 1 << x;
 
1326
                }
 
1327
                srcp += pitch;
 
1328
            }
 
1329
        } else if(pPixmap->drawable.bitsPerPixel == 24) {
 
1330
            CARD32 val;
 
1331
            unsigned char *srcp = pPixmap->devPrivate.ptr;
 
1332
            fg = *((CARD32*)srcp) & 0x00FFFFFF;
 
1333
            pitch = pPixmap->devKind;
 
1334
            j *= 3;
 
1335
            for(y = 0; y < i; y++) {
 
1336
                bits[y] = 0;
 
1337
                for(x = 0; x < j; x+=3) {
 
1338
                   val = *((CARD32*)(srcp+x)) & 0x00FFFFFF;
 
1339
                   if(val != fg) {
 
1340
                        if(bg == -1) bg = val;
 
1341
                        else if(bg != val) 
 
1342
                                return TRUE;
 
1343
                   } else bits[y] |= 1 << (x/3);
 
1344
                }
 
1345
                srcp += pitch;
 
1346
            }
 
1347
        } else if(pPixmap->drawable.bitsPerPixel == 32) {
 
1348
            IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
 
1349
            fg = IntPtr[0];
 
1350
            for(y = 0; y < i; y++) {
 
1351
                bits[y] = 0;
 
1352
                for(x = 0; x < j; x++) {
 
1353
                   if(IntPtr[x] != fg) {
 
1354
                        if(bg == -1) bg = IntPtr[x];
 
1355
                        else if(bg != IntPtr[x]) return TRUE;
 
1356
                   } else bits[y] |= 1 << x;
 
1357
                }
 
1358
                IntPtr += pitch;
 
1359
            }
 
1360
        } else return TRUE;
 
1361
 
 
1362
        pPriv->fg = fg;
 
1363
        if(bg == -1) pPriv->bg = fg;
 
1364
        else pPriv->bg = bg;
 
1365
   
 
1366
        if(h < 8) {
 
1367
           switch(h) {
 
1368
                case 1: bits[1] = bits[0];
 
1369
                case 2: bits[2] = bits[0];      bits[3] = bits[1];
 
1370
                case 4: bits[4] = bits[0];      bits[5] = bits[1];
 
1371
                        bits[6] = bits[2];      bits[7] = bits[3];
 
1372
                        break;
 
1373
           }
 
1374
        }
 
1375
 
 
1376
        pPriv->pattern0 = 
 
1377
                bits[0] | (bits[1]<<8) | (bits[2]<<16) | (bits[3]<<24);
 
1378
        pPriv->pattern1 = 
 
1379
                bits[4] | (bits[5]<<8) | (bits[6]<<16) | (bits[7]<<24);
 
1380
 
 
1381
        if(w < 8) {
 
1382
           switch(w) {
 
1383
           case 1:      pPriv->pattern0 |= (pPriv->pattern0 << 1);
 
1384
                        pPriv->pattern1 |= (pPriv->pattern1 << 1);
 
1385
           case 2:      pPriv->pattern0 |= (pPriv->pattern0 << 2);
 
1386
                        pPriv->pattern1 |= (pPriv->pattern1 << 2);
 
1387
           case 4:      pPriv->pattern0 |= (pPriv->pattern0 << 4);
 
1388
                        pPriv->pattern1 |= (pPriv->pattern1 << 4);
 
1389
           }
 
1390
        }
 
1391
        pPriv->flags |= REDUCIBLE_TO_2_COLOR;
 
1392
 
 
1393
        if(infoRec->Mono8x8PatternFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
 
1394
            pPriv->pattern0 = SWAP_BITS_IN_BYTES(pPriv->pattern0);
 
1395
            pPriv->pattern1 = SWAP_BITS_IN_BYTES(pPriv->pattern1);
 
1396
        }
 
1397
 
 
1398
    }
 
1399
 
 
1400
    return TRUE;
 
1401
}
 
1402
 
 
1403
 
 
1404
void XAATileCache(
 
1405
   ScrnInfoPtr pScrn, 
 
1406
   XAACacheInfoPtr pCache,
 
1407
   int w, int h
 
1408
) {
 
1409
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
 
1410
 
 
1411
   (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, GXcopy, ~0, -1);
 
1412
 
 
1413
   while((w << 1) <= pCache->w) {
 
1414
        (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
 
1415
                pCache->x + w, pCache->y, w, h);
 
1416
        w <<= 1;
 
1417
   }
 
1418
   if(w != pCache->w) {
 
1419
        (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
 
1420
                pCache->x + w, pCache->y, pCache->w - w, h);
 
1421
        w = pCache->w;
 
1422
   }
 
1423
 
 
1424
   while((h << 1) <= pCache->h) {
 
1425
        (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
 
1426
                pCache->x, pCache->y + h, w, h);
 
1427
        h <<= 1;
 
1428
   }
 
1429
   if(h != pCache->h) {
 
1430
        (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
 
1431
                pCache->x, pCache->y + h, w, pCache->h - h);
 
1432
   }
 
1433
   SET_SYNC_FLAG(infoRec);
 
1434
}
 
1435
 
 
1436
XAACacheInfoPtr
 
1437
XAACacheTile(ScrnInfoPtr pScrn, PixmapPtr pPix)
 
1438
{
 
1439
   int w = pPix->drawable.width;
 
1440
   int h = pPix->drawable.height;
 
1441
   int size = max(w, h);
 
1442
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
 
1443
   XAAPixmapCachePrivatePtr pCachePriv = 
 
1444
        (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
 
1445
   XAACacheInfoPtr pCache, cacheRoot = NULL;
 
1446
   int i, max = 0;
 
1447
   int *current;
 
1448
 
 
1449
   if(size <= 128) {
 
1450
        if(pCachePriv->Info128) {
 
1451
            cacheRoot = pCachePriv->Info128; 
 
1452
            max = pCachePriv->Num128x128;
 
1453
            current = &pCachePriv->Current128;
 
1454
        } else {     
 
1455
            cacheRoot = pCachePriv->InfoPartial;
 
1456
            max = pCachePriv->NumPartial;
 
1457
            current = &pCachePriv->CurrentPartial;
 
1458
        }
 
1459
   } else if(size <= 256) {
 
1460
        cacheRoot = pCachePriv->Info256;      
 
1461
        max = pCachePriv->Num256x256;
 
1462
        current = &pCachePriv->Current256;
 
1463
   } else if(size <= 512) {
 
1464
        cacheRoot = pCachePriv->Info512;      
 
1465
        max = pCachePriv->Num512x512;
 
1466
        current = &pCachePriv->Current512;
 
1467
   } else { /* something's wrong */ 
 
1468
        ErrorF("Something's wrong in XAACacheTile()\n");
 
1469
        return pCachePriv->Info128; 
 
1470
   }
 
1471
 
 
1472
   pCache = cacheRoot;
 
1473
 
 
1474
   /* lets look for it */
 
1475
   for(i = 0; i < max; i++, pCache++) {
 
1476
        if(pCache->serialNumber == pPix->drawable.serialNumber) {
 
1477
            pCache->trans_color = -1;
 
1478
            return pCache;
 
1479
        }
 
1480
   }
 
1481
 
 
1482
   pCache = &cacheRoot[(*current)++];
 
1483
   if(*current >= max) *current = 0;
 
1484
 
 
1485
   pCache->serialNumber = pPix->drawable.serialNumber;
 
1486
   pCache->trans_color = pCache->bg = pCache->fg = -1;
 
1487
   pCache->orig_w = w;  pCache->orig_h = h;
 
1488
   (*infoRec->WritePixmapToCache)(
 
1489
        pScrn, pCache->x, pCache->y, w, h, pPix->devPrivate.ptr,
 
1490
        pPix->devKind, pPix->drawable.bitsPerPixel, pPix->drawable.depth);
 
1491
   if(!(infoRec->PixmapCacheFlags & DO_NOT_TILE_COLOR_DATA) && 
 
1492
        ((w != pCache->w) || (h != pCache->h)))
 
1493
        XAATileCache(pScrn, pCache, w, h);
 
1494
 
 
1495
   return pCache;
 
1496
}
 
1497
 
 
1498
XAACacheInfoPtr
 
1499
XAACacheMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
 
1500
{
 
1501
   int w = pPix->drawable.width;
 
1502
   int h = pPix->drawable.height;
 
1503
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
 
1504
   XAAPixmapCachePrivatePtr pCachePriv = 
 
1505
        (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
 
1506
   XAACacheInfoPtr pCache, cacheRoot = NULL;
 
1507
   int i, max = 0, funcNo, pad, dwords, bpp = pScrn->bitsPerPixel;
 
1508
   int *current;
 
1509
   StippleScanlineProcPtr StippleFunc;
 
1510
   unsigned char *data, *srcPtr, *dstPtr;
 
1511
 
 
1512
   if((h <= 128) && (w <= 128 * bpp)) {
 
1513
        if(pCachePriv->Info128) {
 
1514
            cacheRoot = pCachePriv->Info128; 
 
1515
            max = pCachePriv->Num128x128;
 
1516
            current = &pCachePriv->Current128;
 
1517
        } else {     
 
1518
            cacheRoot = pCachePriv->InfoPartial;
 
1519
            max = pCachePriv->NumPartial;
 
1520
            current = &pCachePriv->CurrentPartial;
 
1521
        }
 
1522
   } else if((h <= 256) && (w <= 256 * bpp)){
 
1523
        cacheRoot = pCachePriv->Info256;      
 
1524
        max = pCachePriv->Num256x256;
 
1525
        current = &pCachePriv->Current256;
 
1526
   } else if((h <= 512) && (w <= 526 * bpp)){
 
1527
        cacheRoot = pCachePriv->Info512;      
 
1528
        max = pCachePriv->Num512x512;
 
1529
        current = &pCachePriv->Current512;
 
1530
   } else { /* something's wrong */ 
 
1531
        ErrorF("Something's wrong in XAACacheMonoStipple()\n");
 
1532
        return pCachePriv->Info128; 
 
1533
   }
 
1534
 
 
1535
   pCache = cacheRoot;
 
1536
 
 
1537
   /* lets look for it */
 
1538
   for(i = 0; i < max; i++, pCache++) {
 
1539
        if((pCache->serialNumber == pPix->drawable.serialNumber) &&
 
1540
            (pCache->fg == -1) && (pCache->bg == -1)) {
 
1541
            pCache->trans_color = -1;
 
1542
            return pCache;
 
1543
        }
 
1544
   }
 
1545
 
 
1546
   pCache = &cacheRoot[(*current)++];
 
1547
   if(*current >= max) *current = 0;
 
1548
 
 
1549
   pCache->serialNumber = pPix->drawable.serialNumber;
 
1550
   pCache->trans_color = pCache->bg = pCache->fg = -1;
 
1551
   pCache->orig_w = w;  pCache->orig_h = h;
 
1552
 
 
1553
   if(w <= 32) {
 
1554
        if(w & (w - 1)) funcNo = 1;
 
1555
        else            funcNo = 0;
 
1556
   } else               funcNo = 2;
 
1557
 
 
1558
   pad = BitmapBytePad(pCache->w * bpp);
 
1559
   dwords = pad >> 2;
 
1560
   dstPtr = data = (unsigned char*)ALLOCATE_LOCAL(pad * pCache->h);
 
1561
   srcPtr = (unsigned char*)pPix->devPrivate.ptr;
 
1562
 
 
1563
   if(infoRec->ScreenToScreenColorExpandFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST)
 
1564
        StippleFunc = XAAStippleScanlineFuncMSBFirst[funcNo];
 
1565
   else
 
1566
        StippleFunc = XAAStippleScanlineFuncLSBFirst[funcNo];
 
1567
 
 
1568
   /* don't bother generating more than we'll ever use */
 
1569
   max = ((pScrn->displayWidth + w - 1) + 31) >> 5;
 
1570
   if(dwords > max)
 
1571
        dwords = max;
 
1572
 
 
1573
   for(i = 0; i < h; i++) {
 
1574
        (*StippleFunc)((CARD32*)dstPtr, (CARD32*)srcPtr, 0, w, dwords);
 
1575
        srcPtr += pPix->devKind;
 
1576
        dstPtr += pad;
 
1577
   }
 
1578
 
 
1579
   while((h<<1) <= pCache->h) {
 
1580
        memcpy(data + (pad * h), data, pad * h);
 
1581
        h <<= 1;
 
1582
   }
 
1583
 
 
1584
   if(h < pCache->h)   
 
1585
        memcpy(data + (pad * h), data, pad * (pCache->h - h));
 
1586
 
 
1587
   (*infoRec->WritePixmapToCache)(
 
1588
        pScrn, pCache->x, pCache->y, pCache->w, pCache->h, data,
 
1589
        pad, bpp, pScrn->depth);
 
1590
 
 
1591
   DEALLOCATE_LOCAL(data);
 
1592
 
 
1593
   return pCache;
 
1594
}
 
1595
 
 
1596
XAACacheInfoPtr
 
1597
XAACachePlanarMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
 
1598
{
 
1599
   int w = pPix->drawable.width;
 
1600
   int h = pPix->drawable.height;
 
1601
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
 
1602
   XAAPixmapCachePrivatePtr pCachePriv = 
 
1603
        (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
 
1604
   XAACacheInfoPtr pCache, cacheRoot = NULL;
 
1605
   int i, max = 0;
 
1606
   int *current;
 
1607
 
 
1608
   if((h <= 128) && (w <= 128)) {
 
1609
        if(pCachePriv->Info128) {
 
1610
            cacheRoot = pCachePriv->Info128; 
 
1611
            max = pCachePriv->Num128x128;
 
1612
            current = &pCachePriv->Current128;
 
1613
        } else {     
 
1614
            cacheRoot = pCachePriv->InfoPartial;
 
1615
            max = pCachePriv->NumPartial;
 
1616
            current = &pCachePriv->CurrentPartial;
 
1617
        }
 
1618
   } else if((h <= 256) && (w <= 256)){
 
1619
        cacheRoot = pCachePriv->Info256;      
 
1620
        max = pCachePriv->Num256x256;
 
1621
        current = &pCachePriv->Current256;
 
1622
   } else if((h <= 512) && (w <= 526)){
 
1623
        cacheRoot = pCachePriv->Info512;      
 
1624
        max = pCachePriv->Num512x512;
 
1625
        current = &pCachePriv->Current512;
 
1626
   } else { /* something's wrong */ 
 
1627
        ErrorF("Something's wrong in XAACachePlanarMonoStipple()\n");
 
1628
        return pCachePriv->Info128; 
 
1629
   }
 
1630
 
 
1631
   pCache = cacheRoot;
 
1632
 
 
1633
   /* lets look for it */
 
1634
   for(i = 0; i < max; i++, pCache++) {
 
1635
        if((pCache->serialNumber == pPix->drawable.serialNumber) &&
 
1636
            (pCache->fg == -1) && (pCache->bg == -1)) {
 
1637
            pCache->trans_color = -1;
 
1638
            return pCache;
 
1639
        }
 
1640
   }
 
1641
 
 
1642
   pCache = &cacheRoot[(*current)++];
 
1643
   if(*current >= max) *current = 0;
 
1644
 
 
1645
   pCache->serialNumber = pPix->drawable.serialNumber;
 
1646
   pCache->trans_color = pCache->bg = pCache->fg = -1;
 
1647
   pCache->orig_w = w;  pCache->orig_h = h;
 
1648
 
 
1649
   /* Plane 0 holds the stipple. Plane 1 holds the inverted stipple */
 
1650
   (*infoRec->WriteBitmapToCache)(pScrn, pCache->x, pCache->y, 
 
1651
        pPix->drawable.width, pPix->drawable.height, pPix->devPrivate.ptr,
 
1652
        pPix->devKind, 1, 2);
 
1653
   if(!(infoRec->PixmapCacheFlags & DO_NOT_TILE_MONO_DATA) && 
 
1654
        ((w != pCache->w) || (h != pCache->h)))
 
1655
        XAATileCache(pScrn, pCache, w, h);
 
1656
 
 
1657
   return pCache;
 
1658
}
 
1659
 
 
1660
XAACachePlanarMonoStippleProc
 
1661
XAAGetCachePlanarMonoStipple(void) { return XAACachePlanarMonoStipple; }
 
1662
 
 
1663
XAACacheInfoPtr
 
1664
XAACacheStipple(ScrnInfoPtr pScrn, PixmapPtr pPix, int fg, int bg)
 
1665
{
 
1666
   int w = pPix->drawable.width;
 
1667
   int h = pPix->drawable.height;
 
1668
   int size = max(w, h);
 
1669
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
 
1670
   XAAPixmapCachePrivatePtr pCachePriv = 
 
1671
        (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
 
1672
   XAACacheInfoPtr pCache, cacheRoot = NULL;
 
1673
   int i, max = 0;
 
1674
   int *current;
 
1675
 
 
1676
   if(size <= 128) {
 
1677
        if(pCachePriv->Info128) {
 
1678
            cacheRoot = pCachePriv->Info128; 
 
1679
            max = pCachePriv->Num128x128;
 
1680
            current = &pCachePriv->Current128;
 
1681
        } else {     
 
1682
            cacheRoot = pCachePriv->InfoPartial;
 
1683
            max = pCachePriv->NumPartial;
 
1684
            current = &pCachePriv->CurrentPartial;
 
1685
        }
 
1686
   } else if(size <= 256) {
 
1687
        cacheRoot = pCachePriv->Info256;      
 
1688
        max = pCachePriv->Num256x256;
 
1689
        current = &pCachePriv->Current256;
 
1690
   } else if(size <= 512) {
 
1691
        cacheRoot = pCachePriv->Info512;      
 
1692
        max = pCachePriv->Num512x512;
 
1693
        current = &pCachePriv->Current512;
 
1694
   } else { /* something's wrong */
 
1695
        ErrorF("Something's wrong in XAACacheStipple()\n");
 
1696
        return pCachePriv->Info128; 
 
1697
   }
 
1698
 
 
1699
   pCache = cacheRoot;
 
1700
   /* lets look for it */
 
1701
   if(bg == -1)
 
1702
        for(i = 0; i < max; i++, pCache++) {
 
1703
            if((pCache->serialNumber == pPix->drawable.serialNumber) &&
 
1704
                (fg == pCache->fg) && (pCache->fg != pCache->bg)) {
 
1705
                pCache->trans_color = pCache->bg;
 
1706
                return pCache;
 
1707
             }
 
1708
        }
 
1709
   else
 
1710
        for(i = 0; i < max; i++, pCache++) {
 
1711
            if((pCache->serialNumber == pPix->drawable.serialNumber) &&
 
1712
                (fg == pCache->fg) && (bg == pCache->bg)) {
 
1713
                pCache->trans_color = -1;
 
1714
                return pCache;
 
1715
             }
 
1716
        }
 
1717
 
 
1718
   pCache = &cacheRoot[(*current)++];
 
1719
   if(*current >= max) *current = 0;
 
1720
 
 
1721
   pCache->serialNumber = pPix->drawable.serialNumber;
 
1722
   pCache->fg = fg;
 
1723
   if(bg == -1)
 
1724
        pCache->trans_color = bg = fg ^ 1;
 
1725
   else
 
1726
        pCache->trans_color = -1;
 
1727
   pCache->bg = bg;
 
1728
 
 
1729
   pCache->orig_w = w;  pCache->orig_h = h;
 
1730
   (*infoRec->WriteBitmapToCache)(pScrn, pCache->x, pCache->y, 
 
1731
        pPix->drawable.width, pPix->drawable.height, pPix->devPrivate.ptr,
 
1732
        pPix->devKind, fg, bg);
 
1733
   if(!(infoRec->PixmapCacheFlags & DO_NOT_TILE_COLOR_DATA) && 
 
1734
        ((w != pCache->w) || (h != pCache->h)))
 
1735
        XAATileCache(pScrn, pCache, w, h);
 
1736
 
 
1737
   return pCache;
 
1738
}
 
1739
 
 
1740
 
 
1741
 
 
1742
XAACacheInfoPtr
 
1743
XAACacheMono8x8Pattern(ScrnInfoPtr pScrn, int pat0, int pat1)
 
1744
{
 
1745
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
 
1746
   XAAPixmapCachePrivatePtr pCachePriv = 
 
1747
        (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
 
1748
   XAACacheInfoPtr pCache = pCachePriv->InfoMono;
 
1749
   int i;
 
1750
 
 
1751
   for(i = 0; i < pCachePriv->NumMono; i++, pCache++) {
 
1752
        if(pCache->serialNumber && 
 
1753
           (pCache->pat0 == pat0) && (pCache->pat1 == pat1))
 
1754
                return pCache;
 
1755
   }
 
1756
 
 
1757
   /* OK, let's cache it */
 
1758
   pCache = &pCachePriv->InfoMono[pCachePriv->CurrentMono++]; 
 
1759
   if(pCachePriv->CurrentMono >= pCachePriv->NumMono) 
 
1760
        pCachePriv->CurrentMono = 0;
 
1761
 
 
1762
   pCache->serialNumber = 1; /* we don't care since we do lookups by pattern */
 
1763
   pCache->pat0 = pat0;
 
1764
   pCache->pat1 = pat1;
 
1765
 
 
1766
   (*infoRec->WriteMono8x8PatternToCache)(pScrn, pCache);
 
1767
 
 
1768
   return pCache;
 
1769
}
 
1770
 
 
1771
 
 
1772
 
 
1773
XAACacheInfoPtr
 
1774
XAACacheColor8x8Pattern(ScrnInfoPtr pScrn, PixmapPtr pPix, int fg, int bg)
 
1775
{
 
1776
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
 
1777
   XAAPixmapCachePrivatePtr pCachePriv = 
 
1778
        (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
 
1779
   XAACacheInfoPtr pCache = pCachePriv->InfoColor;
 
1780
   XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
 
1781
   int i;
 
1782
 
 
1783
   if(!(pixPriv->flags & REDUCIBLE_TO_2_COLOR)) {
 
1784
        for(i = 0; i < pCachePriv->NumColor; i++, pCache++) {
 
1785
             if(pCache->serialNumber == pPix->drawable.serialNumber) {
 
1786
                pCache->trans_color = -1;
 
1787
                return pCache;  
 
1788
             }
 
1789
        }
 
1790
        pCache = &pCachePriv->InfoColor[pCachePriv->CurrentColor++]; 
 
1791
        if(pCachePriv->CurrentColor >= pCachePriv->NumColor) 
 
1792
                pCachePriv->CurrentColor = 0;
 
1793
 
 
1794
        pCache->serialNumber = pPix->drawable.serialNumber;
 
1795
        pCache->trans_color = pCache->fg = pCache->bg = -1;
 
1796
   } else {
 
1797
        int pat0 = pixPriv->pattern0;
 
1798
        int pat1 = pixPriv->pattern1;
 
1799
 
 
1800
        if(fg == -1) { /* it's a tile */
 
1801
           fg = pixPriv->fg; bg = pixPriv->bg;
 
1802
        }
 
1803
 
 
1804
        if(bg == -1) { /* stipple */
 
1805
            for(i = 0; i < pCachePriv->NumColor; i++, pCache++) {
 
1806
                if(pCache->serialNumber &&
 
1807
                   (pCache->pat0 == pat0) && (pCache->pat1 == pat1) &&
 
1808
                   (pCache->fg == fg) && (pCache->bg != fg)) {
 
1809
                   pCache->trans_color = pCache->bg;
 
1810
                   return pCache;       
 
1811
                }
 
1812
            }
 
1813
        } else {  /* opaque stipple */
 
1814
            for(i = 0; i < pCachePriv->NumColor; i++, pCache++) {
 
1815
                if(pCache->serialNumber &&
 
1816
                   (pCache->pat0 == pat0) && (pCache->pat1 == pat1) &&
 
1817
                   (pCache->fg == fg) && (pCache->bg == bg)) {
 
1818
                   pCache->trans_color = -1;
 
1819
                   return pCache;       
 
1820
                }
 
1821
            }
 
1822
        }
 
1823
        pCache = &pCachePriv->InfoColor[pCachePriv->CurrentColor++]; 
 
1824
        if(pCachePriv->CurrentColor >= pCachePriv->NumColor) 
 
1825
                pCachePriv->CurrentColor = 0;
 
1826
 
 
1827
        if(bg == -1)
 
1828
            pCache->trans_color = bg = fg ^ 1;
 
1829
        else
 
1830
            pCache->trans_color = -1;
 
1831
 
 
1832
        pCache->pat0 = pat0; pCache->pat1 = pat1;
 
1833
        pCache->fg = fg; pCache->bg = bg;
 
1834
        pCache->serialNumber = 1;
 
1835
   }
 
1836
 
 
1837
   (*infoRec->WriteColor8x8PatternToCache)(pScrn, pPix, pCache);
 
1838
 
 
1839
   return pCache;
 
1840
}
 
1841
 
 
1842
 
 
1843
void 
 
1844
XAAWriteBitmapToCache(
 
1845
   ScrnInfoPtr pScrn,
 
1846
   int x, int y, int w, int h,
 
1847
   unsigned char *src,
 
1848
   int srcwidth,
 
1849
   int fg, int bg
 
1850
) {
 
1851
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
 
1852
 
 
1853
   (*infoRec->WriteBitmap)(pScrn, x, y, w, h, src, srcwidth, 
 
1854
                                        0, fg, bg, GXcopy, ~0);
 
1855
}
 
1856
 
 
1857
void 
 
1858
XAAWriteBitmapToCacheLinear(
 
1859
   ScrnInfoPtr pScrn,
 
1860
   int x, int y, int w, int h,
 
1861
   unsigned char *src,
 
1862
   int srcwidth,
 
1863
   int fg, int bg
 
1864
){
 
1865
   ScreenPtr pScreen = pScrn->pScreen;
 
1866
   PixmapPtr pScreenPix, pDstPix;
 
1867
   XID gcvals[2];
 
1868
   GCPtr pGC;
 
1869
 
 
1870
   pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
 
1871
 
 
1872
   pDstPix = GetScratchPixmapHeader(pScreen, pScreenPix->drawable.width, 
 
1873
                                        y + h, pScreenPix->drawable.depth, 
 
1874
                                        pScreenPix->drawable.bitsPerPixel, 
 
1875
                                        pScreenPix->devKind,
 
1876
                                        pScreenPix->devPrivate.ptr);
 
1877
   
 
1878
   pGC = GetScratchGC(pScreenPix->drawable.depth, pScreen);
 
1879
   gcvals[0] = fg;
 
1880
   gcvals[1] = bg;
 
1881
   DoChangeGC(pGC, GCForeground | GCBackground, gcvals, 0);
 
1882
   ValidateGC((DrawablePtr)pDstPix, pGC);
 
1883
 
 
1884
   /* We've unwrapped already so these ops miss a sync */
 
1885
   SYNC_CHECK(pScrn);
 
1886
 
 
1887
   (*pGC->ops->PutImage)((DrawablePtr)pDstPix, pGC, 1, x, y, w, h, 0,
 
1888
                                                XYBitmap, (pointer)src);
 
1889
 
 
1890
   FreeScratchGC(pGC);
 
1891
   FreeScratchPixmapHeader(pDstPix);
 
1892
}
 
1893
 
 
1894
 
 
1895
void 
 
1896
XAAWritePixmapToCache(
 
1897
   ScrnInfoPtr pScrn,
 
1898
   int x, int y, int w, int h,
 
1899
   unsigned char *src,
 
1900
   int srcwidth,
 
1901
   int bpp, int depth
 
1902
) {
 
1903
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
 
1904
 
 
1905
   (*infoRec->WritePixmap)(pScrn, x, y, w, h, src, srcwidth,
 
1906
                                GXcopy, ~0, -1, bpp, depth);
 
1907
}
 
1908
 
 
1909
 
 
1910
 
 
1911
void 
 
1912
XAAWritePixmapToCacheLinear(
 
1913
   ScrnInfoPtr pScrn,
 
1914
   int x, int y, int w, int h,
 
1915
   unsigned char *src,
 
1916
   int srcwidth,
 
1917
   int bpp, int depth
 
1918
){
 
1919
   ScreenPtr pScreen = pScrn->pScreen;
 
1920
   PixmapPtr pScreenPix, pDstPix;
 
1921
   GCPtr pGC;
 
1922
 
 
1923
   pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
 
1924
 
 
1925
   pDstPix = GetScratchPixmapHeader(pScreen, x + w, y + h, 
 
1926
                                        depth, bpp, pScreenPix->devKind,
 
1927
                                        pScreenPix->devPrivate.ptr);
 
1928
   
 
1929
   pGC = GetScratchGC(depth, pScreen);
 
1930
   ValidateGC((DrawablePtr)pDstPix, pGC);
 
1931
 
 
1932
   /* We've unwrapped already so these ops miss a sync */
 
1933
   SYNC_CHECK(pScrn);
 
1934
 
 
1935
   if(bpp == BitsPerPixel(depth))
 
1936
        (*pGC->ops->PutImage)((DrawablePtr)pDstPix, pGC, depth, x, y, w, 
 
1937
                                        h, 0, ZPixmap, (pointer)src);
 
1938
   else {
 
1939
        PixmapPtr pSrcPix;
 
1940
 
 
1941
        pSrcPix = GetScratchPixmapHeader(pScreen, w, h, depth, bpp,
 
1942
                                        srcwidth, (pointer)src);
 
1943
        
 
1944
        (*pGC->ops->CopyArea)((DrawablePtr)pSrcPix, (DrawablePtr)pDstPix,
 
1945
                                        pGC, 0, 0, w, h, x, y);
 
1946
                
 
1947
        FreeScratchPixmapHeader(pSrcPix);
 
1948
   }
 
1949
 
 
1950
   FreeScratchGC(pGC);
 
1951
   FreeScratchPixmapHeader(pDstPix);
 
1952
}
 
1953
 
 
1954
 
 
1955
void 
 
1956
XAAWriteMono8x8PatternToCache(
 
1957
   ScrnInfoPtr pScrn, 
 
1958
   XAACacheInfoPtr pCache
 
1959
){
 
1960
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
 
1961
   XAAPixmapCachePrivatePtr pCachePriv = 
 
1962
        (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
 
1963
   unsigned char *data;
 
1964
   int pad, Bpp = (pScrn->bitsPerPixel >> 3);
 
1965
   
 
1966
   pCache->offsets = pCachePriv->MonoOffsets;
 
1967
 
 
1968
   pad = BitmapBytePad(pCache->w * pScrn->bitsPerPixel);
 
1969
 
 
1970
   data = (unsigned char*)ALLOCATE_LOCAL(pad * pCache->h);
 
1971
   if(!data) return;
 
1972
 
 
1973
   if(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
 
1974
        CARD32* ptr = (CARD32*)data;
 
1975
        ptr[0] = pCache->pat0;  ptr[1] = pCache->pat1;
 
1976
   } else {
 
1977
        CARD32 *ptr;
 
1978
        DDXPointPtr pPoint = pCache->offsets;
 
1979
        int patx, paty, i;
 
1980
 
 
1981
        for(i = 0; i < 64; i++, pPoint++) {
 
1982
             patx = pCache->pat0; paty = pCache->pat1;
 
1983
             XAARotateMonoPattern(&patx, &paty, i & 0x07, i >> 3,
 
1984
                                (infoRec->Mono8x8PatternFillFlags &             
 
1985
                                BIT_ORDER_IN_BYTE_MSBFIRST));
 
1986
             ptr = (CARD32*)(data + (pad * pPoint->y) + (Bpp * pPoint->x));
 
1987
             ptr[0] = patx;  ptr[1] = paty;
 
1988
        }
 
1989
   }
 
1990
 
 
1991
   (*infoRec->WritePixmapToCache)(pScrn, pCache->x, pCache->y, 
 
1992
        pCache->w, pCache->h, data, pad, pScrn->bitsPerPixel, pScrn->depth);
 
1993
 
 
1994
   DEALLOCATE_LOCAL(data);
 
1995
}
 
1996
 
 
1997
void 
 
1998
XAAWriteColor8x8PatternToCache(
 
1999
   ScrnInfoPtr pScrn, 
 
2000
   PixmapPtr pPix, 
 
2001
   XAACacheInfoPtr pCache
 
2002
){
 
2003
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
 
2004
   XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
 
2005
   XAAPixmapCachePrivatePtr pCachePriv = 
 
2006
        (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
 
2007
   int pad, i, w, h, nw, nh, Bpp;
 
2008
   unsigned char *data, *srcPtr, *dstPtr;
 
2009
 
 
2010
   pCache->offsets = pCachePriv->ColorOffsets;
 
2011
 
 
2012
   if(pixPriv->flags & REDUCIBLE_TO_2_COLOR) {
 
2013
        CARD32* ptr;
 
2014
        pad = BitmapBytePad(pCache->w);
 
2015
        data = (unsigned char*)ALLOCATE_LOCAL(pad * pCache->h);
 
2016
        if(!data) return;
 
2017
 
 
2018
        if(infoRec->Color8x8PatternFillFlags & 
 
2019
                                HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
 
2020
             ptr = (CARD32*)data;
 
2021
             ptr[0] = pCache->pat0; ptr[1] = pCache->pat1;
 
2022
        } else {
 
2023
           int patx, paty;
 
2024
        
 
2025
           ptr = (CARD32*)data;
 
2026
           ptr[0] = ptr[2] = pCache->pat0;  ptr[1] = ptr[3] = pCache->pat1;
 
2027
           for(i = 1; i < 8; i++) {
 
2028
                patx = pCache->pat0; paty = pCache->pat1;
 
2029
                XAARotateMonoPattern(&patx, &paty, i, 0,
 
2030
                                (infoRec->Mono8x8PatternFillFlags &             
 
2031
                                BIT_ORDER_IN_BYTE_MSBFIRST));
 
2032
                ptr = (CARD32*)(data + (pad * i));
 
2033
                ptr[0] = ptr[2] = patx;  ptr[1] = ptr[3] = paty;
 
2034
           }
 
2035
        }
 
2036
 
 
2037
        (*infoRec->WriteBitmapToCache)(pScrn, pCache->x, pCache->y, 
 
2038
                pCache->w, pCache->h, data, pad, pCache->fg, pCache->bg);
 
2039
 
 
2040
        DEALLOCATE_LOCAL(data);
 
2041
        return;
 
2042
   } 
 
2043
 
 
2044
   Bpp = pScrn->bitsPerPixel >> 3;
 
2045
   h = min(8,pPix->drawable.height);
 
2046
   w = min(8,pPix->drawable.width);
 
2047
   pad = BitmapBytePad(pCache->w * pScrn->bitsPerPixel);
 
2048
 
 
2049
   data = (unsigned char*)ALLOCATE_LOCAL(pad * pCache->h);
 
2050
   if(!data) return;
 
2051
 
 
2052
   /* Write and expand horizontally. */
 
2053
   for (i = h, dstPtr = data, srcPtr = pPix->devPrivate.ptr; i--; 
 
2054
        srcPtr += pPix->devKind, dstPtr += pScrn->bitsPerPixel) {
 
2055
         nw = w;
 
2056
         memcpy(dstPtr, srcPtr, w * Bpp);
 
2057
         while (nw != 8) {
 
2058
            memcpy(dstPtr + (nw * Bpp), dstPtr, nw * Bpp);
 
2059
            nw <<= 1;
 
2060
         }
 
2061
   }
 
2062
   nh = h;
 
2063
   /* Expand vertically. */
 
2064
   while (nh != 8) {
 
2065
        memcpy(data + (nh*pScrn->bitsPerPixel), data, nh*pScrn->bitsPerPixel);
 
2066
        nh <<= 1;
 
2067
   }
 
2068
 
 
2069
   if(!(infoRec->Color8x8PatternFillFlags & 
 
2070
                                HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
 
2071
        int j;
 
2072
        unsigned char *ptr = data + (128 * Bpp);
 
2073
 
 
2074
        memcpy(data + (64 * Bpp), data, 64 * Bpp);
 
2075
        for(i = 1; i < 8; i++, ptr += (128 * Bpp)) {
 
2076
           for(j = 0; j < 8; j++) {
 
2077
                memcpy(ptr + (j * 8) * Bpp, data + (j * 8 + i) * Bpp,
 
2078
                        (8 - i) * Bpp);
 
2079
                memcpy(ptr + (j * 8 + 8 - i) * Bpp, data + j * 8 * Bpp, i*Bpp);
 
2080
           }
 
2081
           memcpy(ptr + (64 * Bpp), ptr, 64 * Bpp);
 
2082
        }
 
2083
   }
 
2084
 
 
2085
   (*infoRec->WritePixmapToCache)(pScrn, pCache->x, pCache->y, 
 
2086
        pCache->w, pCache->h, data, pad, pScrn->bitsPerPixel, pScrn->depth);
 
2087
 
 
2088
   DEALLOCATE_LOCAL(data);   
 
2089
}
 
2090
 
 
2091
 
 
2092
 
 
2093
int
 
2094
XAAStippledFillChooser(GCPtr pGC)
 
2095
{
 
2096
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
 
2097
    PixmapPtr pPixmap = pGC->stipple;
 
2098
    XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
 
2099
 
 
2100
    if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
 
2101
        (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
 
2102
        XAACheckStippleReducibility(pPixmap);
 
2103
    }
 
2104
 
 
2105
 
 
2106
    if(pPriv->flags & REDUCIBLE_TO_8x8) {
 
2107
        if(infoRec->CanDoMono8x8 && 
 
2108
           !(infoRec->FillMono8x8PatternSpansFlags & NO_TRANSPARENCY) && 
 
2109
           ((pGC->alu == GXcopy) || !(infoRec->FillMono8x8PatternSpansFlags & 
 
2110
                TRANSPARENCY_GXCOPY_ONLY)) &&
 
2111
           CHECK_ROP(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
 
2112
           CHECK_ROPSRC(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
 
2113
           CHECK_FG(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
 
2114
           CHECK_PLANEMASK(pGC,infoRec->FillMono8x8PatternSpansFlags)) {
 
2115
 
 
2116
              return DO_MONO_8x8;
 
2117
        }
 
2118
 
 
2119
        if(infoRec->CanDoColor8x8 && 
 
2120
           !(infoRec->FillColor8x8PatternSpansFlags & NO_TRANSPARENCY) && 
 
2121
           ((pGC->alu == GXcopy) || !(infoRec->FillColor8x8PatternSpansFlags &
 
2122
                TRANSPARENCY_GXCOPY_ONLY)) &&
 
2123
           CHECK_ROP(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
 
2124
           CHECK_ROPSRC(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
 
2125
           CHECK_PLANEMASK(pGC,infoRec->FillColor8x8PatternSpansFlags)) {
 
2126
 
 
2127
              return DO_COLOR_8x8;
 
2128
        }
 
2129
    }
 
2130
 
 
2131
    if(infoRec->UsingPixmapCache && infoRec->FillCacheExpandSpans && 
 
2132
        (pPixmap->drawable.height <= infoRec->MaxCacheableStippleHeight) &&
 
2133
        (pPixmap->drawable.width <= infoRec->MaxCacheableStippleWidth /
 
2134
         infoRec->CacheColorExpandDensity) &&
 
2135
        !(infoRec->FillCacheExpandSpansFlags & NO_TRANSPARENCY) && 
 
2136
        ((pGC->alu == GXcopy) || !(infoRec->FillCacheExpandSpansFlags & 
 
2137
                TRANSPARENCY_GXCOPY_ONLY)) &&
 
2138
        CHECK_ROP(pGC,infoRec->FillCacheExpandSpansFlags) &&
 
2139
        CHECK_ROPSRC(pGC,infoRec->FillCacheExpandSpansFlags) &&
 
2140
        CHECK_FG(pGC,infoRec->FillCacheExpandSpansFlags) &&
 
2141
        CHECK_PLANEMASK(pGC,infoRec->FillCacheExpandSpansFlags)) {
 
2142
 
 
2143
              return DO_CACHE_EXPAND;
 
2144
    }
 
2145
 
 
2146
 
 
2147
    if(infoRec->UsingPixmapCache && 
 
2148
        !(infoRec->PixmapCacheFlags & DO_NOT_BLIT_STIPPLES) && 
 
2149
        infoRec->FillCacheBltSpans && 
 
2150
        (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
 
2151
        (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
 
2152
        !(infoRec->FillCacheBltSpansFlags & NO_TRANSPARENCY) && 
 
2153
        ((pGC->alu == GXcopy) || !(infoRec->FillCacheBltSpansFlags & 
 
2154
                TRANSPARENCY_GXCOPY_ONLY)) &&
 
2155
        CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
 
2156
        CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
 
2157
        CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
 
2158
 
 
2159
              return DO_CACHE_BLT;
 
2160
    }
 
2161
 
 
2162
    if(infoRec->FillColorExpandSpans && 
 
2163
        !(infoRec->FillColorExpandSpansFlags & NO_TRANSPARENCY) && 
 
2164
        ((pGC->alu == GXcopy) || !(infoRec->FillColorExpandSpansFlags & 
 
2165
                TRANSPARENCY_GXCOPY_ONLY)) &&
 
2166
        CHECK_ROP(pGC,infoRec->FillColorExpandSpansFlags) &&
 
2167
        CHECK_ROPSRC(pGC,infoRec->FillColorExpandSpansFlags) &&
 
2168
        CHECK_FG(pGC,infoRec->FillColorExpandSpansFlags) &&
 
2169
        CHECK_PLANEMASK(pGC,infoRec->FillColorExpandSpansFlags)) {
 
2170
 
 
2171
              return DO_COLOR_EXPAND;
 
2172
    }
 
2173
 
 
2174
    return 0;
 
2175
}
 
2176
 
 
2177
 
 
2178
int
 
2179
XAAOpaqueStippledFillChooser(GCPtr pGC)
 
2180
{
 
2181
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
 
2182
    PixmapPtr pPixmap = pGC->stipple;
 
2183
    XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
 
2184
 
 
2185
    if(XAA_DEPTH_BUG(pGC))
 
2186
         return 0;
 
2187
 
 
2188
    if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
 
2189
        (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
 
2190
        XAACheckStippleReducibility(pPixmap);
 
2191
    }
 
2192
 
 
2193
    if(pPriv->flags & REDUCIBLE_TO_8x8) {
 
2194
        if(infoRec->CanDoMono8x8 && 
 
2195
           !(infoRec->FillMono8x8PatternSpansFlags & TRANSPARENCY_ONLY) && 
 
2196
           CHECK_ROP(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
 
2197
           CHECK_ROPSRC(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
 
2198
           CHECK_COLORS(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
 
2199
           CHECK_PLANEMASK(pGC,infoRec->FillMono8x8PatternSpansFlags)) {
 
2200
 
 
2201
              return DO_MONO_8x8;
 
2202
        }
 
2203
 
 
2204
        if(infoRec->CanDoColor8x8 && 
 
2205
           CHECK_ROP(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
 
2206
           CHECK_ROPSRC(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
 
2207
           CHECK_PLANEMASK(pGC,infoRec->FillColor8x8PatternSpansFlags)) {
 
2208
 
 
2209
              return DO_COLOR_8x8;
 
2210
        }
 
2211
    }
 
2212
 
 
2213
    if(infoRec->UsingPixmapCache && infoRec->FillCacheExpandSpans && 
 
2214
        (pPixmap->drawable.height <= infoRec->MaxCacheableStippleHeight) &&
 
2215
        (pPixmap->drawable.width <= infoRec->MaxCacheableStippleWidth /
 
2216
         infoRec->CacheColorExpandDensity) &&
 
2217
        !(infoRec->FillCacheExpandSpansFlags & TRANSPARENCY_ONLY) && 
 
2218
        CHECK_ROP(pGC,infoRec->FillCacheExpandSpansFlags) &&
 
2219
        CHECK_ROPSRC(pGC,infoRec->FillCacheExpandSpansFlags) &&
 
2220
        CHECK_COLORS(pGC,infoRec->FillCacheExpandSpansFlags) &&
 
2221
        CHECK_PLANEMASK(pGC,infoRec->FillCacheExpandSpansFlags)) {
 
2222
 
 
2223
              return DO_CACHE_EXPAND;
 
2224
    } 
 
2225
 
 
2226
    if(infoRec->UsingPixmapCache &&
 
2227
        !(infoRec->PixmapCacheFlags & DO_NOT_BLIT_STIPPLES) && 
 
2228
        infoRec->FillCacheBltSpans && 
 
2229
        (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
 
2230
        (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
 
2231
        CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
 
2232
        CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
 
2233
        CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
 
2234
 
 
2235
              return DO_CACHE_BLT;
 
2236
    } 
 
2237
 
 
2238
    if(infoRec->FillColorExpandSpans && 
 
2239
        !(infoRec->FillColorExpandSpansFlags & TRANSPARENCY_ONLY) && 
 
2240
        CHECK_ROP(pGC,infoRec->FillColorExpandSpansFlags) &&
 
2241
        CHECK_ROPSRC(pGC,infoRec->FillColorExpandSpansFlags) &&
 
2242
        CHECK_COLORS(pGC,infoRec->FillColorExpandSpansFlags) &&
 
2243
        CHECK_PLANEMASK(pGC,infoRec->FillColorExpandSpansFlags)) {
 
2244
 
 
2245
              return DO_COLOR_EXPAND;
 
2246
    }
 
2247
 
 
2248
    return 0;
 
2249
}
 
2250
 
 
2251
 
 
2252
 
 
2253
int
 
2254
XAATiledFillChooser(GCPtr pGC)
 
2255
{
 
2256
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
 
2257
    PixmapPtr pPixmap = pGC->tile.pixmap;
 
2258
    XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
 
2259
 
 
2260
    if(IS_OFFSCREEN_PIXMAP(pPixmap) && infoRec->FillCacheBltSpans &&
 
2261
        CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
 
2262
        CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
 
2263
        CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
 
2264
 
 
2265
        return DO_PIXMAP_COPY;
 
2266
    }
 
2267
 
 
2268
    if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
 
2269
        (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
 
2270
        XAACheckTileReducibility(pPixmap,infoRec->CanDoMono8x8);
 
2271
    }
 
2272
 
 
2273
    if(pPriv->flags & REDUCIBLE_TO_8x8) {
 
2274
        if((pPriv->flags & REDUCIBLE_TO_2_COLOR) && infoRec->CanDoMono8x8 && 
 
2275
           !(infoRec->FillMono8x8PatternSpansFlags & TRANSPARENCY_ONLY) && 
 
2276
           CHECK_ROP(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
 
2277
           CHECK_ROPSRC(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
 
2278
           (!(infoRec->FillMono8x8PatternSpansFlags & RGB_EQUAL) || 
 
2279
                (CHECK_RGB_EQUAL(pPriv->fg) && CHECK_RGB_EQUAL(pPriv->bg))) &&
 
2280
           CHECK_PLANEMASK(pGC,infoRec->FillMono8x8PatternSpansFlags)) {
 
2281
 
 
2282
              return DO_MONO_8x8;
 
2283
        }
 
2284
 
 
2285
        if(infoRec->CanDoColor8x8 && 
 
2286
           CHECK_ROP(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
 
2287
           CHECK_ROPSRC(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
 
2288
           CHECK_PLANEMASK(pGC,infoRec->FillColor8x8PatternSpansFlags)) {
 
2289
 
 
2290
              return DO_COLOR_8x8;
 
2291
        }
 
2292
    }
 
2293
 
 
2294
    if(infoRec->UsingPixmapCache && infoRec->FillCacheBltSpans && 
 
2295
        (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
 
2296
        (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
 
2297
        CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
 
2298
        CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
 
2299
        CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
 
2300
 
 
2301
              return DO_CACHE_BLT;
 
2302
    }
 
2303
 
 
2304
    if(infoRec->FillImageWriteRects && 
 
2305
        CHECK_NO_GXCOPY(pGC,infoRec->FillImageWriteRectsFlags) &&
 
2306
        CHECK_ROP(pGC,infoRec->FillImageWriteRectsFlags) &&
 
2307
        CHECK_ROPSRC(pGC,infoRec->FillImageWriteRectsFlags) &&
 
2308
        CHECK_PLANEMASK(pGC,infoRec->FillImageWriteRectsFlags)) {
 
2309
 
 
2310
              return DO_IMAGE_WRITE;
 
2311
    }
 
2312
 
 
2313
    return 0;
 
2314
}
 
2315
 
 
2316
 
 
2317
static int RotateMasksX[8] = {
 
2318
   0xFFFFFFFF, 0x7F7F7F7F, 0x3F3F3F3F, 0x1F1F1F1F,
 
2319
   0x0F0F0F0F, 0x07070707, 0x03030303, 0x01010101
 
2320
};
 
2321
 
 
2322
static int RotateMasksY[4] = {
 
2323
   0xFFFFFFFF, 0x00FFFFFF, 0x0000FFFF, 0x000000FF
 
2324
};
 
2325
 
 
2326
void 
 
2327
XAARotateMonoPattern(
 
2328
    int *pat0, int *pat1,
 
2329
    int xorg, int yorg,
 
2330
    Bool msbfirst
 
2331
){
 
2332
    int tmp, mask;    
 
2333
 
 
2334
    if(xorg) {
 
2335
        if(msbfirst) xorg = 8 - xorg;
 
2336
        mask = RotateMasksX[xorg];
 
2337
        *pat0 = ((*pat0 >> xorg) & mask) | ((*pat0 << (8 - xorg)) & ~mask);
 
2338
        *pat1 = ((*pat1 >> xorg) & mask) | ((*pat1 << (8 - xorg)) & ~mask);
 
2339
    } 
 
2340
    if(yorg >= 4) {
 
2341
        tmp = *pat0; *pat0 = *pat1; *pat1 = tmp;
 
2342
        yorg -= 4;
 
2343
    }
 
2344
    if(yorg) {
 
2345
        mask = RotateMasksY[yorg];
 
2346
        yorg <<= 3;
 
2347
        tmp = *pat0;
 
2348
        *pat0 = ((*pat0 >> yorg) & mask) | ((*pat1 << (32 - yorg)) & ~mask);  
 
2349
        *pat1 = ((*pat1 >> yorg) & mask) | ((tmp << (32 - yorg)) & ~mask);
 
2350
    }
 
2351
}
 
2352
 
 
2353
 
 
2354
 
 
2355
void
 
2356
XAAInvalidatePixmapCache(ScreenPtr pScreen)
 
2357
{
 
2358
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
 
2359
   XAAPixmapCachePrivatePtr pCachePriv = 
 
2360
        (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
 
2361
   int i;
 
2362
 
 
2363
   if(!pCachePriv) return;
 
2364
 
 
2365
   for(i = 0; i < pCachePriv->Num512x512; i++) 
 
2366
        (pCachePriv->Info512)[i].serialNumber = 0;
 
2367
   for(i = 0; i < pCachePriv->Num256x256; i++) 
 
2368
        (pCachePriv->Info256)[i].serialNumber = 0;
 
2369
   for(i = 0; i < pCachePriv->Num128x128; i++) 
 
2370
        (pCachePriv->Info128)[i].serialNumber = 0;
 
2371
   for(i = 0; i < pCachePriv->NumPartial; i++) 
 
2372
        (pCachePriv->InfoPartial)[i].serialNumber = 0;
 
2373
   for(i = 0; i < pCachePriv->NumMono; i++) 
 
2374
        (pCachePriv->InfoMono)[i].serialNumber = 0;
 
2375
   for(i = 0; i < pCachePriv->NumColor; i++) 
 
2376
        (pCachePriv->InfoColor)[i].serialNumber = 0;
 
2377
}