Add patch that contain Mali fixes.
[deb_xorg-server.git] / fb / fbimage.c
CommitLineData
a09e091a
JB
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 <string.h>
28
29#include "fb.h"
30
31void
32fbPutImage(DrawablePtr pDrawable,
33 GCPtr pGC,
34 int depth,
35 int x, int y, int w, int h, int leftPad, int format, char *pImage)
36{
37 FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
38 unsigned long i;
39 FbStride srcStride;
40 FbStip *src = (FbStip *) pImage;
41
42 x += pDrawable->x;
43 y += pDrawable->y;
44
45 switch (format) {
46 case XYBitmap:
47 srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip);
48 fbPutXYImage(pDrawable,
49 fbGetCompositeClip(pGC),
50 pPriv->fg,
51 pPriv->bg,
52 pPriv->pm,
53 pGC->alu, TRUE, x, y, w, h, src, srcStride, leftPad);
54 break;
55 case XYPixmap:
56 srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip);
57 for (i = (unsigned long) 1 << (pDrawable->depth - 1); i; i >>= 1) {
58 if (i & pGC->planemask) {
59 fbPutXYImage(pDrawable,
60 fbGetCompositeClip(pGC),
61 FB_ALLONES,
62 0,
63 fbReplicatePixel(i, pDrawable->bitsPerPixel),
64 pGC->alu,
65 TRUE, x, y, w, h, src, srcStride, leftPad);
66 src += srcStride * h;
67 }
68 }
69 break;
70 case ZPixmap:
71 if (pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth)) {
72 srcStride = PixmapBytePad(w, pDrawable->depth);
73 fb24_32PutZImage(pDrawable,
74 fbGetCompositeClip(pGC),
75 pGC->alu,
76 (FbBits) pGC->planemask,
77 x, y, w, h, (CARD8 *) pImage, srcStride);
78 }
79 else {
80 srcStride = PixmapBytePad(w, pDrawable->depth) / sizeof(FbStip);
81 fbPutZImage(pDrawable,
82 fbGetCompositeClip(pGC),
83 pGC->alu, pPriv->pm, x, y, w, h, src, srcStride);
84 }
85 }
86}
87
88void
89fbPutZImage(DrawablePtr pDrawable,
90 RegionPtr pClip,
91 int alu,
92 FbBits pm,
93 int x,
94 int y, int width, int height, FbStip * src, FbStride srcStride)
95{
96 FbStip *dst;
97 FbStride dstStride;
98 int dstBpp;
99 int dstXoff, dstYoff;
100 int nbox;
101 BoxPtr pbox;
102 int x1, y1, x2, y2;
103
104 fbGetStipDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
105
106 for (nbox = RegionNumRects(pClip),
107 pbox = RegionRects(pClip); nbox--; pbox++) {
108 x1 = x;
109 y1 = y;
110 x2 = x + width;
111 y2 = y + height;
112 if (x1 < pbox->x1)
113 x1 = pbox->x1;
114 if (y1 < pbox->y1)
115 y1 = pbox->y1;
116 if (x2 > pbox->x2)
117 x2 = pbox->x2;
118 if (y2 > pbox->y2)
119 y2 = pbox->y2;
120 if (x1 >= x2 || y1 >= y2)
121 continue;
122 fbBltStip(src + (y1 - y) * srcStride,
123 srcStride,
124 (x1 - x) * dstBpp,
125 dst + (y1 + dstYoff) * dstStride,
126 dstStride,
127 (x1 + dstXoff) * dstBpp,
128 (x2 - x1) * dstBpp, (y2 - y1), alu, pm, dstBpp);
129 }
130
131 fbFinishAccess(pDrawable);
132}
133
134void
135fbPutXYImage(DrawablePtr pDrawable,
136 RegionPtr pClip,
137 FbBits fg,
138 FbBits bg,
139 FbBits pm,
140 int alu,
141 Bool opaque,
142 int x,
143 int y,
144 int width, int height, FbStip * src, FbStride srcStride, int srcX)
145{
146 FbBits *dst;
147 FbStride dstStride;
148 int dstBpp;
149 int dstXoff, dstYoff;
150 int nbox;
151 BoxPtr pbox;
152 int x1, y1, x2, y2;
153 FbBits fgand = 0, fgxor = 0, bgand = 0, bgxor = 0;
154
155 fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
156
157 if (dstBpp == 1) {
158 if (opaque)
159 alu = FbOpaqueStipple1Rop(alu, fg, bg);
160 else
161 alu = FbStipple1Rop(alu, fg);
162 }
163 else {
164 fgand = fbAnd(alu, fg, pm);
165 fgxor = fbXor(alu, fg, pm);
166 if (opaque) {
167 bgand = fbAnd(alu, bg, pm);
168 bgxor = fbXor(alu, bg, pm);
169 }
170 else {
171 bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES);
172 bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES);
173 }
174 }
175
176 for (nbox = RegionNumRects(pClip),
177 pbox = RegionRects(pClip); nbox--; pbox++) {
178 x1 = x;
179 y1 = y;
180 x2 = x + width;
181 y2 = y + height;
182 if (x1 < pbox->x1)
183 x1 = pbox->x1;
184 if (y1 < pbox->y1)
185 y1 = pbox->y1;
186 if (x2 > pbox->x2)
187 x2 = pbox->x2;
188 if (y2 > pbox->y2)
189 y2 = pbox->y2;
190 if (x1 >= x2 || y1 >= y2)
191 continue;
192 if (dstBpp == 1) {
193 fbBltStip(src + (y1 - y) * srcStride,
194 srcStride,
195 (x1 - x) + srcX,
196 (FbStip *) (dst + (y1 + dstYoff) * dstStride),
197 FbBitsStrideToStipStride(dstStride),
198 (x1 + dstXoff) * dstBpp,
199 (x2 - x1) * dstBpp, (y2 - y1), alu, pm, dstBpp);
200 }
201 else {
202 fbBltOne(src + (y1 - y) * srcStride,
203 srcStride,
204 (x1 - x) + srcX,
205 dst + (y1 + dstYoff) * dstStride,
206 dstStride,
207 (x1 + dstXoff) * dstBpp,
208 dstBpp,
209 (x2 - x1) * dstBpp, (y2 - y1), fgand, fgxor, bgand, bgxor);
210 }
211 }
212
213 fbFinishAccess(pDrawable);
214}
215
216void
217fbGetImage(DrawablePtr pDrawable,
218 int x,
219 int y,
220 int w, int h, unsigned int format, unsigned long planeMask, char *d)
221{
222 FbBits *src;
223 FbStride srcStride;
224 int srcBpp;
225 int srcXoff, srcYoff;
226 FbStip *dst;
227 FbStride dstStride;
228
229 /*
230 * XFree86 DDX empties the root borderClip when the VT is
231 * switched away; this checks for that case
232 */
233 if (!fbDrawableEnabled(pDrawable))
234 return;
235
236 if (format == ZPixmap &&
237 pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth)) {
238 fb24_32GetImage(pDrawable, x, y, w, h, format, planeMask, d);
239 return;
240 }
241
242 fbGetDrawable(pDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
243
244 x += pDrawable->x;
245 y += pDrawable->y;
246
247 dst = (FbStip *) d;
248 if (format == ZPixmap || srcBpp == 1) {
249 FbBits pm;
250
251 pm = fbReplicatePixel(planeMask, srcBpp);
252 dstStride = PixmapBytePad(w, pDrawable->depth);
253 if (pm != FB_ALLONES)
254 memset(d, 0, dstStride * h);
255 dstStride /= sizeof(FbStip);
256 fbBltStip((FbStip *) (src + (y + srcYoff) * srcStride),
257 FbBitsStrideToStipStride(srcStride),
258 (x + srcXoff) * srcBpp,
259 dst, dstStride, 0, w * srcBpp, h, GXcopy, pm, srcBpp);
260 }
261 else {
262 dstStride = BitmapBytePad(w) / sizeof(FbStip);
263 fbBltPlane(src + (y + srcYoff) * srcStride,
264 srcStride,
265 (x + srcXoff) * srcBpp,
266 srcBpp,
267 dst,
268 dstStride,
269 0,
270 w * srcBpp, h,
271 fbAndStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES),
272 fbXorStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES),
273 fbAndStip(GXcopy, 0, FB_STIP_ALLONES),
274 fbXorStip(GXcopy, 0, FB_STIP_ALLONES), planeMask);
275 }
276
277 fbFinishAccess(pDrawable);
278}