Add patch that contain Mali fixes.
[deb_xorg-server.git] / fb / fb24_32.c
CommitLineData
a09e091a
JB
1/*
2 * Copyright © 2000 SuSE, Inc.
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 SuSE not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. SuSE makes no representations about the
11 * suitability of this software for any purpose. It is provided "as is"
12 * without express or implied warranty.
13 *
14 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
16 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
18 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
19 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 *
21 * Author: Keith Packard, SuSE, Inc.
22 */
23
24#ifdef HAVE_DIX_CONFIG_H
25#include <dix-config.h>
26#endif
27
28#include <string.h>
29
30#include "fb.h"
31
32/* X apps don't like 24bpp images, this code exposes 32bpp images */
33
34/*
35 * These two functions do a full CopyArea while reformatting
36 * the data between 24 and 32bpp. They try to go a bit faster
37 * by reading/writing aligned CARD32s where it's easy
38 */
39
40#define Get8(a) ((CARD32) READ(a))
41
42#if BITMAP_BIT_ORDER == MSBFirst
43#define Get24(a) ((Get8(a) << 16) | (Get8((a)+1) << 8) | Get8((a)+2))
44#define Put24(a,p) ((WRITE((a+0), (CARD8) ((p) >> 16))), \
45 (WRITE((a+1), (CARD8) ((p) >> 8))), \
46 (WRITE((a+2), (CARD8) (p))))
47#else
48#define Get24(a) (Get8(a) | (Get8((a)+1) << 8) | (Get8((a)+2)<<16))
49#define Put24(a,p) ((WRITE((a+0), (CARD8) (p))), \
50 (WRITE((a+1), (CARD8) ((p) >> 8))), \
51 (WRITE((a+2), (CARD8) ((p) >> 16))))
52#endif
53
54typedef void (*fb24_32BltFunc) (CARD8 *srcLine,
55 FbStride srcStride,
56 int srcX,
57 CARD8 *dstLine,
58 FbStride dstStride,
59 int dstX,
60 int width, int height, int alu, FbBits pm);
61
62static void
63fb24_32BltDown(CARD8 *srcLine,
64 FbStride srcStride,
65 int srcX,
66 CARD8 *dstLine,
67 FbStride dstStride,
68 int dstX, int width, int height, int alu, FbBits pm)
69{
70 CARD32 *src;
71 CARD8 *dst;
72 int w;
73 Bool destInvarient;
74 CARD32 pixel, dpixel;
75
76 FbDeclareMergeRop();
77
78 srcLine += srcX * 4;
79 dstLine += dstX * 3;
80
81 FbInitializeMergeRop(alu, (pm | ~(FbBits) 0xffffff));
82 destInvarient = FbDestInvarientMergeRop();
83
84 while (height--) {
85 src = (CARD32 *) srcLine;
86 dst = dstLine;
87 srcLine += srcStride;
88 dstLine += dstStride;
89 w = width;
90 if (destInvarient) {
91 while (((long) dst & 3) && w) {
92 w--;
93 pixel = READ(src++);
94 pixel = FbDoDestInvarientMergeRop(pixel);
95 Put24(dst, pixel);
96 dst += 3;
97 }
98 /* Do four aligned pixels at a time */
99 while (w >= 4) {
100 CARD32 s0, s1;
101
102 s0 = READ(src++);
103 s0 = FbDoDestInvarientMergeRop(s0);
104 s1 = READ(src++);
105 s1 = FbDoDestInvarientMergeRop(s1);
106#if BITMAP_BIT_ORDER == LSBFirst
107 WRITE((CARD32 *) dst, (s0 & 0xffffff) | (s1 << 24));
108#else
109 WRITE((CARD32 *) dst, (s0 << 8) | ((s1 & 0xffffff) >> 16));
110#endif
111 s0 = READ(src++);
112 s0 = FbDoDestInvarientMergeRop(s0);
113#if BITMAP_BIT_ORDER == LSBFirst
114 WRITE((CARD32 *) (dst + 4),
115 ((s1 & 0xffffff) >> 8) | (s0 << 16));
116#else
117 WRITE((CARD32 *) (dst + 4),
118 (s1 << 16) | ((s0 & 0xffffff) >> 8));
119#endif
120 s1 = READ(src++);
121 s1 = FbDoDestInvarientMergeRop(s1);
122#if BITMAP_BIT_ORDER == LSBFirst
123 WRITE((CARD32 *) (dst + 8),
124 ((s0 & 0xffffff) >> 16) | (s1 << 8));
125#else
126 WRITE((CARD32 *) (dst + 8), (s0 << 24) | (s1 & 0xffffff));
127#endif
128 dst += 12;
129 w -= 4;
130 }
131 while (w--) {
132 pixel = READ(src++);
133 pixel = FbDoDestInvarientMergeRop(pixel);
134 Put24(dst, pixel);
135 dst += 3;
136 }
137 }
138 else {
139 while (w--) {
140 pixel = READ(src++);
141 dpixel = Get24(dst);
142 pixel = FbDoMergeRop(pixel, dpixel);
143 Put24(dst, pixel);
144 dst += 3;
145 }
146 }
147 }
148}
149
150static void
151fb24_32BltUp(CARD8 *srcLine,
152 FbStride srcStride,
153 int srcX,
154 CARD8 *dstLine,
155 FbStride dstStride,
156 int dstX, int width, int height, int alu, FbBits pm)
157{
158 CARD8 *src;
159 CARD32 *dst;
160 int w;
161 Bool destInvarient;
162 CARD32 pixel;
163
164 FbDeclareMergeRop();
165
166 FbInitializeMergeRop(alu, (pm | (~(FbBits) 0xffffff)));
167 destInvarient = FbDestInvarientMergeRop();
168
169 srcLine += srcX * 3;
170 dstLine += dstX * 4;
171
172 while (height--) {
173 w = width;
174 src = srcLine;
175 dst = (CARD32 *) dstLine;
176 srcLine += srcStride;
177 dstLine += dstStride;
178 if (destInvarient) {
179 while (((long) src & 3) && w) {
180 w--;
181 pixel = Get24(src);
182 src += 3;
183 WRITE(dst++, FbDoDestInvarientMergeRop(pixel));
184 }
185 /* Do four aligned pixels at a time */
186 while (w >= 4) {
187 CARD32 s0, s1;
188
189 s0 = READ((CARD32 *) src);
190#if BITMAP_BIT_ORDER == LSBFirst
191 pixel = s0 & 0xffffff;
192#else
193 pixel = s0 >> 8;
194#endif
195 WRITE(dst++, FbDoDestInvarientMergeRop(pixel));
196 s1 = READ((CARD32 *) (src + 4));
197#if BITMAP_BIT_ORDER == LSBFirst
198 pixel = (s0 >> 24) | ((s1 << 8) & 0xffffff);
199#else
200 pixel = ((s0 << 16) & 0xffffff) | (s1 >> 16);
201#endif
202 WRITE(dst++, FbDoDestInvarientMergeRop(pixel));
203 s0 = READ((CARD32 *) (src + 8));
204#if BITMAP_BIT_ORDER == LSBFirst
205 pixel = (s1 >> 16) | ((s0 << 16) & 0xffffff);
206#else
207 pixel = ((s1 << 8) & 0xffffff) | (s0 >> 24);
208#endif
209 WRITE(dst++, FbDoDestInvarientMergeRop(pixel));
210#if BITMAP_BIT_ORDER == LSBFirst
211 pixel = s0 >> 8;
212#else
213 pixel = s0 & 0xffffff;
214#endif
215 WRITE(dst++, FbDoDestInvarientMergeRop(pixel));
216 src += 12;
217 w -= 4;
218 }
219 while (w) {
220 w--;
221 pixel = Get24(src);
222 src += 3;
223 WRITE(dst++, FbDoDestInvarientMergeRop(pixel));
224 }
225 }
226 else {
227 while (w--) {
228 pixel = Get24(src);
229 src += 3;
230 WRITE(dst, FbDoMergeRop(pixel, READ(dst)));
231 dst++;
232 }
233 }
234 }
235}
236
237/*
238 * Spans functions; probably unused.
239 */
240void
241fb24_32GetSpans(DrawablePtr pDrawable,
242 int wMax,
243 DDXPointPtr ppt, int *pwidth, int nspans, char *pchardstStart)
244{
245 FbBits *srcBits;
246 CARD8 *src;
247 FbStride srcStride;
248 int srcBpp;
249 int srcXoff, srcYoff;
250 CARD8 *dst;
251
252 fbGetDrawable(pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
253 src = (CARD8 *) srcBits;
254 srcStride *= sizeof(FbBits);
255
256 while (nspans--) {
257 dst = (CARD8 *) pchardstStart;
258 fb24_32BltUp(src + (ppt->y + srcYoff) * srcStride, srcStride,
259 ppt->x + srcXoff,
260 dst, 1, 0, *pwidth, 1, GXcopy, FB_ALLONES);
261
262 pchardstStart += PixmapBytePad(*pwidth, pDrawable->depth);
263 ppt++;
264 pwidth++;
265 }
266
267 fbFinishAccess(pDrawable);
268}
269
270void
271fb24_32SetSpans(DrawablePtr pDrawable,
272 GCPtr pGC,
273 char *src,
274 DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
275{
276 FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
277 RegionPtr pClip = fbGetCompositeClip(pGC);
278 FbBits *dstBits;
279 CARD8 *dst, *d, *s;
280 FbStride dstStride;
281 int dstBpp;
282 int dstXoff, dstYoff;
283 BoxPtr pbox;
284 int n;
285 int x1, x2;
286
287 fbGetDrawable(pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
288 dst = (CARD8 *) dstBits;
289 dstStride *= sizeof(FbBits);
290 while (nspans--) {
291 d = dst + (ppt->y + dstYoff) * dstStride;
292 s = (CARD8 *) src;
293 n = RegionNumRects(pClip);
294 pbox = RegionRects(pClip);
295 while (n--) {
296 if (pbox->y1 > ppt->y)
297 break;
298 if (pbox->y2 > ppt->y) {
299 x1 = ppt->x;
300 x2 = x1 + *pwidth;
301 if (pbox->x1 > x1)
302 x1 = pbox->x1;
303 if (pbox->x2 < x2)
304 x2 = pbox->x2;
305 if (x1 < x2)
306 fb24_32BltDown(s,
307 0,
308 (x1 - ppt->x),
309 d,
310 dstStride,
311 x1 + dstXoff,
312 (x2 - x1), 1, pGC->alu, pPriv->pm);
313 }
314 }
315 src += PixmapBytePad(*pwidth, pDrawable->depth);
316 ppt++;
317 pwidth++;
318 }
319
320 fbFinishAccess(pDrawable);
321}
322
323/*
324 * Clip and put 32bpp Z-format images to a 24bpp drawable
325 */
326void
327fb24_32PutZImage(DrawablePtr pDrawable,
328 RegionPtr pClip,
329 int alu,
330 FbBits pm,
331 int x,
332 int y, int width, int height, CARD8 *src, FbStride srcStride)
333{
334 FbBits *dstBits;
335 CARD8 *dst;
336 FbStride dstStride;
337 int dstBpp;
338 int dstXoff, dstYoff;
339 int nbox;
340 BoxPtr pbox;
341 int x1, y1, x2, y2;
342
343 fbGetDrawable(pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
344 dstStride *= sizeof(FbBits);
345 dst = (CARD8 *) dstBits;
346
347 for (nbox = RegionNumRects(pClip),
348 pbox = RegionRects(pClip); nbox--; pbox++) {
349 x1 = x;
350 y1 = y;
351 x2 = x + width;
352 y2 = y + height;
353 if (x1 < pbox->x1)
354 x1 = pbox->x1;
355 if (y1 < pbox->y1)
356 y1 = pbox->y1;
357 if (x2 > pbox->x2)
358 x2 = pbox->x2;
359 if (y2 > pbox->y2)
360 y2 = pbox->y2;
361 if (x1 >= x2 || y1 >= y2)
362 continue;
363 fb24_32BltDown(src + (y1 - y) * srcStride,
364 srcStride,
365 (x1 - x),
366 dst + (y1 + dstYoff) * dstStride,
367 dstStride, x1 + dstXoff, (x2 - x1), (y2 - y1), alu, pm);
368 }
369
370 fbFinishAccess(pDrawable);
371}
372
373void
374fb24_32GetImage(DrawablePtr pDrawable,
375 int x,
376 int y,
377 int w,
378 int h, unsigned int format, unsigned long planeMask, char *d)
379{
380 FbBits *srcBits;
381 CARD8 *src;
382 FbStride srcStride;
383 int srcBpp;
384 int srcXoff, srcYoff;
385 FbStride dstStride;
386 FbBits pm;
387
388 fbGetDrawable(pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
389 src = (CARD8 *) srcBits;
390 srcStride *= sizeof(FbBits);
391
392 x += pDrawable->x;
393 y += pDrawable->y;
394
395 pm = fbReplicatePixel(planeMask, 32);
396 dstStride = PixmapBytePad(w, pDrawable->depth);
397 if (pm != FB_ALLONES)
398 memset(d, 0, dstStride * h);
399 fb24_32BltUp(src + (y + srcYoff) * srcStride, srcStride, x + srcXoff,
400 (CARD8 *) d, dstStride, 0, w, h, GXcopy, pm);
401
402 fbFinishAccess(pDrawable);
403}
404
405void
406fb24_32CopyMtoN(DrawablePtr pSrcDrawable,
407 DrawablePtr pDstDrawable,
408 GCPtr pGC,
409 BoxPtr pbox,
410 int nbox,
411 int dx,
412 int dy,
413 Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
414{
415 FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
416 FbBits *srcBits;
417 CARD8 *src;
418 FbStride srcStride;
419 int srcBpp;
420 FbBits *dstBits;
421 CARD8 *dst;
422 FbStride dstStride;
423 int dstBpp;
424 fb24_32BltFunc blt;
425 int srcXoff, srcYoff;
426 int dstXoff, dstYoff;
427
428 fbGetDrawable(pSrcDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
429 src = (CARD8 *) srcBits;
430 srcStride *= sizeof(FbBits);
431 fbGetDrawable(pDstDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
432 dst = (CARD8 *) dstBits;
433 dstStride *= sizeof(FbBits);
434 if (srcBpp == 24)
435 blt = fb24_32BltUp;
436 else
437 blt = fb24_32BltDown;
438
439 while (nbox--) {
440 (*blt) (src + (pbox->y1 + dy + srcYoff) * srcStride,
441 srcStride,
442 (pbox->x1 + dx + srcXoff),
443 dst + (pbox->y1 + dstYoff) * dstStride,
444 dstStride,
445 (pbox->x1 + dstXoff),
446 (pbox->x2 - pbox->x1),
447 (pbox->y2 - pbox->y1), pGC->alu, pPriv->pm);
448 pbox++;
449 }
450
451 fbFinishAccess(pSrcDrawable);
452 fbFinishAccess(pDstDrawable);
453}
454
455PixmapPtr
456fb24_32ReformatTile(PixmapPtr pOldTile, int bitsPerPixel)
457{
458 ScreenPtr pScreen = pOldTile->drawable.pScreen;
459 PixmapPtr pNewTile;
460 FbBits *old, *new;
461 FbStride oldStride, newStride;
462 int oldBpp, newBpp;
463 fb24_32BltFunc blt;
464 _X_UNUSED int oldXoff, oldYoff;
465 _X_UNUSED int newXoff, newYoff;
466
467 pNewTile = pScreen->CreatePixmap(pScreen, pOldTile->drawable.width,
468 pOldTile->drawable.height,
469 pOldTile->drawable.depth,
470 pOldTile->usage_hint);
471 if (!pNewTile)
472 return 0;
473 fbGetDrawable(&pOldTile->drawable,
474 old, oldStride, oldBpp, oldXoff, oldYoff);
475 fbGetDrawable(&pNewTile->drawable,
476 new, newStride, newBpp, newXoff, newYoff);
477 if (oldBpp == 24)
478 blt = fb24_32BltUp;
479 else
480 blt = fb24_32BltDown;
481
482 (*blt) ((CARD8 *) old,
483 oldStride * sizeof(FbBits),
484 0,
485 (CARD8 *) new,
486 newStride * sizeof(FbBits),
487 0,
488 pOldTile->drawable.width,
489 pOldTile->drawable.height, GXcopy, FB_ALLONES);
490
491 fbFinishAccess(&pOldTile->drawable);
492 fbFinishAccess(&pNewTile->drawable);
493
494 return pNewTile;
495}
496
497typedef struct {
498 pointer pbits;
499 int width;
500} miScreenInitParmsRec, *miScreenInitParmsPtr;
501
502Bool
503fb24_32CreateScreenResources(ScreenPtr pScreen)
504{
505 miScreenInitParmsPtr pScrInitParms;
506 int pitch;
507 Bool retval;
508
509 /* get the pitch before mi destroys it */
510 pScrInitParms = (miScreenInitParmsPtr) pScreen->devPrivate;
511 pitch = BitmapBytePad(pScrInitParms->width * 24);
512
513 if ((retval = miCreateScreenResources(pScreen))) {
514 /* fix the screen pixmap */
515 PixmapPtr pPix = (PixmapPtr) pScreen->devPrivate;
516
517 pPix->drawable.bitsPerPixel = 24;
518 pPix->devKind = pitch;
519 }
520
521 return retval;
522}
523
524Bool
525fb24_32ModifyPixmapHeader(PixmapPtr pPixmap,
526 int width,
527 int height,
528 int depth,
529 int bitsPerPixel, int devKind, pointer pPixData)
530{
531 int bpp, w;
532
533 if (!pPixmap)
534 return FALSE;
535 bpp = bitsPerPixel;
536 if (bpp <= 0)
537 bpp = pPixmap->drawable.bitsPerPixel;
538 if (bpp == 24) {
539 if (devKind < 0) {
540 w = width;
541 if (w <= 0)
542 w = pPixmap->drawable.width;
543 devKind = BitmapBytePad(w * 24);
544 }
545 }
546 return miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel,
547 devKind, pPixData);
548}