aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xfree86/xaa/xaaPCache.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xfree86/xaa/xaaPCache.c')
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaPCache.c4901
1 files changed, 2527 insertions, 2374 deletions
diff --git a/xorg-server/hw/xfree86/xaa/xaaPCache.c b/xorg-server/hw/xfree86/xaa/xaaPCache.c
index ff3f9ef56..02c0cd498 100644
--- a/xorg-server/hw/xfree86/xaa/xaaPCache.c
+++ b/xorg-server/hw/xfree86/xaa/xaaPCache.c
@@ -1,2374 +1,2527 @@
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "gc.h"
-#include "mi.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "regionstr.h"
-#include "servermd.h"
-#include "xf86str.h"
-#include "xaa.h"
-#include "xaacexp.h"
-#include "xaalocal.h"
-#include "xaawrap.h"
-
-#define MAX_COLOR 32
-#define MAX_MONO 32
-#define MAX_8 32
-#define MAX_128 32
-#define MAX_256 32
-#define MAX_512 16
-
-static int CacheInitIndex = -1;
-#define CACHEINIT(p) ((p)->privates[CacheInitIndex].val)
-
-
-typedef struct _CacheLink {
- int x;
- int y;
- int w;
- int h;
- struct _CacheLink *next;
-} CacheLink, *CacheLinkPtr;
-
-
-static void
-TransferList(CacheLinkPtr list, XAACacheInfoPtr array, int num)
-{
- while(num--) {
- array->x = list->x;
- array->y = list->y;
- array->w = list->w;
- array->h = list->h;
- array->serialNumber = 0;
- array->fg = array->bg = -1;
- list = list->next;
- array++;
- }
-}
-
-
-
-static CacheLinkPtr
-Enlist(CacheLinkPtr link, int x, int y, int w, int h)
-{
- CacheLinkPtr newLink;
-
- newLink = malloc(sizeof(CacheLink));
- newLink->next = link;
- newLink->x = x; newLink->y = y;
- newLink->w = w; newLink->h = h;
- return newLink;
-}
-
-
-
-static CacheLinkPtr
-Delist(CacheLinkPtr link) {
- CacheLinkPtr ret = NULL;
-
- if(link) {
- ret = link->next;
- free(link);
- }
- return ret;
-}
-
-
-
-static void
-FreeList(CacheLinkPtr link) {
- CacheLinkPtr tmp;
-
- while(link) {
- tmp = link;
- link = link->next;
- free(tmp);
- }
-}
-
-
-
-static CacheLinkPtr
-QuadLinks(CacheLinkPtr big, CacheLinkPtr little)
-{
- /* CAUTION: This doesn't free big */
- int w1, w2, h1, h2;
-
- while(big) {
- w1 = big->w >> 1;
- w2 = big->w - w1;
- h1 = big->h >> 1;
- h2 = big->h - h1;
-
- little = Enlist(little, big->x, big->y, w1, h1);
- little = Enlist(little, big->x + w1, big->y, w2, h1);
- little = Enlist(little, big->x, big->y + h1, w1, h2);
- little = Enlist(little, big->x + w1, big->y + h1, w2, h2);
-
- big = big->next;
- }
- return little;
-}
-
-
-static void
-SubdivideList(CacheLinkPtr *large, CacheLinkPtr *small)
-{
- CacheLinkPtr big = *large;
- CacheLinkPtr little = *small;
- int size = big->w >> 1;
-
- little = Enlist(little, big->x, big->y, size, size);
- little = Enlist(little, big->x + size, big->y, size, size);
- little = Enlist(little, big->x, big->y + size, size, size);
- little = Enlist(little, big->x + size, big->y + size, size, size);
- *small = little;
- big = Delist(big);
- *large = big;
-}
-
-static void
-FreePixmapCachePrivate(XAAPixmapCachePrivatePtr pPriv)
-{
- if(!pPriv) return;
-
- free(pPriv->Info512);
- free(pPriv->Info256);
- free(pPriv->Info128);
- free(pPriv->InfoColor);
- free(pPriv->InfoMono);
- free(pPriv->InfoPartial);
-
- free(pPriv);
-}
-
-void
-XAAClosePixmapCache(ScreenPtr pScreen)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
-
- if(infoRec->PixmapCachePrivate)
- FreePixmapCachePrivate(
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate);
-
- infoRec->PixmapCachePrivate = NULL;
-}
-
-
-
-static CacheLinkPtr
-ThinOutPartials(
- CacheLinkPtr ListPartial,
- int *num, int *maxw, int *maxh
-) {
-/* This guy's job is to get at least 4 big slots out of a list of fragments */
-
- CacheLinkPtr List64, List32, List16, List8, pCur, next, ListKeepers;
- int Num64, Num32, Num16, Num8, NumKeepers;
- int w, h;
-
- List64 = List32 = List16 = List8 = ListKeepers = NULL;
- Num64 = Num32 = Num16 = Num8 = NumKeepers = 0;
- w = h = 0;
-
- /* We sort partials by how large a square tile they can cache.
- If a partial can't store a 64x64, 32x32, 16x16 or 8x8 tile,
- we free it. */
-
- pCur = ListPartial;
- while(pCur) {
- next = pCur->next;
- if((pCur->w >= 64) && (pCur->h >= 64)) {
- pCur->next = List64; List64 = pCur;
- Num64++;
- } else
- if((pCur->w >= 32) && (pCur->h >= 32)) {
- pCur->next = List32; List32 = pCur;
- Num32++;
- } else
- if((pCur->w >= 16) && (pCur->h >= 16)) {
- pCur->next = List16; List16 = pCur;
- Num16++;
- } else
- if((pCur->w >= 8) && (pCur->h >= 8)) {
- pCur->next = List8; List8 = pCur;
- Num8++;
- } else {
- free(pCur);
- }
-
- pCur = next;
- }
-
- /* We save all the tiles from the largest bin that we can get
- at least 4 of. If there are too few of a bigger slot, we
- cut it in fourths to make smaller slots. */
-
- if(Num64 >= 4) {
- ListKeepers = List64; List64 = NULL;
- NumKeepers = Num64;
- goto GOT_EM;
- } else if(Num64) {
- List32 = QuadLinks(List64, List32);
- Num32 += Num64 * 4;
- Num64 = 0;
- }
-
- if(Num32 >= 4) {
- ListKeepers = List32; List32 = NULL;
- NumKeepers = Num32;
- goto GOT_EM;
- } else if(Num32) {
- List16 = QuadLinks(List32, List16);
- Num16 += Num32 * 4;
- Num32 = 0;
- }
-
- if(Num16 >= 4) {
- ListKeepers = List16; List16 = NULL;
- NumKeepers = Num16;
- goto GOT_EM;
- } else if(Num16) {
- List8 = QuadLinks(List16, List8);
- Num8 += Num16 * 4;
- Num16 = 0;
- }
-
- if(Num8 >= 4) {
- ListKeepers = List8; List8 = NULL;
- NumKeepers = Num8;
- goto GOT_EM;
- }
-
-GOT_EM:
-
- /* Free the ones we aren't using */
-
- if(List64) FreeList(List64);
- if(List32) FreeList(List32);
- if(List16) FreeList(List16);
- if(List8) FreeList(List8);
-
-
- /* Enlarge the slots if we can */
-
- if(ListKeepers) {
- CacheLinkPtr pLink = ListKeepers;
- w = h = 128;
-
- while(pLink) {
- if(pLink->w < w) w = pLink->w;
- if(pLink->h < h) h = pLink->h;
- pLink = pLink->next;
- }
- }
-
- *maxw = w;
- *maxh = h;
- *num = NumKeepers;
- return ListKeepers;
-}
-
-static void
-ConvertColorToMono(
- CacheLinkPtr *ColorList,
- int ColorW, int ColorH,
- CacheLinkPtr *MonoList,
- int MonoW, int MonoH
-){
- int x, y, w;
-
- x = (*ColorList)->x; y = (*ColorList)->y;
- *ColorList = Delist(*ColorList);
-
- while(ColorH) {
- ColorH -= MonoH;
- for(w = 0; w <= (ColorW - MonoW); w += MonoW)
- *MonoList = Enlist(*MonoList, x + w, y + ColorH, MonoW, MonoH);
- }
-}
-
-static void
-ConvertAllPartialsTo8x8(
- int *NumMono, int *NumColor,
- CacheLinkPtr ListPartial,
- CacheLinkPtr *ListMono,
- CacheLinkPtr *ListColor,
- XAAInfoRecPtr infoRec
-){
-/* This guy extracts as many 8x8 slots as it can out of fragments */
-
- int ColorH = infoRec->CacheHeightColor8x8Pattern;
- int ColorW = infoRec->CacheWidthColor8x8Pattern;
- int MonoH = infoRec->CacheHeightMono8x8Pattern;
- int MonoW = infoRec->CacheWidthMono8x8Pattern;
- int x, y, w, Height, Width;
- Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
- Bool DoMono = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
- CacheLinkPtr pLink = ListPartial;
- CacheLinkPtr MonoList = *ListMono, ColorList = *ListColor;
-
- if(DoColor && DoMono) {
- /* we assume color patterns take more space than color ones */
- if(MonoH > ColorH) ColorH = MonoH;
- if(MonoW > ColorW) ColorW = MonoW;
- }
-
- /* Break up the area into as many Color and Mono slots as we can */
-
- while(pLink) {
- Height = pLink->h;
- Width = pLink->w;
- x = pLink->x;
- y = pLink->y;
-
- if(DoColor) {
- while(Height >= ColorH) {
- Height -= ColorH;
- for(w = 0; w <= (Width - ColorW); w += ColorW) {
- ColorList = Enlist(
- ColorList, x + w, y + Height, ColorW, ColorH);
- (*NumColor)++;
- }
- }
- }
-
- if(DoMono && (Height >= MonoH)) {
- while(Height >= MonoH) {
- Height -= MonoH;
- for(w = 0; w <= (Width - MonoW); w += MonoW) {
- MonoList = Enlist(
- MonoList, x + w, y + Height, MonoW, MonoH);
- (*NumMono)++;
- }
- }
- }
-
- pLink = pLink->next;
- }
-
-
- *ListMono = MonoList;
- *ListColor = ColorList;
- FreeList(ListPartial);
-}
-
-
-static CacheLinkPtr
-ExtractOneThatFits(CacheLinkPtr *initList, int w, int h)
-{
- CacheLinkPtr list = *initList;
- CacheLinkPtr prev = NULL;
-
- while(list) {
- if((list->w >= w) && (list->h >= h))
- break;
- prev = list;
- list = list->next;
- }
-
- if(list) {
- if(prev)
- prev->next = list->next;
- else
- *initList = list->next;
-
- list->next = NULL;
- }
-
- return list;
-}
-
-
-static CacheLinkPtr
-ConvertSomePartialsTo8x8(
- int *NumMono, int *NumColor, int *NumPartial,
- CacheLinkPtr ListPartial,
- CacheLinkPtr *ListMono,
- CacheLinkPtr *ListColor,
- int *maxw, int *maxh,
- XAAInfoRecPtr infoRec
-){
-/* This guy tries to get 4 of each type of 8x8 slot requested out of
- a list of fragments all while trying to retain some big fragments
- for the cache blits */
-
- int ColorH = infoRec->CacheHeightColor8x8Pattern;
- int ColorW = infoRec->CacheWidthColor8x8Pattern;
- int MonoH = infoRec->CacheHeightMono8x8Pattern;
- int MonoW = infoRec->CacheWidthMono8x8Pattern;
- Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
- Bool DoMono = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
- CacheLinkPtr List64, List32, List16, List8, pCur, next, ListKeepers;
- CacheLinkPtr MonoList = *ListMono, ColorList = *ListColor;
- int Num64, Num32, Num16, Num8, NumKeepers;
- int w, h, Width, Height;
- int MonosPerColor = 1;
-
- if(DoColor && DoMono) {
- /* we assume color patterns take more space than color ones */
- if(MonoH > ColorH) ColorH = MonoH;
- if(MonoW > ColorW) ColorW = MonoW;
- MonosPerColor = (ColorH/MonoH) * (ColorW/MonoW);
- }
-
- List64 = List32 = List16 = List8 = ListKeepers = MonoList = ColorList = NULL;
- Num64 = Num32 = Num16 = Num8 = NumKeepers = 0;
- Width = Height = 0;
-
- /* We sort partials by how large a square tile they can cache.
- We make 8x8 patterns from the leftovers if we can. */
-
- pCur = ListPartial;
- while(pCur) {
- next = pCur->next;
- if((pCur->w >= 64) && (pCur->h >= 64)) {
- pCur->next = List64; List64 = pCur;
- Num64++;
- } else
- if((pCur->w >= 32) && (pCur->h >= 32)) {
- pCur->next = List32; List32 = pCur;
- Num32++;
- } else
- if((pCur->w >= 16) && (pCur->h >= 16)) {
- pCur->next = List16; List16 = pCur;
- Num16++;
- } else
- if((pCur->w >= 8) && (pCur->h >= 8)) {
- pCur->next = List8; List8 = pCur;
- Num8++;
- } else {
- h = pCur->h;
- if(DoColor && (pCur->w >= ColorW) && (h >= ColorH)) {
- while(h >= ColorH) {
- h -= ColorH;
- for(w = 0; w <= (pCur->w - ColorW); w += ColorW) {
- ColorList = Enlist( ColorList,
- pCur->x + w, pCur->y + h, ColorW, ColorH);
- (*NumColor)++;
- }
- }
- }
- if(DoMono && (pCur->w >= MonoW) && (h >= MonoH)) {
- while(h >= MonoH) {
- h -= MonoH;
- for(w = 0; w <= (pCur->w - MonoW); w += MonoW) {
- MonoList = Enlist( MonoList,
- pCur->x + w, pCur->y + h, MonoW, MonoH);
- (*NumMono)++;
- }
- }
- }
- free(pCur);
- }
-
- pCur = next;
- }
-
- /* Try to extract at least 4 of each type of 8x8 slot that we need */
-
- if(DoColor) {
- CacheLinkPtr theOne;
- while(*NumColor < 4) {
- theOne = NULL;
- if(Num8) {
- if((theOne = ExtractOneThatFits(&List8, ColorW, ColorH)))
- Num8--;
- }
- if(Num16 && !theOne) {
- if((theOne = ExtractOneThatFits(&List16, ColorW, ColorH)))
- Num16--;
- }
- if(Num32 && !theOne) {
- if((theOne = ExtractOneThatFits(&List32, ColorW, ColorH)))
- Num32--;
- }
- if(Num64 && !theOne) {
- if((theOne = ExtractOneThatFits(&List64, ColorW, ColorH)))
- Num64--;
- }
-
- if(!theOne) break;
-
-
- ConvertAllPartialsTo8x8(NumMono, NumColor, theOne,
- &MonoList, &ColorList, infoRec);
-
- if(DoMono) {
- while(*NumColor && (*NumMono < 4)) {
- ConvertColorToMono(&ColorList, ColorW, ColorH,
- &MonoList, MonoW, MonoH);
- (*NumColor)--; *NumMono += MonosPerColor;
- }
- }
- }
- }
-
- if(DoMono) {
- CacheLinkPtr theOne;
- while(*NumMono < 4) {
- theOne = NULL;
- if(Num8) {
- if((theOne = ExtractOneThatFits(&List8, MonoW, MonoH)))
- Num8--;
- }
- if(Num16 && !theOne) {
- if((theOne = ExtractOneThatFits(&List16, MonoW, MonoH)))
- Num16--;
- }
- if(Num32 && !theOne) {
- if((theOne = ExtractOneThatFits(&List32, MonoW, MonoH)))
- Num32--;
- }
- if(Num64 && !theOne) {
- if((theOne = ExtractOneThatFits(&List64, MonoW, MonoH)))
- Num64--;
- }
-
- if(!theOne) break;
-
- ConvertAllPartialsTo8x8(NumMono, NumColor, theOne,
- &MonoList, &ColorList, infoRec);
- }
- }
-
- /* We save all the tiles from the largest bin that we can get
- at least 4 of. If there are too few of a bigger slot, we
- cut it in fourths to make smaller slots. */
-
- if(Num64 >= 4) {
- ListKeepers = List64; List64 = NULL;
- NumKeepers = Num64;
- goto GOT_EM;
- } else if(Num64) {
- List32 = QuadLinks(List64, List32);
- Num32 += Num64 * 4;
- Num64 = 0;
- }
-
- if(Num32 >= 4) {
- ListKeepers = List32; List32 = NULL;
- NumKeepers = Num32;
- goto GOT_EM;
- } else if(Num32) {
- List16 = QuadLinks(List32, List16);
- Num16 += Num32 * 4;
- Num32 = 0;
- }
-
- if(Num16 >= 4) {
- ListKeepers = List16; List16 = NULL;
- NumKeepers = Num16;
- goto GOT_EM;
- } else if(Num16) {
- List8 = QuadLinks(List16, List8);
- Num8 += Num16 * 4;
- Num16 = 0;
- }
-
- if(Num8 >= 4) {
- ListKeepers = List8; List8 = NULL;
- NumKeepers = Num8;
- goto GOT_EM;
- }
-
-GOT_EM:
-
- /* Free the ones we aren't using */
-
- if(List64)
- ConvertAllPartialsTo8x8(NumMono, NumColor, List64,
- &MonoList, &ColorList, infoRec);
- if(List32)
- ConvertAllPartialsTo8x8(NumMono, NumColor, List32,
- &MonoList, &ColorList, infoRec);
- if(List16)
- ConvertAllPartialsTo8x8(NumMono, NumColor, List16,
- &MonoList, &ColorList, infoRec);
- if(List8)
- ConvertAllPartialsTo8x8(NumMono, NumColor, List8,
- &MonoList, &ColorList, infoRec);
-
-
- /* Enlarge the slots if we can */
-
- if(ListKeepers) {
- CacheLinkPtr pLink = ListKeepers;
- Width = Height = 128;
-
- while(pLink) {
- if(pLink->w < Width) Width = pLink->w;
- if(pLink->h < Height) Height = pLink->h;
- pLink = pLink->next;
- }
- }
-
- *ListMono = MonoList;
- *ListColor = ColorList;
- *maxw = Width;
- *maxh = Height;
- *NumPartial = NumKeepers;
- return ListKeepers;
-}
-
-
-void
-XAAInitPixmapCache(
- ScreenPtr pScreen,
- RegionPtr areas,
- pointer data
-) {
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- XAAInfoRecPtr infoRec = (XAAInfoRecPtr)data;
- XAAPixmapCachePrivatePtr pCachePriv;
- BoxPtr pBox = RegionRects(areas);
- int nBox = RegionNumRects(areas);
- int Num512, Num256, Num128, NumPartial, NumColor, NumMono;
- int Target512, Target256;
- CacheLinkPtr List512, List256, List128, ListPartial, ListColor, ListMono;
- int x, y, w, h, ntotal, granularity, width, height, i;
- int MaxPartialWidth, MaxPartialHeight;
-
- infoRec->MaxCacheableTileWidth = 0;
- infoRec->MaxCacheableTileHeight = 0;
- infoRec->MaxCacheableStippleHeight = 0;
- infoRec->MaxCacheableStippleWidth = 0;
- infoRec->UsingPixmapCache = FALSE;
-
-
- if(!nBox || !pBox || !(infoRec->Flags & PIXMAP_CACHE))
- return;
-
- /* Allocate a persistent per-screen init flag to control messages */
- if (CacheInitIndex < 0)
- CacheInitIndex = xf86AllocateScrnInfoPrivateIndex();
-
- /* free the old private data if it exists */
- if(infoRec->PixmapCachePrivate) {
- FreePixmapCachePrivate(
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate);
- infoRec->PixmapCachePrivate = NULL;
- }
-
- Num512 = Num256 = Num128 = NumPartial = NumMono = NumColor = 0;
- List512 = List256 = List128 = ListPartial = ListMono = ListColor = NULL;
- granularity = infoRec->CachePixelGranularity;
- if(granularity <= 1) granularity = 0;
-
- /* go through the boxes and break it into as many pieces as we can fit */
-
- while(nBox--) {
- x = pBox->x1;
- if(granularity) {
- int tmp = x % granularity;
- if(tmp) x += (granularity - tmp);
- }
- width = pBox->x2 - x;
- if(width <= 0) {pBox++; continue;}
-
- y = pBox->y1;
- height = pBox->y2 - y;
-
- for(h = 0; h <= (height - 512); h += 512) {
- for(w = 0; w <= (width - 512); w += 512) {
- List512 = Enlist(List512, x + w, y + h, 512, 512);
- Num512++;
- }
- for(; w <= (width - 256); w += 256) {
- List256 = Enlist(List256, x + w, y + h, 256, 256);
- List256 = Enlist(List256, x + w, y + h + 256, 256, 256);
- Num256 += 2;
- }
- for(; w <= (width - 128); w += 128) {
- List128 = Enlist(List128, x + w, y + h, 128, 128);
- List128 = Enlist(List128, x + w, y + h + 128, 128, 128);
- List128 = Enlist(List128, x + w, y + h + 256, 128, 128);
- List128 = Enlist(List128, x + w, y + h + 384, 128, 128);
- Num128 += 4;
- }
- if(w < width) {
- int d = width - w;
- ListPartial = Enlist(ListPartial, x + w, y + h, d, 128);
- ListPartial = Enlist(ListPartial, x + w, y + h + 128, d, 128);
- ListPartial = Enlist(ListPartial, x + w, y + h + 256, d, 128);
- ListPartial = Enlist(ListPartial, x + w, y + h + 384, d, 128);
- NumPartial += 4;
- }
- }
- for(; h <= (height - 256); h += 256) {
- for(w = 0; w <= (width - 256); w += 256) {
- List256 = Enlist(List256, x + w, y + h, 256, 256);
- Num256++;
- }
- for(; w <= (width - 128); w += 128) {
- List128 = Enlist(List128, x + w, y + h, 128, 128);
- List128 = Enlist(List128, x + w, y + h + 128, 128, 128);
- Num128 += 2;
- }
- if(w < width) {
- int d = width - w;
- ListPartial = Enlist(ListPartial, x + w, y + h, d, 128);
- ListPartial = Enlist(ListPartial, x + w, y + h + 128, d, 128);
- NumPartial += 2;
- }
- }
- for(; h <= (height - 128); h += 128) {
- for(w = 0; w <= (width - 128); w += 128) {
- List128 = Enlist(List128, x + w, y + h, 128, 128);
- Num128++;
- }
- if(w < width) {
- ListPartial = Enlist(
- ListPartial, x + w, y + h, width - w, 128);
- NumPartial++;
- }
- }
- if(h < height) {
- int d = height - h;
- for(w = 0; w <= (width - 128); w += 128) {
- ListPartial = Enlist(ListPartial, x + w, y + h, 128, d);
- NumPartial++;
- }
- if(w < width) {
- ListPartial = Enlist(ListPartial, x + w, y + h, width - w, d);
- NumPartial++;
- }
- }
- pBox++;
- }
-
-
-/*
- by this point we've carved the space into as many 512x512, 256x256
- and 128x128 blocks as we could fit. We will then break larger
- blocks into smaller ones if we need to. The rules are as follows:
-
- 512x512 -
- 1) Don't take up more than half the memory.
- 2) Don't bother if you can't get at least four.
- 3) Don't make more than MAX_512.
- 4) Don't have any of there are no 256x256s.
-
- 256x256 -
- 1) Don't take up more than a quarter of the memory enless there
- aren't any 512x512s. Then we can take up to half.
- 2) Don't bother if you can't get at least four.
- 3) Don't make more than MAX_256.
-
- 128x128 -
- 1) Don't make more than MAX_128.
-
- We don't bother with the partial blocks unless we can use them
- for 8x8 pattern fills or we are short on larger blocks.
-
-*/
-
- ntotal = Num128 + (Num256<<2) + (Num512<<4);
-
- Target512 = ntotal >> 5;
- if(Target512 < 4) Target512 = 0;
- if(!Target512) Target256 = ntotal >> 3;
- else Target256 = ntotal >> 4;
- if(Target256 < 4) Target256 = 0;
-
- if(Num512 && Num256 < 4) {
- while(Num512 && Num256 < Target256) {
- SubdivideList(&List512, &List256);
- Num256 += 4; Num512--;
- }
- }
-
- if(!Num512) { /* no room */
- } else if((Num512 < 4) || (!Target512)) {
- while(Num512) {
- SubdivideList(&List512, &List256);
- Num256 += 4; Num512--;
- }
- } else if((Num512 > MAX_512) || (Num512 > Target512)){
- while(Num512 > MAX_512) {
- SubdivideList(&List512, &List256);
- Num256 += 4; Num512--;
- }
- while(Num512 > Target512) {
- if(Num256 < MAX_256) {
- SubdivideList(&List512, &List256);
- Num256 += 4; Num512--;
- } else break;
- }
- }
-
- if(!Num256) { /* no room */
- } else if((Num256 < 4) || (!Target256)) {
- while(Num256) {
- SubdivideList(&List256, &List128);
- Num128 += 4; Num256--;
- }
- } else if((Num256 > MAX_256) || (Num256 > Target256)) {
- while(Num256 > MAX_256) {
- SubdivideList(&List256, &List128);
- Num128 += 4; Num256--;
- }
- while(Num256 > Target256) {
- if(Num128 < MAX_128) {
- SubdivideList(&List256, &List128);
- Num128 += 4; Num256--;
- } else break;
- }
- }
-
- if(Num128 && ((Num128 < 4) || (Num128 > MAX_128))) {
- CacheLinkPtr next;
- int max = (Num128 > MAX_128) ? MAX_128 : 0;
-
- /*
- * Note: next is set in this way to work around a code generation
- * bug in gcc 2.7.2.3.
- */
- next = List128->next;
- while(Num128 > max) {
- List128->next = ListPartial;
- ListPartial = List128;
- if((List128 = next))
- next = List128->next;
- NumPartial++; Num128--;
- }
- }
-
- MaxPartialHeight = MaxPartialWidth = 0;
-
- /* at this point we have as many 512x512 and 256x256 slots as we
- want but may have an excess of 128x128 slots. We still need
- to find out if we need 8x8 slots. We take these from the
- partials if we have them. Otherwise, we break some 128x128's */
-
- if(!(infoRec->PixmapCacheFlags & (CACHE_MONO_8x8 | CACHE_COLOR_8x8))) {
- if(NumPartial) {
- if(Num128) { /* don't bother with partials */
- FreeList(ListPartial);
- NumPartial = 0; ListPartial = NULL;
- } else {
- /* We have no big slots. Weed out the unusable partials */
- ListPartial = ThinOutPartials(ListPartial, &NumPartial,
- &MaxPartialWidth, &MaxPartialHeight);
- }
- }
- } else {
- int MonosPerColor = 1;
- int ColorH = infoRec->CacheHeightColor8x8Pattern;
- int ColorW = infoRec->CacheWidthColor8x8Pattern;
- int MonoH = infoRec->CacheHeightMono8x8Pattern;
- int MonoW = infoRec->CacheWidthMono8x8Pattern;
- Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
- Bool DoMono = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
-
- if(DoColor) infoRec->CanDoColor8x8 = FALSE;
- if(DoMono) infoRec->CanDoMono8x8 = FALSE;
-
- if(DoColor && DoMono) {
- /* we assume color patterns take more space than color ones */
- if(MonoH > ColorH) ColorH = MonoH;
- if(MonoW > ColorW) ColorW = MonoW;
- MonosPerColor = (ColorH/MonoH) * (ColorW/MonoW);
- }
-
- if(Num128) {
- if(NumPartial) { /* use all for 8x8 slots */
- ConvertAllPartialsTo8x8(&NumMono, &NumColor,
- ListPartial, &ListMono, &ListColor, infoRec);
- NumPartial = 0; ListPartial = NULL;
- }
-
- /* Get some 8x8 slots from the 128 slots */
- while((Num128 > 4) &&
- ((NumMono < MAX_MONO) && (NumColor < MAX_COLOR))) {
- CacheLinkPtr tmp = NULL;
-
- tmp = Enlist(tmp, List128->x, List128->y,
- List128->w, List128->h);
- List128 = Delist(List128);
- Num128--;
-
- ConvertAllPartialsTo8x8(&NumMono, &NumColor,
- tmp, &ListMono, &ListColor, infoRec);
- }
- } else if(NumPartial) {
- /* We have share partials between 8x8 slots and tiles. */
- ListPartial = ConvertSomePartialsTo8x8(&NumMono, &NumColor,
- &NumPartial, ListPartial, &ListMono, &ListColor,
- &MaxPartialWidth, &MaxPartialHeight, infoRec);
- }
-
-
- if(DoMono && DoColor) {
- if(NumColor && ((NumColor > MAX_COLOR) || (NumColor < 4))) {
- int max = (NumColor > MAX_COLOR) ? MAX_COLOR : 0;
-
- while(NumColor > max) {
- ConvertColorToMono(&ListColor, ColorW, ColorH,
- &ListMono, MonoW, MonoH);
- NumColor--; NumMono += MonosPerColor;
- }
- }
-
- /* favor Mono slots over Color ones */
- while((NumColor > 4) && (NumMono < MAX_MONO)) {
- ConvertColorToMono(&ListColor, ColorW, ColorH,
- &ListMono, MonoW, MonoH);
- NumColor--; NumMono += MonosPerColor;
- }
- }
-
- if(NumMono && ((NumMono > MAX_MONO) || (NumMono < 4))) {
- int max = (NumMono > MAX_MONO) ? MAX_MONO : 0;
-
- while(NumMono > max) {
- ListMono = Delist(ListMono);
- NumMono--;
- }
- }
- if(NumColor && ((NumColor > MAX_COLOR) || (NumColor < 4))) {
- int max = (NumColor > MAX_COLOR) ? MAX_COLOR : 0;
-
- while(NumColor > max) {
- ListColor = Delist(ListColor);
- NumColor--;
- }
- }
- }
-
-
- pCachePriv = calloc(1,sizeof(XAAPixmapCachePrivate));
- if(!pCachePriv) {
- if(Num512) FreeList(List512);
- if(Num256) FreeList(List256);
- if(Num128) FreeList(List128);
- if(NumPartial) FreeList(ListPartial);
- if(NumColor) FreeList(ListColor);
- if(NumMono) FreeList(ListMono);
- return;
- }
-
- infoRec->PixmapCachePrivate = (char*)pCachePriv;
-
- if(Num512) {
- pCachePriv->Info512 = calloc(Num512,sizeof(XAACacheInfoRec));
- if(!pCachePriv->Info512) Num512 = 0;
- if(Num512) TransferList(List512, pCachePriv->Info512, Num512);
- FreeList(List512);
- pCachePriv->Num512x512 = Num512;
- }
- if(Num256) {
- pCachePriv->Info256 = calloc(Num256, sizeof(XAACacheInfoRec));
- if(!pCachePriv->Info256) Num256 = 0;
- if(Num256) TransferList(List256, pCachePriv->Info256, Num256);
- FreeList(List256);
- pCachePriv->Num256x256 = Num256;
- }
- if(Num128) {
- pCachePriv->Info128 = calloc(Num128, sizeof(XAACacheInfoRec));
- if(!pCachePriv->Info128) Num128 = 0;
- if(Num128) TransferList(List128, pCachePriv->Info128, Num128);
- FreeList(List128);
- pCachePriv->Num128x128 = Num128;
- }
-
- if(NumPartial) {
- pCachePriv->InfoPartial = calloc(NumPartial, sizeof(XAACacheInfoRec));
- if(!pCachePriv->InfoPartial) NumPartial = 0;
- if(NumPartial)
- TransferList(ListPartial, pCachePriv->InfoPartial, NumPartial);
- FreeList(ListPartial);
- pCachePriv->NumPartial = NumPartial;
- }
-
- if(NumColor) {
- pCachePriv->InfoColor = calloc(NumColor, sizeof(XAACacheInfoRec));
- if(!pCachePriv->InfoColor) NumColor = 0;
- if(NumColor) TransferList(ListColor, pCachePriv->InfoColor, NumColor);
- FreeList(ListColor);
- pCachePriv->NumColor = NumColor;
- }
-
- if(NumMono) {
- pCachePriv->InfoMono = calloc(NumMono, sizeof(XAACacheInfoRec));
- if(!pCachePriv->InfoMono) NumMono = 0;
- if(NumMono) TransferList(ListMono, pCachePriv->InfoMono, NumMono);
- FreeList(ListMono);
- pCachePriv->NumMono = NumMono;
- }
-
-
- if(NumPartial) {
- infoRec->MaxCacheableTileWidth = MaxPartialWidth;
- infoRec->MaxCacheableTileHeight = MaxPartialHeight;
- }
- if(Num128)
- infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 128;
- if(Num256)
- infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 256;
- if(Num512)
- infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 512;
-
-
- infoRec->MaxCacheableStippleHeight = infoRec->MaxCacheableTileHeight;
- infoRec->MaxCacheableStippleWidth =
- infoRec->MaxCacheableTileWidth * pScrn->bitsPerPixel;
- if(infoRec->ScreenToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP)
- infoRec->MaxCacheableStippleWidth /= 3;
-
- if(NumMono) {
- if(!(infoRec->Mono8x8PatternFillFlags &
- (HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
- HARDWARE_PATTERN_PROGRAMMED_BITS))) {
- int numPerLine =
- infoRec->CacheWidthMono8x8Pattern/infoRec->MonoPatternPitch;
-
- for(i = 0; i < 64; i++) {
- pCachePriv->MonoOffsets[i].y = i/numPerLine;
- pCachePriv->MonoOffsets[i].x = (i % numPerLine) *
- infoRec->MonoPatternPitch;
- }
- }
- infoRec->CanDoMono8x8 = TRUE;
- }
- if(NumColor) {
- if(!(infoRec->Color8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) {
-
- for(i = 0; i < 64; i++) {
- pCachePriv->ColorOffsets[i].y = i & 0x07;
- pCachePriv->ColorOffsets[i].x = i & ~0x07;
- }
- }
- infoRec->CanDoColor8x8 = TRUE;
- }
-
- if(!CACHEINIT(pScrn)) {
- xf86ErrorF("\tSetting up tile and stipple cache:\n");
- if(NumPartial)
- xf86ErrorF("\t\t%i %ix%i slots\n",
- NumPartial, MaxPartialWidth, MaxPartialHeight);
- if(Num128) xf86ErrorF("\t\t%i 128x128 slots\n", Num128);
- if(Num256) xf86ErrorF("\t\t%i 256x256 slots\n", Num256);
- if(Num512) xf86ErrorF("\t\t%i 512x512 slots\n", Num512);
- if(NumColor) xf86ErrorF("\t\t%i 8x8 color pattern slots\n", NumColor);
- if(NumMono) xf86ErrorF("\t\t%i 8x8 color expansion slots\n", NumMono);
- }
-
- if(!(NumPartial | Num128 | Num256 | Num512 | NumColor | NumMono)) {
- if(!CACHEINIT(pScrn))
- xf86ErrorF("\t\tNot enough video memory for pixmap cache\n");
- } else infoRec->UsingPixmapCache = TRUE;
-
- CACHEINIT(pScrn) = 1;
-}
-
-#if X_BYTE_ORDER == X_BIG_ENDIAN
-static CARD32 StippleMasks[4] = {
- 0x80808080,
- 0xC0C0C0C0,
- 0x00000000,
- 0xF0F0F0F0
-};
-#else
-static CARD32 StippleMasks[4] = {
- 0x01010101,
- 0x03030303,
- 0x00000000,
- 0x0F0F0F0F
-};
-#endif
-
-Bool
-XAACheckStippleReducibility(PixmapPtr pPixmap)
-{
- XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_DRAWABLE(&pPixmap->drawable);
- CARD32 *IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
- int w = pPixmap->drawable.width;
- int h = pPixmap->drawable.height;
- int i;
- CARD32 bits[8];
- CARD32 mask = SHIFT_R(0xFFFFFFFF,24);
-
- pPriv->flags |= REDUCIBILITY_CHECKED | REDUCIBLE_TO_2_COLOR;
- pPriv->flags &= ~REDUCIBLE_TO_8x8;
-
- if((w > 32) || (h > 32) || (w & (w - 1)) || (h & (h - 1)))
- return FALSE;
-
- i = (h > 8) ? 8 : h;
-
- switch(w) {
- case 32:
- while(i--) {
- bits[i] = IntPtr[i] & mask;
- if( (bits[i] != SHIFT_R((IntPtr[i] & SHIFT_L(mask, 8)), 8)) ||
- (bits[i] != SHIFT_R((IntPtr[i] & SHIFT_L(mask,16)),16)) ||
- (bits[i] != SHIFT_R((IntPtr[i] & SHIFT_L(mask,24)),24)))
- return FALSE;
- }
- break;
- case 16:
- while(i--) {
- bits[i] = IntPtr[i] & mask;
- if(bits[i] != ((IntPtr[i] & SHIFT_R(SHIFT_L(mask,8),8))))
- return FALSE;
- }
- break;
- default:
- while(i--)
- bits[i] = IntPtr[i] & mask;
- break;
- }
-
- switch(h) {
- case 32:
- if( (IntPtr[8] != IntPtr[16]) || (IntPtr[9] != IntPtr[17]) ||
- (IntPtr[10] != IntPtr[18]) || (IntPtr[11] != IntPtr[19]) ||
- (IntPtr[12] != IntPtr[20]) || (IntPtr[13] != IntPtr[21]) ||
- (IntPtr[14] != IntPtr[22]) || (IntPtr[15] != IntPtr[23]) ||
- (IntPtr[16] != IntPtr[24]) || (IntPtr[17] != IntPtr[25]) ||
- (IntPtr[18] != IntPtr[26]) || (IntPtr[19] != IntPtr[27]) ||
- (IntPtr[20] != IntPtr[28]) || (IntPtr[21] != IntPtr[29]) ||
- (IntPtr[22] != IntPtr[30]) || (IntPtr[23] != IntPtr[31]))
- return FALSE;
- /* fall through */
- case 16:
- if( (IntPtr[0] != IntPtr[8]) || (IntPtr[1] != IntPtr[9]) ||
- (IntPtr[2] != IntPtr[10]) || (IntPtr[3] != IntPtr[11]) ||
- (IntPtr[4] != IntPtr[12]) || (IntPtr[5] != IntPtr[13]) ||
- (IntPtr[6] != IntPtr[14]) || (IntPtr[7] != IntPtr[15]))
- return FALSE;
- case 8: break;
- case 1: bits[1] = bits[0];
- case 2: bits[2] = bits[0]; bits[3] = bits[1];
- case 4: bits[4] = bits[0]; bits[5] = bits[1];
- bits[6] = bits[2]; bits[7] = bits[3];
- break;
- }
-
- pPriv->flags |= REDUCIBLE_TO_8x8;
-
- pPriv->pattern0 = bits[0] | SHIFT_L(bits[1],8) | SHIFT_L(bits[2],16) | SHIFT_L(bits[3],24);
- pPriv->pattern1 = bits[4] | SHIFT_L(bits[5],8) | SHIFT_L(bits[6],16) | SHIFT_L(bits[7],24);
-
- if(w < 8) {
- pPriv->pattern0 &= StippleMasks[w - 1];
- pPriv->pattern1 &= StippleMasks[w - 1];
-
- switch(w) {
- case 1: pPriv->pattern0 |= SHIFT_L(pPriv->pattern0,1);
- pPriv->pattern1 |= SHIFT_L(pPriv->pattern1,1);
- case 2: pPriv->pattern0 |= SHIFT_L(pPriv->pattern0,2);
- pPriv->pattern1 |= SHIFT_L(pPriv->pattern1,2);
- case 4: pPriv->pattern0 |= SHIFT_L(pPriv->pattern0,4);
- pPriv->pattern1 |= SHIFT_L(pPriv->pattern1,4);
- }
- }
-
- if(infoRec->Mono8x8PatternFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
- pPriv->pattern0 = SWAP_BITS_IN_BYTES(pPriv->pattern0);
- pPriv->pattern1 = SWAP_BITS_IN_BYTES(pPriv->pattern1);
- }
-
-
- return TRUE;
-}
-
-
-Bool
-XAACheckTileReducibility(PixmapPtr pPixmap, Bool checkMono)
-{
- XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
- CARD32 *IntPtr;
- int w = pPixmap->drawable.width;
- int h = pPixmap->drawable.height;
- int pitch = pPixmap->devKind >> 2;
- int dwords, i, j;
-
- pPriv->flags |= REDUCIBILITY_CHECKED;
- pPriv->flags &= ~(REDUCIBILITY_CHECKED | REDUCIBLE_TO_2_COLOR);
-
- if((w > 32) || (h > 32) || (w & (w - 1)) || (h & (h - 1)))
- return FALSE;
-
- dwords = ((w * pPixmap->drawable.bitsPerPixel) + 31) >> 5;
- i = (h > 8) ? 8 : h;
-
-
- if(w > 8) {
- IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
- switch(pPixmap->drawable.bitsPerPixel) {
- case 8:
- while(i--) {
- for(j = 2; j < dwords; j++)
- if(IntPtr[j] != IntPtr[j & 0x01])
- return FALSE;
- IntPtr += pitch;
- }
- break;
- case 16:
- while(i--) {
- for(j = 4; j < dwords; j++)
- if(IntPtr[j] != IntPtr[j & 0x03])
- return FALSE;
- IntPtr += pitch;
- }
- break;
- case 24:
- while(i--) {
- for(j = 6; j < dwords; j++)
- if(IntPtr[j] != IntPtr[j % 6])
- return FALSE;
- IntPtr += pitch;
- }
- break;
- case 32:
- while(i--) {
- for(j = 8; j < dwords; j++)
- if(IntPtr[j] != IntPtr[j & 0x07])
- return FALSE;
- IntPtr += pitch;
- }
- break;
- default: return FALSE;
- }
-
- }
-
-
- if(h == 32) {
- CARD32 *IntPtr2, *IntPtr3, *IntPtr4;
- i = 8;
- IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
- IntPtr2 = IntPtr + (pitch << 3);
- IntPtr3 = IntPtr2 + (pitch << 3);
- IntPtr4 = IntPtr3 + (pitch << 3);
- while(i--) {
- for(j = 0; j < dwords; j++)
- if((IntPtr[j] != IntPtr2[j]) || (IntPtr[j] != IntPtr3[j]) ||
- (IntPtr[j] != IntPtr4[j]))
- return FALSE;
- IntPtr += pitch;
- IntPtr2 += pitch;
- IntPtr3 += pitch;
- IntPtr4 += pitch;
- }
- } else if (h == 16) {
- CARD32 *IntPtr2;
- i = 8;
- IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
- IntPtr2 = IntPtr + (pitch << 3);
- while(i--) {
- for(j = 0; j < dwords; j++)
- if(IntPtr[j] != IntPtr2[j])
- return FALSE;
- IntPtr += pitch;
- IntPtr2 += pitch;
- }
- }
-
- pPriv->flags |= REDUCIBLE_TO_8x8;
-
- if(checkMono) {
- XAAInfoRecPtr infoRec =
- GET_XAAINFORECPTR_FROM_DRAWABLE(&pPixmap->drawable);
- unsigned char bits[8];
- int fg, bg = -1, x, y;
-
- i = (h > 8) ? 8 : h;
- j = (w > 8) ? 8 : w;
-
- if(pPixmap->drawable.bitsPerPixel == 8) {
- unsigned char *srcp = pPixmap->devPrivate.ptr;
- fg = srcp[0];
- pitch = pPixmap->devKind;
- for(y = 0; y < i; y++) {
- bits[y] = 0;
- for(x = 0; x < j; x++) {
- if(srcp[x] != fg) {
- if(bg == -1) bg = srcp[x];
- else if(bg != srcp[x]) return TRUE;
- } else bits[y] |= 1 << x;
- }
- srcp += pitch;
- }
- } else if(pPixmap->drawable.bitsPerPixel == 16) {
- unsigned short *srcp = (unsigned short*)pPixmap->devPrivate.ptr;
- fg = srcp[0];
- pitch = pPixmap->devKind >> 1;
- for(y = 0; y < i; y++) {
- bits[y] = 0;
- for(x = 0; x < j; x++) {
- if(srcp[x] != fg) {
- if(bg == -1) bg = srcp[x];
- else if(bg != srcp[x]) return TRUE;
- } else bits[y] |= 1 << x;
- }
- srcp += pitch;
- }
- } else if(pPixmap->drawable.bitsPerPixel == 24) {
- CARD32 val;
- unsigned char *srcp = pPixmap->devPrivate.ptr;
- fg = *((CARD32*)srcp) & 0x00FFFFFF;
- pitch = pPixmap->devKind;
- j *= 3;
- for(y = 0; y < i; y++) {
- bits[y] = 0;
- for(x = 0; x < j; x+=3) {
- val = *((CARD32*)(srcp+x)) & 0x00FFFFFF;
- if(val != fg) {
- if(bg == -1) bg = val;
- else if(bg != val)
- return TRUE;
- } else bits[y] |= 1 << (x/3);
- }
- srcp += pitch;
- }
- } else if(pPixmap->drawable.bitsPerPixel == 32) {
- IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
- fg = IntPtr[0];
- for(y = 0; y < i; y++) {
- bits[y] = 0;
- for(x = 0; x < j; x++) {
- if(IntPtr[x] != fg) {
- if(bg == -1) bg = IntPtr[x];
- else if(bg != IntPtr[x]) return TRUE;
- } else bits[y] |= 1 << x;
- }
- IntPtr += pitch;
- }
- } else return TRUE;
-
- pPriv->fg = fg;
- if(bg == -1) pPriv->bg = fg;
- else pPriv->bg = bg;
-
- if(h < 8) {
- switch(h) {
- case 1: bits[1] = bits[0];
- case 2: bits[2] = bits[0]; bits[3] = bits[1];
- case 4: bits[4] = bits[0]; bits[5] = bits[1];
- bits[6] = bits[2]; bits[7] = bits[3];
- break;
- }
- }
-
- pPriv->pattern0 =
- bits[0] | (bits[1]<<8) | (bits[2]<<16) | (bits[3]<<24);
- pPriv->pattern1 =
- bits[4] | (bits[5]<<8) | (bits[6]<<16) | (bits[7]<<24);
-
- if(w < 8) {
- switch(w) {
- case 1: pPriv->pattern0 |= (pPriv->pattern0 << 1);
- pPriv->pattern1 |= (pPriv->pattern1 << 1);
- case 2: pPriv->pattern0 |= (pPriv->pattern0 << 2);
- pPriv->pattern1 |= (pPriv->pattern1 << 2);
- case 4: pPriv->pattern0 |= (pPriv->pattern0 << 4);
- pPriv->pattern1 |= (pPriv->pattern1 << 4);
- }
- }
- pPriv->flags |= REDUCIBLE_TO_2_COLOR;
-
- if(infoRec->Mono8x8PatternFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
- pPriv->pattern0 = SWAP_BITS_IN_BYTES(pPriv->pattern0);
- pPriv->pattern1 = SWAP_BITS_IN_BYTES(pPriv->pattern1);
- }
-
- }
-
- return TRUE;
-}
-
-
-void XAATileCache(
- ScrnInfoPtr pScrn,
- XAACacheInfoPtr pCache,
- int w, int h
-) {
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
-
- (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, GXcopy, ~0, -1);
-
- while((w << 1) <= pCache->w) {
- (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
- pCache->x + w, pCache->y, w, h);
- w <<= 1;
- }
- if(w != pCache->w) {
- (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
- pCache->x + w, pCache->y, pCache->w - w, h);
- w = pCache->w;
- }
-
- while((h << 1) <= pCache->h) {
- (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
- pCache->x, pCache->y + h, w, h);
- h <<= 1;
- }
- if(h != pCache->h) {
- (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
- pCache->x, pCache->y + h, w, pCache->h - h);
- }
- SET_SYNC_FLAG(infoRec);
-}
-
-XAACacheInfoPtr
-XAACacheTile(ScrnInfoPtr pScrn, PixmapPtr pPix)
-{
- int w = pPix->drawable.width;
- int h = pPix->drawable.height;
- int size = max(w, h);
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- XAAPixmapCachePrivatePtr pCachePriv =
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
- XAACacheInfoPtr pCache, cacheRoot = NULL;
- int i, max = 0;
- int *current;
-
- if(size <= 128) {
- if(pCachePriv->Info128) {
- cacheRoot = pCachePriv->Info128;
- max = pCachePriv->Num128x128;
- current = &pCachePriv->Current128;
- } else {
- cacheRoot = pCachePriv->InfoPartial;
- max = pCachePriv->NumPartial;
- current = &pCachePriv->CurrentPartial;
- }
- } else if(size <= 256) {
- cacheRoot = pCachePriv->Info256;
- max = pCachePriv->Num256x256;
- current = &pCachePriv->Current256;
- } else if(size <= 512) {
- cacheRoot = pCachePriv->Info512;
- max = pCachePriv->Num512x512;
- current = &pCachePriv->Current512;
- } else { /* something's wrong */
- ErrorF("Something's wrong in XAACacheTile()\n");
- return pCachePriv->Info128;
- }
-
- pCache = cacheRoot;
-
- /* lets look for it */
- for(i = 0; i < max; i++, pCache++) {
- if(pCache->serialNumber == pPix->drawable.serialNumber) {
- pCache->trans_color = -1;
- return pCache;
- }
- }
-
- pCache = &cacheRoot[(*current)++];
- if(*current >= max) *current = 0;
-
- pCache->serialNumber = pPix->drawable.serialNumber;
- pCache->trans_color = pCache->bg = pCache->fg = -1;
- pCache->orig_w = w; pCache->orig_h = h;
- (*infoRec->WritePixmapToCache)(
- pScrn, pCache->x, pCache->y, w, h, pPix->devPrivate.ptr,
- pPix->devKind, pPix->drawable.bitsPerPixel, pPix->drawable.depth);
- if(!(infoRec->PixmapCacheFlags & DO_NOT_TILE_COLOR_DATA) &&
- ((w != pCache->w) || (h != pCache->h)))
- XAATileCache(pScrn, pCache, w, h);
-
- return pCache;
-}
-
-XAACacheInfoPtr
-XAACacheMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
-{
- int w = pPix->drawable.width;
- int h = pPix->drawable.height;
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- XAAPixmapCachePrivatePtr pCachePriv =
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
- XAACacheInfoPtr pCache, cacheRoot = NULL;
- int i, max = 0, funcNo, pad, dwords, bpp = pScrn->bitsPerPixel;
- int *current;
- StippleScanlineProcPtr StippleFunc;
- unsigned char *data, *srcPtr, *dstPtr;
-
- if((h <= 128) && (w <= 128 * bpp)) {
- if(pCachePriv->Info128) {
- cacheRoot = pCachePriv->Info128;
- max = pCachePriv->Num128x128;
- current = &pCachePriv->Current128;
- } else {
- cacheRoot = pCachePriv->InfoPartial;
- max = pCachePriv->NumPartial;
- current = &pCachePriv->CurrentPartial;
- }
- } else if((h <= 256) && (w <= 256 * bpp)){
- cacheRoot = pCachePriv->Info256;
- max = pCachePriv->Num256x256;
- current = &pCachePriv->Current256;
- } else if((h <= 512) && (w <= 526 * bpp)){
- cacheRoot = pCachePriv->Info512;
- max = pCachePriv->Num512x512;
- current = &pCachePriv->Current512;
- } else { /* something's wrong */
- ErrorF("Something's wrong in XAACacheMonoStipple()\n");
- return pCachePriv->Info128;
- }
-
- pCache = cacheRoot;
-
- /* lets look for it */
- for(i = 0; i < max; i++, pCache++) {
- if((pCache->serialNumber == pPix->drawable.serialNumber) &&
- (pCache->fg == -1) && (pCache->bg == -1)) {
- pCache->trans_color = -1;
- return pCache;
- }
- }
-
- pCache = &cacheRoot[(*current)++];
- if(*current >= max) *current = 0;
-
- pCache->serialNumber = pPix->drawable.serialNumber;
- pCache->trans_color = pCache->bg = pCache->fg = -1;
- pCache->orig_w = w; pCache->orig_h = h;
-
- if(w <= 32) {
- if(w & (w - 1)) funcNo = 1;
- else funcNo = 0;
- } else funcNo = 2;
-
- pad = BitmapBytePad(pCache->w * bpp);
- dwords = bytes_to_int32(pad);
- dstPtr = data = (unsigned char*)malloc(pad * pCache->h);
- srcPtr = (unsigned char*)pPix->devPrivate.ptr;
-
- if(infoRec->ScreenToScreenColorExpandFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST)
- StippleFunc = XAAStippleScanlineFuncMSBFirst[funcNo];
- else
- StippleFunc = XAAStippleScanlineFuncLSBFirst[funcNo];
-
- /* don't bother generating more than we'll ever use */
- max = ((pScrn->displayWidth + w - 1) + 31) >> 5;
- if(dwords > max)
- dwords = max;
-
- for(i = 0; i < h; i++) {
- (*StippleFunc)((CARD32*)dstPtr, (CARD32*)srcPtr, 0, w, dwords);
- srcPtr += pPix->devKind;
- dstPtr += pad;
- }
-
- while((h<<1) <= pCache->h) {
- memcpy(data + (pad * h), data, pad * h);
- h <<= 1;
- }
-
- if(h < pCache->h)
- memcpy(data + (pad * h), data, pad * (pCache->h - h));
-
- (*infoRec->WritePixmapToCache)(
- pScrn, pCache->x, pCache->y, pCache->w, pCache->h, data,
- pad, bpp, pScrn->depth);
-
- free(data);
-
- return pCache;
-}
-
-XAACacheInfoPtr
-XAACachePlanarMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
-{
- int w = pPix->drawable.width;
- int h = pPix->drawable.height;
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- XAAPixmapCachePrivatePtr pCachePriv =
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
- XAACacheInfoPtr pCache, cacheRoot = NULL;
- int i, max = 0;
- int *current;
-
- if((h <= 128) && (w <= 128)) {
- if(pCachePriv->Info128) {
- cacheRoot = pCachePriv->Info128;
- max = pCachePriv->Num128x128;
- current = &pCachePriv->Current128;
- } else {
- cacheRoot = pCachePriv->InfoPartial;
- max = pCachePriv->NumPartial;
- current = &pCachePriv->CurrentPartial;
- }
- } else if((h <= 256) && (w <= 256)){
- cacheRoot = pCachePriv->Info256;
- max = pCachePriv->Num256x256;
- current = &pCachePriv->Current256;
- } else if((h <= 512) && (w <= 526)){
- cacheRoot = pCachePriv->Info512;
- max = pCachePriv->Num512x512;
- current = &pCachePriv->Current512;
- } else { /* something's wrong */
- ErrorF("Something's wrong in XAACachePlanarMonoStipple()\n");
- return pCachePriv->Info128;
- }
-
- pCache = cacheRoot;
-
- /* lets look for it */
- for(i = 0; i < max; i++, pCache++) {
- if((pCache->serialNumber == pPix->drawable.serialNumber) &&
- (pCache->fg == -1) && (pCache->bg == -1)) {
- pCache->trans_color = -1;
- return pCache;
- }
- }
-
- pCache = &cacheRoot[(*current)++];
- if(*current >= max) *current = 0;
-
- pCache->serialNumber = pPix->drawable.serialNumber;
- pCache->trans_color = pCache->bg = pCache->fg = -1;
- pCache->orig_w = w; pCache->orig_h = h;
-
- /* Plane 0 holds the stipple. Plane 1 holds the inverted stipple */
- (*infoRec->WriteBitmapToCache)(pScrn, pCache->x, pCache->y,
- pPix->drawable.width, pPix->drawable.height, pPix->devPrivate.ptr,
- pPix->devKind, 1, 2);
- if(!(infoRec->PixmapCacheFlags & DO_NOT_TILE_MONO_DATA) &&
- ((w != pCache->w) || (h != pCache->h)))
- XAATileCache(pScrn, pCache, w, h);
-
- return pCache;
-}
-
-XAACachePlanarMonoStippleProc
-XAAGetCachePlanarMonoStipple(void)
-{
- return XAACachePlanarMonoStipple;
-}
-
-XAACacheInfoPtr
-XAACacheStipple(ScrnInfoPtr pScrn, PixmapPtr pPix, int fg, int bg)
-{
- int w = pPix->drawable.width;
- int h = pPix->drawable.height;
- int size = max(w, h);
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- XAAPixmapCachePrivatePtr pCachePriv =
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
- XAACacheInfoPtr pCache, cacheRoot = NULL;
- int i, max = 0;
- int *current;
-
- if(size <= 128) {
- if(pCachePriv->Info128) {
- cacheRoot = pCachePriv->Info128;
- max = pCachePriv->Num128x128;
- current = &pCachePriv->Current128;
- } else {
- cacheRoot = pCachePriv->InfoPartial;
- max = pCachePriv->NumPartial;
- current = &pCachePriv->CurrentPartial;
- }
- } else if(size <= 256) {
- cacheRoot = pCachePriv->Info256;
- max = pCachePriv->Num256x256;
- current = &pCachePriv->Current256;
- } else if(size <= 512) {
- cacheRoot = pCachePriv->Info512;
- max = pCachePriv->Num512x512;
- current = &pCachePriv->Current512;
- } else { /* something's wrong */
- ErrorF("Something's wrong in XAACacheStipple()\n");
- return pCachePriv->Info128;
- }
-
- pCache = cacheRoot;
- /* lets look for it */
- if(bg == -1)
- for(i = 0; i < max; i++, pCache++) {
- if((pCache->serialNumber == pPix->drawable.serialNumber) &&
- (fg == pCache->fg) && (pCache->fg != pCache->bg)) {
- pCache->trans_color = pCache->bg;
- return pCache;
- }
- }
- else
- for(i = 0; i < max; i++, pCache++) {
- if((pCache->serialNumber == pPix->drawable.serialNumber) &&
- (fg == pCache->fg) && (bg == pCache->bg)) {
- pCache->trans_color = -1;
- return pCache;
- }
- }
-
- pCache = &cacheRoot[(*current)++];
- if(*current >= max) *current = 0;
-
- pCache->serialNumber = pPix->drawable.serialNumber;
- pCache->fg = fg;
- if(bg == -1)
- pCache->trans_color = bg = fg ^ 1;
- else
- pCache->trans_color = -1;
- pCache->bg = bg;
-
- pCache->orig_w = w; pCache->orig_h = h;
- (*infoRec->WriteBitmapToCache)(pScrn, pCache->x, pCache->y,
- pPix->drawable.width, pPix->drawable.height, pPix->devPrivate.ptr,
- pPix->devKind, fg, bg);
- if(!(infoRec->PixmapCacheFlags & DO_NOT_TILE_COLOR_DATA) &&
- ((w != pCache->w) || (h != pCache->h)))
- XAATileCache(pScrn, pCache, w, h);
-
- return pCache;
-}
-
-
-
-XAACacheInfoPtr
-XAACacheMono8x8Pattern(ScrnInfoPtr pScrn, int pat0, int pat1)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- XAAPixmapCachePrivatePtr pCachePriv =
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
- XAACacheInfoPtr pCache = pCachePriv->InfoMono;
- int i;
-
- for(i = 0; i < pCachePriv->NumMono; i++, pCache++) {
- if(pCache->serialNumber &&
- (pCache->pat0 == pat0) && (pCache->pat1 == pat1))
- return pCache;
- }
-
- /* OK, let's cache it */
- pCache = &pCachePriv->InfoMono[pCachePriv->CurrentMono++];
- if(pCachePriv->CurrentMono >= pCachePriv->NumMono)
- pCachePriv->CurrentMono = 0;
-
- pCache->serialNumber = 1; /* we don't care since we do lookups by pattern */
- pCache->pat0 = pat0;
- pCache->pat1 = pat1;
-
- (*infoRec->WriteMono8x8PatternToCache)(pScrn, pCache);
-
- return pCache;
-}
-
-
-
-XAACacheInfoPtr
-XAACacheColor8x8Pattern(ScrnInfoPtr pScrn, PixmapPtr pPix, int fg, int bg)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- XAAPixmapCachePrivatePtr pCachePriv =
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
- XAACacheInfoPtr pCache = pCachePriv->InfoColor;
- XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
- int i;
-
- if(!(pixPriv->flags & REDUCIBLE_TO_2_COLOR)) {
- for(i = 0; i < pCachePriv->NumColor; i++, pCache++) {
- if(pCache->serialNumber == pPix->drawable.serialNumber) {
- pCache->trans_color = -1;
- return pCache;
- }
- }
- pCache = &pCachePriv->InfoColor[pCachePriv->CurrentColor++];
- if(pCachePriv->CurrentColor >= pCachePriv->NumColor)
- pCachePriv->CurrentColor = 0;
-
- pCache->serialNumber = pPix->drawable.serialNumber;
- pCache->trans_color = pCache->fg = pCache->bg = -1;
- } else {
- int pat0 = pixPriv->pattern0;
- int pat1 = pixPriv->pattern1;
-
- if(fg == -1) { /* it's a tile */
- fg = pixPriv->fg; bg = pixPriv->bg;
- }
-
- if(bg == -1) { /* stipple */
- for(i = 0; i < pCachePriv->NumColor; i++, pCache++) {
- if(pCache->serialNumber &&
- (pCache->pat0 == pat0) && (pCache->pat1 == pat1) &&
- (pCache->fg == fg) && (pCache->bg != fg)) {
- pCache->trans_color = pCache->bg;
- return pCache;
- }
- }
- } else { /* opaque stipple */
- for(i = 0; i < pCachePriv->NumColor; i++, pCache++) {
- if(pCache->serialNumber &&
- (pCache->pat0 == pat0) && (pCache->pat1 == pat1) &&
- (pCache->fg == fg) && (pCache->bg == bg)) {
- pCache->trans_color = -1;
- return pCache;
- }
- }
- }
- pCache = &pCachePriv->InfoColor[pCachePriv->CurrentColor++];
- if(pCachePriv->CurrentColor >= pCachePriv->NumColor)
- pCachePriv->CurrentColor = 0;
-
- if(bg == -1)
- pCache->trans_color = bg = fg ^ 1;
- else
- pCache->trans_color = -1;
-
- pCache->pat0 = pat0; pCache->pat1 = pat1;
- pCache->fg = fg; pCache->bg = bg;
- pCache->serialNumber = 1;
- }
-
- (*infoRec->WriteColor8x8PatternToCache)(pScrn, pPix, pCache);
-
- return pCache;
-}
-
-
-void
-XAAWriteBitmapToCache(
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int fg, int bg
-) {
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
-
- (*infoRec->WriteBitmap)(pScrn, x, y, w, h, src, srcwidth,
- 0, fg, bg, GXcopy, ~0);
-}
-
-void
-XAAWriteBitmapToCacheLinear(
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int fg, int bg
-){
- ScreenPtr pScreen = pScrn->pScreen;
- PixmapPtr pScreenPix, pDstPix;
- ChangeGCVal gcvals[2];
- GCPtr pGC;
-
- pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
-
- pDstPix = GetScratchPixmapHeader(pScreen, pScreenPix->drawable.width,
- y + h, pScreenPix->drawable.depth,
- pScreenPix->drawable.bitsPerPixel,
- pScreenPix->devKind,
- pScreenPix->devPrivate.ptr);
-
- pGC = GetScratchGC(pScreenPix->drawable.depth, pScreen);
- gcvals[0].val = fg;
- gcvals[1].val = bg;
- ChangeGC(NullClient, pGC, GCForeground | GCBackground, gcvals);
- ValidateGC((DrawablePtr)pDstPix, pGC);
-
- /* We've unwrapped already so these ops miss a sync */
- SYNC_CHECK(pScrn);
-
- (*pGC->ops->PutImage)((DrawablePtr)pDstPix, pGC, 1, x, y, w, h, 0,
- XYBitmap, (pointer)src);
-
- FreeScratchGC(pGC);
- FreeScratchPixmapHeader(pDstPix);
-}
-
-
-void
-XAAWritePixmapToCache(
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int bpp, int depth
-) {
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
-
- (*infoRec->WritePixmap)(pScrn, x, y, w, h, src, srcwidth,
- GXcopy, ~0, -1, bpp, depth);
-}
-
-
-
-void
-XAAWritePixmapToCacheLinear(
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int bpp, int depth
-){
- ScreenPtr pScreen = pScrn->pScreen;
- PixmapPtr pScreenPix, pDstPix;
- GCPtr pGC;
-
- pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
-
- pDstPix = GetScratchPixmapHeader(pScreen, x + w, y + h,
- depth, bpp, pScreenPix->devKind,
- pScreenPix->devPrivate.ptr);
-
- pGC = GetScratchGC(depth, pScreen);
- ValidateGC((DrawablePtr)pDstPix, pGC);
-
- /* We've unwrapped already so these ops miss a sync */
- SYNC_CHECK(pScrn);
-
- if(bpp == BitsPerPixel(depth))
- (*pGC->ops->PutImage)((DrawablePtr)pDstPix, pGC, depth, x, y, w,
- h, 0, ZPixmap, (pointer)src);
- else {
- PixmapPtr pSrcPix;
-
- pSrcPix = GetScratchPixmapHeader(pScreen, w, h, depth, bpp,
- srcwidth, (pointer)src);
-
- (*pGC->ops->CopyArea)((DrawablePtr)pSrcPix, (DrawablePtr)pDstPix,
- pGC, 0, 0, w, h, x, y);
-
- FreeScratchPixmapHeader(pSrcPix);
- }
-
- FreeScratchGC(pGC);
- FreeScratchPixmapHeader(pDstPix);
-}
-
-
-void
-XAAWriteMono8x8PatternToCache(
- ScrnInfoPtr pScrn,
- XAACacheInfoPtr pCache
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- XAAPixmapCachePrivatePtr pCachePriv =
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
- unsigned char *data;
- int pad, Bpp = (pScrn->bitsPerPixel >> 3);
-
- pCache->offsets = pCachePriv->MonoOffsets;
-
- pad = BitmapBytePad(pCache->w * pScrn->bitsPerPixel);
-
- data = (unsigned char*)malloc(pad * pCache->h);
- if(!data) return;
-
- if(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
- CARD32* ptr = (CARD32*)data;
- ptr[0] = pCache->pat0; ptr[1] = pCache->pat1;
- } else {
- CARD32 *ptr;
- DDXPointPtr pPoint = pCache->offsets;
- int patx, paty, i;
-
- for(i = 0; i < 64; i++, pPoint++) {
- patx = pCache->pat0; paty = pCache->pat1;
- XAARotateMonoPattern(&patx, &paty, i & 0x07, i >> 3,
- (infoRec->Mono8x8PatternFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST));
- ptr = (CARD32*)(data + (pad * pPoint->y) + (Bpp * pPoint->x));
- ptr[0] = patx; ptr[1] = paty;
- }
- }
-
- (*infoRec->WritePixmapToCache)(pScrn, pCache->x, pCache->y,
- pCache->w, pCache->h, data, pad, pScrn->bitsPerPixel, pScrn->depth);
-
- free(data);
-}
-
-void
-XAAWriteColor8x8PatternToCache(
- ScrnInfoPtr pScrn,
- PixmapPtr pPix,
- XAACacheInfoPtr pCache
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
- XAAPixmapCachePrivatePtr pCachePriv =
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
- int pad, i, w, h, nw, nh, Bpp;
- unsigned char *data, *srcPtr, *dstPtr;
-
- pCache->offsets = pCachePriv->ColorOffsets;
-
- if(pixPriv->flags & REDUCIBLE_TO_2_COLOR) {
- CARD32* ptr;
- pad = BitmapBytePad(pCache->w);
- data = (unsigned char*)malloc(pad * pCache->h);
- if(!data) return;
-
- if(infoRec->Color8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
- ptr = (CARD32*)data;
- ptr[0] = pCache->pat0; ptr[1] = pCache->pat1;
- } else {
- int patx, paty;
-
- ptr = (CARD32*)data;
- ptr[0] = ptr[2] = pCache->pat0; ptr[1] = ptr[3] = pCache->pat1;
- for(i = 1; i < 8; i++) {
- patx = pCache->pat0; paty = pCache->pat1;
- XAARotateMonoPattern(&patx, &paty, i, 0,
- (infoRec->Mono8x8PatternFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST));
- ptr = (CARD32*)(data + (pad * i));
- ptr[0] = ptr[2] = patx; ptr[1] = ptr[3] = paty;
- }
- }
-
- (*infoRec->WriteBitmapToCache)(pScrn, pCache->x, pCache->y,
- pCache->w, pCache->h, data, pad, pCache->fg, pCache->bg);
-
- free(data);
- return;
- }
-
- Bpp = pScrn->bitsPerPixel >> 3;
- h = min(8,pPix->drawable.height);
- w = min(8,pPix->drawable.width);
- pad = BitmapBytePad(pCache->w * pScrn->bitsPerPixel);
-
- data = (unsigned char*)malloc(pad * pCache->h);
- if(!data) return;
-
- /* Write and expand horizontally. */
- for (i = h, dstPtr = data, srcPtr = pPix->devPrivate.ptr; i--;
- srcPtr += pPix->devKind, dstPtr += pScrn->bitsPerPixel) {
- nw = w;
- memcpy(dstPtr, srcPtr, w * Bpp);
- while (nw != 8) {
- memcpy(dstPtr + (nw * Bpp), dstPtr, nw * Bpp);
- nw <<= 1;
- }
- }
- nh = h;
- /* Expand vertically. */
- while (nh != 8) {
- memcpy(data + (nh*pScrn->bitsPerPixel), data, nh*pScrn->bitsPerPixel);
- nh <<= 1;
- }
-
- if(!(infoRec->Color8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
- int j;
- unsigned char *ptr = data + (128 * Bpp);
-
- memcpy(data + (64 * Bpp), data, 64 * Bpp);
- for(i = 1; i < 8; i++, ptr += (128 * Bpp)) {
- for(j = 0; j < 8; j++) {
- memcpy(ptr + (j * 8) * Bpp, data + (j * 8 + i) * Bpp,
- (8 - i) * Bpp);
- memcpy(ptr + (j * 8 + 8 - i) * Bpp, data + j * 8 * Bpp, i*Bpp);
- }
- memcpy(ptr + (64 * Bpp), ptr, 64 * Bpp);
- }
- }
-
- (*infoRec->WritePixmapToCache)(pScrn, pCache->x, pCache->y,
- pCache->w, pCache->h, data, pad, pScrn->bitsPerPixel, pScrn->depth);
-
- free(data);
-}
-
-
-
-int
-XAAStippledFillChooser(GCPtr pGC)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- PixmapPtr pPixmap = pGC->stipple;
- XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
-
- if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
- (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
- XAACheckStippleReducibility(pPixmap);
- }
-
-
- if(pPriv->flags & REDUCIBLE_TO_8x8) {
- if(infoRec->CanDoMono8x8 &&
- !(infoRec->FillMono8x8PatternSpansFlags & NO_TRANSPARENCY) &&
- ((pGC->alu == GXcopy) || !(infoRec->FillMono8x8PatternSpansFlags &
- TRANSPARENCY_GXCOPY_ONLY)) &&
- CHECK_ROP(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
- CHECK_FG(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillMono8x8PatternSpansFlags)) {
-
- return DO_MONO_8x8;
- }
-
- if(infoRec->CanDoColor8x8 &&
- !(infoRec->FillColor8x8PatternSpansFlags & NO_TRANSPARENCY) &&
- ((pGC->alu == GXcopy) || !(infoRec->FillColor8x8PatternSpansFlags &
- TRANSPARENCY_GXCOPY_ONLY)) &&
- CHECK_ROP(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillColor8x8PatternSpansFlags)) {
-
- return DO_COLOR_8x8;
- }
- }
-
- if(infoRec->UsingPixmapCache && infoRec->FillCacheExpandSpans &&
- (pPixmap->drawable.height <= infoRec->MaxCacheableStippleHeight) &&
- (pPixmap->drawable.width <= infoRec->MaxCacheableStippleWidth /
- infoRec->CacheColorExpandDensity) &&
- !(infoRec->FillCacheExpandSpansFlags & NO_TRANSPARENCY) &&
- ((pGC->alu == GXcopy) || !(infoRec->FillCacheExpandSpansFlags &
- TRANSPARENCY_GXCOPY_ONLY)) &&
- CHECK_ROP(pGC,infoRec->FillCacheExpandSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillCacheExpandSpansFlags) &&
- CHECK_FG(pGC,infoRec->FillCacheExpandSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillCacheExpandSpansFlags)) {
-
- return DO_CACHE_EXPAND;
- }
-
-
- if(infoRec->UsingPixmapCache &&
- !(infoRec->PixmapCacheFlags & DO_NOT_BLIT_STIPPLES) &&
- infoRec->FillCacheBltSpans &&
- (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
- (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
- !(infoRec->FillCacheBltSpansFlags & NO_TRANSPARENCY) &&
- ((pGC->alu == GXcopy) || !(infoRec->FillCacheBltSpansFlags &
- TRANSPARENCY_GXCOPY_ONLY)) &&
- CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
-
- return DO_CACHE_BLT;
- }
-
- if(infoRec->FillColorExpandSpans &&
- !(infoRec->FillColorExpandSpansFlags & NO_TRANSPARENCY) &&
- ((pGC->alu == GXcopy) || !(infoRec->FillColorExpandSpansFlags &
- TRANSPARENCY_GXCOPY_ONLY)) &&
- CHECK_ROP(pGC,infoRec->FillColorExpandSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillColorExpandSpansFlags) &&
- CHECK_FG(pGC,infoRec->FillColorExpandSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillColorExpandSpansFlags)) {
-
- return DO_COLOR_EXPAND;
- }
-
- return 0;
-}
-
-
-int
-XAAOpaqueStippledFillChooser(GCPtr pGC)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- PixmapPtr pPixmap = pGC->stipple;
- XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
-
- if(XAA_DEPTH_BUG(pGC))
- return 0;
-
- if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
- (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
- XAACheckStippleReducibility(pPixmap);
- }
-
- if(pPriv->flags & REDUCIBLE_TO_8x8) {
- if(infoRec->CanDoMono8x8 &&
- !(infoRec->FillMono8x8PatternSpansFlags & TRANSPARENCY_ONLY) &&
- CHECK_ROP(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
- CHECK_COLORS(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillMono8x8PatternSpansFlags)) {
-
- return DO_MONO_8x8;
- }
-
- if(infoRec->CanDoColor8x8 &&
- CHECK_ROP(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillColor8x8PatternSpansFlags)) {
-
- return DO_COLOR_8x8;
- }
- }
-
- if(infoRec->UsingPixmapCache && infoRec->FillCacheExpandSpans &&
- (pPixmap->drawable.height <= infoRec->MaxCacheableStippleHeight) &&
- (pPixmap->drawable.width <= infoRec->MaxCacheableStippleWidth /
- infoRec->CacheColorExpandDensity) &&
- !(infoRec->FillCacheExpandSpansFlags & TRANSPARENCY_ONLY) &&
- CHECK_ROP(pGC,infoRec->FillCacheExpandSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillCacheExpandSpansFlags) &&
- CHECK_COLORS(pGC,infoRec->FillCacheExpandSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillCacheExpandSpansFlags)) {
-
- return DO_CACHE_EXPAND;
- }
-
- if(infoRec->UsingPixmapCache &&
- !(infoRec->PixmapCacheFlags & DO_NOT_BLIT_STIPPLES) &&
- infoRec->FillCacheBltSpans &&
- (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
- (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
- CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
-
- return DO_CACHE_BLT;
- }
-
- if(infoRec->FillColorExpandSpans &&
- !(infoRec->FillColorExpandSpansFlags & TRANSPARENCY_ONLY) &&
- CHECK_ROP(pGC,infoRec->FillColorExpandSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillColorExpandSpansFlags) &&
- CHECK_COLORS(pGC,infoRec->FillColorExpandSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillColorExpandSpansFlags)) {
-
- return DO_COLOR_EXPAND;
- }
-
- return 0;
-}
-
-
-
-int
-XAATiledFillChooser(GCPtr pGC)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- PixmapPtr pPixmap = pGC->tile.pixmap;
- XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
-
- if(IS_OFFSCREEN_PIXMAP(pPixmap) && infoRec->FillCacheBltSpans &&
- CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
-
- return DO_PIXMAP_COPY;
- }
-
- if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
- (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
- XAACheckTileReducibility(pPixmap,infoRec->CanDoMono8x8);
- }
-
- if(pPriv->flags & REDUCIBLE_TO_8x8) {
- if((pPriv->flags & REDUCIBLE_TO_2_COLOR) && infoRec->CanDoMono8x8 &&
- !(infoRec->FillMono8x8PatternSpansFlags & TRANSPARENCY_ONLY) &&
- CHECK_ROP(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
- (!(infoRec->FillMono8x8PatternSpansFlags & RGB_EQUAL) ||
- (CHECK_RGB_EQUAL(pPriv->fg) && CHECK_RGB_EQUAL(pPriv->bg))) &&
- CHECK_PLANEMASK(pGC,infoRec->FillMono8x8PatternSpansFlags)) {
-
- return DO_MONO_8x8;
- }
-
- if(infoRec->CanDoColor8x8 &&
- CHECK_ROP(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillColor8x8PatternSpansFlags)) {
-
- return DO_COLOR_8x8;
- }
- }
-
- if(infoRec->UsingPixmapCache && infoRec->FillCacheBltSpans &&
- (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
- (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
- CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
-
- return DO_CACHE_BLT;
- }
-
- if(infoRec->FillImageWriteRects &&
- CHECK_NO_GXCOPY(pGC,infoRec->FillImageWriteRectsFlags) &&
- CHECK_ROP(pGC,infoRec->FillImageWriteRectsFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillImageWriteRectsFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillImageWriteRectsFlags)) {
-
- return DO_IMAGE_WRITE;
- }
-
- return 0;
-}
-
-
-static int RotateMasksX[8] = {
- 0xFFFFFFFF, 0x7F7F7F7F, 0x3F3F3F3F, 0x1F1F1F1F,
- 0x0F0F0F0F, 0x07070707, 0x03030303, 0x01010101
-};
-
-static int RotateMasksY[4] = {
- 0xFFFFFFFF, 0x00FFFFFF, 0x0000FFFF, 0x000000FF
-};
-
-void
-XAARotateMonoPattern(
- int *pat0, int *pat1,
- int xorg, int yorg,
- Bool msbfirst
-){
- int tmp, mask;
-
- if(xorg) {
- if(msbfirst) xorg = 8 - xorg;
- mask = RotateMasksX[xorg];
- *pat0 = ((*pat0 >> xorg) & mask) | ((*pat0 << (8 - xorg)) & ~mask);
- *pat1 = ((*pat1 >> xorg) & mask) | ((*pat1 << (8 - xorg)) & ~mask);
- }
- if(yorg >= 4) {
- tmp = *pat0; *pat0 = *pat1; *pat1 = tmp;
- yorg -= 4;
- }
- if(yorg) {
- mask = RotateMasksY[yorg];
- yorg <<= 3;
- tmp = *pat0;
- *pat0 = ((*pat0 >> yorg) & mask) | ((*pat1 << (32 - yorg)) & ~mask);
- *pat1 = ((*pat1 >> yorg) & mask) | ((tmp << (32 - yorg)) & ~mask);
- }
-}
-
-
-
-void
-XAAInvalidatePixmapCache(ScreenPtr pScreen)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
- XAAPixmapCachePrivatePtr pCachePriv =
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
- int i;
-
- if(!pCachePriv) return;
-
- for(i = 0; i < pCachePriv->Num512x512; i++)
- (pCachePriv->Info512)[i].serialNumber = 0;
- for(i = 0; i < pCachePriv->Num256x256; i++)
- (pCachePriv->Info256)[i].serialNumber = 0;
- for(i = 0; i < pCachePriv->Num128x128; i++)
- (pCachePriv->Info128)[i].serialNumber = 0;
- for(i = 0; i < pCachePriv->NumPartial; i++)
- (pCachePriv->InfoPartial)[i].serialNumber = 0;
- for(i = 0; i < pCachePriv->NumMono; i++)
- (pCachePriv->InfoMono)[i].serialNumber = 0;
- for(i = 0; i < pCachePriv->NumColor; i++)
- (pCachePriv->InfoColor)[i].serialNumber = 0;
-}
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "gc.h"
+#include "mi.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "regionstr.h"
+#include "servermd.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaacexp.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+
+#define MAX_COLOR 32
+#define MAX_MONO 32
+#define MAX_8 32
+#define MAX_128 32
+#define MAX_256 32
+#define MAX_512 16
+
+static int CacheInitIndex = -1;
+
+#define CACHEINIT(p) ((p)->privates[CacheInitIndex].val)
+
+typedef struct _CacheLink {
+ int x;
+ int y;
+ int w;
+ int h;
+ struct _CacheLink *next;
+} CacheLink, *CacheLinkPtr;
+
+static void
+TransferList(CacheLinkPtr list, XAACacheInfoPtr array, int num)
+{
+ while (num--) {
+ array->x = list->x;
+ array->y = list->y;
+ array->w = list->w;
+ array->h = list->h;
+ array->serialNumber = 0;
+ array->fg = array->bg = -1;
+ list = list->next;
+ array++;
+ }
+}
+
+static CacheLinkPtr
+Enlist(CacheLinkPtr link, int x, int y, int w, int h)
+{
+ CacheLinkPtr newLink;
+
+ newLink = malloc(sizeof(CacheLink));
+ newLink->next = link;
+ newLink->x = x;
+ newLink->y = y;
+ newLink->w = w;
+ newLink->h = h;
+ return newLink;
+}
+
+static CacheLinkPtr
+Delist(CacheLinkPtr link)
+{
+ CacheLinkPtr ret = NULL;
+
+ if (link) {
+ ret = link->next;
+ free(link);
+ }
+ return ret;
+}
+
+static void
+FreeList(CacheLinkPtr link)
+{
+ CacheLinkPtr tmp;
+
+ while (link) {
+ tmp = link;
+ link = link->next;
+ free(tmp);
+ }
+}
+
+static CacheLinkPtr
+QuadLinks(CacheLinkPtr big, CacheLinkPtr little)
+{
+ /* CAUTION: This doesn't free big */
+ int w1, w2, h1, h2;
+
+ while (big) {
+ w1 = big->w >> 1;
+ w2 = big->w - w1;
+ h1 = big->h >> 1;
+ h2 = big->h - h1;
+
+ little = Enlist(little, big->x, big->y, w1, h1);
+ little = Enlist(little, big->x + w1, big->y, w2, h1);
+ little = Enlist(little, big->x, big->y + h1, w1, h2);
+ little = Enlist(little, big->x + w1, big->y + h1, w2, h2);
+
+ big = big->next;
+ }
+ return little;
+}
+
+static void
+SubdivideList(CacheLinkPtr * large, CacheLinkPtr * small)
+{
+ CacheLinkPtr big = *large;
+ CacheLinkPtr little = *small;
+ int size = big->w >> 1;
+
+ little = Enlist(little, big->x, big->y, size, size);
+ little = Enlist(little, big->x + size, big->y, size, size);
+ little = Enlist(little, big->x, big->y + size, size, size);
+ little = Enlist(little, big->x + size, big->y + size, size, size);
+ *small = little;
+ big = Delist(big);
+ *large = big;
+}
+
+static void
+FreePixmapCachePrivate(XAAPixmapCachePrivatePtr pPriv)
+{
+ if (!pPriv)
+ return;
+
+ free(pPriv->Info512);
+ free(pPriv->Info256);
+ free(pPriv->Info128);
+ free(pPriv->InfoColor);
+ free(pPriv->InfoMono);
+ free(pPriv->InfoPartial);
+
+ free(pPriv);
+}
+
+void
+XAAClosePixmapCache(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+
+ if (infoRec->PixmapCachePrivate)
+ FreePixmapCachePrivate((XAAPixmapCachePrivatePtr) infoRec->
+ PixmapCachePrivate);
+
+ infoRec->PixmapCachePrivate = NULL;
+}
+
+static CacheLinkPtr
+ThinOutPartials(CacheLinkPtr ListPartial, int *num, int *maxw, int *maxh)
+{
+/* This guy's job is to get at least 4 big slots out of a list of fragments */
+
+ CacheLinkPtr List64, List32, List16, List8, pCur, next, ListKeepers;
+ int Num64, Num32, Num16, Num8, NumKeepers;
+ int w, h;
+
+ List64 = List32 = List16 = List8 = ListKeepers = NULL;
+ Num64 = Num32 = Num16 = Num8 = NumKeepers = 0;
+ w = h = 0;
+
+ /* We sort partials by how large a square tile they can cache.
+ If a partial can't store a 64x64, 32x32, 16x16 or 8x8 tile,
+ we free it. */
+
+ pCur = ListPartial;
+ while (pCur) {
+ next = pCur->next;
+ if ((pCur->w >= 64) && (pCur->h >= 64)) {
+ pCur->next = List64;
+ List64 = pCur;
+ Num64++;
+ }
+ else if ((pCur->w >= 32) && (pCur->h >= 32)) {
+ pCur->next = List32;
+ List32 = pCur;
+ Num32++;
+ }
+ else if ((pCur->w >= 16) && (pCur->h >= 16)) {
+ pCur->next = List16;
+ List16 = pCur;
+ Num16++;
+ }
+ else if ((pCur->w >= 8) && (pCur->h >= 8)) {
+ pCur->next = List8;
+ List8 = pCur;
+ Num8++;
+ }
+ else {
+ free(pCur);
+ }
+
+ pCur = next;
+ }
+
+ /* We save all the tiles from the largest bin that we can get
+ at least 4 of. If there are too few of a bigger slot, we
+ cut it in fourths to make smaller slots. */
+
+ if (Num64 >= 4) {
+ ListKeepers = List64;
+ List64 = NULL;
+ NumKeepers = Num64;
+ goto GOT_EM;
+ }
+ else if (Num64) {
+ List32 = QuadLinks(List64, List32);
+ Num32 += Num64 * 4;
+ Num64 = 0;
+ }
+
+ if (Num32 >= 4) {
+ ListKeepers = List32;
+ List32 = NULL;
+ NumKeepers = Num32;
+ goto GOT_EM;
+ }
+ else if (Num32) {
+ List16 = QuadLinks(List32, List16);
+ Num16 += Num32 * 4;
+ Num32 = 0;
+ }
+
+ if (Num16 >= 4) {
+ ListKeepers = List16;
+ List16 = NULL;
+ NumKeepers = Num16;
+ goto GOT_EM;
+ }
+ else if (Num16) {
+ List8 = QuadLinks(List16, List8);
+ Num8 += Num16 * 4;
+ Num16 = 0;
+ }
+
+ if (Num8 >= 4) {
+ ListKeepers = List8;
+ List8 = NULL;
+ NumKeepers = Num8;
+ goto GOT_EM;
+ }
+
+ GOT_EM:
+
+ /* Free the ones we aren't using */
+
+ if (List64)
+ FreeList(List64);
+ if (List32)
+ FreeList(List32);
+ if (List16)
+ FreeList(List16);
+ if (List8)
+ FreeList(List8);
+
+ /* Enlarge the slots if we can */
+
+ if (ListKeepers) {
+ CacheLinkPtr pLink = ListKeepers;
+
+ w = h = 128;
+
+ while (pLink) {
+ if (pLink->w < w)
+ w = pLink->w;
+ if (pLink->h < h)
+ h = pLink->h;
+ pLink = pLink->next;
+ }
+ }
+
+ *maxw = w;
+ *maxh = h;
+ *num = NumKeepers;
+ return ListKeepers;
+}
+
+static void
+ConvertColorToMono(CacheLinkPtr * ColorList,
+ int ColorW, int ColorH,
+ CacheLinkPtr * MonoList, int MonoW, int MonoH)
+{
+ int x, y, w;
+
+ x = (*ColorList)->x;
+ y = (*ColorList)->y;
+ *ColorList = Delist(*ColorList);
+
+ while (ColorH) {
+ ColorH -= MonoH;
+ for (w = 0; w <= (ColorW - MonoW); w += MonoW)
+ *MonoList = Enlist(*MonoList, x + w, y + ColorH, MonoW, MonoH);
+ }
+}
+
+static void
+ConvertAllPartialsTo8x8(int *NumMono, int *NumColor,
+ CacheLinkPtr ListPartial,
+ CacheLinkPtr * ListMono,
+ CacheLinkPtr * ListColor, XAAInfoRecPtr infoRec)
+{
+/* This guy extracts as many 8x8 slots as it can out of fragments */
+
+ int ColorH = infoRec->CacheHeightColor8x8Pattern;
+ int ColorW = infoRec->CacheWidthColor8x8Pattern;
+ int MonoH = infoRec->CacheHeightMono8x8Pattern;
+ int MonoW = infoRec->CacheWidthMono8x8Pattern;
+ int x, y, w, Height, Width;
+ Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
+ Bool DoMono = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
+ CacheLinkPtr pLink = ListPartial;
+ CacheLinkPtr MonoList = *ListMono, ColorList = *ListColor;
+
+ if (DoColor && DoMono) {
+ /* we assume color patterns take more space than color ones */
+ if (MonoH > ColorH)
+ ColorH = MonoH;
+ if (MonoW > ColorW)
+ ColorW = MonoW;
+ }
+
+ /* Break up the area into as many Color and Mono slots as we can */
+
+ while (pLink) {
+ Height = pLink->h;
+ Width = pLink->w;
+ x = pLink->x;
+ y = pLink->y;
+
+ if (DoColor) {
+ while (Height >= ColorH) {
+ Height -= ColorH;
+ for (w = 0; w <= (Width - ColorW); w += ColorW) {
+ ColorList =
+ Enlist(ColorList, x + w, y + Height, ColorW, ColorH);
+ (*NumColor)++;
+ }
+ }
+ }
+
+ if (DoMono && (Height >= MonoH)) {
+ while (Height >= MonoH) {
+ Height -= MonoH;
+ for (w = 0; w <= (Width - MonoW); w += MonoW) {
+ MonoList =
+ Enlist(MonoList, x + w, y + Height, MonoW, MonoH);
+ (*NumMono)++;
+ }
+ }
+ }
+
+ pLink = pLink->next;
+ }
+
+ *ListMono = MonoList;
+ *ListColor = ColorList;
+ FreeList(ListPartial);
+}
+
+static CacheLinkPtr
+ExtractOneThatFits(CacheLinkPtr * initList, int w, int h)
+{
+ CacheLinkPtr list = *initList;
+ CacheLinkPtr prev = NULL;
+
+ while (list) {
+ if ((list->w >= w) && (list->h >= h))
+ break;
+ prev = list;
+ list = list->next;
+ }
+
+ if (list) {
+ if (prev)
+ prev->next = list->next;
+ else
+ *initList = list->next;
+
+ list->next = NULL;
+ }
+
+ return list;
+}
+
+static CacheLinkPtr
+ConvertSomePartialsTo8x8(int *NumMono, int *NumColor, int *NumPartial,
+ CacheLinkPtr ListPartial,
+ CacheLinkPtr * ListMono,
+ CacheLinkPtr * ListColor,
+ int *maxw, int *maxh, XAAInfoRecPtr infoRec)
+{
+/* This guy tries to get 4 of each type of 8x8 slot requested out of
+ a list of fragments all while trying to retain some big fragments
+ for the cache blits */
+
+ int ColorH = infoRec->CacheHeightColor8x8Pattern;
+ int ColorW = infoRec->CacheWidthColor8x8Pattern;
+ int MonoH = infoRec->CacheHeightMono8x8Pattern;
+ int MonoW = infoRec->CacheWidthMono8x8Pattern;
+ Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
+ Bool DoMono = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
+ CacheLinkPtr List64, List32, List16, List8, pCur, next, ListKeepers;
+ CacheLinkPtr MonoList = *ListMono, ColorList = *ListColor;
+ int Num64, Num32, Num16, Num8, NumKeepers;
+ int w, h, Width, Height;
+ int MonosPerColor = 1;
+
+ if (DoColor && DoMono) {
+ /* we assume color patterns take more space than color ones */
+ if (MonoH > ColorH)
+ ColorH = MonoH;
+ if (MonoW > ColorW)
+ ColorW = MonoW;
+ MonosPerColor = (ColorH / MonoH) * (ColorW / MonoW);
+ }
+
+ List64 = List32 = List16 = List8 = ListKeepers = MonoList = ColorList =
+ NULL;
+ Num64 = Num32 = Num16 = Num8 = NumKeepers = 0;
+ Width = Height = 0;
+
+ /* We sort partials by how large a square tile they can cache.
+ We make 8x8 patterns from the leftovers if we can. */
+
+ pCur = ListPartial;
+ while (pCur) {
+ next = pCur->next;
+ if ((pCur->w >= 64) && (pCur->h >= 64)) {
+ pCur->next = List64;
+ List64 = pCur;
+ Num64++;
+ }
+ else if ((pCur->w >= 32) && (pCur->h >= 32)) {
+ pCur->next = List32;
+ List32 = pCur;
+ Num32++;
+ }
+ else if ((pCur->w >= 16) && (pCur->h >= 16)) {
+ pCur->next = List16;
+ List16 = pCur;
+ Num16++;
+ }
+ else if ((pCur->w >= 8) && (pCur->h >= 8)) {
+ pCur->next = List8;
+ List8 = pCur;
+ Num8++;
+ }
+ else {
+ h = pCur->h;
+ if (DoColor && (pCur->w >= ColorW) && (h >= ColorH)) {
+ while (h >= ColorH) {
+ h -= ColorH;
+ for (w = 0; w <= (pCur->w - ColorW); w += ColorW) {
+ ColorList = Enlist(ColorList,
+ pCur->x + w, pCur->y + h, ColorW,
+ ColorH);
+ (*NumColor)++;
+ }
+ }
+ }
+ if (DoMono && (pCur->w >= MonoW) && (h >= MonoH)) {
+ while (h >= MonoH) {
+ h -= MonoH;
+ for (w = 0; w <= (pCur->w - MonoW); w += MonoW) {
+ MonoList = Enlist(MonoList,
+ pCur->x + w, pCur->y + h, MonoW,
+ MonoH);
+ (*NumMono)++;
+ }
+ }
+ }
+ free(pCur);
+ }
+
+ pCur = next;
+ }
+
+ /* Try to extract at least 4 of each type of 8x8 slot that we need */
+
+ if (DoColor) {
+ CacheLinkPtr theOne;
+
+ while (*NumColor < 4) {
+ theOne = NULL;
+ if (Num8) {
+ if ((theOne = ExtractOneThatFits(&List8, ColorW, ColorH)))
+ Num8--;
+ }
+ if (Num16 && !theOne) {
+ if ((theOne = ExtractOneThatFits(&List16, ColorW, ColorH)))
+ Num16--;
+ }
+ if (Num32 && !theOne) {
+ if ((theOne = ExtractOneThatFits(&List32, ColorW, ColorH)))
+ Num32--;
+ }
+ if (Num64 && !theOne) {
+ if ((theOne = ExtractOneThatFits(&List64, ColorW, ColorH)))
+ Num64--;
+ }
+
+ if (!theOne)
+ break;
+
+ ConvertAllPartialsTo8x8(NumMono, NumColor, theOne,
+ &MonoList, &ColorList, infoRec);
+
+ if (DoMono) {
+ while (*NumColor && (*NumMono < 4)) {
+ ConvertColorToMono(&ColorList, ColorW, ColorH,
+ &MonoList, MonoW, MonoH);
+ (*NumColor)--;
+ *NumMono += MonosPerColor;
+ }
+ }
+ }
+ }
+
+ if (DoMono) {
+ CacheLinkPtr theOne;
+
+ while (*NumMono < 4) {
+ theOne = NULL;
+ if (Num8) {
+ if ((theOne = ExtractOneThatFits(&List8, MonoW, MonoH)))
+ Num8--;
+ }
+ if (Num16 && !theOne) {
+ if ((theOne = ExtractOneThatFits(&List16, MonoW, MonoH)))
+ Num16--;
+ }
+ if (Num32 && !theOne) {
+ if ((theOne = ExtractOneThatFits(&List32, MonoW, MonoH)))
+ Num32--;
+ }
+ if (Num64 && !theOne) {
+ if ((theOne = ExtractOneThatFits(&List64, MonoW, MonoH)))
+ Num64--;
+ }
+
+ if (!theOne)
+ break;
+
+ ConvertAllPartialsTo8x8(NumMono, NumColor, theOne,
+ &MonoList, &ColorList, infoRec);
+ }
+ }
+
+ /* We save all the tiles from the largest bin that we can get
+ at least 4 of. If there are too few of a bigger slot, we
+ cut it in fourths to make smaller slots. */
+
+ if (Num64 >= 4) {
+ ListKeepers = List64;
+ List64 = NULL;
+ NumKeepers = Num64;
+ goto GOT_EM;
+ }
+ else if (Num64) {
+ List32 = QuadLinks(List64, List32);
+ Num32 += Num64 * 4;
+ Num64 = 0;
+ }
+
+ if (Num32 >= 4) {
+ ListKeepers = List32;
+ List32 = NULL;
+ NumKeepers = Num32;
+ goto GOT_EM;
+ }
+ else if (Num32) {
+ List16 = QuadLinks(List32, List16);
+ Num16 += Num32 * 4;
+ Num32 = 0;
+ }
+
+ if (Num16 >= 4) {
+ ListKeepers = List16;
+ List16 = NULL;
+ NumKeepers = Num16;
+ goto GOT_EM;
+ }
+ else if (Num16) {
+ List8 = QuadLinks(List16, List8);
+ Num8 += Num16 * 4;
+ Num16 = 0;
+ }
+
+ if (Num8 >= 4) {
+ ListKeepers = List8;
+ List8 = NULL;
+ NumKeepers = Num8;
+ goto GOT_EM;
+ }
+
+ GOT_EM:
+
+ /* Free the ones we aren't using */
+
+ if (List64)
+ ConvertAllPartialsTo8x8(NumMono, NumColor, List64,
+ &MonoList, &ColorList, infoRec);
+ if (List32)
+ ConvertAllPartialsTo8x8(NumMono, NumColor, List32,
+ &MonoList, &ColorList, infoRec);
+ if (List16)
+ ConvertAllPartialsTo8x8(NumMono, NumColor, List16,
+ &MonoList, &ColorList, infoRec);
+ if (List8)
+ ConvertAllPartialsTo8x8(NumMono, NumColor, List8,
+ &MonoList, &ColorList, infoRec);
+
+ /* Enlarge the slots if we can */
+
+ if (ListKeepers) {
+ CacheLinkPtr pLink = ListKeepers;
+
+ Width = Height = 128;
+
+ while (pLink) {
+ if (pLink->w < Width)
+ Width = pLink->w;
+ if (pLink->h < Height)
+ Height = pLink->h;
+ pLink = pLink->next;
+ }
+ }
+
+ *ListMono = MonoList;
+ *ListColor = ColorList;
+ *maxw = Width;
+ *maxh = Height;
+ *NumPartial = NumKeepers;
+ return ListKeepers;
+}
+
+void
+XAAInitPixmapCache(ScreenPtr pScreen, RegionPtr areas, pointer data)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAInfoRecPtr infoRec = (XAAInfoRecPtr) data;
+ XAAPixmapCachePrivatePtr pCachePriv;
+ BoxPtr pBox = RegionRects(areas);
+ int nBox = RegionNumRects(areas);
+ int Num512, Num256, Num128, NumPartial, NumColor, NumMono;
+ int Target512, Target256;
+ CacheLinkPtr List512, List256, List128, ListPartial, ListColor, ListMono;
+ int x, y, w, h, ntotal, granularity, width, height, i;
+ int MaxPartialWidth, MaxPartialHeight;
+
+ infoRec->MaxCacheableTileWidth = 0;
+ infoRec->MaxCacheableTileHeight = 0;
+ infoRec->MaxCacheableStippleHeight = 0;
+ infoRec->MaxCacheableStippleWidth = 0;
+ infoRec->UsingPixmapCache = FALSE;
+
+ if (!nBox || !pBox || !(infoRec->Flags & PIXMAP_CACHE))
+ return;
+
+ /* Allocate a persistent per-screen init flag to control messages */
+ if (CacheInitIndex < 0)
+ CacheInitIndex = xf86AllocateScrnInfoPrivateIndex();
+
+ /* free the old private data if it exists */
+ if (infoRec->PixmapCachePrivate) {
+ FreePixmapCachePrivate((XAAPixmapCachePrivatePtr) infoRec->
+ PixmapCachePrivate);
+ infoRec->PixmapCachePrivate = NULL;
+ }
+
+ Num512 = Num256 = Num128 = NumPartial = NumMono = NumColor = 0;
+ List512 = List256 = List128 = ListPartial = ListMono = ListColor = NULL;
+ granularity = infoRec->CachePixelGranularity;
+ if (granularity <= 1)
+ granularity = 0;
+
+ /* go through the boxes and break it into as many pieces as we can fit */
+
+ while (nBox--) {
+ x = pBox->x1;
+ if (granularity) {
+ int tmp = x % granularity;
+
+ if (tmp)
+ x += (granularity - tmp);
+ }
+ width = pBox->x2 - x;
+ if (width <= 0) {
+ pBox++;
+ continue;
+ }
+
+ y = pBox->y1;
+ height = pBox->y2 - y;
+
+ for (h = 0; h <= (height - 512); h += 512) {
+ for (w = 0; w <= (width - 512); w += 512) {
+ List512 = Enlist(List512, x + w, y + h, 512, 512);
+ Num512++;
+ }
+ for (; w <= (width - 256); w += 256) {
+ List256 = Enlist(List256, x + w, y + h, 256, 256);
+ List256 = Enlist(List256, x + w, y + h + 256, 256, 256);
+ Num256 += 2;
+ }
+ for (; w <= (width - 128); w += 128) {
+ List128 = Enlist(List128, x + w, y + h, 128, 128);
+ List128 = Enlist(List128, x + w, y + h + 128, 128, 128);
+ List128 = Enlist(List128, x + w, y + h + 256, 128, 128);
+ List128 = Enlist(List128, x + w, y + h + 384, 128, 128);
+ Num128 += 4;
+ }
+ if (w < width) {
+ int d = width - w;
+
+ ListPartial = Enlist(ListPartial, x + w, y + h, d, 128);
+ ListPartial = Enlist(ListPartial, x + w, y + h + 128, d, 128);
+ ListPartial = Enlist(ListPartial, x + w, y + h + 256, d, 128);
+ ListPartial = Enlist(ListPartial, x + w, y + h + 384, d, 128);
+ NumPartial += 4;
+ }
+ }
+ for (; h <= (height - 256); h += 256) {
+ for (w = 0; w <= (width - 256); w += 256) {
+ List256 = Enlist(List256, x + w, y + h, 256, 256);
+ Num256++;
+ }
+ for (; w <= (width - 128); w += 128) {
+ List128 = Enlist(List128, x + w, y + h, 128, 128);
+ List128 = Enlist(List128, x + w, y + h + 128, 128, 128);
+ Num128 += 2;
+ }
+ if (w < width) {
+ int d = width - w;
+
+ ListPartial = Enlist(ListPartial, x + w, y + h, d, 128);
+ ListPartial = Enlist(ListPartial, x + w, y + h + 128, d, 128);
+ NumPartial += 2;
+ }
+ }
+ for (; h <= (height - 128); h += 128) {
+ for (w = 0; w <= (width - 128); w += 128) {
+ List128 = Enlist(List128, x + w, y + h, 128, 128);
+ Num128++;
+ }
+ if (w < width) {
+ ListPartial = Enlist(ListPartial, x + w, y + h, width - w, 128);
+ NumPartial++;
+ }
+ }
+ if (h < height) {
+ int d = height - h;
+
+ for (w = 0; w <= (width - 128); w += 128) {
+ ListPartial = Enlist(ListPartial, x + w, y + h, 128, d);
+ NumPartial++;
+ }
+ if (w < width) {
+ ListPartial = Enlist(ListPartial, x + w, y + h, width - w, d);
+ NumPartial++;
+ }
+ }
+ pBox++;
+ }
+
+/*
+ by this point we've carved the space into as many 512x512, 256x256
+ and 128x128 blocks as we could fit. We will then break larger
+ blocks into smaller ones if we need to. The rules are as follows:
+
+ 512x512 -
+ 1) Don't take up more than half the memory.
+ 2) Don't bother if you can't get at least four.
+ 3) Don't make more than MAX_512.
+ 4) Don't have any of there are no 256x256s.
+
+ 256x256 -
+ 1) Don't take up more than a quarter of the memory enless there
+ aren't any 512x512s. Then we can take up to half.
+ 2) Don't bother if you can't get at least four.
+ 3) Don't make more than MAX_256.
+
+ 128x128 -
+ 1) Don't make more than MAX_128.
+
+ We don't bother with the partial blocks unless we can use them
+ for 8x8 pattern fills or we are short on larger blocks.
+
+*/
+
+ ntotal = Num128 + (Num256 << 2) + (Num512 << 4);
+
+ Target512 = ntotal >> 5;
+ if (Target512 < 4)
+ Target512 = 0;
+ if (!Target512)
+ Target256 = ntotal >> 3;
+ else
+ Target256 = ntotal >> 4;
+ if (Target256 < 4)
+ Target256 = 0;
+
+ if (Num512 && Num256 < 4) {
+ while (Num512 && Num256 < Target256) {
+ SubdivideList(&List512, &List256);
+ Num256 += 4;
+ Num512--;
+ }
+ }
+
+ if (!Num512) { /* no room */
+ }
+ else if ((Num512 < 4) || (!Target512)) {
+ while (Num512) {
+ SubdivideList(&List512, &List256);
+ Num256 += 4;
+ Num512--;
+ }
+ }
+ else if ((Num512 > MAX_512) || (Num512 > Target512)) {
+ while (Num512 > MAX_512) {
+ SubdivideList(&List512, &List256);
+ Num256 += 4;
+ Num512--;
+ }
+ while (Num512 > Target512) {
+ if (Num256 < MAX_256) {
+ SubdivideList(&List512, &List256);
+ Num256 += 4;
+ Num512--;
+ }
+ else
+ break;
+ }
+ }
+
+ if (!Num256) { /* no room */
+ }
+ else if ((Num256 < 4) || (!Target256)) {
+ while (Num256) {
+ SubdivideList(&List256, &List128);
+ Num128 += 4;
+ Num256--;
+ }
+ }
+ else if ((Num256 > MAX_256) || (Num256 > Target256)) {
+ while (Num256 > MAX_256) {
+ SubdivideList(&List256, &List128);
+ Num128 += 4;
+ Num256--;
+ }
+ while (Num256 > Target256) {
+ if (Num128 < MAX_128) {
+ SubdivideList(&List256, &List128);
+ Num128 += 4;
+ Num256--;
+ }
+ else
+ break;
+ }
+ }
+
+ if (Num128 && ((Num128 < 4) || (Num128 > MAX_128))) {
+ CacheLinkPtr next;
+ int max = (Num128 > MAX_128) ? MAX_128 : 0;
+
+ /*
+ * Note: next is set in this way to work around a code generation
+ * bug in gcc 2.7.2.3.
+ */
+ next = List128->next;
+ while (Num128 > max) {
+ List128->next = ListPartial;
+ ListPartial = List128;
+ if ((List128 = next))
+ next = List128->next;
+ NumPartial++;
+ Num128--;
+ }
+ }
+
+ MaxPartialHeight = MaxPartialWidth = 0;
+
+ /* at this point we have as many 512x512 and 256x256 slots as we
+ want but may have an excess of 128x128 slots. We still need
+ to find out if we need 8x8 slots. We take these from the
+ partials if we have them. Otherwise, we break some 128x128's */
+
+ if (!(infoRec->PixmapCacheFlags & (CACHE_MONO_8x8 | CACHE_COLOR_8x8))) {
+ if (NumPartial) {
+ if (Num128) { /* don't bother with partials */
+ FreeList(ListPartial);
+ NumPartial = 0;
+ ListPartial = NULL;
+ }
+ else {
+ /* We have no big slots. Weed out the unusable partials */
+ ListPartial = ThinOutPartials(ListPartial, &NumPartial,
+ &MaxPartialWidth,
+ &MaxPartialHeight);
+ }
+ }
+ }
+ else {
+ int MonosPerColor = 1;
+ int ColorH = infoRec->CacheHeightColor8x8Pattern;
+ int ColorW = infoRec->CacheWidthColor8x8Pattern;
+ int MonoH = infoRec->CacheHeightMono8x8Pattern;
+ int MonoW = infoRec->CacheWidthMono8x8Pattern;
+ Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
+ Bool DoMono = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
+
+ if (DoColor)
+ infoRec->CanDoColor8x8 = FALSE;
+ if (DoMono)
+ infoRec->CanDoMono8x8 = FALSE;
+
+ if (DoColor && DoMono) {
+ /* we assume color patterns take more space than color ones */
+ if (MonoH > ColorH)
+ ColorH = MonoH;
+ if (MonoW > ColorW)
+ ColorW = MonoW;
+ MonosPerColor = (ColorH / MonoH) * (ColorW / MonoW);
+ }
+
+ if (Num128) {
+ if (NumPartial) { /* use all for 8x8 slots */
+ ConvertAllPartialsTo8x8(&NumMono, &NumColor,
+ ListPartial, &ListMono, &ListColor,
+ infoRec);
+ NumPartial = 0;
+ ListPartial = NULL;
+ }
+
+ /* Get some 8x8 slots from the 128 slots */
+ while ((Num128 > 4) &&
+ ((NumMono < MAX_MONO) && (NumColor < MAX_COLOR))) {
+ CacheLinkPtr tmp = NULL;
+
+ tmp = Enlist(tmp, List128->x, List128->y,
+ List128->w, List128->h);
+ List128 = Delist(List128);
+ Num128--;
+
+ ConvertAllPartialsTo8x8(&NumMono, &NumColor,
+ tmp, &ListMono, &ListColor, infoRec);
+ }
+ }
+ else if (NumPartial) {
+ /* We have share partials between 8x8 slots and tiles. */
+ ListPartial = ConvertSomePartialsTo8x8(&NumMono, &NumColor,
+ &NumPartial, ListPartial,
+ &ListMono, &ListColor,
+ &MaxPartialWidth,
+ &MaxPartialHeight, infoRec);
+ }
+
+ if (DoMono && DoColor) {
+ if (NumColor && ((NumColor > MAX_COLOR) || (NumColor < 4))) {
+ int max = (NumColor > MAX_COLOR) ? MAX_COLOR : 0;
+
+ while (NumColor > max) {
+ ConvertColorToMono(&ListColor, ColorW, ColorH,
+ &ListMono, MonoW, MonoH);
+ NumColor--;
+ NumMono += MonosPerColor;
+ }
+ }
+
+ /* favor Mono slots over Color ones */
+ while ((NumColor > 4) && (NumMono < MAX_MONO)) {
+ ConvertColorToMono(&ListColor, ColorW, ColorH,
+ &ListMono, MonoW, MonoH);
+ NumColor--;
+ NumMono += MonosPerColor;
+ }
+ }
+
+ if (NumMono && ((NumMono > MAX_MONO) || (NumMono < 4))) {
+ int max = (NumMono > MAX_MONO) ? MAX_MONO : 0;
+
+ while (NumMono > max) {
+ ListMono = Delist(ListMono);
+ NumMono--;
+ }
+ }
+ if (NumColor && ((NumColor > MAX_COLOR) || (NumColor < 4))) {
+ int max = (NumColor > MAX_COLOR) ? MAX_COLOR : 0;
+
+ while (NumColor > max) {
+ ListColor = Delist(ListColor);
+ NumColor--;
+ }
+ }
+ }
+
+ pCachePriv = calloc(1, sizeof(XAAPixmapCachePrivate));
+ if (!pCachePriv) {
+ if (Num512)
+ FreeList(List512);
+ if (Num256)
+ FreeList(List256);
+ if (Num128)
+ FreeList(List128);
+ if (NumPartial)
+ FreeList(ListPartial);
+ if (NumColor)
+ FreeList(ListColor);
+ if (NumMono)
+ FreeList(ListMono);
+ return;
+ }
+
+ infoRec->PixmapCachePrivate = (char *) pCachePriv;
+
+ if (Num512) {
+ pCachePriv->Info512 = calloc(Num512, sizeof(XAACacheInfoRec));
+ if (!pCachePriv->Info512)
+ Num512 = 0;
+ if (Num512)
+ TransferList(List512, pCachePriv->Info512, Num512);
+ FreeList(List512);
+ pCachePriv->Num512x512 = Num512;
+ }
+ if (Num256) {
+ pCachePriv->Info256 = calloc(Num256, sizeof(XAACacheInfoRec));
+ if (!pCachePriv->Info256)
+ Num256 = 0;
+ if (Num256)
+ TransferList(List256, pCachePriv->Info256, Num256);
+ FreeList(List256);
+ pCachePriv->Num256x256 = Num256;
+ }
+ if (Num128) {
+ pCachePriv->Info128 = calloc(Num128, sizeof(XAACacheInfoRec));
+ if (!pCachePriv->Info128)
+ Num128 = 0;
+ if (Num128)
+ TransferList(List128, pCachePriv->Info128, Num128);
+ FreeList(List128);
+ pCachePriv->Num128x128 = Num128;
+ }
+
+ if (NumPartial) {
+ pCachePriv->InfoPartial = calloc(NumPartial, sizeof(XAACacheInfoRec));
+ if (!pCachePriv->InfoPartial)
+ NumPartial = 0;
+ if (NumPartial)
+ TransferList(ListPartial, pCachePriv->InfoPartial, NumPartial);
+ FreeList(ListPartial);
+ pCachePriv->NumPartial = NumPartial;
+ }
+
+ if (NumColor) {
+ pCachePriv->InfoColor = calloc(NumColor, sizeof(XAACacheInfoRec));
+ if (!pCachePriv->InfoColor)
+ NumColor = 0;
+ if (NumColor)
+ TransferList(ListColor, pCachePriv->InfoColor, NumColor);
+ FreeList(ListColor);
+ pCachePriv->NumColor = NumColor;
+ }
+
+ if (NumMono) {
+ pCachePriv->InfoMono = calloc(NumMono, sizeof(XAACacheInfoRec));
+ if (!pCachePriv->InfoMono)
+ NumMono = 0;
+ if (NumMono)
+ TransferList(ListMono, pCachePriv->InfoMono, NumMono);
+ FreeList(ListMono);
+ pCachePriv->NumMono = NumMono;
+ }
+
+ if (NumPartial) {
+ infoRec->MaxCacheableTileWidth = MaxPartialWidth;
+ infoRec->MaxCacheableTileHeight = MaxPartialHeight;
+ }
+ if (Num128)
+ infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 128;
+ if (Num256)
+ infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 256;
+ if (Num512)
+ infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 512;
+
+ infoRec->MaxCacheableStippleHeight = infoRec->MaxCacheableTileHeight;
+ infoRec->MaxCacheableStippleWidth =
+ infoRec->MaxCacheableTileWidth * pScrn->bitsPerPixel;
+ if (infoRec->ScreenToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP)
+ infoRec->MaxCacheableStippleWidth /= 3;
+
+ if (NumMono) {
+ if (!(infoRec->Mono8x8PatternFillFlags &
+ (HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS))) {
+ int numPerLine =
+ infoRec->CacheWidthMono8x8Pattern / infoRec->MonoPatternPitch;
+
+ for (i = 0; i < 64; i++) {
+ pCachePriv->MonoOffsets[i].y = i / numPerLine;
+ pCachePriv->MonoOffsets[i].x = (i % numPerLine) *
+ infoRec->MonoPatternPitch;
+ }
+ }
+ infoRec->CanDoMono8x8 = TRUE;
+ }
+ if (NumColor) {
+ if (!(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) {
+
+ for (i = 0; i < 64; i++) {
+ pCachePriv->ColorOffsets[i].y = i & 0x07;
+ pCachePriv->ColorOffsets[i].x = i & ~0x07;
+ }
+ }
+ infoRec->CanDoColor8x8 = TRUE;
+ }
+
+ if (!CACHEINIT(pScrn)) {
+ xf86ErrorF("\tSetting up tile and stipple cache:\n");
+ if (NumPartial)
+ xf86ErrorF("\t\t%i %ix%i slots\n",
+ NumPartial, MaxPartialWidth, MaxPartialHeight);
+ if (Num128)
+ xf86ErrorF("\t\t%i 128x128 slots\n", Num128);
+ if (Num256)
+ xf86ErrorF("\t\t%i 256x256 slots\n", Num256);
+ if (Num512)
+ xf86ErrorF("\t\t%i 512x512 slots\n", Num512);
+ if (NumColor)
+ xf86ErrorF("\t\t%i 8x8 color pattern slots\n", NumColor);
+ if (NumMono)
+ xf86ErrorF("\t\t%i 8x8 color expansion slots\n", NumMono);
+ }
+
+ if (!(NumPartial | Num128 | Num256 | Num512 | NumColor | NumMono)) {
+ if (!CACHEINIT(pScrn))
+ xf86ErrorF("\t\tNot enough video memory for pixmap cache\n");
+ }
+ else
+ infoRec->UsingPixmapCache = TRUE;
+
+ CACHEINIT(pScrn) = 1;
+}
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+static CARD32 StippleMasks[4] = {
+ 0x80808080,
+ 0xC0C0C0C0,
+ 0x00000000,
+ 0xF0F0F0F0
+};
+#else
+static CARD32 StippleMasks[4] = {
+ 0x01010101,
+ 0x03030303,
+ 0x00000000,
+ 0x0F0F0F0F
+};
+#endif
+
+Bool
+XAACheckStippleReducibility(PixmapPtr pPixmap)
+{
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_DRAWABLE(&pPixmap->drawable);
+ CARD32 *IntPtr = (CARD32 *) pPixmap->devPrivate.ptr;
+ int w = pPixmap->drawable.width;
+ int h = pPixmap->drawable.height;
+ int i;
+ CARD32 bits[8];
+ CARD32 mask = SHIFT_R(0xFFFFFFFF, 24);
+
+ pPriv->flags |= REDUCIBILITY_CHECKED | REDUCIBLE_TO_2_COLOR;
+ pPriv->flags &= ~REDUCIBLE_TO_8x8;
+
+ if ((w > 32) || (h > 32) || (w & (w - 1)) || (h & (h - 1)))
+ return FALSE;
+
+ i = (h > 8) ? 8 : h;
+
+ switch (w) {
+ case 32:
+ while (i--) {
+ bits[i] = IntPtr[i] & mask;
+ if ((bits[i] != SHIFT_R((IntPtr[i] & SHIFT_L(mask, 8)), 8)) ||
+ (bits[i] != SHIFT_R((IntPtr[i] & SHIFT_L(mask, 16)), 16)) ||
+ (bits[i] != SHIFT_R((IntPtr[i] & SHIFT_L(mask, 24)), 24)))
+ return FALSE;
+ }
+ break;
+ case 16:
+ while (i--) {
+ bits[i] = IntPtr[i] & mask;
+ if (bits[i] != ((IntPtr[i] & SHIFT_R(SHIFT_L(mask, 8), 8))))
+ return FALSE;
+ }
+ break;
+ default:
+ while (i--)
+ bits[i] = IntPtr[i] & mask;
+ break;
+ }
+
+ switch (h) {
+ case 32:
+ if ((IntPtr[8] != IntPtr[16]) || (IntPtr[9] != IntPtr[17]) ||
+ (IntPtr[10] != IntPtr[18]) || (IntPtr[11] != IntPtr[19]) ||
+ (IntPtr[12] != IntPtr[20]) || (IntPtr[13] != IntPtr[21]) ||
+ (IntPtr[14] != IntPtr[22]) || (IntPtr[15] != IntPtr[23]) ||
+ (IntPtr[16] != IntPtr[24]) || (IntPtr[17] != IntPtr[25]) ||
+ (IntPtr[18] != IntPtr[26]) || (IntPtr[19] != IntPtr[27]) ||
+ (IntPtr[20] != IntPtr[28]) || (IntPtr[21] != IntPtr[29]) ||
+ (IntPtr[22] != IntPtr[30]) || (IntPtr[23] != IntPtr[31]))
+ return FALSE;
+ /* fall through */
+ case 16:
+ if ((IntPtr[0] != IntPtr[8]) || (IntPtr[1] != IntPtr[9]) ||
+ (IntPtr[2] != IntPtr[10]) || (IntPtr[3] != IntPtr[11]) ||
+ (IntPtr[4] != IntPtr[12]) || (IntPtr[5] != IntPtr[13]) ||
+ (IntPtr[6] != IntPtr[14]) || (IntPtr[7] != IntPtr[15]))
+ return FALSE;
+ case 8:
+ break;
+ case 1:
+ bits[1] = bits[0];
+ case 2:
+ bits[2] = bits[0];
+ bits[3] = bits[1];
+ case 4:
+ bits[4] = bits[0];
+ bits[5] = bits[1];
+ bits[6] = bits[2];
+ bits[7] = bits[3];
+ break;
+ }
+
+ pPriv->flags |= REDUCIBLE_TO_8x8;
+
+ pPriv->pattern0 =
+ bits[0] | SHIFT_L(bits[1], 8) | SHIFT_L(bits[2], 16) | SHIFT_L(bits[3],
+ 24);
+ pPriv->pattern1 =
+ bits[4] | SHIFT_L(bits[5], 8) | SHIFT_L(bits[6], 16) | SHIFT_L(bits[7],
+ 24);
+
+ if (w < 8) {
+ pPriv->pattern0 &= StippleMasks[w - 1];
+ pPriv->pattern1 &= StippleMasks[w - 1];
+
+ switch (w) {
+ case 1:
+ pPriv->pattern0 |= SHIFT_L(pPriv->pattern0, 1);
+ pPriv->pattern1 |= SHIFT_L(pPriv->pattern1, 1);
+ case 2:
+ pPriv->pattern0 |= SHIFT_L(pPriv->pattern0, 2);
+ pPriv->pattern1 |= SHIFT_L(pPriv->pattern1, 2);
+ case 4:
+ pPriv->pattern0 |= SHIFT_L(pPriv->pattern0, 4);
+ pPriv->pattern1 |= SHIFT_L(pPriv->pattern1, 4);
+ }
+ }
+
+ if (infoRec->Mono8x8PatternFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
+ pPriv->pattern0 = SWAP_BITS_IN_BYTES(pPriv->pattern0);
+ pPriv->pattern1 = SWAP_BITS_IN_BYTES(pPriv->pattern1);
+ }
+
+ return TRUE;
+}
+
+Bool
+XAACheckTileReducibility(PixmapPtr pPixmap, Bool checkMono)
+{
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+ CARD32 *IntPtr;
+ int w = pPixmap->drawable.width;
+ int h = pPixmap->drawable.height;
+ int pitch = pPixmap->devKind >> 2;
+ int dwords, i, j;
+
+ pPriv->flags |= REDUCIBILITY_CHECKED;
+ pPriv->flags &= ~(REDUCIBILITY_CHECKED | REDUCIBLE_TO_2_COLOR);
+
+ if ((w > 32) || (h > 32) || (w & (w - 1)) || (h & (h - 1)))
+ return FALSE;
+
+ dwords = ((w * pPixmap->drawable.bitsPerPixel) + 31) >> 5;
+ i = (h > 8) ? 8 : h;
+
+ if (w > 8) {
+ IntPtr = (CARD32 *) pPixmap->devPrivate.ptr;
+ switch (pPixmap->drawable.bitsPerPixel) {
+ case 8:
+ while (i--) {
+ for (j = 2; j < dwords; j++)
+ if (IntPtr[j] != IntPtr[j & 0x01])
+ return FALSE;
+ IntPtr += pitch;
+ }
+ break;
+ case 16:
+ while (i--) {
+ for (j = 4; j < dwords; j++)
+ if (IntPtr[j] != IntPtr[j & 0x03])
+ return FALSE;
+ IntPtr += pitch;
+ }
+ break;
+ case 24:
+ while (i--) {
+ for (j = 6; j < dwords; j++)
+ if (IntPtr[j] != IntPtr[j % 6])
+ return FALSE;
+ IntPtr += pitch;
+ }
+ break;
+ case 32:
+ while (i--) {
+ for (j = 8; j < dwords; j++)
+ if (IntPtr[j] != IntPtr[j & 0x07])
+ return FALSE;
+ IntPtr += pitch;
+ }
+ break;
+ default:
+ return FALSE;
+ }
+
+ }
+
+ if (h == 32) {
+ CARD32 *IntPtr2, *IntPtr3, *IntPtr4;
+
+ i = 8;
+ IntPtr = (CARD32 *) pPixmap->devPrivate.ptr;
+ IntPtr2 = IntPtr + (pitch << 3);
+ IntPtr3 = IntPtr2 + (pitch << 3);
+ IntPtr4 = IntPtr3 + (pitch << 3);
+ while (i--) {
+ for (j = 0; j < dwords; j++)
+ if ((IntPtr[j] != IntPtr2[j]) || (IntPtr[j] != IntPtr3[j]) ||
+ (IntPtr[j] != IntPtr4[j]))
+ return FALSE;
+ IntPtr += pitch;
+ IntPtr2 += pitch;
+ IntPtr3 += pitch;
+ IntPtr4 += pitch;
+ }
+ }
+ else if (h == 16) {
+ CARD32 *IntPtr2;
+
+ i = 8;
+ IntPtr = (CARD32 *) pPixmap->devPrivate.ptr;
+ IntPtr2 = IntPtr + (pitch << 3);
+ while (i--) {
+ for (j = 0; j < dwords; j++)
+ if (IntPtr[j] != IntPtr2[j])
+ return FALSE;
+ IntPtr += pitch;
+ IntPtr2 += pitch;
+ }
+ }
+
+ pPriv->flags |= REDUCIBLE_TO_8x8;
+
+ if (checkMono) {
+ XAAInfoRecPtr infoRec =
+ GET_XAAINFORECPTR_FROM_DRAWABLE(&pPixmap->drawable);
+ unsigned char bits[8];
+ int fg, bg = -1, x, y;
+
+ i = (h > 8) ? 8 : h;
+ j = (w > 8) ? 8 : w;
+
+ if (pPixmap->drawable.bitsPerPixel == 8) {
+ unsigned char *srcp = pPixmap->devPrivate.ptr;
+
+ fg = srcp[0];
+ pitch = pPixmap->devKind;
+ for (y = 0; y < i; y++) {
+ bits[y] = 0;
+ for (x = 0; x < j; x++) {
+ if (srcp[x] != fg) {
+ if (bg == -1)
+ bg = srcp[x];
+ else if (bg != srcp[x])
+ return TRUE;
+ }
+ else
+ bits[y] |= 1 << x;
+ }
+ srcp += pitch;
+ }
+ }
+ else if (pPixmap->drawable.bitsPerPixel == 16) {
+ unsigned short *srcp = (unsigned short *) pPixmap->devPrivate.ptr;
+
+ fg = srcp[0];
+ pitch = pPixmap->devKind >> 1;
+ for (y = 0; y < i; y++) {
+ bits[y] = 0;
+ for (x = 0; x < j; x++) {
+ if (srcp[x] != fg) {
+ if (bg == -1)
+ bg = srcp[x];
+ else if (bg != srcp[x])
+ return TRUE;
+ }
+ else
+ bits[y] |= 1 << x;
+ }
+ srcp += pitch;
+ }
+ }
+ else if (pPixmap->drawable.bitsPerPixel == 24) {
+ CARD32 val;
+ unsigned char *srcp = pPixmap->devPrivate.ptr;
+
+ fg = *((CARD32 *) srcp) & 0x00FFFFFF;
+ pitch = pPixmap->devKind;
+ j *= 3;
+ for (y = 0; y < i; y++) {
+ bits[y] = 0;
+ for (x = 0; x < j; x += 3) {
+ val = *((CARD32 *) (srcp + x)) & 0x00FFFFFF;
+ if (val != fg) {
+ if (bg == -1)
+ bg = val;
+ else if (bg != val)
+ return TRUE;
+ }
+ else
+ bits[y] |= 1 << (x / 3);
+ }
+ srcp += pitch;
+ }
+ }
+ else if (pPixmap->drawable.bitsPerPixel == 32) {
+ IntPtr = (CARD32 *) pPixmap->devPrivate.ptr;
+ fg = IntPtr[0];
+ for (y = 0; y < i; y++) {
+ bits[y] = 0;
+ for (x = 0; x < j; x++) {
+ if (IntPtr[x] != fg) {
+ if (bg == -1)
+ bg = IntPtr[x];
+ else if (bg != IntPtr[x])
+ return TRUE;
+ }
+ else
+ bits[y] |= 1 << x;
+ }
+ IntPtr += pitch;
+ }
+ }
+ else
+ return TRUE;
+
+ pPriv->fg = fg;
+ if (bg == -1)
+ pPriv->bg = fg;
+ else
+ pPriv->bg = bg;
+
+ if (h < 8) {
+ switch (h) {
+ case 1:
+ bits[1] = bits[0];
+ case 2:
+ bits[2] = bits[0];
+ bits[3] = bits[1];
+ case 4:
+ bits[4] = bits[0];
+ bits[5] = bits[1];
+ bits[6] = bits[2];
+ bits[7] = bits[3];
+ break;
+ }
+ }
+
+ pPriv->pattern0 =
+ bits[0] | (bits[1] << 8) | (bits[2] << 16) | (bits[3] << 24);
+ pPriv->pattern1 =
+ bits[4] | (bits[5] << 8) | (bits[6] << 16) | (bits[7] << 24);
+
+ if (w < 8) {
+ switch (w) {
+ case 1:
+ pPriv->pattern0 |= (pPriv->pattern0 << 1);
+ pPriv->pattern1 |= (pPriv->pattern1 << 1);
+ case 2:
+ pPriv->pattern0 |= (pPriv->pattern0 << 2);
+ pPriv->pattern1 |= (pPriv->pattern1 << 2);
+ case 4:
+ pPriv->pattern0 |= (pPriv->pattern0 << 4);
+ pPriv->pattern1 |= (pPriv->pattern1 << 4);
+ }
+ }
+ pPriv->flags |= REDUCIBLE_TO_2_COLOR;
+
+ if (infoRec->Mono8x8PatternFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
+ pPriv->pattern0 = SWAP_BITS_IN_BYTES(pPriv->pattern0);
+ pPriv->pattern1 = SWAP_BITS_IN_BYTES(pPriv->pattern1);
+ }
+
+ }
+
+ return TRUE;
+}
+
+void
+XAATileCache(ScrnInfoPtr pScrn, XAACacheInfoPtr pCache, int w, int h)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->SetupForScreenToScreenCopy) (pScrn, 1, 1, GXcopy, ~0, -1);
+
+ while ((w << 1) <= pCache->w) {
+ (*infoRec->SubsequentScreenToScreenCopy) (pScrn, pCache->x, pCache->y,
+ pCache->x + w, pCache->y, w,
+ h);
+ w <<= 1;
+ }
+ if (w != pCache->w) {
+ (*infoRec->SubsequentScreenToScreenCopy) (pScrn, pCache->x, pCache->y,
+ pCache->x + w, pCache->y,
+ pCache->w - w, h);
+ w = pCache->w;
+ }
+
+ while ((h << 1) <= pCache->h) {
+ (*infoRec->SubsequentScreenToScreenCopy) (pScrn, pCache->x, pCache->y,
+ pCache->x, pCache->y + h, w,
+ h);
+ h <<= 1;
+ }
+ if (h != pCache->h) {
+ (*infoRec->SubsequentScreenToScreenCopy) (pScrn, pCache->x, pCache->y,
+ pCache->x, pCache->y + h, w,
+ pCache->h - h);
+ }
+ SET_SYNC_FLAG(infoRec);
+}
+
+XAACacheInfoPtr
+XAACacheTile(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ int w = pPix->drawable.width;
+ int h = pPix->drawable.height;
+ int size = max(w, h);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr) infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache, cacheRoot = NULL;
+ int i, max = 0;
+ int *current;
+
+ if (size <= 128) {
+ if (pCachePriv->Info128) {
+ cacheRoot = pCachePriv->Info128;
+ max = pCachePriv->Num128x128;
+ current = &pCachePriv->Current128;
+ }
+ else {
+ cacheRoot = pCachePriv->InfoPartial;
+ max = pCachePriv->NumPartial;
+ current = &pCachePriv->CurrentPartial;
+ }
+ }
+ else if (size <= 256) {
+ cacheRoot = pCachePriv->Info256;
+ max = pCachePriv->Num256x256;
+ current = &pCachePriv->Current256;
+ }
+ else if (size <= 512) {
+ cacheRoot = pCachePriv->Info512;
+ max = pCachePriv->Num512x512;
+ current = &pCachePriv->Current512;
+ }
+ else { /* something's wrong */
+ ErrorF("Something's wrong in XAACacheTile()\n");
+ return pCachePriv->Info128;
+ }
+
+ pCache = cacheRoot;
+
+ /* lets look for it */
+ for (i = 0; i < max; i++, pCache++) {
+ if (pCache->serialNumber == pPix->drawable.serialNumber) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+
+ pCache = &cacheRoot[(*current)++];
+ if (*current >= max)
+ *current = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->trans_color = pCache->bg = pCache->fg = -1;
+ pCache->orig_w = w;
+ pCache->orig_h = h;
+ (*infoRec->WritePixmapToCache) (pScrn, pCache->x, pCache->y, w, h,
+ pPix->devPrivate.ptr, pPix->devKind,
+ pPix->drawable.bitsPerPixel,
+ pPix->drawable.depth);
+ if (!(infoRec->PixmapCacheFlags & DO_NOT_TILE_COLOR_DATA) &&
+ ((w != pCache->w) || (h != pCache->h)))
+ XAATileCache(pScrn, pCache, w, h);
+
+ return pCache;
+}
+
+XAACacheInfoPtr
+XAACacheMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ int w = pPix->drawable.width;
+ int h = pPix->drawable.height;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr) infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache, cacheRoot = NULL;
+ int i, max = 0, funcNo, pad, dwords, bpp = pScrn->bitsPerPixel;
+ int *current;
+ StippleScanlineProcPtr StippleFunc;
+ unsigned char *data, *srcPtr, *dstPtr;
+
+ if ((h <= 128) && (w <= 128 * bpp)) {
+ if (pCachePriv->Info128) {
+ cacheRoot = pCachePriv->Info128;
+ max = pCachePriv->Num128x128;
+ current = &pCachePriv->Current128;
+ }
+ else {
+ cacheRoot = pCachePriv->InfoPartial;
+ max = pCachePriv->NumPartial;
+ current = &pCachePriv->CurrentPartial;
+ }
+ }
+ else if ((h <= 256) && (w <= 256 * bpp)) {
+ cacheRoot = pCachePriv->Info256;
+ max = pCachePriv->Num256x256;
+ current = &pCachePriv->Current256;
+ }
+ else if ((h <= 512) && (w <= 526 * bpp)) {
+ cacheRoot = pCachePriv->Info512;
+ max = pCachePriv->Num512x512;
+ current = &pCachePriv->Current512;
+ }
+ else { /* something's wrong */
+ ErrorF("Something's wrong in XAACacheMonoStipple()\n");
+ return pCachePriv->Info128;
+ }
+
+ pCache = cacheRoot;
+
+ /* lets look for it */
+ for (i = 0; i < max; i++, pCache++) {
+ if ((pCache->serialNumber == pPix->drawable.serialNumber) &&
+ (pCache->fg == -1) && (pCache->bg == -1)) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+
+ pCache = &cacheRoot[(*current)++];
+ if (*current >= max)
+ *current = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->trans_color = pCache->bg = pCache->fg = -1;
+ pCache->orig_w = w;
+ pCache->orig_h = h;
+
+ if (w <= 32) {
+ if (w & (w - 1))
+ funcNo = 1;
+ else
+ funcNo = 0;
+ }
+ else
+ funcNo = 2;
+
+ pad = BitmapBytePad(pCache->w * bpp);
+ dwords = bytes_to_int32(pad);
+ dstPtr = data = (unsigned char *) malloc(pad * pCache->h);
+ srcPtr = (unsigned char *) pPix->devPrivate.ptr;
+
+ if (infoRec->
+ ScreenToScreenColorExpandFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST)
+ StippleFunc = XAAStippleScanlineFuncMSBFirst[funcNo];
+ else
+ StippleFunc = XAAStippleScanlineFuncLSBFirst[funcNo];
+
+ /* don't bother generating more than we'll ever use */
+ max = ((pScrn->displayWidth + w - 1) + 31) >> 5;
+ if (dwords > max)
+ dwords = max;
+
+ for (i = 0; i < h; i++) {
+ (*StippleFunc) ((CARD32 *) dstPtr, (CARD32 *) srcPtr, 0, w, dwords);
+ srcPtr += pPix->devKind;
+ dstPtr += pad;
+ }
+
+ while ((h << 1) <= pCache->h) {
+ memcpy(data + (pad * h), data, pad * h);
+ h <<= 1;
+ }
+
+ if (h < pCache->h)
+ memcpy(data + (pad * h), data, pad * (pCache->h - h));
+
+ (*infoRec->WritePixmapToCache) (pScrn, pCache->x, pCache->y, pCache->w,
+ pCache->h, data, pad, bpp, pScrn->depth);
+
+ free(data);
+
+ return pCache;
+}
+
+XAACacheInfoPtr
+XAACachePlanarMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ int w = pPix->drawable.width;
+ int h = pPix->drawable.height;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr) infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache, cacheRoot = NULL;
+ int i, max = 0;
+ int *current;
+
+ if ((h <= 128) && (w <= 128)) {
+ if (pCachePriv->Info128) {
+ cacheRoot = pCachePriv->Info128;
+ max = pCachePriv->Num128x128;
+ current = &pCachePriv->Current128;
+ }
+ else {
+ cacheRoot = pCachePriv->InfoPartial;
+ max = pCachePriv->NumPartial;
+ current = &pCachePriv->CurrentPartial;
+ }
+ }
+ else if ((h <= 256) && (w <= 256)) {
+ cacheRoot = pCachePriv->Info256;
+ max = pCachePriv->Num256x256;
+ current = &pCachePriv->Current256;
+ }
+ else if ((h <= 512) && (w <= 526)) {
+ cacheRoot = pCachePriv->Info512;
+ max = pCachePriv->Num512x512;
+ current = &pCachePriv->Current512;
+ }
+ else { /* something's wrong */
+ ErrorF("Something's wrong in XAACachePlanarMonoStipple()\n");
+ return pCachePriv->Info128;
+ }
+
+ pCache = cacheRoot;
+
+ /* lets look for it */
+ for (i = 0; i < max; i++, pCache++) {
+ if ((pCache->serialNumber == pPix->drawable.serialNumber) &&
+ (pCache->fg == -1) && (pCache->bg == -1)) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+
+ pCache = &cacheRoot[(*current)++];
+ if (*current >= max)
+ *current = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->trans_color = pCache->bg = pCache->fg = -1;
+ pCache->orig_w = w;
+ pCache->orig_h = h;
+
+ /* Plane 0 holds the stipple. Plane 1 holds the inverted stipple */
+ (*infoRec->WriteBitmapToCache) (pScrn, pCache->x, pCache->y,
+ pPix->drawable.width, pPix->drawable.height,
+ pPix->devPrivate.ptr, pPix->devKind, 1, 2);
+ if (!(infoRec->PixmapCacheFlags & DO_NOT_TILE_MONO_DATA) &&
+ ((w != pCache->w) || (h != pCache->h)))
+ XAATileCache(pScrn, pCache, w, h);
+
+ return pCache;
+}
+
+XAACachePlanarMonoStippleProc
+XAAGetCachePlanarMonoStipple(void)
+{
+ return XAACachePlanarMonoStipple;
+}
+
+XAACacheInfoPtr
+XAACacheStipple(ScrnInfoPtr pScrn, PixmapPtr pPix, int fg, int bg)
+{
+ int w = pPix->drawable.width;
+ int h = pPix->drawable.height;
+ int size = max(w, h);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr) infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache, cacheRoot = NULL;
+ int i, max = 0;
+ int *current;
+
+ if (size <= 128) {
+ if (pCachePriv->Info128) {
+ cacheRoot = pCachePriv->Info128;
+ max = pCachePriv->Num128x128;
+ current = &pCachePriv->Current128;
+ }
+ else {
+ cacheRoot = pCachePriv->InfoPartial;
+ max = pCachePriv->NumPartial;
+ current = &pCachePriv->CurrentPartial;
+ }
+ }
+ else if (size <= 256) {
+ cacheRoot = pCachePriv->Info256;
+ max = pCachePriv->Num256x256;
+ current = &pCachePriv->Current256;
+ }
+ else if (size <= 512) {
+ cacheRoot = pCachePriv->Info512;
+ max = pCachePriv->Num512x512;
+ current = &pCachePriv->Current512;
+ }
+ else { /* something's wrong */
+ ErrorF("Something's wrong in XAACacheStipple()\n");
+ return pCachePriv->Info128;
+ }
+
+ pCache = cacheRoot;
+ /* lets look for it */
+ if (bg == -1)
+ for (i = 0; i < max; i++, pCache++) {
+ if ((pCache->serialNumber == pPix->drawable.serialNumber) &&
+ (fg == pCache->fg) && (pCache->fg != pCache->bg)) {
+ pCache->trans_color = pCache->bg;
+ return pCache;
+ }
+ }
+ else
+ for (i = 0; i < max; i++, pCache++) {
+ if ((pCache->serialNumber == pPix->drawable.serialNumber) &&
+ (fg == pCache->fg) && (bg == pCache->bg)) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+
+ pCache = &cacheRoot[(*current)++];
+ if (*current >= max)
+ *current = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->fg = fg;
+ if (bg == -1)
+ pCache->trans_color = bg = fg ^ 1;
+ else
+ pCache->trans_color = -1;
+ pCache->bg = bg;
+
+ pCache->orig_w = w;
+ pCache->orig_h = h;
+ (*infoRec->WriteBitmapToCache) (pScrn, pCache->x, pCache->y,
+ pPix->drawable.width, pPix->drawable.height,
+ pPix->devPrivate.ptr, pPix->devKind, fg,
+ bg);
+ if (!(infoRec->PixmapCacheFlags & DO_NOT_TILE_COLOR_DATA) &&
+ ((w != pCache->w) || (h != pCache->h)))
+ XAATileCache(pScrn, pCache, w, h);
+
+ return pCache;
+}
+
+XAACacheInfoPtr
+XAACacheMono8x8Pattern(ScrnInfoPtr pScrn, int pat0, int pat1)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr) infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache = pCachePriv->InfoMono;
+ int i;
+
+ for (i = 0; i < pCachePriv->NumMono; i++, pCache++) {
+ if (pCache->serialNumber &&
+ (pCache->pat0 == pat0) && (pCache->pat1 == pat1))
+ return pCache;
+ }
+
+ /* OK, let's cache it */
+ pCache = &pCachePriv->InfoMono[pCachePriv->CurrentMono++];
+ if (pCachePriv->CurrentMono >= pCachePriv->NumMono)
+ pCachePriv->CurrentMono = 0;
+
+ pCache->serialNumber = 1; /* we don't care since we do lookups by pattern */
+ pCache->pat0 = pat0;
+ pCache->pat1 = pat1;
+
+ (*infoRec->WriteMono8x8PatternToCache) (pScrn, pCache);
+
+ return pCache;
+}
+
+XAACacheInfoPtr
+XAACacheColor8x8Pattern(ScrnInfoPtr pScrn, PixmapPtr pPix, int fg, int bg)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr) infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache = pCachePriv->InfoColor;
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ int i;
+
+ if (!(pixPriv->flags & REDUCIBLE_TO_2_COLOR)) {
+ for (i = 0; i < pCachePriv->NumColor; i++, pCache++) {
+ if (pCache->serialNumber == pPix->drawable.serialNumber) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+ pCache = &pCachePriv->InfoColor[pCachePriv->CurrentColor++];
+ if (pCachePriv->CurrentColor >= pCachePriv->NumColor)
+ pCachePriv->CurrentColor = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->trans_color = pCache->fg = pCache->bg = -1;
+ }
+ else {
+ int pat0 = pixPriv->pattern0;
+ int pat1 = pixPriv->pattern1;
+
+ if (fg == -1) { /* it's a tile */
+ fg = pixPriv->fg;
+ bg = pixPriv->bg;
+ }
+
+ if (bg == -1) { /* stipple */
+ for (i = 0; i < pCachePriv->NumColor; i++, pCache++) {
+ if (pCache->serialNumber &&
+ (pCache->pat0 == pat0) && (pCache->pat1 == pat1) &&
+ (pCache->fg == fg) && (pCache->bg != fg)) {
+ pCache->trans_color = pCache->bg;
+ return pCache;
+ }
+ }
+ }
+ else { /* opaque stipple */
+ for (i = 0; i < pCachePriv->NumColor; i++, pCache++) {
+ if (pCache->serialNumber &&
+ (pCache->pat0 == pat0) && (pCache->pat1 == pat1) &&
+ (pCache->fg == fg) && (pCache->bg == bg)) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+ }
+ pCache = &pCachePriv->InfoColor[pCachePriv->CurrentColor++];
+ if (pCachePriv->CurrentColor >= pCachePriv->NumColor)
+ pCachePriv->CurrentColor = 0;
+
+ if (bg == -1)
+ pCache->trans_color = bg = fg ^ 1;
+ else
+ pCache->trans_color = -1;
+
+ pCache->pat0 = pat0;
+ pCache->pat1 = pat1;
+ pCache->fg = fg;
+ pCache->bg = bg;
+ pCache->serialNumber = 1;
+ }
+
+ (*infoRec->WriteColor8x8PatternToCache) (pScrn, pPix, pCache);
+
+ return pCache;
+}
+
+void
+XAAWriteBitmapToCache(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int fg, int bg)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->WriteBitmap) (pScrn, x, y, w, h, src, srcwidth,
+ 0, fg, bg, GXcopy, ~0);
+}
+
+void
+XAAWriteBitmapToCacheLinear(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int fg, int bg)
+{
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr pScreenPix, pDstPix;
+ ChangeGCVal gcvals[2];
+ GCPtr pGC;
+
+ pScreenPix = (*pScreen->GetScreenPixmap) (pScreen);
+
+ pDstPix = GetScratchPixmapHeader(pScreen, pScreenPix->drawable.width,
+ y + h, pScreenPix->drawable.depth,
+ pScreenPix->drawable.bitsPerPixel,
+ pScreenPix->devKind,
+ pScreenPix->devPrivate.ptr);
+
+ pGC = GetScratchGC(pScreenPix->drawable.depth, pScreen);
+ gcvals[0].val = fg;
+ gcvals[1].val = bg;
+ ChangeGC(NullClient, pGC, GCForeground | GCBackground, gcvals);
+ ValidateGC((DrawablePtr) pDstPix, pGC);
+
+ /* We've unwrapped already so these ops miss a sync */
+ SYNC_CHECK(pScrn);
+
+ (*pGC->ops->PutImage) ((DrawablePtr) pDstPix, pGC, 1, x, y, w, h, 0,
+ XYBitmap, (pointer) src);
+
+ FreeScratchGC(pGC);
+ FreeScratchPixmapHeader(pDstPix);
+}
+
+void
+XAAWritePixmapToCache(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int bpp, int depth)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->WritePixmap) (pScrn, x, y, w, h, src, srcwidth,
+ GXcopy, ~0, -1, bpp, depth);
+}
+
+void
+XAAWritePixmapToCacheLinear(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth, int bpp, int depth)
+{
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr pScreenPix, pDstPix;
+ GCPtr pGC;
+
+ pScreenPix = (*pScreen->GetScreenPixmap) (pScreen);
+
+ pDstPix = GetScratchPixmapHeader(pScreen, x + w, y + h,
+ depth, bpp, pScreenPix->devKind,
+ pScreenPix->devPrivate.ptr);
+
+ pGC = GetScratchGC(depth, pScreen);
+ ValidateGC((DrawablePtr) pDstPix, pGC);
+
+ /* We've unwrapped already so these ops miss a sync */
+ SYNC_CHECK(pScrn);
+
+ if (bpp == BitsPerPixel(depth))
+ (*pGC->ops->PutImage) ((DrawablePtr) pDstPix, pGC, depth, x, y, w,
+ h, 0, ZPixmap, (pointer) src);
+ else {
+ PixmapPtr pSrcPix;
+
+ pSrcPix = GetScratchPixmapHeader(pScreen, w, h, depth, bpp,
+ srcwidth, (pointer) src);
+
+ (*pGC->ops->CopyArea) ((DrawablePtr) pSrcPix, (DrawablePtr) pDstPix,
+ pGC, 0, 0, w, h, x, y);
+
+ FreeScratchPixmapHeader(pSrcPix);
+ }
+
+ FreeScratchGC(pGC);
+ FreeScratchPixmapHeader(pDstPix);
+}
+
+void
+XAAWriteMono8x8PatternToCache(ScrnInfoPtr pScrn, XAACacheInfoPtr pCache)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr) infoRec->PixmapCachePrivate;
+ unsigned char *data;
+ int pad, Bpp = (pScrn->bitsPerPixel >> 3);
+
+ pCache->offsets = pCachePriv->MonoOffsets;
+
+ pad = BitmapBytePad(pCache->w * pScrn->bitsPerPixel);
+
+ data = (unsigned char *) malloc(pad * pCache->h);
+ if (!data)
+ return;
+
+ if (infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
+ CARD32 *ptr = (CARD32 *) data;
+
+ ptr[0] = pCache->pat0;
+ ptr[1] = pCache->pat1;
+ }
+ else {
+ CARD32 *ptr;
+ DDXPointPtr pPoint = pCache->offsets;
+ int patx, paty, i;
+
+ for (i = 0; i < 64; i++, pPoint++) {
+ patx = pCache->pat0;
+ paty = pCache->pat1;
+ XAARotateMonoPattern(&patx, &paty, i & 0x07, i >> 3,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ ptr = (CARD32 *) (data + (pad * pPoint->y) + (Bpp * pPoint->x));
+ ptr[0] = patx;
+ ptr[1] = paty;
+ }
+ }
+
+ (*infoRec->WritePixmapToCache) (pScrn, pCache->x, pCache->y,
+ pCache->w, pCache->h, data, pad,
+ pScrn->bitsPerPixel, pScrn->depth);
+
+ free(data);
+}
+
+void
+XAAWriteColor8x8PatternToCache(ScrnInfoPtr pScrn,
+ PixmapPtr pPix, XAACacheInfoPtr pCache)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr) infoRec->PixmapCachePrivate;
+ int pad, i, w, h, nw, nh, Bpp;
+ unsigned char *data, *srcPtr, *dstPtr;
+
+ pCache->offsets = pCachePriv->ColorOffsets;
+
+ if (pixPriv->flags & REDUCIBLE_TO_2_COLOR) {
+ CARD32 *ptr;
+
+ pad = BitmapBytePad(pCache->w);
+ data = (unsigned char *) malloc(pad * pCache->h);
+ if (!data)
+ return;
+
+ if (infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
+ ptr = (CARD32 *) data;
+ ptr[0] = pCache->pat0;
+ ptr[1] = pCache->pat1;
+ }
+ else {
+ int patx, paty;
+
+ ptr = (CARD32 *) data;
+ ptr[0] = ptr[2] = pCache->pat0;
+ ptr[1] = ptr[3] = pCache->pat1;
+ for (i = 1; i < 8; i++) {
+ patx = pCache->pat0;
+ paty = pCache->pat1;
+ XAARotateMonoPattern(&patx, &paty, i, 0,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ ptr = (CARD32 *) (data + (pad * i));
+ ptr[0] = ptr[2] = patx;
+ ptr[1] = ptr[3] = paty;
+ }
+ }
+
+ (*infoRec->WriteBitmapToCache) (pScrn, pCache->x, pCache->y,
+ pCache->w, pCache->h, data, pad,
+ pCache->fg, pCache->bg);
+
+ free(data);
+ return;
+ }
+
+ Bpp = pScrn->bitsPerPixel >> 3;
+ h = min(8, pPix->drawable.height);
+ w = min(8, pPix->drawable.width);
+ pad = BitmapBytePad(pCache->w * pScrn->bitsPerPixel);
+
+ data = (unsigned char *) malloc(pad * pCache->h);
+ if (!data)
+ return;
+
+ /* Write and expand horizontally. */
+ for (i = h, dstPtr = data, srcPtr = pPix->devPrivate.ptr; i--;
+ srcPtr += pPix->devKind, dstPtr += pScrn->bitsPerPixel) {
+ nw = w;
+ memcpy(dstPtr, srcPtr, w * Bpp);
+ while (nw != 8) {
+ memcpy(dstPtr + (nw * Bpp), dstPtr, nw * Bpp);
+ nw <<= 1;
+ }
+ }
+ nh = h;
+ /* Expand vertically. */
+ while (nh != 8) {
+ memcpy(data + (nh * pScrn->bitsPerPixel), data,
+ nh * pScrn->bitsPerPixel);
+ nh <<= 1;
+ }
+
+ if (!(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) {
+ int j;
+ unsigned char *ptr = data + (128 * Bpp);
+
+ memcpy(data + (64 * Bpp), data, 64 * Bpp);
+ for (i = 1; i < 8; i++, ptr += (128 * Bpp)) {
+ for (j = 0; j < 8; j++) {
+ memcpy(ptr + (j * 8) * Bpp, data + (j * 8 + i) * Bpp,
+ (8 - i) * Bpp);
+ memcpy(ptr + (j * 8 + 8 - i) * Bpp, data + j * 8 * Bpp,
+ i * Bpp);
+ }
+ memcpy(ptr + (64 * Bpp), ptr, 64 * Bpp);
+ }
+ }
+
+ (*infoRec->WritePixmapToCache) (pScrn, pCache->x, pCache->y,
+ pCache->w, pCache->h, data, pad,
+ pScrn->bitsPerPixel, pScrn->depth);
+
+ free(data);
+}
+
+int
+XAAStippledFillChooser(GCPtr pGC)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ PixmapPtr pPixmap = pGC->stipple;
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+
+ if (!(pPriv->flags & REDUCIBILITY_CHECKED) &&
+ (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
+ XAACheckStippleReducibility(pPixmap);
+ }
+
+ if (pPriv->flags & REDUCIBLE_TO_8x8) {
+ if (infoRec->CanDoMono8x8 &&
+ !(infoRec->FillMono8x8PatternSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillMono8x8PatternSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC, infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC, infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_FG(pGC, infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC, infoRec->FillMono8x8PatternSpansFlags)) {
+
+ return DO_MONO_8x8;
+ }
+
+ if (infoRec->CanDoColor8x8 &&
+ !(infoRec->FillColor8x8PatternSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillColor8x8PatternSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC, infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC, infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC, infoRec->FillColor8x8PatternSpansFlags)) {
+
+ return DO_COLOR_8x8;
+ }
+ }
+
+ if (infoRec->UsingPixmapCache && infoRec->FillCacheExpandSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableStippleHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableStippleWidth /
+ infoRec->CacheColorExpandDensity) &&
+ !(infoRec->FillCacheExpandSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillCacheExpandSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC, infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_ROPSRC(pGC, infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_FG(pGC, infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_PLANEMASK(pGC, infoRec->FillCacheExpandSpansFlags)) {
+
+ return DO_CACHE_EXPAND;
+ }
+
+ if (infoRec->UsingPixmapCache &&
+ !(infoRec->PixmapCacheFlags & DO_NOT_BLIT_STIPPLES) &&
+ infoRec->FillCacheBltSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
+ !(infoRec->FillCacheBltSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillCacheBltSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC, infoRec->FillCacheBltSpansFlags) &&
+ CHECK_ROPSRC(pGC, infoRec->FillCacheBltSpansFlags) &&
+ CHECK_PLANEMASK(pGC, infoRec->FillCacheBltSpansFlags)) {
+
+ return DO_CACHE_BLT;
+ }
+
+ if (infoRec->FillColorExpandSpans &&
+ !(infoRec->FillColorExpandSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillColorExpandSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC, infoRec->FillColorExpandSpansFlags) &&
+ CHECK_ROPSRC(pGC, infoRec->FillColorExpandSpansFlags) &&
+ CHECK_FG(pGC, infoRec->FillColorExpandSpansFlags) &&
+ CHECK_PLANEMASK(pGC, infoRec->FillColorExpandSpansFlags)) {
+
+ return DO_COLOR_EXPAND;
+ }
+
+ return 0;
+}
+
+int
+XAAOpaqueStippledFillChooser(GCPtr pGC)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ PixmapPtr pPixmap = pGC->stipple;
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+
+ if (XAA_DEPTH_BUG(pGC))
+ return 0;
+
+ if (!(pPriv->flags & REDUCIBILITY_CHECKED) &&
+ (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
+ XAACheckStippleReducibility(pPixmap);
+ }
+
+ if (pPriv->flags & REDUCIBLE_TO_8x8) {
+ if (infoRec->CanDoMono8x8 &&
+ !(infoRec->FillMono8x8PatternSpansFlags & TRANSPARENCY_ONLY) &&
+ CHECK_ROP(pGC, infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC, infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_COLORS(pGC, infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC, infoRec->FillMono8x8PatternSpansFlags)) {
+
+ return DO_MONO_8x8;
+ }
+
+ if (infoRec->CanDoColor8x8 &&
+ CHECK_ROP(pGC, infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC, infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC, infoRec->FillColor8x8PatternSpansFlags)) {
+
+ return DO_COLOR_8x8;
+ }
+ }
+
+ if (infoRec->UsingPixmapCache && infoRec->FillCacheExpandSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableStippleHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableStippleWidth /
+ infoRec->CacheColorExpandDensity) &&
+ !(infoRec->FillCacheExpandSpansFlags & TRANSPARENCY_ONLY) &&
+ CHECK_ROP(pGC, infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_ROPSRC(pGC, infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_COLORS(pGC, infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_PLANEMASK(pGC, infoRec->FillCacheExpandSpansFlags)) {
+
+ return DO_CACHE_EXPAND;
+ }
+
+ if (infoRec->UsingPixmapCache &&
+ !(infoRec->PixmapCacheFlags & DO_NOT_BLIT_STIPPLES) &&
+ infoRec->FillCacheBltSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
+ CHECK_ROP(pGC, infoRec->FillCacheBltSpansFlags) &&
+ CHECK_ROPSRC(pGC, infoRec->FillCacheBltSpansFlags) &&
+ CHECK_PLANEMASK(pGC, infoRec->FillCacheBltSpansFlags)) {
+
+ return DO_CACHE_BLT;
+ }
+
+ if (infoRec->FillColorExpandSpans &&
+ !(infoRec->FillColorExpandSpansFlags & TRANSPARENCY_ONLY) &&
+ CHECK_ROP(pGC, infoRec->FillColorExpandSpansFlags) &&
+ CHECK_ROPSRC(pGC, infoRec->FillColorExpandSpansFlags) &&
+ CHECK_COLORS(pGC, infoRec->FillColorExpandSpansFlags) &&
+ CHECK_PLANEMASK(pGC, infoRec->FillColorExpandSpansFlags)) {
+
+ return DO_COLOR_EXPAND;
+ }
+
+ return 0;
+}
+
+int
+XAATiledFillChooser(GCPtr pGC)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ PixmapPtr pPixmap = pGC->tile.pixmap;
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+
+ if (IS_OFFSCREEN_PIXMAP(pPixmap) && infoRec->FillCacheBltSpans &&
+ CHECK_ROP(pGC, infoRec->FillCacheBltSpansFlags) &&
+ CHECK_ROPSRC(pGC, infoRec->FillCacheBltSpansFlags) &&
+ CHECK_PLANEMASK(pGC, infoRec->FillCacheBltSpansFlags)) {
+
+ return DO_PIXMAP_COPY;
+ }
+
+ if (!(pPriv->flags & REDUCIBILITY_CHECKED) &&
+ (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
+ XAACheckTileReducibility(pPixmap, infoRec->CanDoMono8x8);
+ }
+
+ if (pPriv->flags & REDUCIBLE_TO_8x8) {
+ if ((pPriv->flags & REDUCIBLE_TO_2_COLOR) && infoRec->CanDoMono8x8 &&
+ !(infoRec->FillMono8x8PatternSpansFlags & TRANSPARENCY_ONLY) &&
+ CHECK_ROP(pGC, infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC, infoRec->FillMono8x8PatternSpansFlags) &&
+ (!(infoRec->FillMono8x8PatternSpansFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(pPriv->fg) && CHECK_RGB_EQUAL(pPriv->bg))) &&
+ CHECK_PLANEMASK(pGC, infoRec->FillMono8x8PatternSpansFlags)) {
+
+ return DO_MONO_8x8;
+ }
+
+ if (infoRec->CanDoColor8x8 &&
+ CHECK_ROP(pGC, infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC, infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC, infoRec->FillColor8x8PatternSpansFlags)) {
+
+ return DO_COLOR_8x8;
+ }
+ }
+
+ if (infoRec->UsingPixmapCache && infoRec->FillCacheBltSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
+ CHECK_ROP(pGC, infoRec->FillCacheBltSpansFlags) &&
+ CHECK_ROPSRC(pGC, infoRec->FillCacheBltSpansFlags) &&
+ CHECK_PLANEMASK(pGC, infoRec->FillCacheBltSpansFlags)) {
+
+ return DO_CACHE_BLT;
+ }
+
+ if (infoRec->FillImageWriteRects &&
+ CHECK_NO_GXCOPY(pGC, infoRec->FillImageWriteRectsFlags) &&
+ CHECK_ROP(pGC, infoRec->FillImageWriteRectsFlags) &&
+ CHECK_ROPSRC(pGC, infoRec->FillImageWriteRectsFlags) &&
+ CHECK_PLANEMASK(pGC, infoRec->FillImageWriteRectsFlags)) {
+
+ return DO_IMAGE_WRITE;
+ }
+
+ return 0;
+}
+
+static int RotateMasksX[8] = {
+ 0xFFFFFFFF, 0x7F7F7F7F, 0x3F3F3F3F, 0x1F1F1F1F,
+ 0x0F0F0F0F, 0x07070707, 0x03030303, 0x01010101
+};
+
+static int RotateMasksY[4] = {
+ 0xFFFFFFFF, 0x00FFFFFF, 0x0000FFFF, 0x000000FF
+};
+
+void
+XAARotateMonoPattern(int *pat0, int *pat1, int xorg, int yorg, Bool msbfirst)
+{
+ int tmp, mask;
+
+ if (xorg) {
+ if (msbfirst)
+ xorg = 8 - xorg;
+ mask = RotateMasksX[xorg];
+ *pat0 = ((*pat0 >> xorg) & mask) | ((*pat0 << (8 - xorg)) & ~mask);
+ *pat1 = ((*pat1 >> xorg) & mask) | ((*pat1 << (8 - xorg)) & ~mask);
+ }
+ if (yorg >= 4) {
+ tmp = *pat0;
+ *pat0 = *pat1;
+ *pat1 = tmp;
+ yorg -= 4;
+ }
+ if (yorg) {
+ mask = RotateMasksY[yorg];
+ yorg <<= 3;
+ tmp = *pat0;
+ *pat0 = ((*pat0 >> yorg) & mask) | ((*pat1 << (32 - yorg)) & ~mask);
+ *pat1 = ((*pat1 >> yorg) & mask) | ((tmp << (32 - yorg)) & ~mask);
+ }
+}
+
+void
+XAAInvalidatePixmapCache(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr) infoRec->PixmapCachePrivate;
+ int i;
+
+ if (!pCachePriv)
+ return;
+
+ for (i = 0; i < pCachePriv->Num512x512; i++)
+ (pCachePriv->Info512)[i].serialNumber = 0;
+ for (i = 0; i < pCachePriv->Num256x256; i++)
+ (pCachePriv->Info256)[i].serialNumber = 0;
+ for (i = 0; i < pCachePriv->Num128x128; i++)
+ (pCachePriv->Info128)[i].serialNumber = 0;
+ for (i = 0; i < pCachePriv->NumPartial; i++)
+ (pCachePriv->InfoPartial)[i].serialNumber = 0;
+ for (i = 0; i < pCachePriv->NumMono; i++)
+ (pCachePriv->InfoMono)[i].serialNumber = 0;
+ for (i = 0; i < pCachePriv->NumColor; i++)
+ (pCachePriv->InfoColor)[i].serialNumber = 0;
+}