xref: /OK3568_Linux_fs/external/xserver/fb/fbgc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright © 1998 Keith Packard
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Permission to use, copy, modify, distribute, and sell this software and its
5*4882a593Smuzhiyun  * documentation for any purpose is hereby granted without fee, provided that
6*4882a593Smuzhiyun  * the above copyright notice appear in all copies and that both that
7*4882a593Smuzhiyun  * copyright notice and this permission notice appear in supporting
8*4882a593Smuzhiyun  * documentation, and that the name of Keith Packard not be used in
9*4882a593Smuzhiyun  * advertising or publicity pertaining to distribution of the software without
10*4882a593Smuzhiyun  * specific, written prior permission.  Keith Packard makes no
11*4882a593Smuzhiyun  * representations about the suitability of this software for any purpose.  It
12*4882a593Smuzhiyun  * is provided "as is" without express or implied warranty.
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15*4882a593Smuzhiyun  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16*4882a593Smuzhiyun  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17*4882a593Smuzhiyun  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18*4882a593Smuzhiyun  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19*4882a593Smuzhiyun  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20*4882a593Smuzhiyun  * PERFORMANCE OF THIS SOFTWARE.
21*4882a593Smuzhiyun  */
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
24*4882a593Smuzhiyun #include <dix-config.h>
25*4882a593Smuzhiyun #endif
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #include <stdlib.h>
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun #include "fb.h"
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun const GCFuncs fbGCFuncs = {
32*4882a593Smuzhiyun     fbValidateGC,
33*4882a593Smuzhiyun     miChangeGC,
34*4882a593Smuzhiyun     miCopyGC,
35*4882a593Smuzhiyun     miDestroyGC,
36*4882a593Smuzhiyun     miChangeClip,
37*4882a593Smuzhiyun     miDestroyClip,
38*4882a593Smuzhiyun     miCopyClip,
39*4882a593Smuzhiyun };
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun const GCOps fbGCOps = {
42*4882a593Smuzhiyun     fbFillSpans,
43*4882a593Smuzhiyun     fbSetSpans,
44*4882a593Smuzhiyun     fbPutImage,
45*4882a593Smuzhiyun     fbCopyArea,
46*4882a593Smuzhiyun     fbCopyPlane,
47*4882a593Smuzhiyun     fbPolyPoint,
48*4882a593Smuzhiyun     fbPolyLine,
49*4882a593Smuzhiyun     fbPolySegment,
50*4882a593Smuzhiyun     fbPolyRectangle,
51*4882a593Smuzhiyun     fbPolyArc,
52*4882a593Smuzhiyun     miFillPolygon,
53*4882a593Smuzhiyun     fbPolyFillRect,
54*4882a593Smuzhiyun     fbPolyFillArc,
55*4882a593Smuzhiyun     miPolyText8,
56*4882a593Smuzhiyun     miPolyText16,
57*4882a593Smuzhiyun     miImageText8,
58*4882a593Smuzhiyun     miImageText16,
59*4882a593Smuzhiyun     fbImageGlyphBlt,
60*4882a593Smuzhiyun     fbPolyGlyphBlt,
61*4882a593Smuzhiyun     fbPushPixels
62*4882a593Smuzhiyun };
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun Bool
fbCreateGC(GCPtr pGC)65*4882a593Smuzhiyun fbCreateGC(GCPtr pGC)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun     pGC->ops = (GCOps *) &fbGCOps;
68*4882a593Smuzhiyun     pGC->funcs = (GCFuncs *) &fbGCFuncs;
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun     /* fb wants to translate before scan conversion */
71*4882a593Smuzhiyun     pGC->miTranslate = 1;
72*4882a593Smuzhiyun     pGC->fExpose = 1;
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun     return TRUE;
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun /*
78*4882a593Smuzhiyun  * Pad pixmap to FB_UNIT bits wide
79*4882a593Smuzhiyun  */
80*4882a593Smuzhiyun void
fbPadPixmap(PixmapPtr pPixmap)81*4882a593Smuzhiyun fbPadPixmap(PixmapPtr pPixmap)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun     int width;
84*4882a593Smuzhiyun     FbBits *bits;
85*4882a593Smuzhiyun     FbBits b;
86*4882a593Smuzhiyun     FbBits mask;
87*4882a593Smuzhiyun     int height;
88*4882a593Smuzhiyun     int w;
89*4882a593Smuzhiyun     int stride;
90*4882a593Smuzhiyun     int bpp;
91*4882a593Smuzhiyun     _X_UNUSED int xOff, yOff;
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun     fbGetDrawable(&pPixmap->drawable, bits, stride, bpp, xOff, yOff);
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun     width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel;
96*4882a593Smuzhiyun     height = pPixmap->drawable.height;
97*4882a593Smuzhiyun     mask = FbBitsMask(0, width);
98*4882a593Smuzhiyun     while (height--) {
99*4882a593Smuzhiyun         b = READ(bits) & mask;
100*4882a593Smuzhiyun         w = width;
101*4882a593Smuzhiyun         while (w < FB_UNIT) {
102*4882a593Smuzhiyun             b = b | FbScrRight(b, w);
103*4882a593Smuzhiyun             w <<= 1;
104*4882a593Smuzhiyun         }
105*4882a593Smuzhiyun         WRITE(bits, b);
106*4882a593Smuzhiyun         bits += stride;
107*4882a593Smuzhiyun     }
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun     fbFinishAccess(&pPixmap->drawable);
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun void
fbValidateGC(GCPtr pGC,unsigned long changes,DrawablePtr pDrawable)113*4882a593Smuzhiyun fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun     FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
116*4882a593Smuzhiyun     FbBits mask;
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun     /*
119*4882a593Smuzhiyun      * if the client clip is different or moved OR the subwindowMode has
120*4882a593Smuzhiyun      * changed OR the window's clip has changed since the last validation
121*4882a593Smuzhiyun      * we need to recompute the composite clip
122*4882a593Smuzhiyun      */
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun     if ((changes &
125*4882a593Smuzhiyun          (GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode)) ||
126*4882a593Smuzhiyun         (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
127*4882a593Smuzhiyun         ) {
128*4882a593Smuzhiyun         miComputeCompositeClip(pGC, pDrawable);
129*4882a593Smuzhiyun     }
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun     if (changes & GCTile) {
132*4882a593Smuzhiyun         if (!pGC->tileIsPixel &&
133*4882a593Smuzhiyun             FbEvenTile(pGC->tile.pixmap->drawable.width *
134*4882a593Smuzhiyun                        pDrawable->bitsPerPixel))
135*4882a593Smuzhiyun             fbPadPixmap(pGC->tile.pixmap);
136*4882a593Smuzhiyun     }
137*4882a593Smuzhiyun     if (changes & GCStipple) {
138*4882a593Smuzhiyun         if (pGC->stipple) {
139*4882a593Smuzhiyun             if (pGC->stipple->drawable.width * pDrawable->bitsPerPixel <
140*4882a593Smuzhiyun                 FB_UNIT)
141*4882a593Smuzhiyun                 fbPadPixmap(pGC->stipple);
142*4882a593Smuzhiyun         }
143*4882a593Smuzhiyun     }
144*4882a593Smuzhiyun     /*
145*4882a593Smuzhiyun      * Recompute reduced rop values
146*4882a593Smuzhiyun      */
147*4882a593Smuzhiyun     if (changes & (GCForeground | GCBackground | GCPlaneMask | GCFunction)) {
148*4882a593Smuzhiyun         int s;
149*4882a593Smuzhiyun         FbBits depthMask;
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun         mask = FbFullMask(pDrawable->bitsPerPixel);
152*4882a593Smuzhiyun         depthMask = FbFullMask(pDrawable->depth);
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun         pPriv->fg = pGC->fgPixel & mask;
155*4882a593Smuzhiyun         pPriv->bg = pGC->bgPixel & mask;
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun         if ((pGC->planemask & depthMask) == depthMask)
158*4882a593Smuzhiyun             pPriv->pm = mask;
159*4882a593Smuzhiyun         else
160*4882a593Smuzhiyun             pPriv->pm = pGC->planemask & mask;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun         s = pDrawable->bitsPerPixel;
163*4882a593Smuzhiyun         while (s < FB_UNIT) {
164*4882a593Smuzhiyun             pPriv->fg |= pPriv->fg << s;
165*4882a593Smuzhiyun             pPriv->bg |= pPriv->bg << s;
166*4882a593Smuzhiyun             pPriv->pm |= pPriv->pm << s;
167*4882a593Smuzhiyun             s <<= 1;
168*4882a593Smuzhiyun         }
169*4882a593Smuzhiyun         pPriv->and = fbAnd(pGC->alu, pPriv->fg, pPriv->pm);
170*4882a593Smuzhiyun         pPriv->xor = fbXor(pGC->alu, pPriv->fg, pPriv->pm);
171*4882a593Smuzhiyun         pPriv->bgand = fbAnd(pGC->alu, pPriv->bg, pPriv->pm);
172*4882a593Smuzhiyun         pPriv->bgxor = fbXor(pGC->alu, pPriv->bg, pPriv->pm);
173*4882a593Smuzhiyun     }
174*4882a593Smuzhiyun     if (changes & GCDashList) {
175*4882a593Smuzhiyun         unsigned short n = pGC->numInDashList;
176*4882a593Smuzhiyun         unsigned char *dash = pGC->dash;
177*4882a593Smuzhiyun         unsigned int dashLength = 0;
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun         while (n--)
180*4882a593Smuzhiyun             dashLength += (unsigned int) *dash++;
181*4882a593Smuzhiyun         pPriv->dashLength = dashLength;
182*4882a593Smuzhiyun     }
183*4882a593Smuzhiyun }
184