+++ /dev/null
-/*
- * Support for RENDER extension with rootless
- */
-/*
- * Copyright (c) 2002 Torrey T. Lyons. All Rights Reserved.
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the sale,
- * use or other dealings in this Software without prior written authorization.
- */
-/* This file is largely based on fbcompose.c and fbpict.c, which contain
- * the following copyright:
- *
- * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
- */
- /* $XFree86: xc/programs/Xserver/hw/darwin/quartz/aquaPicture.c,v 1.3 2002/09/28 00:00:03 torrey Exp $ */
-
-#define DEFAULT_LOG_FORMATS 0
-
-#ifdef RENDER
-
-#include "fb.h"
-#include "picturestr.h"
-#include "mipict.h"
-#include "fbpict.h"
-#include "rootless.h"
-
-# define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
-
-
-// Replacement for fbStore_x8r8g8b8 that sets the alpha channel
-void
-RootlessStore_x8r8g8b8 (FbCompositeOperand *op, CARD32 value)
-{
- FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
- ((CARD32 *)line)[offset >> 5] = (value & 0xffffff) | 0xff000000;
-}
-
-
-// Defined in fbcompose.c
-extern FbCombineFunc fbCombineFuncU[];
-extern FbCombineFunc fbCombineFuncC[];
-
-void
-RootlessCompositeGeneral(
- CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height)
-{
- FbCompositeOperand src[4],msk[4],dst[4],*pmsk;
- FbCompositeOperand *srcPict, *srcAlpha;
- FbCompositeOperand *dstPict, *dstAlpha;
- FbCompositeOperand *mskPict = 0, *mskAlpha = 0;
- FbCombineFunc f;
- int w;
-
- if (!fbBuildCompositeOperand (pSrc, src, xSrc, ySrc, TRUE, TRUE))
- return;
- if (!fbBuildCompositeOperand (pDst, dst, xDst, yDst, FALSE, TRUE))
- return;
-
- // Use Rootless operands for on screen picture formats
- if (pDst->format == PICT_x8r8g8b8) {
- dst[0].store = RootlessStore_x8r8g8b8;
- }
-
- if (pSrc->alphaMap)
- {
- srcPict = &src[1];
- srcAlpha = &src[2];
- }
- else
- {
- srcPict = &src[0];
- srcAlpha = 0;
- }
- if (pDst->alphaMap)
- {
- dstPict = &dst[1];
- dstAlpha = &dst[2];
- }
- else
- {
- dstPict = &dst[0];
- dstAlpha = 0;
- }
- f = fbCombineFuncU[op];
- if (pMask)
- {
- if (!fbBuildCompositeOperand (pMask, msk, xMask, yMask, TRUE, TRUE))
- return;
- pmsk = msk;
- if (pMask->componentAlpha)
- f = fbCombineFuncC[op];
- if (pMask->alphaMap)
- {
- mskPict = &msk[1];
- mskAlpha = &msk[2];
- }
- else
- {
- mskPict = &msk[0];
- mskAlpha = 0;
- }
- }
- else
- pmsk = 0;
- while (height--)
- {
- w = width;
-
- while (w--)
- {
- (*f) (src, pmsk, dst);
- (*src->over) (src);
- (*dst->over) (dst);
- if (pmsk)
- (*pmsk->over) (pmsk);
- }
- (*src->down) (src);
- (*dst->down) (dst);
- if (pmsk)
- (*pmsk->down) (pmsk);
- }
-}
-
-static int rootless_log_pict_formats = DEFAULT_LOG_FORMATS;
-
-static const char *op_name (int op)
-{
- static const char *ops[] = {
- "Clear", "Src", "Dst", "Over", "OverReverse", "In", "InReverse",
- "Out", "OutReverse", "Atop", "AtopReverse", "Xor", "Add",
- "Saturate", "Maximum",
-
- "DisjointClear", "DisjointSrc", "DisjointDst", "DisjointOver",
- "DisjointOverReverse", "DisjointIn", "DisjointInReverse",
- "DisjointOut", "DisjointOutReverse", "DisjointAtop",
- "DisjointAtopReverse", "DisjointXor", "DisjointMaximum",
-
- "ConjointClear", "ConjointSrc", "ConjointDst", "ConjointOver",
- "ConjointOverReverse", "ConjointIn", "ConjointInReverse",
- "ConjointOut", "ConjointOutReverse", "ConjointAtop",
- "ConjointAtopReverse", "ConjointXor", "ConjointMaximum",
- };
-
- if (op >= 0 && op < (int) (sizeof (ops) / sizeof (ops[0])))
- return ops[op];
- else
- return "Unknown";
-}
-
-static const char *type_name (int type)
-{
- switch (type)
- {
- case PICT_TYPE_OTHER:
- return "Other";
- case PICT_TYPE_A:
- return "A";
- case PICT_TYPE_ARGB:
- return "ARGB";
- case PICT_TYPE_ABGR:
- return "ABGR";
- case PICT_TYPE_COLOR:
- return "Color";
- case PICT_TYPE_GRAY:
- return "Gray";
- default:
- return "Unknown";
- }
-}
-
-static void log_format (int op, unsigned int src,
- unsigned int dst, unsigned int mask)
-{
- struct op {
- int op;
- unsigned int src, dst, mask;
- };
-
- static struct op *ops;
- static int n_ops, allocated_ops;
-
- int i;
-
- for (i = 0; i < n_ops; i++)
- {
- if (ops[i].op == op && ops[i].src == src
- && ops[i].dst == dst && ops[i].mask == mask)
- {
- return;
- }
- }
-
- if (n_ops == allocated_ops)
- {
- allocated_ops *= 2;
- ops = realloc (ops, allocated_ops * sizeof (struct op));
- }
-
- ops[n_ops].op = op;
- ops[n_ops].src = src;
- ops[n_ops].dst = dst;
- ops[n_ops].mask = mask;
- n_ops++;
-
- fprintf (stderr,
- "op: %s src (%dbpp %s %04x) dst (%dbpp %s %04x) mask (%dbpp %s %04x)\n",
- op_name (op), PICT_FORMAT_BPP (src),
- type_name (PICT_FORMAT_TYPE (src)),
- src & 0xffff, PICT_FORMAT_BPP (dst),
- type_name (PICT_FORMAT_TYPE (dst)),
- dst & 0xffff, PICT_FORMAT_BPP (mask),
- type_name (PICT_FORMAT_TYPE (mask)),
- mask & 0xffff);
-}
-
-void
-RootlessComposite(
- CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height)
-{
- RegionRec region;
- int n;
- BoxPtr pbox;
- CompositeFunc func;
- Bool srcRepeat = pSrc->repeat;
- Bool maskRepeat = FALSE;
- Bool srcAlphaMap = pSrc->alphaMap != 0;
- Bool maskAlphaMap = FALSE;
- Bool dstAlphaMap = pDst->alphaMap != 0;
- int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
- int w, h, w_this, h_this;
- int dstDepth = pDst->pDrawable->depth;
-
- xDst += pDst->pDrawable->x;
- yDst += pDst->pDrawable->y;
- xSrc += pSrc->pDrawable->x;
- ySrc += pSrc->pDrawable->y;
- if (pMask)
- {
- xMask += pMask->pDrawable->x;
- yMask += pMask->pDrawable->y;
- maskRepeat = pMask->repeat;
- maskAlphaMap = pMask->alphaMap != 0;
- }
-
- if (rootless_log_pict_formats)
- {
- log_format (op, pSrc->format, pDst->format,
- pMask != 0 ? pMask->format : 0);
- }
-
- if (!miComputeCompositeRegion (®ion,
- pSrc,
- pMask,
- pDst,
- xSrc,
- ySrc,
- xMask,
- yMask,
- xDst,
- yDst,
- width,
- height))
- return;
-
- if (pDst->pDrawable->type == DRAWABLE_WINDOW
- && pDst->pDrawable->depth == 24
- && pDst->pDrawable->bitsPerPixel == 32)
- {
- /* fbpict code sets bits above depth to zero. We don't want that! */
-
- pDst->pDrawable->depth = 32;
- }
-
- func = RootlessCompositeGeneral;
-
- if (!maskAlphaMap && !srcAlphaMap && !dstAlphaMap)
- switch (op) {
- case PictOpOver:
- if (pMask)
- {
- if (srcRepeat &&
- pSrc->pDrawable->width == 1 &&
- pSrc->pDrawable->height == 1)
- {
- srcRepeat = FALSE;
- if (PICT_FORMAT_COLOR(pSrc->format)) {
- switch (pMask->format) {
- case PICT_a8:
- switch (pDst->format) {
- case PICT_r5g6b5:
- case PICT_b5g6r5:
- func = fbCompositeSolidMask_nx8x0565;
- break;
- case PICT_r8g8b8:
- case PICT_b8g8r8:
- func = fbCompositeSolidMask_nx8x0888;
- break;
- case PICT_a8r8g8b8:
- case PICT_x8r8g8b8:
- case PICT_a8b8g8r8:
- case PICT_x8b8g8r8:
- func = fbCompositeSolidMask_nx8x8888;
- break;
- }
- break;
- case PICT_a8r8g8b8:
- if (pMask->componentAlpha) {
- switch (pDst->format) {
- case PICT_a8r8g8b8:
- case PICT_x8r8g8b8:
- func = fbCompositeSolidMask_nx8888x8888C;
- break;
- case PICT_r5g6b5:
- func = fbCompositeSolidMask_nx8888x0565C;
- break;
- }
- }
- break;
- case PICT_a8b8g8r8:
- if (pMask->componentAlpha) {
- switch (pDst->format) {
- case PICT_a8b8g8r8:
- case PICT_x8b8g8r8:
- func = fbCompositeSolidMask_nx8888x8888C;
- break;
- case PICT_b5g6r5:
- func = fbCompositeSolidMask_nx8888x0565C;
- break;
- }
- }
- break;
- case PICT_a1:
- switch (pDst->format) {
- case PICT_r5g6b5:
- case PICT_b5g6r5:
- case PICT_r8g8b8:
- case PICT_b8g8r8:
- case PICT_a8r8g8b8:
- case PICT_x8r8g8b8:
- case PICT_a8b8g8r8:
- case PICT_x8b8g8r8:
- func = fbCompositeSolidMask_nx1xn;
- break;
- }
- }
- }
- }
- }
- else
- {
- switch (pSrc->format) {
- case PICT_a8r8g8b8:
- case PICT_x8r8g8b8:
- switch (pDst->format) {
- case PICT_a8r8g8b8:
- case PICT_x8r8g8b8:
- func = fbCompositeSrc_8888x8888;
- break;
- case PICT_r8g8b8:
- func = fbCompositeSrc_8888x0888;
- break;
- case PICT_r5g6b5:
- func = fbCompositeSrc_8888x0565;
- break;
- }
- break;
- case PICT_a8b8g8r8:
- case PICT_x8b8g8r8:
- switch (pDst->format) {
- case PICT_a8b8g8r8:
- case PICT_x8b8g8r8:
- func = fbCompositeSrc_8888x8888;
- break;
- case PICT_b8g8r8:
- func = fbCompositeSrc_8888x0888;
- break;
- case PICT_b5g6r5:
- func = fbCompositeSrc_8888x0565;
- break;
- }
- break;
- case PICT_r5g6b5:
- switch (pDst->format) {
- case PICT_r5g6b5:
- func = fbCompositeSrc_0565x0565;
- break;
- }
- break;
- case PICT_b5g6r5:
- switch (pDst->format) {
- case PICT_b5g6r5:
- func = fbCompositeSrc_0565x0565;
- break;
- }
- break;
- }
- }
- break;
- case PictOpAdd:
- if (pMask == 0)
- {
- switch (pSrc->format) {
- case PICT_a8r8g8b8:
- switch (pDst->format) {
- case PICT_a8r8g8b8:
- func = fbCompositeSrcAdd_8888x8888;
- break;
- }
- break;
- case PICT_a8b8g8r8:
- switch (pDst->format) {
- case PICT_a8b8g8r8:
- func = fbCompositeSrcAdd_8888x8888;
- break;
- }
- break;
- case PICT_a8:
- switch (pDst->format) {
- case PICT_a8:
- func = fbCompositeSrcAdd_8000x8000;
- break;
- }
- break;
- case PICT_a1:
- switch (pDst->format) {
- case PICT_a1:
- func = fbCompositeSrcAdd_1000x1000;
- break;
- }
- break;
- }
- }
- break;
- }
-
- n = REGION_NUM_RECTS (®ion);
- pbox = REGION_RECTS (®ion);
- while (n--)
- {
- h = pbox->y2 - pbox->y1;
- y_src = pbox->y1 - yDst + ySrc;
- y_msk = pbox->y1 - yDst + yMask;
- y_dst = pbox->y1;
- while (h)
- {
- h_this = h;
- w = pbox->x2 - pbox->x1;
- x_src = pbox->x1 - xDst + xSrc;
- x_msk = pbox->x1 - xDst + xMask;
- x_dst = pbox->x1;
- if (maskRepeat)
- {
- y_msk = mod (y_msk, pMask->pDrawable->height);
- if (h_this > pMask->pDrawable->height - y_msk)
- h_this = pMask->pDrawable->height - y_msk;
- }
- if (srcRepeat)
- {
- y_src = mod (y_src, pSrc->pDrawable->height);
- if (h_this > pSrc->pDrawable->height - y_src)
- h_this = pSrc->pDrawable->height - y_src;
- }
- while (w)
- {
- w_this = w;
- if (maskRepeat)
- {
- x_msk = mod (x_msk, pMask->pDrawable->width);
- if (w_this > pMask->pDrawable->width - x_msk)
- w_this = pMask->pDrawable->width - x_msk;
- }
- if (srcRepeat)
- {
- x_src = mod (x_src, pSrc->pDrawable->width);
- if (w_this > pSrc->pDrawable->width - x_src)
- w_this = pSrc->pDrawable->width - x_src;
- }
- (*func) (op, pSrc, pMask, pDst,
- x_src, y_src, x_msk, y_msk, x_dst, y_dst,
- w_this, h_this);
- w -= w_this;
- x_src += w_this;
- x_msk += w_this;
- x_dst += w_this;
- }
- h -= h_this;
- y_src += h_this;
- y_msk += h_this;
- y_dst += h_this;
- }
- pbox++;
- }
- REGION_UNINIT (pDst->pDrawable->pScreen, ®ion);
-
- pDst->pDrawable->depth = dstDepth;
-}
-
-#endif /* RENDER */