Imported Upstream version 1.15.1
[deb_xorg-server.git] / fb / fbcopy.c
... / ...
CommitLineData
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 = 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
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 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
254RegionPtr
255fbCopyPlane(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}