diff options
Diffstat (limited to 'src/sna/fb/fb.h')
-rw-r--r-- | src/sna/fb/fb.h | 566 |
1 files changed, 566 insertions, 0 deletions
diff --git a/src/sna/fb/fb.h b/src/sna/fb/fb.h new file mode 100644 index 000000000..e58e03967 --- /dev/null +++ b/src/sna/fb/fb.h @@ -0,0 +1,566 @@ +/* + * Copyright © 1998 Keith Packard + * Copyright © 2012 Intel Corporation + * + * 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 Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD 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. + */ + +#ifndef FB_H +#define FB_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <xorg-server.h> +#include <servermd.h> +#include <gcstruct.h> +#include <colormap.h> +#include <windowstr.h> + +#include <stdbool.h> +#include <pixman.h> + +#if HAS_DEBUG_FULL +#define DBG(x) ErrorF x +#else +#define DBG(x) +#endif + +#include "sfb.h" + +#define WRITE(ptr, val) (*(ptr) = (val)) +#define READ(ptr) (*(ptr)) + +/* + * This single define controls the basic size of data manipulated + * by this software; it must be log2(sizeof (FbBits) * 8) + */ +#define FB_SHIFT LOG2_BITMAP_PAD + +#define FB_UNIT (1 << FB_SHIFT) +#define FB_HALFUNIT (1 << (FB_SHIFT-1)) +#define FB_MASK (FB_UNIT - 1) +#define FB_ALLONES ((FbBits) -1) + +#if IMAGE_BYTE_ORDER != LSBFirst +#error "IMAGE_BYTE_ORDER must be LSBFirst" +#endif + +#if GLYPHPADBYTES != 4 +#error "GLYPHPADBYTES must be 4" +#endif + +#if FB_SHIFT != 5 +#error "FB_SHIFT ala LOG2_BITMAP_PAD must be 5" +#endif + +#define FB_STIP_SHIFT LOG2_BITMAP_PAD +#define FB_STIP_UNIT (1 << FB_STIP_SHIFT) +#define FB_STIP_MASK (FB_STIP_UNIT - 1) +#define FB_STIP_ALLONES ((FbStip) -1) +#define FbFullMask(n) ((n) == FB_UNIT ? FB_ALLONES : ((((FbBits) 1) << n) - 1)) + +typedef uint32_t FbBits; +typedef FbBits FbStip; +typedef int FbStride; + +#include "fbrop.h" + +#define FbScrLeft(x,n) ((x) >> (n)) +#define FbScrRight(x,n) ((x) << (n)) +/* #define FbLeftBits(x,n) ((x) & ((((FbBits) 1) << (n)) - 1)) */ +#define FbLeftStipBits(x,n) ((x) & ((((FbStip) 1) << (n)) - 1)) +#define FbStipMoveLsb(x,s,n) (FbStipRight (x,(s)-(n))) +#define FbPatternOffsetBits 0 + +#define FbStipLeft(x,n) FbScrLeft(x,n) +#define FbStipRight(x,n) FbScrRight(x,n) + +#define FbRotLeft(x,n) FbScrLeft(x,n) | (n ? FbScrRight(x,FB_UNIT-n) : 0) +#define FbRotRight(x,n) FbScrRight(x,n) | (n ? FbScrLeft(x,FB_UNIT-n) : 0) + +#define FbRotStipLeft(x,n) FbStipLeft(x,n) | (n ? FbStipRight(x,FB_STIP_UNIT-n) : 0) +#define FbRotStipRight(x,n) FbStipRight(x,n) | (n ? FbStipLeft(x,FB_STIP_UNIT-n) : 0) + +#define FbLeftMask(x) ( ((x) & FB_MASK) ? \ + FbScrRight(FB_ALLONES,(x) & FB_MASK) : 0) +#define FbRightMask(x) ( ((FB_UNIT - (x)) & FB_MASK) ? \ + FbScrLeft(FB_ALLONES,(FB_UNIT - (x)) & FB_MASK) : 0) + +#define FbLeftStipMask(x) ( ((x) & FB_STIP_MASK) ? \ + FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) : 0) +#define FbRightStipMask(x) ( ((FB_STIP_UNIT - (x)) & FB_STIP_MASK) ? \ + FbScrLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - (x)) & FB_STIP_MASK) : 0) + +#define FbBitsMask(x,w) (FbScrRight(FB_ALLONES,(x) & FB_MASK) & \ + FbScrLeft(FB_ALLONES,(FB_UNIT - ((x) + (w))) & FB_MASK)) + +#define FbStipMask(x,w) (FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) & \ + FbStipLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - ((x)+(w))) & FB_STIP_MASK)) + +#define FbMaskBits(x,w,l,n,r) { \ + n = (w); \ + r = FbRightMask((x)+n); \ + l = FbLeftMask(x); \ + if (l) { \ + n -= FB_UNIT - ((x) & FB_MASK); \ + if (n < 0) { \ + n = 0; \ + l &= r; \ + r = 0; \ + } \ + } \ + n >>= FB_SHIFT; \ +} + +#define FbByteMaskInvalid 0x10 + +#define FbPatternOffset(o,t) ((o) ^ (FbPatternOffsetBits & ~(sizeof (t) - 1))) + +#define FbPtrOffset(p,o,t) ((t *) ((CARD8 *) (p) + (o))) +#define FbSelectPatternPart(xor,o,t) ((xor) >> (FbPatternOffset (o,t) << 3)) +#define FbStorePart(dst,off,t,xor) (WRITE(FbPtrOffset(dst,off,t), \ + FbSelectPart(xor,off,t))) +#ifndef FbSelectPart +#define FbSelectPart(x,o,t) FbSelectPatternPart(x,o,t) +#endif + +#define FbMaskBitsBytes(x,w,copy,l,lb,n,r,rb) { \ + n = (w); \ + lb = 0; \ + rb = 0; \ + r = FbRightMask((x)+n); \ + if (r) { \ + /* compute right byte length */ \ + if ((copy) && (((x) + n) & 7) == 0) { \ + rb = (((x) + n) & FB_MASK) >> 3; \ + } else { \ + rb = FbByteMaskInvalid; \ + } \ + } \ + l = FbLeftMask(x); \ + if (l) { \ + /* compute left byte length */ \ + if ((copy) && ((x) & 7) == 0) { \ + lb = ((x) & FB_MASK) >> 3; \ + } else { \ + lb = FbByteMaskInvalid; \ + } \ + /* subtract out the portion painted by leftMask */ \ + n -= FB_UNIT - ((x) & FB_MASK); \ + if (n < 0) { \ + if (lb != FbByteMaskInvalid) { \ + if (rb == FbByteMaskInvalid) { \ + lb = FbByteMaskInvalid; \ + } else if (rb) { \ + lb |= (rb - lb) << (FB_SHIFT - 3); \ + rb = 0; \ + } \ + } \ + n = 0; \ + l &= r; \ + r = 0; \ + }\ + } \ + n >>= FB_SHIFT; \ +} + +#define FbDoLeftMaskByteRRop(dst,lb,l,and,xor) { \ + switch (lb) { \ + case (sizeof (FbBits) - 3) | (1 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 3) | (2 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 2) | (1 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ + break; \ + case sizeof (FbBits) - 3: \ + FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ + case sizeof (FbBits) - 2: \ + FbStorePart(dst,sizeof (FbBits) - 2,CARD16,xor); \ + break; \ + case sizeof (FbBits) - 1: \ + FbStorePart(dst,sizeof (FbBits) - 1,CARD8,xor); \ + break; \ + default: \ + WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, l)); \ + break; \ + } \ +} + +#define FbDoRightMaskByteRRop(dst,rb,r,and,xor) { \ + switch (rb) { \ + case 1: \ + FbStorePart(dst,0,CARD8,xor); \ + break; \ + case 2: \ + FbStorePart(dst,0,CARD16,xor); \ + break; \ + case 3: \ + FbStorePart(dst,0,CARD16,xor); \ + FbStorePart(dst,2,CARD8,xor); \ + break; \ + default: \ + WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, r)); \ + } \ +} + +#define FbMaskStip(x,w,l,n,r) { \ + n = (w); \ + r = FbRightStipMask((x)+n); \ + l = FbLeftStipMask(x); \ + if (l) { \ + n -= FB_STIP_UNIT - ((x) & FB_STIP_MASK); \ + if (n < 0) { \ + n = 0; \ + l &= r; \ + r = 0; \ + } \ + } \ + n >>= FB_STIP_SHIFT; \ +} + +/* + * These macros are used to transparently stipple + * in copy mode; the expected usage is with 'n' constant + * so all of the conditional parts collapse into a minimal + * sequence of partial word writes + * + * 'n' is the bytemask of which bytes to store, 'a' is the address + * of the FbBits base unit, 'o' is the offset within that unit + * + * The term "lane" comes from the hardware term "byte-lane" which + */ + +#define FbLaneCase1(n,a,o) \ + if ((n) == 0x01) { \ + WRITE((CARD8 *) ((a)+FbPatternOffset(o,CARD8)), fgxor); \ + } + +#define FbLaneCase2(n,a,o) \ + if ((n) == 0x03) { \ + WRITE((CARD16 *) ((a)+FbPatternOffset(o,CARD16)), fgxor); \ + } else { \ + FbLaneCase1((n)&1,a,o) \ + FbLaneCase1((n)>>1,a,(o)+1) \ + } + +#define FbLaneCase4(n,a,o) \ + if ((n) == 0x0f) { \ + WRITE((CARD32 *) ((a)+FbPatternOffset(o,CARD32)), fgxor); \ + } else { \ + FbLaneCase2((n)&3,a,o) \ + FbLaneCase2((n)>>2,a,(o)+2) \ + } + +#define FbLaneCase(n,a) FbLaneCase4(n,(CARD8 *) (a),0) + +typedef struct { + long changes; + long serial; + GCFuncs *old_funcs; + void *priv; + + FbBits and, xor; /* reduced rop values */ + FbBits bgand, bgxor; /* for stipples */ + FbBits fg, bg, pm; /* expanded and filled */ + unsigned int dashLength; /* total of all dash elements */ + unsigned char evenStipple; /* stipple is even */ + unsigned char bpp; /* current drawable bpp */ +} FbGCPrivate, *FbGCPrivPtr; + +extern DevPrivateKeyRec sna_gc_key; +extern DevPrivateKeyRec sna_window_key; + +static inline FbGCPrivate *fb_gc(GCPtr gc) +{ + return dixGetPrivateAddr(&gc->devPrivates, &sna_gc_key); +} + +static inline PixmapPtr fbGetWindowPixmap(WindowPtr window) +{ + return *(PixmapPtr *)dixGetPrivateAddr(&window->devPrivates, &sna_window_key); +} + +#ifdef ROOTLESS +#define __fbPixDrawableX(p) ((p)->drawable.x) +#define __fbPixDrawableY(p) ((p)->drawable.y) +#else +#define __fbPixDrawableX(p) 0 +#define __fbPixDrawableY(p) 0 +#endif + +#ifdef COMPOSITE +#define __fbPixOffXWin(p) (__fbPixDrawableX(p) - (p)->screen_x) +#define __fbPixOffYWin(p) (__fbPixDrawableY(p) - (p)->screen_y) +#else +#define __fbPixOffXWin(p) (__fbPixDrawableX(p)) +#define __fbPixOffYWin(p) (__fbPixDrawableY(p)) +#endif +#define __fbPixOffXPix(p) (__fbPixDrawableX(p)) +#define __fbPixOffYPix(p) (__fbPixDrawableY(p)) + +#define fbGetDrawablePixmap(drawable, pixmap, xoff, yoff) { \ + if ((drawable)->type != DRAWABLE_PIXMAP) { \ + (pixmap) = fbGetWindowPixmap((WindowPtr)drawable); \ + (xoff) = __fbPixOffXWin(pixmap); \ + (yoff) = __fbPixOffYWin(pixmap); \ + } else { \ + (pixmap) = (PixmapPtr) (drawable); \ + (xoff) = __fbPixOffXPix(pixmap); \ + (yoff) = __fbPixOffYPix(pixmap); \ + } \ +} + +#define fbGetPixmapBitsData(pixmap, pointer, stride, bpp) { \ + (pointer) = (FbBits *) (pixmap)->devPrivate.ptr; \ + (stride) = ((int) (pixmap)->devKind) / sizeof (FbBits); (void)(stride);\ + (bpp) = (pixmap)->drawable.bitsPerPixel; (void)(bpp); \ +} + +#define fbGetPixmapStipData(pixmap, pointer, stride, bpp) { \ + (pointer) = (FbStip *) (pixmap)->devPrivate.ptr; \ + (stride) = ((int) (pixmap)->devKind) / sizeof (FbStip); (void)(stride);\ + (bpp) = (pixmap)->drawable.bitsPerPixel; (void)(bpp); \ +} + +#define fbGetDrawable(drawable, pointer, stride, bpp, xoff, yoff) { \ + PixmapPtr _pPix; \ + fbGetDrawablePixmap(drawable, _pPix, xoff, yoff); \ + fbGetPixmapBitsData(_pPix, pointer, stride, bpp); \ +} + +#define fbGetStipDrawable(drawable, pointer, stride, bpp, xoff, yoff) { \ + PixmapPtr _pPix; \ + fbGetDrawablePixmap(drawable, _pPix, xoff, yoff); \ + fbGetPixmapStipData(_pPix, pointer, stride, bpp); \ +} + +/* + * XFree86 empties the root BorderClip when the VT is inactive, + * here's a macro which uses that to disable GetImage and GetSpans + */ +#define fbWindowEnabled(pWin) \ + RegionNotEmpty(&(pWin)->drawable.pScreen->root->borderClip) +#define fbDrawableEnabled(drawable) \ + ((drawable)->type == DRAWABLE_PIXMAP ? \ + TRUE : fbWindowEnabled((WindowPtr) drawable)) + +#define FbPowerOfTwo(w) (((w) & ((w) - 1)) == 0) +/* + * Accelerated tiles are power of 2 width <= FB_UNIT + */ +#define FbEvenTile(w) ((w) <= FB_UNIT && FbPowerOfTwo(w)) +/* + * Accelerated stipples are power of 2 width and <= FB_UNIT/dstBpp + * with dstBpp a power of 2 as well + */ +#define FbEvenStip(w,bpp) ((w) * (bpp) <= FB_UNIT && FbPowerOfTwo(w) && FbPowerOfTwo(bpp)) + +inline static int16_t fbBound(int16_t a, uint16_t b) +{ + int v = (int)a + (int)b; + if (v > MAXSHORT) + return MAXSHORT; + return v; +} + +extern void +fbPolyArc(DrawablePtr drawable, GCPtr gc, int narcs, xArc * parcs); + +extern void +fbBlt(FbBits *src, FbStride srcStride, int srcX, + FbBits *dst, FbStride dstStride, int dstX, + int width, int height, + int alu, FbBits pm, int bpp, + Bool reverse, Bool upsidedown); + +#if FB_STIP_SHIFT == FB_SHIFT +static inline void +fbBltStip(FbStip *src, FbStride srcStride, int srcX, + FbStip *dst, FbStride dstStride, int dstX, + int width, int height, int alu, FbBits pm, int bpp) +{ + fbBlt((FbBits *)src, srcStride, srcX, + (FbBits *)dst, dstStride, dstX, + width, height, alu, pm, bpp, + FALSE, FALSE); +} +#else +#error FB_STIP_SHIFT must equal FB_SHIFT +#endif + +extern void +fbBltOne(FbStip *src, FbStride srcStride, int srcX, + FbBits *dst, FbStride dstStride, int dstX, + int dstBpp, int width, int height, + FbBits fgand, FbBits fbxor, FbBits bgand, FbBits bgxor); + +extern void +fbBltPlane(FbBits *src, FbStride srcStride, int srcX, int srcBpp, + FbStip *dst, FbStride dstStride, int dstX, + int width, int height, + FbStip fgand, FbStip fgxor, FbStip bgand, FbStip bgxor, + Pixel planeMask); + +extern void +fbCopyNtoN(DrawablePtr src, DrawablePtr dst, GCPtr gc, + BoxPtr pbox, int nbox, + int dx, int dy, + Bool reverse, Bool upsidedown, Pixel bitplane, void *closure); + +extern void +fbCopy1toN(DrawablePtr src, DrawablePtr dst, GCPtr gc, + BoxPtr pbox, int nbox, + int dx, int dy, + Bool reverse, Bool upsidedown, Pixel bitplane, void *closure); + +extern void +fbCopyNto1(DrawablePtr src, DrawablePtr dst, GCPtr gc, + BoxPtr pbox, int nbox, + int dx, int dy, + Bool reverse, Bool upsidedown, Pixel bitplane, void *closure); + +extern RegionPtr +fbCopyArea(DrawablePtr src, DrawablePtr dst, GCPtr gc, + int sx, int sy, + int width, int height, + int dx, int dy); + +extern RegionPtr +fbCopyPlane(DrawablePtr src, DrawablePtr dst, GCPtr gc, + int sx, int sy, + int width, int height, + int dx, int dy, + unsigned long bitplane); + +extern void +fbFill(DrawablePtr drawable, GCPtr gc, int x, int y, int width, int height); + +extern void +fbSolidBoxClipped(DrawablePtr drawable, GCPtr gc, + int x1, int y1, int x2, int y2); + +extern void +fbPolyFillRect(DrawablePtr drawable, GCPtr gc, int n, xRectangle *rec); + +extern void +fbFillSpans(DrawablePtr drawable, GCPtr gc, + int n, DDXPointPtr pt, int *width, int fSorted); + +extern void +fbPadPixmap(PixmapPtr pPixmap); + +extern void +fbValidateGC(GCPtr gc, unsigned long changes, DrawablePtr drawable); + +extern void +fbGetSpans(DrawablePtr drawable, int wMax, + DDXPointPtr pt, int *width, int n, char *dst); + +extern void +fbPolyGlyphBlt(DrawablePtr drawable, GCPtr gc, int x, int y, + unsigned int n, CharInfoPtr *info, pointer glyphs); + +extern void +fbImageGlyphBlt(DrawablePtr drawable, GCPtr gc, int x, int y, + unsigned int n, CharInfoPtr *info, pointer glyphs); + +extern void +fbPutImage(DrawablePtr drawable, GCPtr gc, int depth, + int x, int y, int w, int h, + int leftPad, int format, char *image); + +extern void +fbPutXYImage(DrawablePtr drawable, GCPtr gc, + FbBits fg, FbBits bg, FbBits pm, + int alu, Bool opaque, + int x, int y, int width, int height, + FbStip * src, FbStride srcStride, int srcX); + +extern void +fbGetImage(DrawablePtr drawable, + int x, int y, int w, int h, + unsigned int format, unsigned long planeMask, char *d); + +extern void +fbPolyLine(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt); + +extern void +fbFixCoordModePrevious(int n, DDXPointPtr pt); + +extern void +fbPolySegment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg); + +extern RegionPtr +fbBitmapToRegion(PixmapPtr pixmap); + +extern void +fbPolyPoint(DrawablePtr drawable, GCPtr gc, + int mode, int n, xPoint *pt, + unsigned flags); + +extern void +fbPushImage(DrawablePtr drawable, GCPtr gc, + FbStip *src, FbStride srcStride, int srcX, + int x, int y, int width, int height); + +extern void +fbPushPixels(GCPtr gc, PixmapPtr pBitmap, DrawablePtr drawable, + int dx, int dy, int xOrg, int yOrg); + +extern void +fbSetSpans(DrawablePtr drawable, GCPtr gc, + char *src, DDXPointPtr pt, int *width, int n, int fSorted); + +extern void +fbSegment(DrawablePtr drawable, GCPtr gc, + int xa, int ya, int xb, int yb, + bool drawLast, int *dashOffset); + +extern void +fbSegment1(DrawablePtr drawable, GCPtr gc, const BoxRec *clip, + int xa, int ya, int xb, int yb, + bool drawLast, int *dashOffset); + +extern void +fbTransparentSpan(FbBits * dst, FbBits stip, FbBits fgxor, int n); + +extern void +fbStipple(FbBits *dst, FbStride dstStride, int dstX, int dstBpp, + int width, int height, + FbStip *stip, FbStride stipStride, + int stipWidth, int stipHeight, + Bool even, + FbBits fgand, FbBits fgxor, FbBits bgand, FbBits bgxor, + int xRot, int yRot); + +extern void +fbTile(FbBits *dst, FbStride dstStride, int dstX, int width, int height, + FbBits *tile, FbStride tileStride, int tileWidth, int tileHeight, + int alu, FbBits pm, int bpp, + int xRot, int yRot); + +extern FbBits fbReplicatePixel(Pixel p, int bpp); + +#endif /* FB_H */ |