tizen 2.4 release
[framework/uifw/xorg/server/xorg-server.git] / fb / fbcopy.c
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
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
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
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 = malloc(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
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     miCopyProc copy;
245
246     if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel)
247         copy = fb24_32CopyMtoN;
248     else
249         copy = fbCopyNtoN;
250     return miDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
251                     widthSrc, heightSrc, xOut, yOut, copy, 0, 0);
252 }
253
254 RegionPtr
255 fbCopyPlane(DrawablePtr pSrcDrawable,
256             DrawablePtr pDstDrawable,
257             GCPtr pGC,
258             int xIn,
259             int yIn,
260             int widthSrc,
261             int heightSrc, int xOut, int yOut, unsigned long bitplane)
262 {
263     if (pSrcDrawable->bitsPerPixel > 1)
264         return miDoCopy(pSrcDrawable, pDstDrawable, pGC,
265                         xIn, yIn, widthSrc, heightSrc,
266                         xOut, yOut, fbCopyNto1, (Pixel) bitplane, 0);
267     else if (bitplane & 1)
268         return miDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
269                         widthSrc, heightSrc, xOut, yOut, fbCopy1toN,
270                         (Pixel) bitplane, 0);
271     else
272         return miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
273                                  xIn, yIn,
274                                  widthSrc, heightSrc, xOut, yOut, bitplane);
275 }