123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587 |
- /*
- *
- * Copyright © 2000 SuSE, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of SuSE not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. SuSE makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: Keith Packard, SuSE, Inc.
- */
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #include <string.h>
- #include "fb.h"
- /* X apps don't like 24bpp images, this code exposes 32bpp images */
- /*
- * These two functions do a full CopyArea while reformatting
- * the data between 24 and 32bpp. They try to go a bit faster
- * by reading/writing aligned CARD32s where it's easy
- */
- #define Get8(a) ((CARD32) *(a))
- #if BITMAP_BIT_ORDER == MSBFirst
- #define Get24(a) ((Get8(a) << 16) | (Get8((a)+1) << 8) | Get8((a)+2))
- #define Put24(a,p) (((a)[0] = (CARD8) ((p) >> 16)), \
- ((a)[1] = (CARD8) ((p) >> 8)), \
- ((a)[2] = (CARD8) (p)))
- #else
- #define Get24(a) (Get8(a) | (Get8((a)+1) << 8) | (Get8((a)+2)<<16))
- #define Put24(a,p) (((a)[0] = (CARD8) (p)), \
- ((a)[1] = (CARD8) ((p) >> 8)), \
- ((a)[2] = (CARD8) ((p) >> 16)))
- #endif
- typedef void (*fb24_32BltFunc) (CARD8 *srcLine,
- FbStride srcStride,
- int srcX,
- CARD8 *dstLine,
- FbStride dstStride,
- int dstX,
- int width, int height, int alu, FbBits pm);
- static void
- fb24_32BltDown(CARD8 *srcLine,
- FbStride srcStride,
- int srcX,
- CARD8 *dstLine,
- FbStride dstStride,
- int dstX, int width, int height, int alu, FbBits pm)
- {
- CARD32 *src;
- CARD8 *dst;
- int w;
- Bool destInvarient;
- CARD32 pixel, dpixel;
- FbDeclareMergeRop();
- srcLine += srcX * 4;
- dstLine += dstX * 3;
- FbInitializeMergeRop(alu, (pm | ~(FbBits) 0xffffff));
- destInvarient = FbDestInvarientMergeRop();
- while (height--) {
- src = (CARD32 *) srcLine;
- dst = dstLine;
- srcLine += srcStride;
- dstLine += dstStride;
- w = width;
- if (destInvarient) {
- while (((long) dst & 3) && w) {
- w--;
- pixel = *src++;
- pixel = FbDoDestInvarientMergeRop(pixel);
- Put24(dst, pixel);
- dst += 3;
- }
- /* Do four aligned pixels at a time */
- while (w >= 4) {
- CARD32 s0, s1;
- s0 = *src++;
- s0 = FbDoDestInvarientMergeRop(s0);
- s1 = *src++;
- s1 = FbDoDestInvarientMergeRop(s1);
- #if BITMAP_BIT_ORDER == LSBFirst
- *(CARD32 *) (dst) = (s0 & 0xffffff) | (s1 << 24);
- #else
- *(CARD32 *) (dst) = (s0 << 8) | ((s1 & 0xffffff) >> 16);
- #endif
- s0 = *src++;
- s0 = FbDoDestInvarientMergeRop(s0);
- #if BITMAP_BIT_ORDER == LSBFirst
- *(CARD32 *) (dst + 4) = ((s1 & 0xffffff) >> 8) | (s0 << 16);
- #else
- *(CARD32 *) (dst + 4) = (s1 << 16) | ((s0 & 0xffffff) >> 8);
- #endif
- s1 = *src++;
- s1 = FbDoDestInvarientMergeRop(s1);
- #if BITMAP_BIT_ORDER == LSBFirst
- *(CARD32 *) (dst + 8) = ((s0 & 0xffffff) >> 16) | (s1 << 8);
- #else
- *(CARD32 *) (dst + 8) = (s0 << 24) | (s1 & 0xffffff);
- #endif
- dst += 12;
- w -= 4;
- }
- while (w--) {
- pixel = *src++;
- pixel = FbDoDestInvarientMergeRop(pixel);
- Put24(dst, pixel);
- dst += 3;
- }
- }
- else {
- while (w--) {
- pixel = *src++;
- dpixel = Get24(dst);
- pixel = FbDoMergeRop(pixel, dpixel);
- Put24(dst, pixel);
- dst += 3;
- }
- }
- }
- }
- static void
- fb24_32BltUp(CARD8 *srcLine,
- FbStride srcStride,
- int srcX,
- CARD8 *dstLine,
- FbStride dstStride,
- int dstX, int width, int height, int alu, FbBits pm)
- {
- CARD8 *src;
- CARD32 *dst;
- int w;
- Bool destInvarient;
- CARD32 pixel;
- FbDeclareMergeRop();
- FbInitializeMergeRop(alu, (pm | (~(FbBits) 0xffffff)));
- destInvarient = FbDestInvarientMergeRop();
- srcLine += srcX * 3;
- dstLine += dstX * 4;
- while (height--) {
- w = width;
- src = srcLine;
- dst = (CARD32 *) dstLine;
- srcLine += srcStride;
- dstLine += dstStride;
- if (destInvarient) {
- while (((long) src & 3) && w) {
- w--;
- pixel = Get24(src);
- src += 3;
- *dst++ = FbDoDestInvarientMergeRop(pixel);
- }
- /* Do four aligned pixels at a time */
- while (w >= 4) {
- CARD32 s0, s1;
- s0 = *(CARD32 *) (src);
- #if BITMAP_BIT_ORDER == LSBFirst
- pixel = s0 & 0xffffff;
- #else
- pixel = s0 >> 8;
- #endif
- *dst++ = FbDoDestInvarientMergeRop(pixel);
- s1 = *(CARD32 *) (src + 4);
- #if BITMAP_BIT_ORDER == LSBFirst
- pixel = (s0 >> 24) | ((s1 << 8) & 0xffffff);
- #else
- pixel = ((s0 << 16) & 0xffffff) | (s1 >> 16);
- #endif
- *dst++ = FbDoDestInvarientMergeRop(pixel);
- s0 = *(CARD32 *) (src + 8);
- #if BITMAP_BIT_ORDER == LSBFirst
- pixel = (s1 >> 16) | ((s0 << 16) & 0xffffff);
- #else
- pixel = ((s1 << 8) & 0xffffff) | (s0 >> 24);
- #endif
- *dst++ = FbDoDestInvarientMergeRop(pixel);
- #if BITMAP_BIT_ORDER == LSBFirst
- pixel = s0 >> 8;
- #else
- pixel = s0 & 0xffffff;
- #endif
- *dst++ = FbDoDestInvarientMergeRop(pixel);
- src += 12;
- w -= 4;
- }
- while (w) {
- w--;
- pixel = Get24(src);
- src += 3;
- *dst++ = FbDoDestInvarientMergeRop(pixel);
- }
- }
- else {
- while (w--) {
- pixel = Get24(src);
- src += 3;
- *dst = FbDoMergeRop(pixel, *dst);
- dst++;
- }
- }
- }
- }
- /*
- * Spans functions; probably unused.
- */
- void
- fb24_32GetSpans(DrawablePtr pDrawable,
- int wMax,
- DDXPointPtr ppt, int *pwidth, int nspans, char *pchardstStart)
- {
- FbBits *srcBits;
- CARD8 *src;
- FbStride srcStride;
- int srcBpp;
- int srcXoff, srcYoff;
- CARD8 *dst;
- fbGetDrawable(pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
- src = (CARD8 *) srcBits;
- srcStride *= sizeof(FbBits);
- while (nspans--) {
- dst = (CARD8 *) pchardstStart;
- fb24_32BltUp(src + (ppt->y + srcYoff) * srcStride, srcStride,
- ppt->x + srcXoff,
- dst, 1, 0, *pwidth, 1, GXcopy, FB_ALLONES);
- pchardstStart += PixmapBytePad(*pwidth, pDrawable->depth);
- ppt++;
- pwidth++;
- }
- }
- void
- fb24_32SetSpans(DrawablePtr pDrawable,
- GCPtr pGC,
- char *src,
- DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
- {
- FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
- RegionPtr pClip = fbGetCompositeClip(pGC);
- FbBits *dstBits;
- CARD8 *dst, *d, *s;
- FbStride dstStride;
- int dstBpp;
- int dstXoff, dstYoff;
- BoxPtr pbox;
- int n;
- int x1, x2;
- fbGetDrawable(pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
- dst = (CARD8 *) dstBits;
- dstStride *= sizeof(FbBits);
- while (nspans--) {
- d = dst + (ppt->y + dstYoff) * dstStride;
- s = (CARD8 *) src;
- n = REGION_NUM_RECTS(pClip);
- pbox = REGION_RECTS(pClip);
- while (n--) {
- if (pbox->y1 > ppt->y)
- break;
- if (pbox->y2 > ppt->y) {
- x1 = ppt->x;
- x2 = x1 + *pwidth;
- if (pbox->x1 > x1)
- x1 = pbox->x1;
- if (pbox->x2 < x2)
- x2 = pbox->x2;
- if (x1 < x2)
- fb24_32BltDown(s,
- 0,
- (x1 - ppt->x),
- d,
- dstStride,
- x1 + dstXoff,
- (x2 - x1), 1, pGC->alu, pPriv->pm);
- }
- }
- src += PixmapBytePad(*pwidth, pDrawable->depth);
- ppt++;
- pwidth++;
- }
- }
- /*
- * Clip and put 32bpp Z-format images to a 24bpp drawable
- */
- void
- fb24_32PutZImage(DrawablePtr pDrawable,
- RegionPtr pClip,
- int alu,
- FbBits pm,
- int x,
- int y, int width, int height, CARD8 *src, FbStride srcStride)
- {
- FbBits *dstBits;
- CARD8 *dst;
- FbStride dstStride;
- int dstBpp;
- int dstXoff, dstYoff;
- int nbox;
- BoxPtr pbox;
- int x1, y1, x2, y2;
- fbGetDrawable(pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
- dstStride *= sizeof(FbBits);
- dst = (CARD8 *) dstBits;
- for (nbox = REGION_NUM_RECTS(pClip),
- pbox = REGION_RECTS(pClip); nbox--; pbox++) {
- x1 = x;
- y1 = y;
- x2 = x + width;
- y2 = y + height;
- if (x1 < pbox->x1)
- x1 = pbox->x1;
- if (y1 < pbox->y1)
- y1 = pbox->y1;
- if (x2 > pbox->x2)
- x2 = pbox->x2;
- if (y2 > pbox->y2)
- y2 = pbox->y2;
- if (x1 >= x2 || y1 >= y2)
- continue;
- fb24_32BltDown(src + (y1 - y) * srcStride,
- srcStride,
- (x1 - x),
- dst + (y1 + dstYoff) * dstStride,
- dstStride, x1 + dstXoff, (x2 - x1), (y2 - y1), alu, pm);
- }
- }
- void
- fb24_32GetImage(DrawablePtr pDrawable,
- int x,
- int y,
- int w,
- int h, unsigned int format, unsigned long planeMask, char *d)
- {
- FbBits *srcBits;
- CARD8 *src;
- FbStride srcStride;
- int srcBpp;
- int srcXoff, srcYoff;
- FbStride dstStride;
- FbBits pm;
- fbGetDrawable(pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
- src = (CARD8 *) srcBits;
- srcStride *= sizeof(FbBits);
- x += pDrawable->x;
- y += pDrawable->y;
- pm = fbReplicatePixel(planeMask, 32);
- dstStride = PixmapBytePad(w, pDrawable->depth);
- if (pm != FB_ALLONES)
- memset(d, 0, dstStride * h);
- fb24_32BltUp(src + (y + srcYoff) * srcStride, srcStride, x + srcXoff,
- (CARD8 *) d, dstStride, 0, w, h, GXcopy, pm);
- }
- void
- fb24_32CopyMtoN(DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GCPtr pGC,
- BoxPtr pbox,
- int nbox,
- int dx,
- int dy,
- Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
- {
- FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
- FbBits *srcBits;
- CARD8 *src;
- FbStride srcStride;
- int srcBpp;
- FbBits *dstBits;
- CARD8 *dst;
- FbStride dstStride;
- int dstBpp;
- fb24_32BltFunc blt;
- int srcXoff, srcYoff;
- int dstXoff, dstYoff;
- fbGetDrawable(pSrcDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
- src = (CARD8 *) srcBits;
- srcStride *= sizeof(FbBits);
- fbGetDrawable(pDstDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
- dst = (CARD8 *) dstBits;
- dstStride *= sizeof(FbBits);
- if (srcBpp == 24)
- blt = fb24_32BltUp;
- else
- blt = fb24_32BltDown;
- while (nbox--) {
- (*blt) (src + (pbox->y1 + dy + srcYoff) * srcStride,
- srcStride,
- (pbox->x1 + dx + srcXoff),
- dst + (pbox->y1 + dstYoff) * dstStride,
- dstStride,
- (pbox->x1 + dstXoff),
- (pbox->x2 - pbox->x1),
- (pbox->y2 - pbox->y1), pGC->alu, pPriv->pm);
- pbox++;
- }
- }
- PixmapPtr
- fb24_32ReformatTile(PixmapPtr pOldTile, int bitsPerPixel)
- {
- ScreenPtr pScreen = pOldTile->drawable.pScreen;
- PixmapPtr pNewTile;
- FbBits *old, *new;
- FbStride oldStride, newStride;
- int oldBpp, newBpp;
- fb24_32BltFunc blt;
- int oldXoff _X_UNUSED, oldYoff _X_UNUSED;
- int newXoff _X_UNUSED, newYoff _X_UNUSED;
- pNewTile = fbCreatePixmapBpp(pScreen,
- pOldTile->drawable.width,
- pOldTile->drawable.height,
- pOldTile->drawable.depth, bitsPerPixel);
- if (!pNewTile)
- return 0;
- fbGetDrawable(&pOldTile->drawable,
- old, oldStride, oldBpp, oldXoff, oldYoff);
- fbGetDrawable(&pNewTile->drawable,
- new, newStride, newBpp, newXoff, newYoff);
- if (oldBpp == 24)
- blt = fb24_32BltUp;
- else
- blt = fb24_32BltDown;
- (*blt) ((CARD8 *) old,
- oldStride * sizeof(FbBits),
- 0,
- (CARD8 *) new,
- newStride * sizeof(FbBits),
- 0,
- pOldTile->drawable.width,
- pOldTile->drawable.height, GXcopy, FB_ALLONES);
- return pNewTile;
- }
- typedef struct {
- pointer pbits;
- int width;
- } miScreenInitParmsRec, *miScreenInitParmsPtr;
- Bool
- fb24_32CreateScreenResources(ScreenPtr pScreen)
- {
- miScreenInitParmsPtr pScrInitParms;
- int pitch;
- Bool retval;
- /* get the pitch before mi destroys it */
- pScrInitParms = (miScreenInitParmsPtr) pScreen->devPrivate;
- pitch = BitmapBytePad(pScrInitParms->width * 24);
- if ((retval = miCreateScreenResources(pScreen))) {
- /* fix the screen pixmap */
- PixmapPtr pPix = (PixmapPtr) pScreen->devPrivate;
- pPix->drawable.bitsPerPixel = 24;
- pPix->devKind = pitch;
- }
- return retval;
- }
- Bool
- fb24_32ModifyPixmapHeader(PixmapPtr pPixmap,
- int width,
- int height,
- int depth,
- int bitsPerPixel, int devKind, pointer pPixData)
- {
- int bpp, w;
- if (!pPixmap)
- return FALSE;
- bpp = bitsPerPixel;
- if (bpp <= 0)
- bpp = pPixmap->drawable.bitsPerPixel;
- if (bpp == 24) {
- if (devKind < 0) {
- w = width;
- if (w <= 0)
- w = pPixmap->drawable.width;
- devKind = BitmapBytePad(w * 24);
- }
- }
- return miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel,
- devKind, pPixData);
- }
|