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