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