2 #ifdef HAVE_XORG_CONFIG_H
3 #include <xorg-config.h>
10 #include "xf86_OSproc.h"
13 #include "scrnintstr.h"
16 #include "pixmapstr.h"
17 #include "windowstr.h"
18 #include "regionstr.h"
33 static int CacheInitIndex
= -1;
34 #define CACHEINIT(p) ((p)->privates[CacheInitIndex].val)
37 typedef struct _CacheLink
{
42 struct _CacheLink
*next
;
43 } CacheLink
, *CacheLinkPtr
;
47 TransferList(CacheLinkPtr list
, XAACacheInfoPtr array
, int num
)
54 array
->serialNumber
= 0;
55 array
->fg
= array
->bg
= -1;
64 Enlist(CacheLinkPtr link
, int x
, int y
, int w
, int h
)
68 newLink
= xalloc(sizeof(CacheLink
));
70 newLink
->x
= x
; newLink
->y
= y
;
71 newLink
->w
= w
; newLink
->h
= h
;
78 Delist(CacheLinkPtr link
) {
79 CacheLinkPtr ret
= NULL
;
91 FreeList(CacheLinkPtr link
) {
104 QuadLinks(CacheLinkPtr big
, CacheLinkPtr little
)
106 /* CAUTION: This doesn't free big */
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
);
127 SubdivideList(CacheLinkPtr
*large
, CacheLinkPtr
*small
)
129 CacheLinkPtr big
= *large
;
130 CacheLinkPtr little
= *small
;
131 int size
= big
->w
>> 1;
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
);
143 FreePixmapCachePrivate(XAAPixmapCachePrivatePtr pPriv
)
148 xfree(pPriv
->Info512
);
150 xfree(pPriv
->Info256
);
152 xfree(pPriv
->Info128
);
154 xfree(pPriv
->InfoColor
);
156 xfree(pPriv
->InfoMono
);
157 if(pPriv
->InfoPartial
)
158 xfree(pPriv
->InfoPartial
);
164 XAAClosePixmapCache(ScreenPtr pScreen
)
166 XAAInfoRecPtr infoRec
= GET_XAAINFORECPTR_FROM_SCREEN(pScreen
);
168 if(infoRec
->PixmapCachePrivate
)
169 FreePixmapCachePrivate(
170 (XAAPixmapCachePrivatePtr
)infoRec
->PixmapCachePrivate
);
172 infoRec
->PixmapCachePrivate
= NULL
;
179 CacheLinkPtr ListPartial
,
180 int *num
, int *maxw
, int *maxh
182 /* This guy's job is to get at least 4 big slots out of a list of fragments */
184 CacheLinkPtr List64
, List32
, List16
, List8
, pCur
, next
, ListKeepers
;
185 int Num64
, Num32
, Num16
, Num8
, NumKeepers
;
188 List64
= List32
= List16
= List8
= ListKeepers
= NULL
;
189 Num64
= Num32
= Num16
= Num8
= NumKeepers
= 0;
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,
199 if((pCur
->w
>= 64) && (pCur
->h
>= 64)) {
200 pCur
->next
= List64
; List64
= pCur
;
203 if((pCur
->w
>= 32) && (pCur
->h
>= 32)) {
204 pCur
->next
= List32
; List32
= pCur
;
207 if((pCur
->w
>= 16) && (pCur
->h
>= 16)) {
208 pCur
->next
= List16
; List16
= pCur
;
211 if((pCur
->w
>= 8) && (pCur
->h
>= 8)) {
212 pCur
->next
= List8
; List8
= pCur
;
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. */
226 ListKeepers
= List64
; List64
= NULL
;
230 List32
= QuadLinks(List64
, List32
);
236 ListKeepers
= List32
; List32
= NULL
;
240 List16
= QuadLinks(List32
, List16
);
246 ListKeepers
= List16
; List16
= NULL
;
250 List8
= QuadLinks(List16
, List8
);
256 ListKeepers
= List8
; List8
= NULL
;
263 /* Free the ones we aren't using */
265 if(List64
) FreeList(List64
);
266 if(List32
) FreeList(List32
);
267 if(List16
) FreeList(List16
);
268 if(List8
) FreeList(List8
);
271 /* Enlarge the slots if we can */
274 CacheLinkPtr pLink
= ListKeepers
;
278 if(pLink
->w
< w
) w
= pLink
->w
;
279 if(pLink
->h
< h
) h
= pLink
->h
;
292 CacheLinkPtr
*ColorList
,
293 int ColorW
, int ColorH
,
294 CacheLinkPtr
*MonoList
,
299 x
= (*ColorList
)->x
; y
= (*ColorList
)->y
;
300 *ColorList
= Delist(*ColorList
);
304 for(w
= 0; w
<= (ColorW
- MonoW
); w
+= MonoW
)
305 *MonoList
= Enlist(*MonoList
, x
+ w
, y
+ ColorH
, MonoW
, MonoH
);
310 ConvertAllPartialsTo8x8(
311 int *NumMono
, int *NumColor
,
312 CacheLinkPtr ListPartial
,
313 CacheLinkPtr
*ListMono
,
314 CacheLinkPtr
*ListColor
,
315 XAAInfoRecPtr infoRec
317 /* This guy extracts as many 8x8 slots as it can out of fragments */
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
;
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
;
335 /* Break up the area into as many Color and Mono slots as we can */
344 while(Height
>= ColorH
) {
346 for(w
= 0; w
<= (Width
- ColorW
); w
+= ColorW
) {
348 ColorList
, x
+ w
, y
+ Height
, ColorW
, ColorH
);
354 if(DoMono
&& (Height
>= MonoH
)) {
355 while(Height
>= MonoH
) {
357 for(w
= 0; w
<= (Width
- MonoW
); w
+= MonoW
) {
359 MonoList
, x
+ w
, y
+ Height
, MonoW
, MonoH
);
369 *ListMono
= MonoList
;
370 *ListColor
= ColorList
;
371 FreeList(ListPartial
);
376 ExtractOneThatFits(CacheLinkPtr
*initList
, int w
, int h
)
378 CacheLinkPtr list
= *initList
;
379 CacheLinkPtr prev
= NULL
;
382 if((list
->w
>= w
) && (list
->h
>= h
))
390 prev
->next
= list
->next
;
392 *initList
= list
->next
;
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
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 */
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;
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
);
433 List64
= List32
= List16
= List8
= ListKeepers
= MonoList
= ColorList
= NULL
;
434 Num64
= Num32
= Num16
= Num8
= NumKeepers
= 0;
437 /* We sort partials by how large a square tile they can cache.
438 We make 8x8 patterns from the leftovers if we can. */
443 if((pCur
->w
>= 64) && (pCur
->h
>= 64)) {
444 pCur
->next
= List64
; List64
= pCur
;
447 if((pCur
->w
>= 32) && (pCur
->h
>= 32)) {
448 pCur
->next
= List32
; List32
= pCur
;
451 if((pCur
->w
>= 16) && (pCur
->h
>= 16)) {
452 pCur
->next
= List16
; List16
= pCur
;
455 if((pCur
->w
>= 8) && (pCur
->h
>= 8)) {
456 pCur
->next
= List8
; List8
= pCur
;
460 if(DoColor
&& (pCur
->w
>= ColorW
) && (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
);
470 if(DoMono
&& (pCur
->w
>= MonoW
) && (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
);
486 /* Try to extract at least 4 of each type of 8x8 slot that we need */
490 while(*NumColor
< 4) {
493 if((theOne
= ExtractOneThatFits(&List8
, ColorW
, ColorH
)))
496 if(Num16
&& !theOne
) {
497 if((theOne
= ExtractOneThatFits(&List16
, ColorW
, ColorH
)))
500 if(Num32
&& !theOne
) {
501 if((theOne
= ExtractOneThatFits(&List32
, ColorW
, ColorH
)))
504 if(Num64
&& !theOne
) {
505 if((theOne
= ExtractOneThatFits(&List64
, ColorW
, ColorH
)))
512 ConvertAllPartialsTo8x8(NumMono
, NumColor
, theOne
,
513 &MonoList
, &ColorList
, infoRec
);
516 while(*NumColor
&& (*NumMono
< 4)) {
517 ConvertColorToMono(&ColorList
, ColorW
, ColorH
,
518 &MonoList
, MonoW
, MonoH
);
519 (*NumColor
)--; *NumMono
+= MonosPerColor
;
527 while(*NumMono
< 4) {
530 if((theOne
= ExtractOneThatFits(&List8
, MonoW
, MonoH
)))
533 if(Num16
&& !theOne
) {
534 if((theOne
= ExtractOneThatFits(&List16
, MonoW
, MonoH
)))
537 if(Num32
&& !theOne
) {
538 if((theOne
= ExtractOneThatFits(&List32
, MonoW
, MonoH
)))
541 if(Num64
&& !theOne
) {
542 if((theOne
= ExtractOneThatFits(&List64
, MonoW
, MonoH
)))
548 ConvertAllPartialsTo8x8(NumMono
, NumColor
, theOne
,
549 &MonoList
, &ColorList
, infoRec
);
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. */
558 ListKeepers
= List64
; List64
= NULL
;
562 List32
= QuadLinks(List64
, List32
);
568 ListKeepers
= List32
; List32
= NULL
;
572 List16
= QuadLinks(List32
, List16
);
578 ListKeepers
= List16
; List16
= NULL
;
582 List8
= QuadLinks(List16
, List8
);
588 ListKeepers
= List8
; List8
= NULL
;
595 /* Free the ones we aren't using */
598 ConvertAllPartialsTo8x8(NumMono
, NumColor
, List64
,
599 &MonoList
, &ColorList
, infoRec
);
601 ConvertAllPartialsTo8x8(NumMono
, NumColor
, List32
,
602 &MonoList
, &ColorList
, infoRec
);
604 ConvertAllPartialsTo8x8(NumMono
, NumColor
, List16
,
605 &MonoList
, &ColorList
, infoRec
);
607 ConvertAllPartialsTo8x8(NumMono
, NumColor
, List8
,
608 &MonoList
, &ColorList
, infoRec
);
611 /* Enlarge the slots if we can */
614 CacheLinkPtr pLink
= ListKeepers
;
615 Width
= Height
= 128;
618 if(pLink
->w
< Width
) Width
= pLink
->w
;
619 if(pLink
->h
< Height
) Height
= pLink
->h
;
624 *ListMono
= MonoList
;
625 *ListColor
= ColorList
;
628 *NumPartial
= NumKeepers
;
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
;
650 infoRec
->MaxCacheableTileWidth
= 0;
651 infoRec
->MaxCacheableTileHeight
= 0;
652 infoRec
->MaxCacheableStippleHeight
= 0;
653 infoRec
->MaxCacheableStippleWidth
= 0;
654 infoRec
->UsingPixmapCache
= FALSE
;
657 if(!nBox
|| !pBox
|| !(infoRec
->Flags
& PIXMAP_CACHE
))
660 /* Allocate a persistent per-screen init flag to control messages */
661 if (CacheInitIndex
< 0)
662 CacheInitIndex
= xf86AllocateScrnInfoPrivateIndex();
664 /* free the old private data if it exists */
665 if(infoRec
->PixmapCachePrivate
) {
666 FreePixmapCachePrivate(
667 (XAAPixmapCachePrivatePtr
)infoRec
->PixmapCachePrivate
);
668 infoRec
->PixmapCachePrivate
= NULL
;
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;
676 /* go through the boxes and break it into as many pieces as we can fit */
681 int tmp
= x
% granularity
;
682 if(tmp
) x
+= (granularity
- tmp
);
684 width
= pBox
->x2
- x
;
685 if(width
<= 0) {pBox
++; continue;}
688 height
= pBox
->y2
- y
;
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);
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);
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);
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);
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);
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);
728 ListPartial
= Enlist(ListPartial
, x
+ w
, y
+ h
, d
, 128);
729 ListPartial
= Enlist(ListPartial
, x
+ w
, y
+ h
+ 128, d
, 128);
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);
739 ListPartial
= Enlist(
740 ListPartial
, x
+ w
, y
+ h
, width
- w
, 128);
746 for(w
= 0; w
<= (width
- 128); w
+= 128) {
747 ListPartial
= Enlist(ListPartial
, x
+ w
, y
+ h
, 128, d
);
751 ListPartial
= Enlist(ListPartial
, x
+ w
, y
+ h
, width
- w
, d
);
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:
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.
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.
777 1) Don't make more than MAX_128.
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.
784 ntotal
= Num128
+ (Num256
<<2) + (Num512
<<4);
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;
792 if(Num512
&& Num256
< 4) {
793 while(Num512
&& Num256
< Target256
) {
794 SubdivideList(&List512
, &List256
);
795 Num256
+= 4; Num512
--;
799 if(!Num512
) { /* no room */
800 } else if((Num512
< 4) || (!Target512
)) {
802 SubdivideList(&List512
, &List256
);
803 Num256
+= 4; Num512
--;
805 } else if((Num512
> MAX_512
) || (Num512
> Target512
)){
806 while(Num512
> MAX_512
) {
807 SubdivideList(&List512
, &List256
);
808 Num256
+= 4; Num512
--;
810 while(Num512
> Target512
) {
811 if(Num256
< MAX_256
) {
812 SubdivideList(&List512
, &List256
);
813 Num256
+= 4; Num512
--;
818 if(!Num256
) { /* no room */
819 } else if((Num256
< 4) || (!Target256
)) {
821 SubdivideList(&List256
, &List128
);
822 Num128
+= 4; Num256
--;
824 } else if((Num256
> MAX_256
) || (Num256
> Target256
)) {
825 while(Num256
> MAX_256
) {
826 SubdivideList(&List256
, &List128
);
827 Num128
+= 4; Num256
--;
829 while(Num256
> Target256
) {
830 if(Num128
< MAX_128
) {
831 SubdivideList(&List256
, &List128
);
832 Num128
+= 4; Num256
--;
837 if(Num128
&& ((Num128
< 4) || (Num128
> MAX_128
))) {
839 int max
= (Num128
> MAX_128
) ? MAX_128
: 0;
842 * Note: next is set in this way to work around a code generation
843 * bug in gcc 2.7.2.3.
845 next
= List128
->next
;
846 while(Num128
> max
) {
847 List128
->next
= ListPartial
;
848 ListPartial
= List128
;
850 next
= List128
->next
;
851 NumPartial
++; Num128
--;
855 MaxPartialHeight
= MaxPartialWidth
= 0;
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 */
862 if(!(infoRec
->PixmapCacheFlags
& (CACHE_MONO_8x8
| CACHE_COLOR_8x8
))) {
864 if(Num128
) { /* don't bother with partials */
865 FreeList(ListPartial
);
866 NumPartial
= 0; ListPartial
= NULL
;
868 /* We have no big slots. Weed out the unusable partials */
869 ListPartial
= ThinOutPartials(ListPartial
, &NumPartial
,
870 &MaxPartialWidth
, &MaxPartialHeight
);
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
);
882 if(DoColor
) infoRec
->CanDoColor8x8
= FALSE
;
883 if(DoMono
) infoRec
->CanDoMono8x8
= FALSE
;
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
);
893 if(NumPartial
) { /* use all for 8x8 slots */
894 ConvertAllPartialsTo8x8(&NumMono
, &NumColor
,
895 ListPartial
, &ListMono
, &ListColor
, infoRec
);
896 NumPartial
= 0; ListPartial
= NULL
;
899 /* Get some 8x8 slots from the 128 slots */
900 while((Num128
> 4) &&
901 ((NumMono
< MAX_MONO
) && (NumColor
< MAX_COLOR
))) {
902 CacheLinkPtr tmp
= NULL
;
904 tmp
= Enlist(tmp
, List128
->x
, List128
->y
,
905 List128
->w
, List128
->h
);
906 List128
= Delist(List128
);
909 ConvertAllPartialsTo8x8(&NumMono
, &NumColor
,
910 tmp
, &ListMono
, &ListColor
, infoRec
);
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
);
920 if(DoMono
&& DoColor
) {
921 if(NumColor
&& ((NumColor
> MAX_COLOR
) || (NumColor
< 4))) {
922 int max
= (NumColor
> MAX_COLOR
) ? MAX_COLOR
: 0;
924 while(NumColor
> max
) {
925 ConvertColorToMono(&ListColor
, ColorW
, ColorH
,
926 &ListMono
, MonoW
, MonoH
);
927 NumColor
--; NumMono
+= MonosPerColor
;
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
;
939 if(NumMono
&& ((NumMono
> MAX_MONO
) || (NumMono
< 4))) {
940 int max
= (NumMono
> MAX_MONO
) ? MAX_MONO
: 0;
942 while(NumMono
> max
) {
943 ListMono
= Delist(ListMono
);
947 if(NumColor
&& ((NumColor
> MAX_COLOR
) || (NumColor
< 4))) {
948 int max
= (NumColor
> MAX_COLOR
) ? MAX_COLOR
: 0;
950 while(NumColor
> max
) {
951 ListColor
= Delist(ListColor
);
958 pCachePriv
= xcalloc(1,sizeof(XAAPixmapCachePrivate
));
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
);
969 infoRec
->PixmapCachePrivate
= (char*)pCachePriv
;
972 pCachePriv
->Info512
= xcalloc(Num512
,sizeof(XAACacheInfoRec
));
973 if(!pCachePriv
->Info512
) Num512
= 0;
974 if(Num512
) TransferList(List512
, pCachePriv
->Info512
, Num512
);
976 pCachePriv
->Num512x512
= Num512
;
979 pCachePriv
->Info256
= xcalloc(Num256
, sizeof(XAACacheInfoRec
));
980 if(!pCachePriv
->Info256
) Num256
= 0;
981 if(Num256
) TransferList(List256
, pCachePriv
->Info256
, Num256
);
983 pCachePriv
->Num256x256
= Num256
;
986 pCachePriv
->Info128
= xcalloc(Num128
, sizeof(XAACacheInfoRec
));
987 if(!pCachePriv
->Info128
) Num128
= 0;
988 if(Num128
) TransferList(List128
, pCachePriv
->Info128
, Num128
);
990 pCachePriv
->Num128x128
= Num128
;
994 pCachePriv
->InfoPartial
= xcalloc(NumPartial
, sizeof(XAACacheInfoRec
));
995 if(!pCachePriv
->InfoPartial
) NumPartial
= 0;
997 TransferList(ListPartial
, pCachePriv
->InfoPartial
, NumPartial
);
998 FreeList(ListPartial
);
999 pCachePriv
->NumPartial
= NumPartial
;
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
;
1011 pCachePriv
->InfoMono
= xcalloc(NumMono
, sizeof(XAACacheInfoRec
));
1012 if(!pCachePriv
->InfoMono
) NumMono
= 0;
1013 if(NumMono
) TransferList(ListMono
, pCachePriv
->InfoMono
, NumMono
);
1015 pCachePriv
->NumMono
= NumMono
;
1020 infoRec
->MaxCacheableTileWidth
= MaxPartialWidth
;
1021 infoRec
->MaxCacheableTileHeight
= MaxPartialHeight
;
1024 infoRec
->MaxCacheableTileWidth
= infoRec
->MaxCacheableTileHeight
= 128;
1026 infoRec
->MaxCacheableTileWidth
= infoRec
->MaxCacheableTileHeight
= 256;
1028 infoRec
->MaxCacheableTileWidth
= infoRec
->MaxCacheableTileHeight
= 512;
1031 infoRec
->MaxCacheableStippleHeight
= infoRec
->MaxCacheableTileHeight
;
1032 infoRec
->MaxCacheableStippleWidth
=
1033 infoRec
->MaxCacheableTileWidth
* pScrn
->bitsPerPixel
;
1034 if(infoRec
->ScreenToScreenColorExpandFillFlags
& TRIPLE_BITS_24BPP
)
1035 infoRec
->MaxCacheableStippleWidth
/= 3;
1038 if(!(infoRec
->Mono8x8PatternFillFlags
&
1039 (HARDWARE_PATTERN_PROGRAMMED_ORIGIN
|
1040 HARDWARE_PATTERN_PROGRAMMED_BITS
))) {
1042 infoRec
->CacheWidthMono8x8Pattern
/infoRec
->MonoPatternPitch
;
1044 for(i
= 0; i
< 64; i
++) {
1045 pCachePriv
->MonoOffsets
[i
].y
= i
/numPerLine
;
1046 pCachePriv
->MonoOffsets
[i
].x
= (i
% numPerLine
) *
1047 infoRec
->MonoPatternPitch
;
1050 infoRec
->CanDoMono8x8
= TRUE
;
1053 if(!(infoRec
->Color8x8PatternFillFlags
&
1054 HARDWARE_PATTERN_PROGRAMMED_ORIGIN
)) {
1056 for(i
= 0; i
< 64; i
++) {
1057 pCachePriv
->ColorOffsets
[i
].y
= i
& 0x07;
1058 pCachePriv
->ColorOffsets
[i
].x
= i
& ~0x07;
1061 infoRec
->CanDoColor8x8
= TRUE
;
1064 if(!CACHEINIT(pScrn
)) {
1065 xf86ErrorF("\tSetting up tile and stipple cache:\n");
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
);
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
;
1081 CACHEINIT(pScrn
) = 1;
1084 #if X_BYTE_ORDER == X_BIG_ENDIAN
1085 static CARD32 StippleMasks
[4] = {
1092 static CARD32 StippleMasks
[4] = {
1101 XAACheckStippleReducibility(PixmapPtr pPixmap
)
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
;
1110 CARD32 mask
= SHIFT_R(0xFFFFFFFF,24);
1112 pPriv
->flags
|= REDUCIBILITY_CHECKED
| REDUCIBLE_TO_2_COLOR
;
1113 pPriv
->flags
&= ~REDUCIBLE_TO_8x8
;
1115 if((w
> 32) || (h
> 32) || (w
& (w
- 1)) || (h
& (h
- 1)))
1118 i
= (h
> 8) ? 8 : h
;
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)))
1132 bits
[i
] = IntPtr
[i
] & mask
;
1133 if(bits
[i
] != ((IntPtr
[i
] & SHIFT_R(SHIFT_L(mask
,8),8))))
1139 bits
[i
] = IntPtr
[i
] & mask
;
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]))
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]))
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];
1169 pPriv
->flags
|= REDUCIBLE_TO_8x8
;
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);
1175 pPriv
->pattern0
&= StippleMasks
[w
- 1];
1176 pPriv
->pattern1
&= StippleMasks
[w
- 1];
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);
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
);
1199 XAACheckTileReducibility(PixmapPtr pPixmap
, Bool checkMono
)
1201 XAAPixmapPtr pPriv
= XAA_GET_PIXMAP_PRIVATE(pPixmap
);
1203 int w
= pPixmap
->drawable
.width
;
1204 int h
= pPixmap
->drawable
.height
;
1205 int pitch
= pPixmap
->devKind
>> 2;
1208 pPriv
->flags
|= REDUCIBILITY_CHECKED
;
1209 pPriv
->flags
&= ~(REDUCIBILITY_CHECKED
| REDUCIBLE_TO_2_COLOR
);
1211 if((w
> 32) || (h
> 32) || (w
& (w
- 1)) || (h
& (h
- 1)))
1214 dwords
= ((w
* pPixmap
->drawable
.bitsPerPixel
) + 31) >> 5;
1215 i
= (h
> 8) ? 8 : h
;
1219 IntPtr
= (CARD32
*)pPixmap
->devPrivate
.ptr
;
1220 switch(pPixmap
->drawable
.bitsPerPixel
) {
1223 for(j
= 2; j
< dwords
; j
++)
1224 if(IntPtr
[j
] != IntPtr
[j
& 0x01])
1231 for(j
= 4; j
< dwords
; j
++)
1232 if(IntPtr
[j
] != IntPtr
[j
& 0x03])
1239 for(j
= 6; j
< dwords
; j
++)
1240 if(IntPtr
[j
] != IntPtr
[j
% 6])
1247 for(j
= 8; j
< dwords
; j
++)
1248 if(IntPtr
[j
] != IntPtr
[j
& 0x07])
1253 default: return FALSE
;
1260 CARD32
*IntPtr2
, *IntPtr3
, *IntPtr4
;
1262 IntPtr
= (CARD32
*)pPixmap
->devPrivate
.ptr
;
1263 IntPtr2
= IntPtr
+ (pitch
<< 3);
1264 IntPtr3
= IntPtr2
+ (pitch
<< 3);
1265 IntPtr4
= IntPtr3
+ (pitch
<< 3);
1267 for(j
= 0; j
< dwords
; j
++)
1268 if((IntPtr
[j
] != IntPtr2
[j
]) || (IntPtr
[j
] != IntPtr3
[j
]) ||
1269 (IntPtr
[j
] != IntPtr4
[j
]))
1276 } else if (h
== 16) {
1279 IntPtr
= (CARD32
*)pPixmap
->devPrivate
.ptr
;
1280 IntPtr2
= IntPtr
+ (pitch
<< 3);
1282 for(j
= 0; j
< dwords
; j
++)
1283 if(IntPtr
[j
] != IntPtr2
[j
])
1290 pPriv
->flags
|= REDUCIBLE_TO_8x8
;
1293 XAAInfoRecPtr infoRec
=
1294 GET_XAAINFORECPTR_FROM_DRAWABLE(&pPixmap
->drawable
);
1295 unsigned char bits
[8];
1296 int fg
, bg
= -1, x
, y
;
1298 i
= (h
> 8) ? 8 : h
;
1299 j
= (w
> 8) ? 8 : w
;
1301 if(pPixmap
->drawable
.bitsPerPixel
== 8) {
1302 unsigned char *srcp
= pPixmap
->devPrivate
.ptr
;
1304 pitch
= pPixmap
->devKind
;
1305 for(y
= 0; y
< i
; y
++) {
1307 for(x
= 0; x
< j
; x
++) {
1309 if(bg
== -1) bg
= srcp
[x
];
1310 else if(bg
!= srcp
[x
]) return TRUE
;
1311 } else bits
[y
] |= 1 << x
;
1315 } else if(pPixmap
->drawable
.bitsPerPixel
== 16) {
1316 unsigned short *srcp
= (unsigned short*)pPixmap
->devPrivate
.ptr
;
1318 pitch
= pPixmap
->devKind
>> 1;
1319 for(y
= 0; y
< i
; y
++) {
1321 for(x
= 0; x
< j
; x
++) {
1323 if(bg
== -1) bg
= srcp
[x
];
1324 else if(bg
!= srcp
[x
]) return TRUE
;
1325 } else bits
[y
] |= 1 << x
;
1329 } else if(pPixmap
->drawable
.bitsPerPixel
== 24) {
1331 unsigned char *srcp
= pPixmap
->devPrivate
.ptr
;
1332 fg
= *((CARD32
*)srcp
) & 0x00FFFFFF;
1333 pitch
= pPixmap
->devKind
;
1335 for(y
= 0; y
< i
; y
++) {
1337 for(x
= 0; x
< j
; x
+=3) {
1338 val
= *((CARD32
*)(srcp
+x
)) & 0x00FFFFFF;
1340 if(bg
== -1) bg
= val
;
1343 } else bits
[y
] |= 1 << (x
/3);
1347 } else if(pPixmap
->drawable
.bitsPerPixel
== 32) {
1348 IntPtr
= (CARD32
*)pPixmap
->devPrivate
.ptr
;
1350 for(y
= 0; y
< i
; y
++) {
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
;
1363 if(bg
== -1) pPriv
->bg
= fg
;
1364 else pPriv
->bg
= bg
;
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];
1377 bits
[0] | (bits
[1]<<8) | (bits
[2]<<16) | (bits
[3]<<24);
1379 bits
[4] | (bits
[5]<<8) | (bits
[6]<<16) | (bits
[7]<<24);
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);
1391 pPriv
->flags
|= REDUCIBLE_TO_2_COLOR
;
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
);
1406 XAACacheInfoPtr pCache
,
1409 XAAInfoRecPtr infoRec
= GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn
);
1411 (*infoRec
->SetupForScreenToScreenCopy
)(pScrn
, 1, 1, GXcopy
, ~0, -1);
1413 while((w
<< 1) <= pCache
->w
) {
1414 (*infoRec
->SubsequentScreenToScreenCopy
)(pScrn
, pCache
->x
, pCache
->y
,
1415 pCache
->x
+ w
, pCache
->y
, w
, h
);
1418 if(w
!= pCache
->w
) {
1419 (*infoRec
->SubsequentScreenToScreenCopy
)(pScrn
, pCache
->x
, pCache
->y
,
1420 pCache
->x
+ w
, pCache
->y
, pCache
->w
- w
, h
);
1424 while((h
<< 1) <= pCache
->h
) {
1425 (*infoRec
->SubsequentScreenToScreenCopy
)(pScrn
, pCache
->x
, pCache
->y
,
1426 pCache
->x
, pCache
->y
+ h
, w
, h
);
1429 if(h
!= pCache
->h
) {
1430 (*infoRec
->SubsequentScreenToScreenCopy
)(pScrn
, pCache
->x
, pCache
->y
,
1431 pCache
->x
, pCache
->y
+ h
, w
, pCache
->h
- h
);
1433 SET_SYNC_FLAG(infoRec
);
1437 XAACacheTile(ScrnInfoPtr pScrn
, PixmapPtr pPix
)
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
;
1450 if(pCachePriv
->Info128
) {
1451 cacheRoot
= pCachePriv
->Info128
;
1452 max
= pCachePriv
->Num128x128
;
1453 current
= &pCachePriv
->Current128
;
1455 cacheRoot
= pCachePriv
->InfoPartial
;
1456 max
= pCachePriv
->NumPartial
;
1457 current
= &pCachePriv
->CurrentPartial
;
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
;
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;
1482 pCache
= &cacheRoot
[(*current
)++];
1483 if(*current
>= max
) *current
= 0;
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
);
1499 XAACacheMonoStipple(ScrnInfoPtr pScrn
, PixmapPtr pPix
)
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
;
1509 StippleScanlineProcPtr StippleFunc
;
1510 unsigned char *data
, *srcPtr
, *dstPtr
;
1512 if((h
<= 128) && (w
<= 128 * bpp
)) {
1513 if(pCachePriv
->Info128
) {
1514 cacheRoot
= pCachePriv
->Info128
;
1515 max
= pCachePriv
->Num128x128
;
1516 current
= &pCachePriv
->Current128
;
1518 cacheRoot
= pCachePriv
->InfoPartial
;
1519 max
= pCachePriv
->NumPartial
;
1520 current
= &pCachePriv
->CurrentPartial
;
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
;
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;
1546 pCache
= &cacheRoot
[(*current
)++];
1547 if(*current
>= max
) *current
= 0;
1549 pCache
->serialNumber
= pPix
->drawable
.serialNumber
;
1550 pCache
->trans_color
= pCache
->bg
= pCache
->fg
= -1;
1551 pCache
->orig_w
= w
; pCache
->orig_h
= h
;
1554 if(w
& (w
- 1)) funcNo
= 1;
1558 pad
= BitmapBytePad(pCache
->w
* bpp
);
1560 dstPtr
= data
= (unsigned char*)ALLOCATE_LOCAL(pad
* pCache
->h
);
1561 srcPtr
= (unsigned char*)pPix
->devPrivate
.ptr
;
1563 if(infoRec
->ScreenToScreenColorExpandFillFlags
& BIT_ORDER_IN_BYTE_MSBFIRST
)
1564 StippleFunc
= XAAStippleScanlineFuncMSBFirst
[funcNo
];
1566 StippleFunc
= XAAStippleScanlineFuncLSBFirst
[funcNo
];
1568 /* don't bother generating more than we'll ever use */
1569 max
= ((pScrn
->displayWidth
+ w
- 1) + 31) >> 5;
1573 for(i
= 0; i
< h
; i
++) {
1574 (*StippleFunc
)((CARD32
*)dstPtr
, (CARD32
*)srcPtr
, 0, w
, dwords
);
1575 srcPtr
+= pPix
->devKind
;
1579 while((h
<<1) <= pCache
->h
) {
1580 memcpy(data
+ (pad
* h
), data
, pad
* h
);
1585 memcpy(data
+ (pad
* h
), data
, pad
* (pCache
->h
- h
));
1587 (*infoRec
->WritePixmapToCache
)(
1588 pScrn
, pCache
->x
, pCache
->y
, pCache
->w
, pCache
->h
, data
,
1589 pad
, bpp
, pScrn
->depth
);
1591 DEALLOCATE_LOCAL(data
);
1597 XAACachePlanarMonoStipple(ScrnInfoPtr pScrn
, PixmapPtr pPix
)
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
;
1608 if((h
<= 128) && (w
<= 128)) {
1609 if(pCachePriv
->Info128
) {
1610 cacheRoot
= pCachePriv
->Info128
;
1611 max
= pCachePriv
->Num128x128
;
1612 current
= &pCachePriv
->Current128
;
1614 cacheRoot
= pCachePriv
->InfoPartial
;
1615 max
= pCachePriv
->NumPartial
;
1616 current
= &pCachePriv
->CurrentPartial
;
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
;
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;
1642 pCache
= &cacheRoot
[(*current
)++];
1643 if(*current
>= max
) *current
= 0;
1645 pCache
->serialNumber
= pPix
->drawable
.serialNumber
;
1646 pCache
->trans_color
= pCache
->bg
= pCache
->fg
= -1;
1647 pCache
->orig_w
= w
; pCache
->orig_h
= h
;
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
);
1660 XAACachePlanarMonoStippleProc
1661 XAAGetCachePlanarMonoStipple(void) { return XAACachePlanarMonoStipple
; }
1664 XAACacheStipple(ScrnInfoPtr pScrn
, PixmapPtr pPix
, int fg
, int bg
)
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
;
1677 if(pCachePriv
->Info128
) {
1678 cacheRoot
= pCachePriv
->Info128
;
1679 max
= pCachePriv
->Num128x128
;
1680 current
= &pCachePriv
->Current128
;
1682 cacheRoot
= pCachePriv
->InfoPartial
;
1683 max
= pCachePriv
->NumPartial
;
1684 current
= &pCachePriv
->CurrentPartial
;
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
;
1700 /* lets look for it */
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
;
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;
1718 pCache
= &cacheRoot
[(*current
)++];
1719 if(*current
>= max
) *current
= 0;
1721 pCache
->serialNumber
= pPix
->drawable
.serialNumber
;
1724 pCache
->trans_color
= bg
= fg
^ 1;
1726 pCache
->trans_color
= -1;
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
);
1743 XAACacheMono8x8Pattern(ScrnInfoPtr pScrn
, int pat0
, int pat1
)
1745 XAAInfoRecPtr infoRec
= GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn
);
1746 XAAPixmapCachePrivatePtr pCachePriv
=
1747 (XAAPixmapCachePrivatePtr
)infoRec
->PixmapCachePrivate
;
1748 XAACacheInfoPtr pCache
= pCachePriv
->InfoMono
;
1751 for(i
= 0; i
< pCachePriv
->NumMono
; i
++, pCache
++) {
1752 if(pCache
->serialNumber
&&
1753 (pCache
->pat0
== pat0
) && (pCache
->pat1
== pat1
))
1757 /* OK, let's cache it */
1758 pCache
= &pCachePriv
->InfoMono
[pCachePriv
->CurrentMono
++];
1759 if(pCachePriv
->CurrentMono
>= pCachePriv
->NumMono
)
1760 pCachePriv
->CurrentMono
= 0;
1762 pCache
->serialNumber
= 1; /* we don't care since we do lookups by pattern */
1763 pCache
->pat0
= pat0
;
1764 pCache
->pat1
= pat1
;
1766 (*infoRec
->WriteMono8x8PatternToCache
)(pScrn
, pCache
);
1774 XAACacheColor8x8Pattern(ScrnInfoPtr pScrn
, PixmapPtr pPix
, int fg
, int bg
)
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
);
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;
1790 pCache
= &pCachePriv
->InfoColor
[pCachePriv
->CurrentColor
++];
1791 if(pCachePriv
->CurrentColor
>= pCachePriv
->NumColor
)
1792 pCachePriv
->CurrentColor
= 0;
1794 pCache
->serialNumber
= pPix
->drawable
.serialNumber
;
1795 pCache
->trans_color
= pCache
->fg
= pCache
->bg
= -1;
1797 int pat0
= pixPriv
->pattern0
;
1798 int pat1
= pixPriv
->pattern1
;
1800 if(fg
== -1) { /* it's a tile */
1801 fg
= pixPriv
->fg
; bg
= pixPriv
->bg
;
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
;
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;
1823 pCache
= &pCachePriv
->InfoColor
[pCachePriv
->CurrentColor
++];
1824 if(pCachePriv
->CurrentColor
>= pCachePriv
->NumColor
)
1825 pCachePriv
->CurrentColor
= 0;
1828 pCache
->trans_color
= bg
= fg
^ 1;
1830 pCache
->trans_color
= -1;
1832 pCache
->pat0
= pat0
; pCache
->pat1
= pat1
;
1833 pCache
->fg
= fg
; pCache
->bg
= bg
;
1834 pCache
->serialNumber
= 1;
1837 (*infoRec
->WriteColor8x8PatternToCache
)(pScrn
, pPix
, pCache
);
1844 XAAWriteBitmapToCache(
1846 int x
, int y
, int w
, int h
,
1851 XAAInfoRecPtr infoRec
= GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn
);
1853 (*infoRec
->WriteBitmap
)(pScrn
, x
, y
, w
, h
, src
, srcwidth
,
1854 0, fg
, bg
, GXcopy
, ~0);
1858 XAAWriteBitmapToCacheLinear(
1860 int x
, int y
, int w
, int h
,
1865 ScreenPtr pScreen
= pScrn
->pScreen
;
1866 PixmapPtr pScreenPix
, pDstPix
;
1870 pScreenPix
= (*pScreen
->GetScreenPixmap
)(pScreen
);
1872 pDstPix
= GetScratchPixmapHeader(pScreen
, pScreenPix
->drawable
.width
,
1873 y
+ h
, pScreenPix
->drawable
.depth
,
1874 pScreenPix
->drawable
.bitsPerPixel
,
1875 pScreenPix
->devKind
,
1876 pScreenPix
->devPrivate
.ptr
);
1878 pGC
= GetScratchGC(pScreenPix
->drawable
.depth
, pScreen
);
1881 DoChangeGC(pGC
, GCForeground
| GCBackground
, gcvals
, 0);
1882 ValidateGC((DrawablePtr
)pDstPix
, pGC
);
1884 /* We've unwrapped already so these ops miss a sync */
1887 (*pGC
->ops
->PutImage
)((DrawablePtr
)pDstPix
, pGC
, 1, x
, y
, w
, h
, 0,
1888 XYBitmap
, (pointer
)src
);
1891 FreeScratchPixmapHeader(pDstPix
);
1896 XAAWritePixmapToCache(
1898 int x
, int y
, int w
, int h
,
1903 XAAInfoRecPtr infoRec
= GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn
);
1905 (*infoRec
->WritePixmap
)(pScrn
, x
, y
, w
, h
, src
, srcwidth
,
1906 GXcopy
, ~0, -1, bpp
, depth
);
1912 XAAWritePixmapToCacheLinear(
1914 int x
, int y
, int w
, int h
,
1919 ScreenPtr pScreen
= pScrn
->pScreen
;
1920 PixmapPtr pScreenPix
, pDstPix
;
1923 pScreenPix
= (*pScreen
->GetScreenPixmap
)(pScreen
);
1925 pDstPix
= GetScratchPixmapHeader(pScreen
, x
+ w
, y
+ h
,
1926 depth
, bpp
, pScreenPix
->devKind
,
1927 pScreenPix
->devPrivate
.ptr
);
1929 pGC
= GetScratchGC(depth
, pScreen
);
1930 ValidateGC((DrawablePtr
)pDstPix
, pGC
);
1932 /* We've unwrapped already so these ops miss a sync */
1935 if(bpp
== BitsPerPixel(depth
))
1936 (*pGC
->ops
->PutImage
)((DrawablePtr
)pDstPix
, pGC
, depth
, x
, y
, w
,
1937 h
, 0, ZPixmap
, (pointer
)src
);
1941 pSrcPix
= GetScratchPixmapHeader(pScreen
, w
, h
, depth
, bpp
,
1942 srcwidth
, (pointer
)src
);
1944 (*pGC
->ops
->CopyArea
)((DrawablePtr
)pSrcPix
, (DrawablePtr
)pDstPix
,
1945 pGC
, 0, 0, w
, h
, x
, y
);
1947 FreeScratchPixmapHeader(pSrcPix
);
1951 FreeScratchPixmapHeader(pDstPix
);
1956 XAAWriteMono8x8PatternToCache(
1958 XAACacheInfoPtr pCache
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);
1966 pCache
->offsets
= pCachePriv
->MonoOffsets
;
1968 pad
= BitmapBytePad(pCache
->w
* pScrn
->bitsPerPixel
);
1970 data
= (unsigned char*)ALLOCATE_LOCAL(pad
* pCache
->h
);
1973 if(infoRec
->Mono8x8PatternFillFlags
& HARDWARE_PATTERN_PROGRAMMED_ORIGIN
) {
1974 CARD32
* ptr
= (CARD32
*)data
;
1975 ptr
[0] = pCache
->pat0
; ptr
[1] = pCache
->pat1
;
1978 DDXPointPtr pPoint
= pCache
->offsets
;
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
;
1991 (*infoRec
->WritePixmapToCache
)(pScrn
, pCache
->x
, pCache
->y
,
1992 pCache
->w
, pCache
->h
, data
, pad
, pScrn
->bitsPerPixel
, pScrn
->depth
);
1994 DEALLOCATE_LOCAL(data
);
1998 XAAWriteColor8x8PatternToCache(
2001 XAACacheInfoPtr pCache
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
;
2010 pCache
->offsets
= pCachePriv
->ColorOffsets
;
2012 if(pixPriv
->flags
& REDUCIBLE_TO_2_COLOR
) {
2014 pad
= BitmapBytePad(pCache
->w
);
2015 data
= (unsigned char*)ALLOCATE_LOCAL(pad
* pCache
->h
);
2018 if(infoRec
->Color8x8PatternFillFlags
&
2019 HARDWARE_PATTERN_PROGRAMMED_ORIGIN
) {
2020 ptr
= (CARD32
*)data
;
2021 ptr
[0] = pCache
->pat0
; ptr
[1] = pCache
->pat1
;
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
;
2037 (*infoRec
->WriteBitmapToCache
)(pScrn
, pCache
->x
, pCache
->y
,
2038 pCache
->w
, pCache
->h
, data
, pad
, pCache
->fg
, pCache
->bg
);
2040 DEALLOCATE_LOCAL(data
);
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
);
2049 data
= (unsigned char*)ALLOCATE_LOCAL(pad
* pCache
->h
);
2052 /* Write and expand horizontally. */
2053 for (i
= h
, dstPtr
= data
, srcPtr
= pPix
->devPrivate
.ptr
; i
--;
2054 srcPtr
+= pPix
->devKind
, dstPtr
+= pScrn
->bitsPerPixel
) {
2056 memcpy(dstPtr
, srcPtr
, w
* Bpp
);
2058 memcpy(dstPtr
+ (nw
* Bpp
), dstPtr
, nw
* Bpp
);
2063 /* Expand vertically. */
2065 memcpy(data
+ (nh
*pScrn
->bitsPerPixel
), data
, nh
*pScrn
->bitsPerPixel
);
2069 if(!(infoRec
->Color8x8PatternFillFlags
&
2070 HARDWARE_PATTERN_PROGRAMMED_ORIGIN
)){
2072 unsigned char *ptr
= data
+ (128 * Bpp
);
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
,
2079 memcpy(ptr
+ (j
* 8 + 8 - i
) * Bpp
, data
+ j
* 8 * Bpp
, i
*Bpp
);
2081 memcpy(ptr
+ (64 * Bpp
), ptr
, 64 * Bpp
);
2085 (*infoRec
->WritePixmapToCache
)(pScrn
, pCache
->x
, pCache
->y
,
2086 pCache
->w
, pCache
->h
, data
, pad
, pScrn
->bitsPerPixel
, pScrn
->depth
);
2088 DEALLOCATE_LOCAL(data
);
2094 XAAStippledFillChooser(GCPtr pGC
)
2096 XAAInfoRecPtr infoRec
= GET_XAAINFORECPTR_FROM_GC(pGC
);
2097 PixmapPtr pPixmap
= pGC
->stipple
;
2098 XAAPixmapPtr pPriv
= XAA_GET_PIXMAP_PRIVATE(pPixmap
);
2100 if(!(pPriv
->flags
& REDUCIBILITY_CHECKED
) &&
2101 (infoRec
->CanDoMono8x8
|| infoRec
->CanDoColor8x8
)) {
2102 XAACheckStippleReducibility(pPixmap
);
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
)) {
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
)) {
2127 return DO_COLOR_8x8
;
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
)) {
2143 return DO_CACHE_EXPAND
;
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
)) {
2159 return DO_CACHE_BLT
;
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
)) {
2171 return DO_COLOR_EXPAND
;
2179 XAAOpaqueStippledFillChooser(GCPtr pGC
)
2181 XAAInfoRecPtr infoRec
= GET_XAAINFORECPTR_FROM_GC(pGC
);
2182 PixmapPtr pPixmap
= pGC
->stipple
;
2183 XAAPixmapPtr pPriv
= XAA_GET_PIXMAP_PRIVATE(pPixmap
);
2185 if(XAA_DEPTH_BUG(pGC
))
2188 if(!(pPriv
->flags
& REDUCIBILITY_CHECKED
) &&
2189 (infoRec
->CanDoMono8x8
|| infoRec
->CanDoColor8x8
)) {
2190 XAACheckStippleReducibility(pPixmap
);
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
)) {
2204 if(infoRec
->CanDoColor8x8
&&
2205 CHECK_ROP(pGC
,infoRec
->FillColor8x8PatternSpansFlags
) &&
2206 CHECK_ROPSRC(pGC
,infoRec
->FillColor8x8PatternSpansFlags
) &&
2207 CHECK_PLANEMASK(pGC
,infoRec
->FillColor8x8PatternSpansFlags
)) {
2209 return DO_COLOR_8x8
;
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
)) {
2223 return DO_CACHE_EXPAND
;
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
)) {
2235 return DO_CACHE_BLT
;
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
)) {
2245 return DO_COLOR_EXPAND
;
2254 XAATiledFillChooser(GCPtr pGC
)
2256 XAAInfoRecPtr infoRec
= GET_XAAINFORECPTR_FROM_GC(pGC
);
2257 PixmapPtr pPixmap
= pGC
->tile
.pixmap
;
2258 XAAPixmapPtr pPriv
= XAA_GET_PIXMAP_PRIVATE(pPixmap
);
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
)) {
2265 return DO_PIXMAP_COPY
;
2268 if(!(pPriv
->flags
& REDUCIBILITY_CHECKED
) &&
2269 (infoRec
->CanDoMono8x8
|| infoRec
->CanDoColor8x8
)) {
2270 XAACheckTileReducibility(pPixmap
,infoRec
->CanDoMono8x8
);
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
)) {
2285 if(infoRec
->CanDoColor8x8
&&
2286 CHECK_ROP(pGC
,infoRec
->FillColor8x8PatternSpansFlags
) &&
2287 CHECK_ROPSRC(pGC
,infoRec
->FillColor8x8PatternSpansFlags
) &&
2288 CHECK_PLANEMASK(pGC
,infoRec
->FillColor8x8PatternSpansFlags
)) {
2290 return DO_COLOR_8x8
;
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
)) {
2301 return DO_CACHE_BLT
;
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
)) {
2310 return DO_IMAGE_WRITE
;
2317 static int RotateMasksX
[8] = {
2318 0xFFFFFFFF, 0x7F7F7F7F, 0x3F3F3F3F, 0x1F1F1F1F,
2319 0x0F0F0F0F, 0x07070707, 0x03030303, 0x01010101
2322 static int RotateMasksY
[4] = {
2323 0xFFFFFFFF, 0x00FFFFFF, 0x0000FFFF, 0x000000FF
2327 XAARotateMonoPattern(
2328 int *pat0
, int *pat1
,
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
);
2341 tmp
= *pat0
; *pat0
= *pat1
; *pat1
= tmp
;
2345 mask
= RotateMasksY
[yorg
];
2348 *pat0
= ((*pat0
>> yorg
) & mask
) | ((*pat1
<< (32 - yorg
)) & ~mask
);
2349 *pat1
= ((*pat1
>> yorg
) & mask
) | ((tmp
<< (32 - yorg
)) & ~mask
);
2356 XAAInvalidatePixmapCache(ScreenPtr pScreen
)
2358 XAAInfoRecPtr infoRec
= GET_XAAINFORECPTR_FROM_SCREEN(pScreen
);
2359 XAAPixmapCachePrivatePtr pCachePriv
=
2360 (XAAPixmapCachePrivatePtr
)infoRec
->PixmapCachePrivate
;
2363 if(!pCachePriv
) return;
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;