fbcopy.c revision 1b5d61b8
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
31void
32fbCopyNtoN(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
86void
87fbCopy1toN(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
141void
142fbCopyNto1(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
238RegionPtr
239fbCopyArea(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
248RegionPtr
249fbCopyPlane(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