📄 fbpict.c
字号:
/* * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. SuSE makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE * 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. * * Author: Keith Packard, SuSE, Inc. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "pixman-xserver-compat.h"#ifdef RENDER#include "fbpict.h"#include "fbmmx.h"static CARD32fbOver (CARD32 x, CARD32 y){ CARD16 a = ~x >> 24; CARD16 t; CARD32 m,n,o,p; m = FbOverU(x,y,0,a,t); n = FbOverU(x,y,8,a,t); o = FbOverU(x,y,16,a,t); p = FbOverU(x,y,24,a,t); return m|n|o|p;}static CARD32fbOver24 (CARD32 x, CARD32 y){ CARD16 a = ~x >> 24; CARD16 t; CARD32 m,n,o; m = FbOverU(x,y,0,a,t); n = FbOverU(x,y,8,a,t); o = FbOverU(x,y,16,a,t); return m|n|o;}static CARD32fbIn (CARD32 x, CARD8 y){ CARD16 a = y; CARD16 t; CARD32 m,n,o,p; m = FbInU(x,0,a,t); n = FbInU(x,8,a,t); o = FbInU(x,16,a,t); p = FbInU(x,24,a,t); return m|n|o|p;}#define genericCombine24(a,b,c,d) (((a)*(c)+(b)*(d)))/* * This macro does src IN mask OVER dst when src and dst are 0888. * If src has alpha, this will not work */#define inOver0888(alpha, source, destval, dest) { \ CARD32 dstrb=destval&0xFF00FF; CARD32 dstag=(destval>>8)&0xFF00FF; \ CARD32 drb=((source&0xFF00FF)-dstrb)*alpha; CARD32 dag=(((source>>8)&0xFF00FF)-dstag)*alpha; \ dest =((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00)); \ }/* * This macro does src IN mask OVER dst when src and dst are 0565 and * mask is a 5-bit alpha value. Again, if src has alpha, this will not * work. */#define inOver0565(alpha, source, destval, dest) { \ CARD16 dstrb = destval & 0xf81f; CARD16 dstg = destval & 0x7e0; \ CARD32 drb = ((source&0xf81f)-dstrb)*alpha; CARD32 dg=((source & 0x7e0)-dstg)*alpha; \ dest = ((((drb>>5) + dstrb)&0xf81f) | (((dg>>5) + dstg) & 0x7e0)); \ }#define inOver2x0565(alpha, source, destval, dest) { \ CARD32 dstrb = destval & 0x07e0f81f; CARD32 dstg = (destval & 0xf81f07e0)>>5; \ CARD32 drb = ((source&0x07e0f81f)-dstrb)*alpha; CARD32 dg=(((source & 0xf81f07e0)>>5)-dstg)*alpha; \ dest = ((((drb>>5) + dstrb)&0x07e0f81f) | ((((dg>>5) + dstg)<<5) & 0xf81f07e0)); \ }#if IMAGE_BYTE_ORDER == LSBFirst# define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(long)where; \ temp=count&3; \ where-=temp; \ workingWhere=(CARD32 *)where; \ workingVal=*workingWhere++; \ count=4-temp; \ workingVal>>=(8*temp)# define readPacked(where,x,y,z) {if(!(x)) { (x)=4; y=*z++; } where=(y)&0xff; (y)>>=8; (x)--;}# define readPackedSource(where) readPacked(where,ws,workingSource,wsrc)# define readPackedDest(where) readPacked(where,wd,workingiDest,widst)# define writePacked(what) workingoDest>>=8; workingoDest|=(what<<24); ww--; if(!ww) { ww=4; *wodst++=workingoDest; }#else# define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(long)where; \ temp=count&3; \ where-=temp; \ workingWhere=(CARD32 *)where; \ workingVal=*workingWhere++; \ count=4-temp; \ workingVal<<=(8*temp)# define readPacked(where,x,y,z) {if(!(x)) { (x)=4; y=*z++; } where=(y)>>24; (y)<<=8; (x)--;}# define readPackedSource(where) readPacked(where,ws,workingSource,wsrc)# define readPackedDest(where) readPacked(where,wd,workingiDest,widst)# define writePacked(what) workingoDest<<=8; workingoDest|=what; ww--; if(!ww) { ww=4; *wodst++=workingoDest; }#endif/* * Naming convention: * * opSRCxMASKxDST */static voidfbCompositeSolidMask_nx8x8888 (pixman_operator_t op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height){ CARD32 src, srca; CARD32 *dstLine, *dst, d, dstMask; CARD8 *maskLine, *mask, m; FbStride dstStride, maskStride; CARD16 w; fbComposeGetSolid(pSrc, pDst, src); dstMask = FbFullMask (pDst->pDrawable->depth); srca = src >> 24; if (src == 0) return; fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1); fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1); while (height--) { dst = dstLine; dstLine += dstStride; mask = maskLine; maskLine += maskStride; w = width; while (w--) { m = *mask++; if (m == 0xff) { if (srca == 0xff) *dst = src & dstMask; else *dst = fbOver (src, *dst) & dstMask; } else if (m) { d = fbIn (src, m); *dst = fbOver (d, *dst) & dstMask; } dst++; } }}static voidfbCompositeSolidMask_nx8888x8888C (pixman_operator_t op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height){ CARD32 src, srca; CARD32 *dstLine, *dst, d, dstMask; CARD32 *maskLine, *mask, ma; FbStride dstStride, maskStride; CARD16 w; CARD32 m, n, o, p; fbComposeGetSolid(pSrc, pDst, src); dstMask = FbFullMask (pDst->pDrawable->depth); srca = src >> 24; if (src == 0) return; fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1); fbComposeGetStart (pMask, xMask, yMask, CARD32, maskStride, maskLine, 1); while (height--) { dst = dstLine; dstLine += dstStride; mask = maskLine; maskLine += maskStride; w = width; while (w--) { ma = *mask++; if (ma == 0xffffffff) { if (srca == 0xff) *dst = src & dstMask; else *dst = fbOver (src, *dst) & dstMask; } else if (ma) { d = *dst;#define FbInOverC(src,srca,msk,dst,i,result) { \ CARD16 __a = FbGet8(msk,i); \ CARD32 __t, __ta; \ CARD32 __i; \ __t = FbIntMult (FbGet8(src,i), __a,__i); \ __ta = (CARD8) ~FbIntMult (srca, __a,__i); \ __t = __t + FbIntMult(FbGet8(dst,i),__ta,__i); \ __t = (CARD32) (CARD8) (__t | (-(__t >> 8))); \ result = __t << (i); \} FbInOverC (src, srca, ma, d, 0, m); FbInOverC (src, srca, ma, d, 8, n); FbInOverC (src, srca, ma, d, 16, o); FbInOverC (src, srca, ma, d, 24, p); *dst = m|n|o|p; } dst++; } }}#define srcAlphaCombine24(a,b) genericCombine24(a,b,srca,srcia)static voidfbCompositeSolidMask_nx8x0888 (pixman_operator_t op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height){ CARD32 src, srca, srcia; CARD8 *dstLine, *dst, *edst; CARD8 *maskLine, *mask, m; FbStride dstStride, maskStride; CARD16 w; CARD32 rs,gs,bs,rd,gd,bd; fbComposeGetSolid(pSrc, pDst, src); srca = src >> 24; srcia = 255-srca; if (src == 0) return; rs=src&0xff; gs=(src>>8)&0xff; bs=(src>>16)&0xff; fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3); fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1); while (height--) { /* fixme: cleanup unused */ unsigned long wt,wd; CARD32 workingiDest; CARD32 *widst; edst=dst = dstLine; dstLine += dstStride; mask = maskLine; maskLine += maskStride; w = width;#ifndef NO_MASKED_PACKED_READ setupPackedReader(wd,wt,edst,widst,workingiDest);#endif while (w--) {#ifndef NO_MASKED_PACKED_READ readPackedDest(rd); readPackedDest(gd); readPackedDest(bd);#else rd= *edst++; gd= *edst++; bd= *edst++;#endif m = *mask++; if (m == 0xff) { if (srca == 0xff) { *dst++=rs; *dst++=gs; *dst++=bs; } else { *dst++=(srcAlphaCombine24(rs, rd)>>8); *dst++=(srcAlphaCombine24(gs, gd)>>8); *dst++=(srcAlphaCombine24(bs, bd)>>8); } } else if (m) { int na=(srca*(int)m)>>8; int nia=255-na; *dst++=(genericCombine24(rs, rd, na, nia)>>8); *dst++=(genericCombine24(gs, gd, na, nia)>>8); *dst++=(genericCombine24(bs, bd, na, nia)>>8); } else { dst+=3; } } }}static voidfbCompositeSolidMask_nx8x0565 (pixman_operator_t op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height){ CARD32 src, srca8, srca5; CARD16 *dstLine, *dst; CARD16 d; CARD32 t; CARD8 *maskLine, *mask, m; FbStride dstStride, maskStride; CARD16 w,src16; fbComposeGetSolid(pSrc, pDst, src); if (src == 0) return; srca8 = (src >> 24); srca5 = (srca8 >> 3); src16 = cvt8888to0565(src); fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1); fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1); while (height--) { dst = dstLine; dstLine += dstStride; mask = maskLine; maskLine += maskStride; w = width; while (w--) { m = *mask++; if (m == 0) dst++; else if (srca5 == (0xff >> 3)) { if (m == 0xff) *dst++ = src16; else { d = *dst; m >>= 3; inOver0565 (m, src16, d, *dst++); } } else { d = *dst; if (m == 0xff) { t = fbOver24 (src, cvt0565to0888 (d)); } else { t = fbIn (src, m); t = fbOver (t, cvt0565to0888 (d)); } *dst++ = cvt8888to0565 (t); } } }}static voidfbCompositeSolidMask_nx8888x0565 (pixman_operator_t op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height){ CARD32 src, srca8, srca5; CARD16 *dstLine, *dst; CARD16 d; CARD32 *maskLine, *mask; CARD32 t; CARD8 m; FbStride dstStride, maskStride; CARD16 w, src16; fbComposeGetSolid(pSrc, pDst, src); if (src == 0) return; srca8 = src >> 24; srca5 = srca8 >> 3; src16 = cvt8888to0565(src); fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1); fbComposeGetStart (pMask, xMask, yMask, CARD32, maskStride, maskLine, 1); while (height--) { dst = dstLine; dstLine += dstStride; mask = maskLine; maskLine += maskStride; w = width; while (w--) { m = *mask++ >> 24; if (m == 0) dst++; else if (srca5 == (0xff >> 3)) { if (m == 0xff) *dst++ = src16; else { d = *dst; m >>= 3; inOver0565 (m, src16, d, *dst++); } } else { if (m == 0xff) { d = *dst; t = fbOver24 (src, cvt0565to0888 (d)); *dst++ = cvt8888to0565 (t); } else { d = *dst; t = fbIn (src, m); t = fbOver (t, cvt0565to0888 (d)); *dst++ = cvt8888to0565 (t); } } } }}static voidfbCompositeSolidMask_nx8888x0565C (pixman_operator_t op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height){ CARD32 src, srca; CARD16 src16; CARD16 *dstLine, *dst; CARD32 d; CARD32 *maskLine, *mask, ma; FbStride dstStride, maskStride; CARD16 w; CARD32 m, n, o; fbComposeGetSolid(pSrc, pDst, src); srca = src >> 24; if (src == 0) return; src16 = cvt8888to0565(src); fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1); fbComposeGetStart (pMask, xMask, yMask, CARD32, maskStride, maskLine, 1); while (height--) { dst = dstLine; dstLine += dstStride; mask = maskLine; maskLine += maskStride; w = width; while (w--) { ma = *mask++; if (ma == 0xffffffff) { if (srca == 0xff) { *dst = src16; } else { d = *dst; d = fbOver24 (src, cvt0565to0888(d)); *dst = cvt8888to0565(d); } } else if (ma) { d = *dst; d = cvt0565to0888(d); FbInOverC (src, srca, ma, d, 0, m); FbInOverC (src, srca, ma, d, 8, n); FbInOverC (src, srca, ma, d, 16, o); d = m|n|o; *dst = cvt8888to0565(d); } dst++; } }}static voidfbCompositeSrc_8888x8888 (pixman_operator_t op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height){ CARD32 *dstLine, *dst, dstMask; CARD32 *srcLine, *src, s; FbStride dstStride, srcStride; CARD8 a; CARD16 w; fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1); fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1); dstMask = FbFullMask (pDst->pDrawable->depth); while (height--) { dst = dstLine; dstLine += dstStride; src = srcLine; srcLine += srcStride; w = width; while (w--) { s = *src++; a = s >> 24; if (a == 0xff) *dst = s & dstMask; else if (a) *dst = fbOver (s, *dst) & dstMask; dst++; } }}static voidfbCompositeSrc_8888x0888 (pixman_operator_t op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height){ CARD8 *dstLine, *dst; CARD32 d; CARD32 *srcLine, *src, s; CARD8 a; FbStride dstStride, srcStride; CARD16 w; fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3); fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1); while (height--) { dst = dstLine; dstLine += dstStride; src = srcLine; srcLine += srcStride; w = width; while (w--) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -