xref: /OK3568_Linux_fs/external/xserver/fb/fbcopy.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 void
fbCopyNtoN(DrawablePtr pSrcDrawable,DrawablePtr pDstDrawable,GCPtr pGC,BoxPtr pbox,int nbox,int dx,int dy,Bool reverse,Bool upsidedown,Pixel bitplane,void * closure)32*4882a593Smuzhiyun fbCopyNtoN(DrawablePtr pSrcDrawable,
33*4882a593Smuzhiyun            DrawablePtr pDstDrawable,
34*4882a593Smuzhiyun            GCPtr pGC,
35*4882a593Smuzhiyun            BoxPtr pbox,
36*4882a593Smuzhiyun            int nbox,
37*4882a593Smuzhiyun            int dx,
38*4882a593Smuzhiyun            int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun     CARD8 alu = pGC ? pGC->alu : GXcopy;
41*4882a593Smuzhiyun     FbBits pm = pGC ? fbGetGCPrivate(pGC)->pm : FB_ALLONES;
42*4882a593Smuzhiyun     FbBits *src;
43*4882a593Smuzhiyun     FbStride srcStride;
44*4882a593Smuzhiyun     int srcBpp;
45*4882a593Smuzhiyun     int srcXoff, srcYoff;
46*4882a593Smuzhiyun     FbBits *dst;
47*4882a593Smuzhiyun     FbStride dstStride;
48*4882a593Smuzhiyun     int dstBpp;
49*4882a593Smuzhiyun     int dstXoff, dstYoff;
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun     fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
52*4882a593Smuzhiyun     fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun     while (nbox--) {
55*4882a593Smuzhiyun #ifndef FB_ACCESS_WRAPPER       /* pixman_blt() doesn't support accessors yet */
56*4882a593Smuzhiyun         if (pm == FB_ALLONES && alu == GXcopy && !reverse && !upsidedown) {
57*4882a593Smuzhiyun             if (!pixman_blt
58*4882a593Smuzhiyun                 ((uint32_t *) src, (uint32_t *) dst, srcStride, dstStride,
59*4882a593Smuzhiyun                  srcBpp, dstBpp, (pbox->x1 + dx + srcXoff),
60*4882a593Smuzhiyun                  (pbox->y1 + dy + srcYoff), (pbox->x1 + dstXoff),
61*4882a593Smuzhiyun                  (pbox->y1 + dstYoff), (pbox->x2 - pbox->x1),
62*4882a593Smuzhiyun                  (pbox->y2 - pbox->y1)))
63*4882a593Smuzhiyun                 goto fallback;
64*4882a593Smuzhiyun             else
65*4882a593Smuzhiyun                 goto next;
66*4882a593Smuzhiyun         }
67*4882a593Smuzhiyun  fallback:
68*4882a593Smuzhiyun #endif
69*4882a593Smuzhiyun         fbBlt(src + (pbox->y1 + dy + srcYoff) * srcStride,
70*4882a593Smuzhiyun               srcStride,
71*4882a593Smuzhiyun               (pbox->x1 + dx + srcXoff) * srcBpp,
72*4882a593Smuzhiyun               dst + (pbox->y1 + dstYoff) * dstStride,
73*4882a593Smuzhiyun               dstStride,
74*4882a593Smuzhiyun               (pbox->x1 + dstXoff) * dstBpp,
75*4882a593Smuzhiyun               (pbox->x2 - pbox->x1) * dstBpp,
76*4882a593Smuzhiyun               (pbox->y2 - pbox->y1), alu, pm, dstBpp, reverse, upsidedown);
77*4882a593Smuzhiyun #ifndef FB_ACCESS_WRAPPER
78*4882a593Smuzhiyun  next:
79*4882a593Smuzhiyun #endif
80*4882a593Smuzhiyun         pbox++;
81*4882a593Smuzhiyun     }
82*4882a593Smuzhiyun     fbFinishAccess(pDstDrawable);
83*4882a593Smuzhiyun     fbFinishAccess(pSrcDrawable);
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun void
fbCopy1toN(DrawablePtr pSrcDrawable,DrawablePtr pDstDrawable,GCPtr pGC,BoxPtr pbox,int nbox,int dx,int dy,Bool reverse,Bool upsidedown,Pixel bitplane,void * closure)87*4882a593Smuzhiyun fbCopy1toN(DrawablePtr pSrcDrawable,
88*4882a593Smuzhiyun            DrawablePtr pDstDrawable,
89*4882a593Smuzhiyun            GCPtr pGC,
90*4882a593Smuzhiyun            BoxPtr pbox,
91*4882a593Smuzhiyun            int nbox,
92*4882a593Smuzhiyun            int dx,
93*4882a593Smuzhiyun            int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun     FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
96*4882a593Smuzhiyun     FbBits *src;
97*4882a593Smuzhiyun     FbStride srcStride;
98*4882a593Smuzhiyun     int srcBpp;
99*4882a593Smuzhiyun     int srcXoff, srcYoff;
100*4882a593Smuzhiyun     FbBits *dst;
101*4882a593Smuzhiyun     FbStride dstStride;
102*4882a593Smuzhiyun     int dstBpp;
103*4882a593Smuzhiyun     int dstXoff, dstYoff;
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun     fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
106*4882a593Smuzhiyun     fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun     while (nbox--) {
109*4882a593Smuzhiyun         if (dstBpp == 1) {
110*4882a593Smuzhiyun             fbBlt(src + (pbox->y1 + dy + srcYoff) * srcStride,
111*4882a593Smuzhiyun                   srcStride,
112*4882a593Smuzhiyun                   (pbox->x1 + dx + srcXoff) * srcBpp,
113*4882a593Smuzhiyun                   dst + (pbox->y1 + dstYoff) * dstStride,
114*4882a593Smuzhiyun                   dstStride,
115*4882a593Smuzhiyun                   (pbox->x1 + dstXoff) * dstBpp,
116*4882a593Smuzhiyun                   (pbox->x2 - pbox->x1) * dstBpp,
117*4882a593Smuzhiyun                   (pbox->y2 - pbox->y1),
118*4882a593Smuzhiyun                   FbOpaqueStipple1Rop(pGC->alu,
119*4882a593Smuzhiyun                                       pGC->fgPixel, pGC->bgPixel),
120*4882a593Smuzhiyun                   pPriv->pm, dstBpp, reverse, upsidedown);
121*4882a593Smuzhiyun         }
122*4882a593Smuzhiyun         else {
123*4882a593Smuzhiyun             fbBltOne((FbStip *) (src + (pbox->y1 + dy + srcYoff) * srcStride),
124*4882a593Smuzhiyun                      srcStride * (FB_UNIT / FB_STIP_UNIT),
125*4882a593Smuzhiyun                      (pbox->x1 + dx + srcXoff),
126*4882a593Smuzhiyun                      dst + (pbox->y1 + dstYoff) * dstStride,
127*4882a593Smuzhiyun                      dstStride,
128*4882a593Smuzhiyun                      (pbox->x1 + dstXoff) * dstBpp,
129*4882a593Smuzhiyun                      dstBpp,
130*4882a593Smuzhiyun                      (pbox->x2 - pbox->x1) * dstBpp,
131*4882a593Smuzhiyun                      (pbox->y2 - pbox->y1),
132*4882a593Smuzhiyun                      pPriv->and, pPriv->xor, pPriv->bgand, pPriv->bgxor);
133*4882a593Smuzhiyun         }
134*4882a593Smuzhiyun         pbox++;
135*4882a593Smuzhiyun     }
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun     fbFinishAccess(pDstDrawable);
138*4882a593Smuzhiyun     fbFinishAccess(pSrcDrawable);
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun void
fbCopyNto1(DrawablePtr pSrcDrawable,DrawablePtr pDstDrawable,GCPtr pGC,BoxPtr pbox,int nbox,int dx,int dy,Bool reverse,Bool upsidedown,Pixel bitplane,void * closure)142*4882a593Smuzhiyun fbCopyNto1(DrawablePtr pSrcDrawable,
143*4882a593Smuzhiyun            DrawablePtr pDstDrawable,
144*4882a593Smuzhiyun            GCPtr pGC,
145*4882a593Smuzhiyun            BoxPtr pbox,
146*4882a593Smuzhiyun            int nbox,
147*4882a593Smuzhiyun            int dx,
148*4882a593Smuzhiyun            int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun     FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun     while (nbox--) {
153*4882a593Smuzhiyun         if (pDstDrawable->bitsPerPixel == 1) {
154*4882a593Smuzhiyun             FbBits *src;
155*4882a593Smuzhiyun             FbStride srcStride;
156*4882a593Smuzhiyun             int srcBpp;
157*4882a593Smuzhiyun             int srcXoff, srcYoff;
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun             FbStip *dst;
160*4882a593Smuzhiyun             FbStride dstStride;
161*4882a593Smuzhiyun             int dstBpp;
162*4882a593Smuzhiyun             int dstXoff, dstYoff;
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun             fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff,
165*4882a593Smuzhiyun                           srcYoff);
166*4882a593Smuzhiyun             fbGetStipDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff,
167*4882a593Smuzhiyun                               dstYoff);
168*4882a593Smuzhiyun             fbBltPlane(src + (pbox->y1 + dy + srcYoff) * srcStride, srcStride,
169*4882a593Smuzhiyun                        (pbox->x1 + dx + srcXoff) * srcBpp, srcBpp,
170*4882a593Smuzhiyun                        dst + (pbox->y1 + dstYoff) * dstStride, dstStride,
171*4882a593Smuzhiyun                        (pbox->x1 + dstXoff) * dstBpp,
172*4882a593Smuzhiyun                        (pbox->x2 - pbox->x1) * srcBpp, (pbox->y2 - pbox->y1),
173*4882a593Smuzhiyun                        (FbStip) pPriv->and, (FbStip) pPriv->xor,
174*4882a593Smuzhiyun                        (FbStip) pPriv->bgand, (FbStip) pPriv->bgxor, bitplane);
175*4882a593Smuzhiyun             fbFinishAccess(pDstDrawable);
176*4882a593Smuzhiyun             fbFinishAccess(pSrcDrawable);
177*4882a593Smuzhiyun         }
178*4882a593Smuzhiyun         else {
179*4882a593Smuzhiyun             FbBits *src;
180*4882a593Smuzhiyun             FbStride srcStride;
181*4882a593Smuzhiyun             int srcBpp;
182*4882a593Smuzhiyun             int srcXoff, srcYoff;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun             FbBits *dst;
185*4882a593Smuzhiyun             FbStride dstStride;
186*4882a593Smuzhiyun             int dstBpp;
187*4882a593Smuzhiyun             int dstXoff, dstYoff;
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun             FbStip *tmp;
190*4882a593Smuzhiyun             FbStride tmpStride;
191*4882a593Smuzhiyun             int width, height;
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun             width = pbox->x2 - pbox->x1;
194*4882a593Smuzhiyun             height = pbox->y2 - pbox->y1;
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun             tmpStride = ((width + FB_STIP_MASK) >> FB_STIP_SHIFT);
197*4882a593Smuzhiyun             tmp = xallocarray(tmpStride * height, sizeof(FbStip));
198*4882a593Smuzhiyun             if (!tmp)
199*4882a593Smuzhiyun                 return;
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun             fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff,
202*4882a593Smuzhiyun                           srcYoff);
203*4882a593Smuzhiyun             fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff,
204*4882a593Smuzhiyun                           dstYoff);
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun             fbBltPlane(src + (pbox->y1 + dy + srcYoff) * srcStride,
207*4882a593Smuzhiyun                        srcStride,
208*4882a593Smuzhiyun                        (pbox->x1 + dx + srcXoff) * srcBpp,
209*4882a593Smuzhiyun                        srcBpp,
210*4882a593Smuzhiyun                        tmp,
211*4882a593Smuzhiyun                        tmpStride,
212*4882a593Smuzhiyun                        0,
213*4882a593Smuzhiyun                        width * srcBpp,
214*4882a593Smuzhiyun                        height,
215*4882a593Smuzhiyun                        fbAndStip(GXcopy, FB_ALLONES, FB_ALLONES),
216*4882a593Smuzhiyun                        fbXorStip(GXcopy, FB_ALLONES, FB_ALLONES),
217*4882a593Smuzhiyun                        fbAndStip(GXcopy, 0, FB_ALLONES),
218*4882a593Smuzhiyun                        fbXorStip(GXcopy, 0, FB_ALLONES), bitplane);
219*4882a593Smuzhiyun             fbBltOne(tmp,
220*4882a593Smuzhiyun                      tmpStride,
221*4882a593Smuzhiyun                      0,
222*4882a593Smuzhiyun                      dst + (pbox->y1 + dstYoff) * dstStride,
223*4882a593Smuzhiyun                      dstStride,
224*4882a593Smuzhiyun                      (pbox->x1 + dstXoff) * dstBpp,
225*4882a593Smuzhiyun                      dstBpp,
226*4882a593Smuzhiyun                      width * dstBpp,
227*4882a593Smuzhiyun                      height,
228*4882a593Smuzhiyun                      pPriv->and, pPriv->xor, pPriv->bgand, pPriv->bgxor);
229*4882a593Smuzhiyun             free(tmp);
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun             fbFinishAccess(pDstDrawable);
232*4882a593Smuzhiyun             fbFinishAccess(pSrcDrawable);
233*4882a593Smuzhiyun         }
234*4882a593Smuzhiyun         pbox++;
235*4882a593Smuzhiyun     }
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun RegionPtr
fbCopyArea(DrawablePtr pSrcDrawable,DrawablePtr pDstDrawable,GCPtr pGC,int xIn,int yIn,int widthSrc,int heightSrc,int xOut,int yOut)239*4882a593Smuzhiyun fbCopyArea(DrawablePtr pSrcDrawable,
240*4882a593Smuzhiyun            DrawablePtr pDstDrawable,
241*4882a593Smuzhiyun            GCPtr pGC,
242*4882a593Smuzhiyun            int xIn, int yIn, int widthSrc, int heightSrc, int xOut, int yOut)
243*4882a593Smuzhiyun {
244*4882a593Smuzhiyun     return miDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
245*4882a593Smuzhiyun                     widthSrc, heightSrc, xOut, yOut, fbCopyNtoN, 0, 0);
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun RegionPtr
fbCopyPlane(DrawablePtr pSrcDrawable,DrawablePtr pDstDrawable,GCPtr pGC,int xIn,int yIn,int widthSrc,int heightSrc,int xOut,int yOut,unsigned long bitplane)249*4882a593Smuzhiyun fbCopyPlane(DrawablePtr pSrcDrawable,
250*4882a593Smuzhiyun             DrawablePtr pDstDrawable,
251*4882a593Smuzhiyun             GCPtr pGC,
252*4882a593Smuzhiyun             int xIn,
253*4882a593Smuzhiyun             int yIn,
254*4882a593Smuzhiyun             int widthSrc,
255*4882a593Smuzhiyun             int heightSrc, int xOut, int yOut, unsigned long bitplane)
256*4882a593Smuzhiyun {
257*4882a593Smuzhiyun     if (pSrcDrawable->bitsPerPixel > 1)
258*4882a593Smuzhiyun         return miDoCopy(pSrcDrawable, pDstDrawable, pGC,
259*4882a593Smuzhiyun                         xIn, yIn, widthSrc, heightSrc,
260*4882a593Smuzhiyun                         xOut, yOut, fbCopyNto1, (Pixel) bitplane, 0);
261*4882a593Smuzhiyun     else if (bitplane & 1)
262*4882a593Smuzhiyun         return miDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
263*4882a593Smuzhiyun                         widthSrc, heightSrc, xOut, yOut, fbCopy1toN,
264*4882a593Smuzhiyun                         (Pixel) bitplane, 0);
265*4882a593Smuzhiyun     else
266*4882a593Smuzhiyun         return miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
267*4882a593Smuzhiyun                                  xIn, yIn,
268*4882a593Smuzhiyun                                  widthSrc, heightSrc, xOut, yOut);
269*4882a593Smuzhiyun }
270