aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/kdrive/src/kaapict.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/kdrive/src/kaapict.c')
-rw-r--r--xorg-server/hw/kdrive/src/kaapict.c719
1 files changed, 719 insertions, 0 deletions
diff --git a/xorg-server/hw/kdrive/src/kaapict.c b/xorg-server/hw/kdrive/src/kaapict.c
new file mode 100644
index 000000000..501b6b9c4
--- /dev/null
+++ b/xorg-server/hw/kdrive/src/kaapict.c
@@ -0,0 +1,719 @@
+/*
+ * Copyright © 2001 Keith Packard
+ *
+ * Partly based on code that is Copyright © The XFree86 Project Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "kdrive.h"
+#include "kaa.h"
+
+#ifdef RENDER
+#include "mipict.h"
+
+#define KAA_DEBUG_FALLBACKS 0
+
+#if KAA_DEBUG_FALLBACKS
+static void kaaCompositeFallbackPictDesc(PicturePtr pict, char *string, int n)
+{
+ char format[20];
+ char size[20];
+ char loc;
+ int temp;
+
+ if (!pict) {
+ snprintf(string, n, "None");
+ return;
+ }
+
+ switch (pict->format)
+ {
+ case PICT_a8r8g8b8:
+ snprintf(format, 20, "ARGB8888");
+ break;
+ case PICT_r5g6b5:
+ snprintf(format, 20, "RGB565 ");
+ break;
+ case PICT_x1r5g5b5:
+ snprintf(format, 20, "RGB555 ");
+ break;
+ case PICT_a8:
+ snprintf(format, 20, "A8 ");
+ break;
+ case PICT_a1:
+ snprintf(format, 20, "A1 ");
+ break;
+ default:
+ snprintf(format, 20, "0x%x", (int)pict->format);
+ break;
+ }
+
+ loc = kaaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm';
+
+ snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
+ pict->pDrawable->height, pict->repeat ?
+ " R" : "");
+
+ snprintf(string, n, "0x%lx:%c fmt %s (%s)", (long)pict, loc, format, size);
+}
+
+static void
+kaaPrintCompositeFallback(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst)
+{
+ char sop[20];
+ char srcdesc[40], maskdesc[40], dstdesc[40];
+
+ switch(op)
+ {
+ case PictOpSrc:
+ sprintf(sop, "Src");
+ break;
+ case PictOpOver:
+ sprintf(sop, "Over");
+ break;
+ default:
+ sprintf(sop, "0x%x", (int)op);
+ break;
+ }
+
+ kaaCompositeFallbackPictDesc(pSrc, srcdesc, 40);
+ kaaCompositeFallbackPictDesc(pMask, maskdesc, 40);
+ kaaCompositeFallbackPictDesc(pDst, dstdesc, 40);
+
+ ErrorF("Composite fallback: op %s, \n"
+ " src %s, \n"
+ " mask %s, \n"
+ " dst %s, \n",
+ sop, srcdesc, maskdesc, dstdesc);
+}
+
+static void
+kaaPrintTrapezoidFallback(PicturePtr pDst)
+{
+ char dstdesc[40];
+
+ kaaCompositeFallbackPictDesc(pDst, dstdesc, 40);
+
+ ErrorF("Trapezoid fallback: dst %s, %c/%s\n",
+ dstdesc,
+ (pDst->polyMode == PolyModePrecise) ? 'p' : 'i',
+ (pDst->polyEdge == PolyEdgeSharp) ? "a" : "aa");
+}
+#endif
+
+static Bool
+kaaGetPixelFromRGBA(CARD32 *pixel,
+ CARD16 red,
+ CARD16 green,
+ CARD16 blue,
+ CARD16 alpha,
+ CARD32 format)
+{
+ int rbits, bbits, gbits, abits;
+ int rshift, bshift, gshift, ashift;
+
+ *pixel = 0;
+
+ if (!PICT_FORMAT_COLOR(format))
+ return FALSE;
+
+ rbits = PICT_FORMAT_R(format);
+ gbits = PICT_FORMAT_G(format);
+ bbits = PICT_FORMAT_B(format);
+ abits = PICT_FORMAT_A(format);
+
+ if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
+ bshift = 0;
+ gshift = bbits;
+ rshift = gshift + gbits;
+ ashift = rshift + rbits;
+ } else { /* PICT_TYPE_ABGR */
+ rshift = 0;
+ gshift = rbits;
+ bshift = gshift + gbits;
+ ashift = bshift + bbits;
+ }
+
+ *pixel |= ( blue >> (16 - bbits)) << bshift;
+ *pixel |= ( red >> (16 - rbits)) << rshift;
+ *pixel |= (green >> (16 - gbits)) << gshift;
+ *pixel |= (alpha >> (16 - abits)) << ashift;
+
+ return TRUE;
+}
+
+
+static Bool
+kaaGetRGBAFromPixel(CARD32 pixel,
+ CARD16 *red,
+ CARD16 *green,
+ CARD16 *blue,
+ CARD16 *alpha,
+ CARD32 format)
+{
+ int rbits, bbits, gbits, abits;
+ int rshift, bshift, gshift, ashift;
+
+ if (!PICT_FORMAT_COLOR(format))
+ return FALSE;
+
+ rbits = PICT_FORMAT_R(format);
+ gbits = PICT_FORMAT_G(format);
+ bbits = PICT_FORMAT_B(format);
+ abits = PICT_FORMAT_A(format);
+
+ if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
+ bshift = 0;
+ gshift = bbits;
+ rshift = gshift + gbits;
+ ashift = rshift + rbits;
+ } else { /* PICT_TYPE_ABGR */
+ rshift = 0;
+ gshift = rbits;
+ bshift = gshift + gbits;
+ ashift = bshift + bbits;
+ }
+
+ *red = ((pixel >> rshift ) & ((1 << rbits) - 1)) << (16 - rbits);
+ while (rbits < 16) {
+ *red |= *red >> rbits;
+ rbits <<= 1;
+ }
+
+ *green = ((pixel >> gshift ) & ((1 << gbits) - 1)) << (16 - gbits);
+ while (gbits < 16) {
+ *green |= *green >> gbits;
+ gbits <<= 1;
+ }
+
+ *blue = ((pixel >> bshift ) & ((1 << bbits) - 1)) << (16 - bbits);
+ while (bbits < 16) {
+ *blue |= *blue >> bbits;
+ bbits <<= 1;
+ }
+
+ if (abits) {
+ *alpha = ((pixel >> ashift ) & ((1 << abits) - 1)) << (16 - abits);
+ while (abits < 16) {
+ *alpha |= *alpha >> abits;
+ abits <<= 1;
+ }
+ } else
+ *alpha = 0xffff;
+
+ return TRUE;
+}
+
+static int
+kaaTryDriverSolidFill(PicturePtr pSrc,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ KaaScreenPriv (pDst->pDrawable->pScreen);
+ RegionRec region;
+ BoxPtr pbox;
+ int nbox;
+ int dst_off_x, dst_off_y;
+ PixmapPtr pSrcPix, pDstPix;
+ CARD32 pixel;
+ CARD16 red, green, blue, alpha;
+
+ xDst += pDst->pDrawable->x;
+ yDst += pDst->pDrawable->y;
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
+
+ if (!miComputeCompositeRegion (&region, pSrc, NULL, pDst,
+ xSrc, ySrc, 0, 0, xDst, yDst,
+ width, height))
+ return 1;
+
+ if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
+ kaaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable);
+ if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
+ kaaPixmapUseScreen ((PixmapPtr) pDst->pDrawable);
+
+ pDstPix = kaaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
+ if (!pDstPix) {
+ REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+ return 0;
+ }
+
+ if (pSrc->pDrawable->type == DRAWABLE_WINDOW)
+ pSrcPix = (*pSrc->pDrawable->pScreen->GetWindowPixmap)(
+ (WindowPtr) (pSrc->pDrawable));
+ else
+ pSrcPix = (PixmapPtr) (pSrc->pDrawable);
+
+ /* If source is offscreen, we need to sync the accelerator
+ * before accessing it. We'd prefer for it to be in memory.
+ */
+ if (kaaPixmapIsOffscreen(pSrcPix)) {
+ kaaWaitSync(pDst->pDrawable->pScreen);
+ }
+
+ pixel = *(CARD32 *)(pSrcPix->devPrivate.ptr);
+ if (!kaaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
+ pSrc->format))
+ {
+ REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+ return -1;
+ }
+ kaaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
+ pDst->format);
+
+ if (!(*pKaaScr->info->PrepareSolid) (pDstPix, GXcopy, 0xffffffff, pixel))
+ {
+ REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+ return -1;
+ }
+
+ nbox = REGION_NUM_RECTS(&region);
+ pbox = REGION_RECTS(&region);
+ while (nbox--)
+ {
+ (*pKaaScr->info->Solid) (pbox->x1 + dst_off_x,
+ pbox->y1 + dst_off_y,
+ pbox->x2 + dst_off_x,
+ pbox->y2 + dst_off_y);
+ pbox++;
+ }
+
+ (*pKaaScr->info->DoneSolid) ();
+ kaaMarkSync (pDst->pDrawable->pScreen);
+ kaaDrawableDirty (pDst->pDrawable);
+
+ REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+ return 1;
+}
+
+static int
+kaaTryDriverBlend(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ KaaScreenPriv (pDst->pDrawable->pScreen);
+ RegionRec region;
+ BoxPtr pbox;
+ int nbox;
+ int src_off_x, src_off_y, dst_off_x, dst_off_y;
+ PixmapPtr pSrcPix, pDstPix;
+ struct _Pixmap srcScratch;
+
+ xDst += pDst->pDrawable->x;
+ yDst += pDst->pDrawable->y;
+
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
+
+ if (!miComputeCompositeRegion (&region, pSrc, NULL, pDst,
+ xSrc, ySrc, 0, 0, xDst, yDst,
+ width, height))
+ return 1;
+
+
+ if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
+ kaaPixmapUseScreen ((PixmapPtr) pSrc->pDrawable);
+ if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
+ kaaPixmapUseScreen ((PixmapPtr) pDst->pDrawable);
+
+ pSrcPix = kaaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
+ pDstPix = kaaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
+
+ if (!pDstPix) {
+ REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+ return 0;
+ }
+
+ if (!pSrcPix && pKaaScr->info->UploadToScratch) {
+ if ((*pKaaScr->info->UploadToScratch) ((PixmapPtr) pSrc->pDrawable,
+ &srcScratch))
+ pSrcPix = &srcScratch;
+ }
+
+ if (!pSrcPix) {
+ REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+ return 0;
+ }
+
+ if (!(*pKaaScr->info->PrepareBlend) (op, pSrc, pDst, pSrcPix,
+ pDstPix))
+ {
+ REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+ return -1;
+ }
+
+ nbox = REGION_NUM_RECTS(&region);
+ pbox = REGION_RECTS(&region);
+
+ xSrc -= xDst;
+ ySrc -= yDst;
+
+ while (nbox--)
+ {
+ (*pKaaScr->info->Blend) (pbox->x1 + xSrc + src_off_x,
+ pbox->y1 + ySrc + src_off_y,
+ pbox->x1 + dst_off_x,
+ pbox->y1 + dst_off_y,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ pbox++;
+ }
+
+ (*pKaaScr->info->DoneBlend) ();
+ kaaMarkSync (pDst->pDrawable->pScreen);
+ kaaDrawableDirty (pDst->pDrawable);
+
+ REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+ return 1;
+}
+
+static int
+kaaTryDriverComposite(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ KaaScreenPriv (pDst->pDrawable->pScreen);
+ RegionRec region;
+ BoxPtr pbox;
+ int nbox;
+ int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
+ PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
+ struct _Pixmap scratch;
+
+ xDst += pDst->pDrawable->x;
+ yDst += pDst->pDrawable->y;
+
+ if (pMask) {
+ xMask += pMask->pDrawable->x;
+ yMask += pMask->pDrawable->y;
+ }
+
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
+
+ if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ width, height))
+ return 1;
+
+ if (pKaaScr->info->CheckComposite &&
+ !(*pKaaScr->info->CheckComposite) (op, pSrc, pMask, pDst))
+ {
+ REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+ return -1;
+ }
+
+ if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
+ kaaPixmapUseScreen ((PixmapPtr) pSrc->pDrawable);
+ if (pMask && pMask->pDrawable->type == DRAWABLE_PIXMAP)
+ kaaPixmapUseScreen ((PixmapPtr) pMask->pDrawable);
+ if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
+ kaaPixmapUseScreen ((PixmapPtr) pDst->pDrawable);
+
+ pSrcPix = kaaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
+ if (pMask)
+ pMaskPix = kaaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x,
+ &mask_off_y);
+ pDstPix = kaaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
+
+ if (!pDstPix) {
+ REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+ return 0;
+ }
+
+ if (!pSrcPix && (!pMask || pMaskPix) && pKaaScr->info->UploadToScratch) {
+ if (pSrc->pDrawable->type == DRAWABLE_WINDOW)
+ pSrcPix = (*pSrc->pDrawable->pScreen->GetWindowPixmap) (
+ (WindowPtr) pSrc->pDrawable);
+ else
+ pSrcPix = (PixmapPtr) pSrc->pDrawable;
+ if ((*pKaaScr->info->UploadToScratch) (pSrcPix, &scratch))
+ pSrcPix = &scratch;
+ } else if (pSrcPix && pMask && !pMaskPix && pKaaScr->info->UploadToScratch) {
+ if (pMask->pDrawable->type == DRAWABLE_WINDOW)
+ pMaskPix = (*pMask->pDrawable->pScreen->GetWindowPixmap) (
+ (WindowPtr) pMask->pDrawable);
+ else
+ pMaskPix = (PixmapPtr) pMask->pDrawable;
+ if ((*pKaaScr->info->UploadToScratch) (pMaskPix, &scratch))
+ pMaskPix = &scratch;
+ }
+
+ if (!pSrcPix || (pMask && !pMaskPix)) {
+ REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+ return 0;
+ }
+
+ if (!(*pKaaScr->info->PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix,
+ pMaskPix, pDstPix))
+ {
+ REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+ return -1;
+ }
+
+ nbox = REGION_NUM_RECTS(&region);
+ pbox = REGION_RECTS(&region);
+
+ xMask -= xDst;
+ yMask -= yDst;
+
+ xSrc -= xDst;
+ ySrc -= yDst;
+
+ while (nbox--)
+ {
+ (*pKaaScr->info->Composite) (pbox->x1 + xSrc + src_off_x,
+ pbox->y1 + ySrc + src_off_y,
+ pbox->x1 + xMask + mask_off_x,
+ pbox->y1 + yMask + mask_off_y,
+ pbox->x1 + dst_off_x,
+ pbox->y1 + dst_off_y,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ pbox++;
+ }
+
+ (*pKaaScr->info->DoneComposite) ();
+ kaaMarkSync (pDst->pDrawable->pScreen);
+ kaaDrawableDirty (pDst->pDrawable);
+
+ REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+ return 1;
+}
+
+
+void
+kaaComposite(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ KdScreenPriv (pDst->pDrawable->pScreen);
+ KaaScreenPriv (pDst->pDrawable->pScreen);
+ int ret = -1;
+
+ if (!pMask && pSrc->pDrawable)
+ {
+ if (op == PictOpSrc)
+ {
+ if (pScreenPriv->enabled && pSrc->pDrawable && pSrc->pDrawable->width == 1 &&
+ pSrc->pDrawable->height == 1 && pSrc->repeat)
+ {
+ ret = kaaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
+ width, height);
+ if (ret == 1)
+ return;
+ }
+ else if (!pSrc->repeat && !pSrc->transform &&
+ pSrc->format == pDst->format)
+ {
+ RegionRec region;
+
+ xDst += pDst->pDrawable->x;
+ yDst += pDst->pDrawable->y;
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
+
+ if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst,
+ yDst, width, height))
+ return;
+
+
+ kaaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, 0,
+ REGION_RECTS(&region), REGION_NUM_RECTS(&region),
+ xSrc - xDst, ySrc - yDst,
+ FALSE, FALSE, 0, 0);
+ return;
+ }
+ }
+
+ if (pScreenPriv->enabled && pKaaScr->info->PrepareBlend &&
+ !pSrc->alphaMap && !pDst->alphaMap)
+ {
+ ret = kaaTryDriverBlend(op, pSrc, pDst, xSrc, ySrc, xDst, yDst,
+ width, height);
+ if (ret == 1)
+ return;
+ }
+ }
+
+ if (pSrc->pDrawable && (!pMask || pMask->pDrawable) &&
+ pScreenPriv->enabled && pKaaScr->info->PrepareComposite &&
+ !pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap)
+ {
+ ret = kaaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask,
+ yMask, xDst, yDst, width, height);
+ if (ret == 1)
+ return;
+ }
+
+ if (ret != 0) {
+ /* failure to accelerate was not due to pixmaps being in the wrong
+ * locations.
+ */
+ if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
+ kaaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable);
+ if (pMask && pMask->pDrawable->type == DRAWABLE_PIXMAP)
+ kaaPixmapUseMemory ((PixmapPtr) pMask->pDrawable);
+ if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
+ kaaPixmapUseMemory ((PixmapPtr) pDst->pDrawable);
+ }
+
+#if KAA_DEBUG_FALLBACKS
+ kaaPrintCompositeFallback (op, pSrc, pMask, pDst);
+#endif
+
+ KdCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
+ xMask, yMask, xDst, yDst, width, height);
+}
+#endif
+
+static xFixed
+miLineFixedX (xLineFixed *l, xFixed y, Bool ceil)
+{
+ xFixed dx = l->p2.x - l->p1.x;
+ xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx;
+ xFixed dy = l->p2.y - l->p1.y;
+ if (ceil)
+ ex += (dy - 1);
+ return l->p1.x + (xFixed) (ex / dy);
+}
+
+/* Need to decide just how much to trim, to maintain translation independence
+ * when converted to floating point.
+ */
+#define XFIXED_TO_FLOAT(x) (((float)((x) & 0xffffff00)) / 65536.0)
+
+/* This is just to allow us to work on the hardware side of the problem while
+ * waiting for cairo to get a new tesselator. We may not be able to support
+ * RasterizeTrapezoid at all due to the abutting edges requirement, but it might
+ * be technically legal if we widened the trap by some epsilon, so that alpha
+ * values at abutting edges were a little too big and capped at one, rather than
+ * a little too small and looked bad.
+ */
+void kaaRasterizeTrapezoid(PicturePtr pDst,
+ xTrapezoid *trap,
+ int xoff,
+ int yoff)
+{
+ KdScreenPriv (pDst->pDrawable->pScreen);
+ KaaScreenPriv (pDst->pDrawable->pScreen);
+ KaaTrapezoid ktrap;
+ PixmapPtr pPix;
+ xFixed x1, x2;
+
+ if (!pScreenPriv->enabled ||
+ !pKaaScr->info->PrepareTrapezoids ||
+ pDst->pDrawable->type != DRAWABLE_PIXMAP ||
+ pDst->alphaMap || pDst->format != PICT_a8)
+ {
+ KdCheckRasterizeTrapezoid (pDst, trap, xoff, yoff);
+#if KAA_DEBUG_FALLBACKS
+ kaaPrintTrapezoidFallback (pDst);
+#endif
+ return;
+ }
+ pPix = (PixmapPtr)pDst->pDrawable;
+
+ kaaPixmapUseScreen (pPix);
+
+ if (!kaaPixmapIsOffscreen (pPix) ||
+ !(*pKaaScr->info->PrepareTrapezoids) (pDst, pPix))
+ {
+#if KAA_DEBUG_FALLBACKS
+ kaaPrintTrapezoidFallback (pDst);
+#endif
+ KdCheckRasterizeTrapezoid (pDst, trap, xoff, yoff);
+ return;
+ }
+
+ ktrap.ty = XFIXED_TO_FLOAT(trap->top) + yoff;
+ x1 = miLineFixedX (&trap->left, trap->top, FALSE);
+ x2 = miLineFixedX (&trap->right, trap->top, TRUE);
+ ktrap.tl = XFIXED_TO_FLOAT(x1) + xoff;
+ ktrap.tr = XFIXED_TO_FLOAT(x2) + xoff;
+ ktrap.by = XFIXED_TO_FLOAT(trap->bottom) + yoff;
+ x1 = miLineFixedX (&trap->left, trap->bottom, FALSE);
+ x2 = miLineFixedX (&trap->right, trap->bottom, TRUE);
+ ktrap.bl = XFIXED_TO_FLOAT(x1) + xoff;
+ ktrap.br = XFIXED_TO_FLOAT(x2) + xoff;
+
+ (*pKaaScr->info->Trapezoids) (&ktrap, 1);
+ (*pKaaScr->info->DoneTrapezoids) ();
+}
+
+void
+kaaInitTrapOffsets(int grid_order, float *x_offsets, float *y_offsets,
+ float x_offset, float y_offset)
+{
+ int i = 0;
+ float x, y, x_count, y_count;
+
+ x_count = (1 << (grid_order / 2)) + 1;
+ y_count = (1 << (grid_order / 2)) - 1;
+
+ x_offset += 1.0 / x_count / 2.0;
+ y_offset += 1.0 / y_count / 2.0;
+
+ for (x = 0; x < x_count; x++) {
+ for (y = 0; y < y_count; y++) {
+ x_offsets[i] = x / x_count + x_offset;
+ y_offsets[i] = y / y_count + y_offset;
+ i++;
+ }
+ }
+}
+