summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/render/picture.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/programs/Xserver/render/picture.c')
-rw-r--r--xc/programs/Xserver/render/picture.c437
1 files changed, 337 insertions, 100 deletions
diff --git a/xc/programs/Xserver/render/picture.c b/xc/programs/Xserver/render/picture.c
index 1b234580b..1eabd4f27 100644
--- a/xc/programs/Xserver/render/picture.c
+++ b/xc/programs/Xserver/render/picture.c
@@ -1,5 +1,5 @@
/*
- * $XFree86: xc/programs/Xserver/render/picture.c,v 1.12 2000/12/07 23:54:04 keithp Exp $
+ * $XFree86: xc/programs/Xserver/render/picture.c,v 1.18 2001/08/10 22:25:59 keithp Exp $
*
* Copyright © 2000 SuSE, Inc.
*
@@ -71,122 +71,345 @@ PictureCloseScreen (int index, ScreenPtr pScreen)
{
PictureScreenPtr ps = GetPictureScreen(pScreen);
Bool ret;
+ int n;
pScreen->CloseScreen = ps->CloseScreen;
ret = (*pScreen->CloseScreen) (index, pScreen);
+ for (n = 0; n < ps->nformats; n++)
+ if (ps->formats[n].type == PictTypeIndexed)
+ (*ps->CloseIndexed) (pScreen, &ps->formats[n]);
SetPictureScreen(pScreen, 0);
xfree (ps->formats);
xfree (ps);
return ret;
}
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef)
+{
+ ScreenPtr pScreen = pColormap->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ pScreen->StoreColors = ps->StoreColors;
+ (*pScreen->StoreColors) (pColormap, ndef, pdef);
+ ps->StoreColors = pScreen->StoreColors;
+ pScreen->StoreColors = PictureStoreColors;
+
+ if (pColormap->class == PseudoColor || pColormap->class == GrayScale)
+ {
+ PictFormatPtr format = ps->formats;
+ int nformats = ps->nformats;
+
+ while (nformats--)
+ {
+ if (format->pColormap == pColormap)
+ {
+ (*ps->UpdateIndexed) (pScreen, format, ndef, pdef);
+ break;
+ }
+ format++;
+ }
+ }
+}
+
+static int
+visualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+ int d, v;
+ DepthPtr pDepth;
+
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = &pScreen->allowedDepths[d];
+ for (v = 0; v < pDepth->numVids; v++)
+ if (pDepth->vids[v] == pVisual->vid)
+ return pDepth->depth;
+ }
+ return 0;
+}
+
+typedef struct _formatInit {
+ CARD32 format;
+ CARD8 depth;
+} FormatInitRec, *FormatInitPtr;
+
+static int
+addFormat (FormatInitRec formats[256],
+ int nformat,
+ CARD32 format,
+ CARD8 depth)
+{
+ int n;
+
+ for (n = 0; n < nformat; n++)
+ if (formats[n].format == format && formats[n].depth == depth)
+ return nformat;
+ formats[nformat].format = format;
+ formats[nformat].depth = depth;
+ return ++nformat;
+}
+
+#define Mask(n) ((n) == 32 ? 0xffffffff : ((1 << (n))-1))
+
PictFormatPtr
PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
{
- int nformats;
+ int nformats, f;
PictFormatPtr pFormats;
+ FormatInitRec formats[1024];
+ CARD32 format;
+ CARD8 depth;
int i;
+ VisualPtr pVisual;
+ int v;
+ int bpp;
+ int type;
+ int r, g, b;
+ int d;
+ DepthPtr pDepth;
+
+ nformats = 0;
+ /* formats required by protocol */
+ formats[nformats].format = PICT_a8r8g8b8;
+ formats[nformats].depth = 32;
+ nformats++;
+ formats[nformats].format = PICT_x8r8g8b8;
+ formats[nformats].depth = 32;
+ nformats++;
+ formats[nformats].format = PICT_a1;
+ formats[nformats].depth = 1;
+ nformats++;
+ formats[nformats].format = PICT_a4;
+ formats[nformats].depth = 4;
+ nformats++;
+ formats[nformats].format = PICT_a8;
+ formats[nformats].depth = 8;
+ nformats++;
+
+ /* now look through the depths and visuals adding other formats */
+ for (v = 0; v < pScreen->numVisuals; v++)
+ {
+ pVisual = &pScreen->visuals[v];
+ depth = visualDepth (pScreen, pVisual);
+ if (!depth)
+ continue;
+ bpp = BitsPerPixel (depth);
+ switch (pVisual->class) {
+ case DirectColor:
+ case TrueColor:
+ r = Ones (pVisual->redMask);
+ g = Ones (pVisual->greenMask);
+ b = Ones (pVisual->blueMask);
+ type = PICT_TYPE_OTHER;
+ /*
+ * Current rendering code supports only two direct formats,
+ * fields must be packed together at the bottom of the pixel
+ * and must be either RGB or BGR
+ */
+ if (pVisual->offsetBlue == 0 &&
+ pVisual->offsetGreen == b &&
+ pVisual->offsetRed == b + g)
+ {
+ type = PICT_TYPE_ARGB;
+ }
+ else if (pVisual->offsetRed == 0 &&
+ pVisual->offsetGreen == r &&
+ pVisual->offsetBlue == r + g)
+ {
+ type = PICT_TYPE_ABGR;
+ }
+ if (type != PICT_TYPE_OTHER)
+ {
+ format = PICT_FORMAT(bpp, type, 0, r, g, b);
+ nformats = addFormat (formats, nformats, format, depth);
+ }
+ break;
+ case StaticColor:
+ case PseudoColor:
+ format = PICT_FORMAT (bpp, PICT_TYPE_COLOR, v, 0, 0, 0);
+ nformats = addFormat (formats, nformats, format, depth);
+ break;
+ case StaticGray:
+ case GrayScale:
+ format = PICT_FORMAT (bpp, PICT_TYPE_GRAY, v, 0, 0, 0);
+ nformats = addFormat (formats, nformats, format, depth);
+ break;
+ }
+ }
+ /*
+ * Walk supported depths and add useful Direct formats
+ */
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = &pScreen->allowedDepths[d];
+ bpp = BitsPerPixel (pDepth->depth);
+ format = 0;
+ switch (bpp) {
+ case 16:
+ /* depth 15 formats */
+ if (pDepth->depth >= 15)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_x1r5g5b5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_x1b5g5r5, pDepth->depth);
+ }
+ /* depth 16 formats */
+ if (pDepth->depth >= 16)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_a1r5g5b5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_a1b5g5r5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_r5g6b5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_b5g6r5, pDepth->depth);
+ }
+ break;
+ case 24:
+ if (pDepth->depth >= 24)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_r8g8b8, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_b8g8r8, pDepth->depth);
+ }
+ break;
+ case 32:
+ if (pDepth->depth >= 24)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_x8r8g8b8, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_x8b8g8r8, pDepth->depth);
+ }
+ break;
+ }
+ }
+
- nformats = 7;
pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec));
if (!pFormats)
return 0;
- i = 0;
- pFormats[i].id = FakeClientID (0);
- pFormats[i].type = PictTypeDirect;
- pFormats[i].depth = 32;
- pFormats[i].direct.red = 16;
- pFormats[i].direct.redMask = 0xff;
- pFormats[i].direct.green = 8;
- pFormats[i].direct.greenMask = 0xff;
- pFormats[i].direct.blue = 0;
- pFormats[i].direct.blueMask = 0xff;
- pFormats[i].direct.alpha = 24;
- pFormats[i].direct.alphaMask = 0xff;
- pFormats[i].pColormap = 0;
- i++;
- pFormats[i].id = FakeClientID (0);
- pFormats[i].type = PictTypeDirect;
- pFormats[i].depth = 8;
- pFormats[i].direct.red = 0;
- pFormats[i].direct.redMask = 0;
- pFormats[i].direct.green = 0;
- pFormats[i].direct.greenMask = 0;
- pFormats[i].direct.blue = 0;
- pFormats[i].direct.blueMask = 0;
- pFormats[i].direct.alpha = 0;
- pFormats[i].direct.alphaMask = 0xff;
- pFormats[i].pColormap = 0;
- i++;
- pFormats[i].id = FakeClientID (0);
- pFormats[i].type = PictTypeDirect;
- pFormats[i].depth = 24;
- pFormats[i].direct.red = 16;
- pFormats[i].direct.redMask = 0xff;
- pFormats[i].direct.green = 8;
- pFormats[i].direct.greenMask = 0xff;
- pFormats[i].direct.blue = 0;
- pFormats[i].direct.blueMask = 0xff;
- pFormats[i].direct.alpha = 0;
- pFormats[i].direct.alphaMask = 0x0;
- pFormats[i].pColormap = 0;
- i++;
- pFormats[i].id = FakeClientID (0);
- pFormats[i].type = PictTypeDirect;
- pFormats[i].depth = 16;
- pFormats[i].direct.red = 11;
- pFormats[i].direct.redMask = 0x1f;
- pFormats[i].direct.green = 5;
- pFormats[i].direct.greenMask = 0x3f;
- pFormats[i].direct.blue = 0;
- pFormats[i].direct.blueMask = 0x1f;
- pFormats[i].direct.alpha = 0;
- pFormats[i].direct.alphaMask = 0x0;
- pFormats[i].pColormap = 0;
- i++;
- pFormats[i].id = FakeClientID (0);
- pFormats[i].type = PictTypeDirect;
- pFormats[i].depth = 15;
- pFormats[i].direct.red = 10;
- pFormats[i].direct.redMask = 0x1f;
- pFormats[i].direct.green = 5;
- pFormats[i].direct.greenMask = 0x1f;
- pFormats[i].direct.blue = 0;
- pFormats[i].direct.blueMask = 0x1f;
- pFormats[i].direct.alpha = 0;
- pFormats[i].direct.alphaMask = 0x0;
- pFormats[i].pColormap = 0;
- i++;
- pFormats[i].id = FakeClientID (0);
- pFormats[i].type = PictTypeDirect;
- pFormats[i].depth = 16;
- pFormats[i].direct.red = 10;
- pFormats[i].direct.redMask = 0x1f;
- pFormats[i].direct.green = 5;
- pFormats[i].direct.greenMask = 0x1f;
- pFormats[i].direct.blue = 0;
- pFormats[i].direct.blueMask = 0x1f;
- pFormats[i].direct.alpha = 15;
- pFormats[i].direct.alphaMask = 0x1;
- pFormats[i].pColormap = 0;
- i++;
- pFormats[i].id = FakeClientID (0);
- pFormats[i].type = PictTypeDirect;
- pFormats[i].depth = 1;
- pFormats[i].direct.red = 0;
- pFormats[i].direct.redMask = 0;
- pFormats[i].direct.green = 0;
- pFormats[i].direct.greenMask = 0;
- pFormats[i].direct.blue = 0;
- pFormats[i].direct.blueMask = 0;
- pFormats[i].direct.alpha = 0;
- pFormats[i].direct.alphaMask = 0x1;
- pFormats[i].pColormap = 0;
- i++;
- *nformatp = i;
+ memset (pFormats, '\0', nformats * sizeof (PictFormatRec));
+ for (f = 0; f < nformats; f++)
+ {
+ pFormats[f].id = FakeClientID (0);
+ pFormats[f].depth = formats[f].depth;
+ format = formats[f].format;
+ pFormats[f].format = format;
+ switch (PICT_FORMAT_TYPE(format)) {
+ case PICT_TYPE_ARGB:
+ pFormats[f].type = PictTypeDirect;
+
+ pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+ if (pFormats[f].direct.alphaMask)
+ pFormats[f].direct.alpha = (PICT_FORMAT_R(format) +
+ PICT_FORMAT_G(format) +
+ PICT_FORMAT_B(format));
+
+ pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+ pFormats[f].direct.red = (PICT_FORMAT_G(format) +
+ PICT_FORMAT_B(format));
+
+ pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+ pFormats[f].direct.green = PICT_FORMAT_B(format);
+
+ pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+ pFormats[f].direct.blue = 0;
+ break;
+
+ case PICT_TYPE_ABGR:
+ pFormats[f].type = PictTypeDirect;
+
+ pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+ if (pFormats[f].direct.alphaMask)
+ pFormats[f].direct.alpha = (PICT_FORMAT_B(format) +
+ PICT_FORMAT_G(format) +
+ PICT_FORMAT_R(format));
+
+ pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+ pFormats[f].direct.blue = (PICT_FORMAT_G(format) +
+ PICT_FORMAT_R(format));
+
+ pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+ pFormats[f].direct.green = PICT_FORMAT_R(format);
+
+ pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+ pFormats[f].direct.red = 0;
+ break;
+
+ case PICT_TYPE_A:
+ pFormats[f].type = PictTypeDirect;
+
+ pFormats[f].direct.alpha = 0;
+ pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+
+ /* remaining fields already set to zero */
+ break;
+
+ case PICT_TYPE_COLOR:
+ case PICT_TYPE_GRAY:
+ pFormats[f].type = PictTypeIndexed;
+ pFormats[f].format = PICT_FORMAT(PICT_FORMAT_BPP(format),
+ PICT_FORMAT_TYPE(format),
+ 0, 0, 0, 0);
+ pFormats[f].pVisual = &pScreen->visuals[PICT_FORMAT_A(format)];
+ break;
+ }
+ }
+ *nformatp = nformats;
return pFormats;
}
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+ PictFormatPtr format;
+ int nformat;
+
+ if (!ps)
+ return FALSE;
+ format = ps->formats;
+ nformat = ps->nformats;
+ while (nformat--)
+ {
+ if (format->type == PictTypeIndexed && !format->pColormap)
+ {
+ if (format->pVisual->vid == pScreen->rootVisual)
+ format->pColormap = (ColormapPtr) LookupIDByType(pScreen->defColormap,
+ RT_COLORMAP);
+ else
+ {
+ if (CreateColormap (FakeClientID (0), pScreen,
+ format->pVisual,
+ &format->pColormap, AllocNone,
+ 0) != Success)
+ {
+ return FALSE;
+ }
+ }
+ if (!(*ps->InitIndexed) (pScreen, format))
+ return FALSE;
+ }
+ format++;
+ }
+ return TRUE;
+}
+
+Bool
+PictureFinishInit (void)
+{
+ int s;
+
+ for (s = 0; s < screenInfo.numScreens; s++)
+ if (!PictureInitIndexedFormats (screenInfo.screens[s]))
+ return FALSE;
+ return TRUE;
+}
+
PictFormatPtr
PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual)
{
@@ -219,7 +442,7 @@ PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual)
{
if (type == PictTypeIndexed)
{
- if (format->pColormap && format->pColormap->pVisual == pVisual)
+ if (format->pVisual == pVisual)
return format;
}
else
@@ -302,7 +525,10 @@ PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
}
if (formats[n].type == PictTypeIndexed)
{
- type = PICT_TYPE_INDEX;
+ if ((formats[n].pVisual->class | DynamicClass) == PseudoColor)
+ type = PICT_TYPE_COLOR;
+ else
+ type = PICT_TYPE_GRAY;
a = r = g = b = 0;
}
else
@@ -347,8 +573,10 @@ PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
ps->CloseScreen = pScreen->CloseScreen;
ps->DestroyWindow = pScreen->DestroyWindow;
+ ps->StoreColors = pScreen->StoreColors;
pScreen->DestroyWindow = PictureDestroyWindow;
pScreen->CloseScreen = PictureCloseScreen;
+ pScreen->StoreColors = PictureStoreColors;
return TRUE;
}
@@ -364,6 +592,7 @@ SetPictureToDefaults (PicturePtr pPicture)
pPicture->polyMode = PolyModePrecise;
pPicture->freeCompClip = FALSE;
pPicture->clientClipType = CT_NONE;
+ pPicture->componentAlpha = FALSE;
pPicture->alphaMap = 0;
pPicture->alphaOrigin.x = 0;
@@ -715,8 +944,8 @@ SetPictureClipRects (PicturePtr pPicture,
return result;
}
-void
-ValidatePicture(PicturePtr pPicture)
+static void
+ValidateOnePicture (PicturePtr pPicture)
{
if (pPicture->serialNumber != pPicture->pDrawable->serialNumber)
{
@@ -728,6 +957,14 @@ ValidatePicture(PicturePtr pPicture)
}
}
+void
+ValidatePicture(PicturePtr pPicture)
+{
+ ValidateOnePicture (pPicture);
+ if (pPicture->alphaMap)
+ ValidateOnePicture (pPicture->alphaMap);
+}
+
int
FreePicture (pointer value,
XID pid)