2 * Copyright © 2000 SuSE, Inc.
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.
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.
21 * Author: Keith Packard, SuSE, Inc.
24 #ifdef HAVE_DIX_CONFIG_H
25 #include <dix-config.h>
32 /* X apps don't like 24bpp images, this code exposes 32bpp images */
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
40 #define Get8(a) ((CARD32) READ(a))
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))))
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))))
54 typedef void (*fb24_32BltFunc
) (CARD8
*srcLine
,
60 int width
, int height
, int alu
, FbBits pm
);
63 fb24_32BltDown(CARD8
*srcLine
,
68 int dstX
, int width
, int height
, int alu
, FbBits pm
)
81 FbInitializeMergeRop(alu
, (pm
| ~(FbBits
) 0xffffff));
82 destInvarient
= FbDestInvarientMergeRop();
85 src
= (CARD32
*) srcLine
;
91 while (((long) dst
& 3) && w
) {
94 pixel
= FbDoDestInvarientMergeRop(pixel
);
98 /* Do four aligned pixels at a time */
103 s0
= FbDoDestInvarientMergeRop(s0
);
105 s1
= FbDoDestInvarientMergeRop(s1
);
106 #if BITMAP_BIT_ORDER == LSBFirst
107 WRITE((CARD32
*) dst
, (s0
& 0xffffff) | (s1
<< 24));
109 WRITE((CARD32
*) dst
, (s0
<< 8) | ((s1
& 0xffffff) >> 16));
112 s0
= FbDoDestInvarientMergeRop(s0
);
113 #if BITMAP_BIT_ORDER == LSBFirst
114 WRITE((CARD32
*) (dst
+ 4),
115 ((s1
& 0xffffff) >> 8) | (s0
<< 16));
117 WRITE((CARD32
*) (dst
+ 4),
118 (s1
<< 16) | ((s0
& 0xffffff) >> 8));
121 s1
= FbDoDestInvarientMergeRop(s1
);
122 #if BITMAP_BIT_ORDER == LSBFirst
123 WRITE((CARD32
*) (dst
+ 8),
124 ((s0
& 0xffffff) >> 16) | (s1
<< 8));
126 WRITE((CARD32
*) (dst
+ 8), (s0
<< 24) | (s1
& 0xffffff));
133 pixel
= FbDoDestInvarientMergeRop(pixel
);
142 pixel
= FbDoMergeRop(pixel
, dpixel
);
151 fb24_32BltUp(CARD8
*srcLine
,
156 int dstX
, int width
, int height
, int alu
, FbBits pm
)
166 FbInitializeMergeRop(alu
, (pm
| (~(FbBits
) 0xffffff)));
167 destInvarient
= FbDestInvarientMergeRop();
175 dst
= (CARD32
*) dstLine
;
176 srcLine
+= srcStride
;
177 dstLine
+= dstStride
;
179 while (((long) src
& 3) && w
) {
183 WRITE(dst
++, FbDoDestInvarientMergeRop(pixel
));
185 /* Do four aligned pixels at a time */
189 s0
= READ((CARD32
*) src
);
190 #if BITMAP_BIT_ORDER == LSBFirst
191 pixel
= s0
& 0xffffff;
195 WRITE(dst
++, FbDoDestInvarientMergeRop(pixel
));
196 s1
= READ((CARD32
*) (src
+ 4));
197 #if BITMAP_BIT_ORDER == LSBFirst
198 pixel
= (s0
>> 24) | ((s1
<< 8) & 0xffffff);
200 pixel
= ((s0
<< 16) & 0xffffff) | (s1
>> 16);
202 WRITE(dst
++, FbDoDestInvarientMergeRop(pixel
));
203 s0
= READ((CARD32
*) (src
+ 8));
204 #if BITMAP_BIT_ORDER == LSBFirst
205 pixel
= (s1
>> 16) | ((s0
<< 16) & 0xffffff);
207 pixel
= ((s1
<< 8) & 0xffffff) | (s0
>> 24);
209 WRITE(dst
++, FbDoDestInvarientMergeRop(pixel
));
210 #if BITMAP_BIT_ORDER == LSBFirst
213 pixel
= s0
& 0xffffff;
215 WRITE(dst
++, FbDoDestInvarientMergeRop(pixel
));
223 WRITE(dst
++, FbDoDestInvarientMergeRop(pixel
));
230 WRITE(dst
, FbDoMergeRop(pixel
, READ(dst
)));
238 * Spans functions; probably unused.
241 fb24_32GetSpans(DrawablePtr pDrawable
,
243 DDXPointPtr ppt
, int *pwidth
, int nspans
, char *pchardstStart
)
249 int srcXoff
, srcYoff
;
252 fbGetDrawable(pDrawable
, srcBits
, srcStride
, srcBpp
, srcXoff
, srcYoff
);
253 src
= (CARD8
*) srcBits
;
254 srcStride
*= sizeof(FbBits
);
257 dst
= (CARD8
*) pchardstStart
;
258 fb24_32BltUp(src
+ (ppt
->y
+ srcYoff
) * srcStride
, srcStride
,
260 dst
, 1, 0, *pwidth
, 1, GXcopy
, FB_ALLONES
);
262 pchardstStart
+= PixmapBytePad(*pwidth
, pDrawable
->depth
);
267 fbFinishAccess(pDrawable
);
271 fb24_32SetSpans(DrawablePtr pDrawable
,
274 DDXPointPtr ppt
, int *pwidth
, int nspans
, int fSorted
)
276 FbGCPrivPtr pPriv
= fbGetGCPrivate(pGC
);
277 RegionPtr pClip
= fbGetCompositeClip(pGC
);
282 int dstXoff
, dstYoff
;
287 fbGetDrawable(pDrawable
, dstBits
, dstStride
, dstBpp
, dstXoff
, dstYoff
);
288 dst
= (CARD8
*) dstBits
;
289 dstStride
*= sizeof(FbBits
);
291 d
= dst
+ (ppt
->y
+ dstYoff
) * dstStride
;
293 n
= RegionNumRects(pClip
);
294 pbox
= RegionRects(pClip
);
296 if (pbox
->y1
> ppt
->y
)
298 if (pbox
->y2
> ppt
->y
) {
312 (x2
- x1
), 1, pGC
->alu
, pPriv
->pm
);
315 src
+= PixmapBytePad(*pwidth
, pDrawable
->depth
);
320 fbFinishAccess(pDrawable
);
324 * Clip and put 32bpp Z-format images to a 24bpp drawable
327 fb24_32PutZImage(DrawablePtr pDrawable
,
332 int y
, int width
, int height
, CARD8
*src
, FbStride srcStride
)
338 int dstXoff
, dstYoff
;
343 fbGetDrawable(pDrawable
, dstBits
, dstStride
, dstBpp
, dstXoff
, dstYoff
);
344 dstStride
*= sizeof(FbBits
);
345 dst
= (CARD8
*) dstBits
;
347 for (nbox
= RegionNumRects(pClip
),
348 pbox
= RegionRects(pClip
); nbox
--; pbox
++) {
361 if (x1
>= x2
|| y1
>= y2
)
363 fb24_32BltDown(src
+ (y1
- y
) * srcStride
,
366 dst
+ (y1
+ dstYoff
) * dstStride
,
367 dstStride
, x1
+ dstXoff
, (x2
- x1
), (y2
- y1
), alu
, pm
);
370 fbFinishAccess(pDrawable
);
374 fb24_32GetImage(DrawablePtr pDrawable
,
378 int h
, unsigned int format
, unsigned long planeMask
, char *d
)
384 int srcXoff
, srcYoff
;
388 fbGetDrawable(pDrawable
, srcBits
, srcStride
, srcBpp
, srcXoff
, srcYoff
);
389 src
= (CARD8
*) srcBits
;
390 srcStride
*= sizeof(FbBits
);
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
);
402 fbFinishAccess(pDrawable
);
406 fb24_32CopyMtoN(DrawablePtr pSrcDrawable
,
407 DrawablePtr pDstDrawable
,
413 Bool reverse
, Bool upsidedown
, Pixel bitplane
, void *closure
)
415 FbGCPrivPtr pPriv
= fbGetGCPrivate(pGC
);
425 int srcXoff
, srcYoff
;
426 int dstXoff
, dstYoff
;
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
);
437 blt
= fb24_32BltDown
;
440 (*blt
) (src
+ (pbox
->y1
+ dy
+ srcYoff
) * srcStride
,
442 (pbox
->x1
+ dx
+ srcXoff
),
443 dst
+ (pbox
->y1
+ dstYoff
) * dstStride
,
445 (pbox
->x1
+ dstXoff
),
446 (pbox
->x2
- pbox
->x1
),
447 (pbox
->y2
- pbox
->y1
), pGC
->alu
, pPriv
->pm
);
451 fbFinishAccess(pSrcDrawable
);
452 fbFinishAccess(pDstDrawable
);
456 fb24_32ReformatTile(PixmapPtr pOldTile
, int bitsPerPixel
)
458 ScreenPtr pScreen
= pOldTile
->drawable
.pScreen
;
461 FbStride oldStride
, newStride
;
464 _X_UNUSED
int oldXoff
, oldYoff
;
465 _X_UNUSED
int newXoff
, newYoff
;
467 pNewTile
= pScreen
->CreatePixmap(pScreen
, pOldTile
->drawable
.width
,
468 pOldTile
->drawable
.height
,
469 pOldTile
->drawable
.depth
,
470 pOldTile
->usage_hint
);
473 fbGetDrawable(&pOldTile
->drawable
,
474 old
, oldStride
, oldBpp
, oldXoff
, oldYoff
);
475 fbGetDrawable(&pNewTile
->drawable
,
476 new, newStride
, newBpp
, newXoff
, newYoff
);
480 blt
= fb24_32BltDown
;
482 (*blt
) ((CARD8
*) old
,
483 oldStride
* sizeof(FbBits
),
486 newStride
* sizeof(FbBits
),
488 pOldTile
->drawable
.width
,
489 pOldTile
->drawable
.height
, GXcopy
, FB_ALLONES
);
491 fbFinishAccess(&pOldTile
->drawable
);
492 fbFinishAccess(&pNewTile
->drawable
);
500 } miScreenInitParmsRec
, *miScreenInitParmsPtr
;
503 fb24_32CreateScreenResources(ScreenPtr pScreen
)
505 miScreenInitParmsPtr pScrInitParms
;
509 /* get the pitch before mi destroys it */
510 pScrInitParms
= (miScreenInitParmsPtr
) pScreen
->devPrivate
;
511 pitch
= BitmapBytePad(pScrInitParms
->width
* 24);
513 if ((retval
= miCreateScreenResources(pScreen
))) {
514 /* fix the screen pixmap */
515 PixmapPtr pPix
= (PixmapPtr
) pScreen
->devPrivate
;
517 pPix
->drawable
.bitsPerPixel
= 24;
518 pPix
->devKind
= pitch
;
525 fb24_32ModifyPixmapHeader(PixmapPtr pPixmap
,
529 int bitsPerPixel
, int devKind
, pointer pPixData
)
537 bpp
= pPixmap
->drawable
.bitsPerPixel
;
542 w
= pPixmap
->drawable
.width
;
543 devKind
= BitmapBytePad(w
* 24);
546 return miModifyPixmapHeader(pPixmap
, width
, height
, depth
, bitsPerPixel
,