fb.h revision 03b705cf
1/* 2 * Copyright © 1998 Keith Packard 3 * Copyright © 2012 Intel Corporation 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and its 6 * documentation for any purpose is hereby granted without fee, provided that 7 * the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the name of Keith Packard not be used in 10 * advertising or publicity pertaining to distribution of the software without 11 * specific, written prior permission. Keith Packard makes no 12 * representations about the suitability of this software for any purpose. It 13 * is provided "as is" without express or implied warranty. 14 * 15 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 * PERFORMANCE OF THIS SOFTWARE. 22 */ 23 24#ifndef FB_H 25#define FB_H 26 27#ifdef HAVE_CONFIG_H 28#include "config.h" 29#endif 30 31#include <xorg-server.h> 32#include <servermd.h> 33#include <gcstruct.h> 34#include <colormap.h> 35#include <windowstr.h> 36#include <regionstr.h> 37 38#include <stdbool.h> 39#include <pixman.h> 40 41#if HAS_DEBUG_FULL 42#define DBG(x) ErrorF x 43#else 44#define DBG(x) 45#endif 46 47#include "sfb.h" 48 49#include "../../compat-api.h" 50 51#define WRITE(ptr, val) (*(ptr) = (val)) 52#define READ(ptr) (*(ptr)) 53 54/* 55 * This single define controls the basic size of data manipulated 56 * by this software; it must be log2(sizeof (FbBits) * 8) 57 */ 58#define FB_SHIFT LOG2_BITMAP_PAD 59 60#define FB_UNIT (1 << FB_SHIFT) 61#define FB_HALFUNIT (1 << (FB_SHIFT-1)) 62#define FB_MASK (FB_UNIT - 1) 63#define FB_ALLONES ((FbBits) -1) 64 65#if IMAGE_BYTE_ORDER != LSBFirst 66#error "IMAGE_BYTE_ORDER must be LSBFirst" 67#endif 68 69#if GLYPHPADBYTES != 4 70#error "GLYPHPADBYTES must be 4" 71#endif 72 73#if FB_SHIFT != 5 74#error "FB_SHIFT ala LOG2_BITMAP_PAD must be 5" 75#endif 76 77#define FB_STIP_SHIFT LOG2_BITMAP_PAD 78#define FB_STIP_UNIT (1 << FB_STIP_SHIFT) 79#define FB_STIP_MASK (FB_STIP_UNIT - 1) 80#define FB_STIP_ALLONES ((FbStip) -1) 81#define FbFullMask(n) ((n) == FB_UNIT ? FB_ALLONES : ((((FbBits) 1) << n) - 1)) 82 83typedef uint32_t FbBits; 84typedef FbBits FbStip; 85typedef int FbStride; 86 87#include "fbrop.h" 88 89#define FbScrLeft(x,n) ((x) >> (n)) 90#define FbScrRight(x,n) ((x) << (n)) 91/* #define FbLeftBits(x,n) ((x) & ((((FbBits) 1) << (n)) - 1)) */ 92#define FbLeftStipBits(x,n) ((x) & ((((FbStip) 1) << (n)) - 1)) 93#define FbStipMoveLsb(x,s,n) (FbStipRight (x,(s)-(n))) 94#define FbPatternOffsetBits 0 95 96#define FbStipLeft(x,n) FbScrLeft(x,n) 97#define FbStipRight(x,n) FbScrRight(x,n) 98 99#define FbRotLeft(x,n) FbScrLeft(x,n) | (n ? FbScrRight(x,FB_UNIT-n) : 0) 100#define FbRotRight(x,n) FbScrRight(x,n) | (n ? FbScrLeft(x,FB_UNIT-n) : 0) 101 102#define FbRotStipLeft(x,n) FbStipLeft(x,n) | (n ? FbStipRight(x,FB_STIP_UNIT-n) : 0) 103#define FbRotStipRight(x,n) FbStipRight(x,n) | (n ? FbStipLeft(x,FB_STIP_UNIT-n) : 0) 104 105#define FbLeftMask(x) ( ((x) & FB_MASK) ? \ 106 FbScrRight(FB_ALLONES,(x) & FB_MASK) : 0) 107#define FbRightMask(x) ( ((FB_UNIT - (x)) & FB_MASK) ? \ 108 FbScrLeft(FB_ALLONES,(FB_UNIT - (x)) & FB_MASK) : 0) 109 110#define FbLeftStipMask(x) ( ((x) & FB_STIP_MASK) ? \ 111 FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) : 0) 112#define FbRightStipMask(x) ( ((FB_STIP_UNIT - (x)) & FB_STIP_MASK) ? \ 113 FbScrLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - (x)) & FB_STIP_MASK) : 0) 114 115#define FbBitsMask(x,w) (FbScrRight(FB_ALLONES,(x) & FB_MASK) & \ 116 FbScrLeft(FB_ALLONES,(FB_UNIT - ((x) + (w))) & FB_MASK)) 117 118#define FbStipMask(x,w) (FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) & \ 119 FbStipLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - ((x)+(w))) & FB_STIP_MASK)) 120 121#define FbMaskBits(x,w,l,n,r) { \ 122 n = (w); \ 123 r = FbRightMask((x)+n); \ 124 l = FbLeftMask(x); \ 125 if (l) { \ 126 n -= FB_UNIT - ((x) & FB_MASK); \ 127 if (n < 0) { \ 128 n = 0; \ 129 l &= r; \ 130 r = 0; \ 131 } \ 132 } \ 133 n >>= FB_SHIFT; \ 134} 135 136#define FbByteMaskInvalid 0x10 137 138#define FbPatternOffset(o,t) ((o) ^ (FbPatternOffsetBits & ~(sizeof (t) - 1))) 139 140#define FbPtrOffset(p,o,t) ((t *) ((CARD8 *) (p) + (o))) 141#define FbSelectPatternPart(xor,o,t) ((xor) >> (FbPatternOffset (o,t) << 3)) 142#define FbStorePart(dst,off,t,xor) (WRITE(FbPtrOffset(dst,off,t), \ 143 FbSelectPart(xor,off,t))) 144#ifndef FbSelectPart 145#define FbSelectPart(x,o,t) FbSelectPatternPart(x,o,t) 146#endif 147 148#define FbMaskBitsBytes(x,w,copy,l,lb,n,r,rb) { \ 149 n = (w); \ 150 lb = 0; \ 151 rb = 0; \ 152 r = FbRightMask((x)+n); \ 153 if (r) { \ 154 /* compute right byte length */ \ 155 if ((copy) && (((x) + n) & 7) == 0) { \ 156 rb = (((x) + n) & FB_MASK) >> 3; \ 157 } else { \ 158 rb = FbByteMaskInvalid; \ 159 } \ 160 } \ 161 l = FbLeftMask(x); \ 162 if (l) { \ 163 /* compute left byte length */ \ 164 if ((copy) && ((x) & 7) == 0) { \ 165 lb = ((x) & FB_MASK) >> 3; \ 166 } else { \ 167 lb = FbByteMaskInvalid; \ 168 } \ 169 /* subtract out the portion painted by leftMask */ \ 170 n -= FB_UNIT - ((x) & FB_MASK); \ 171 if (n < 0) { \ 172 if (lb != FbByteMaskInvalid) { \ 173 if (rb == FbByteMaskInvalid) { \ 174 lb = FbByteMaskInvalid; \ 175 } else if (rb) { \ 176 lb |= (rb - lb) << (FB_SHIFT - 3); \ 177 rb = 0; \ 178 } \ 179 } \ 180 n = 0; \ 181 l &= r; \ 182 r = 0; \ 183 }\ 184 } \ 185 n >>= FB_SHIFT; \ 186} 187 188#define FbDoLeftMaskByteRRop(dst,lb,l,and,xor) { \ 189 switch (lb) { \ 190 case (sizeof (FbBits) - 3) | (1 << (FB_SHIFT - 3)): \ 191 FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ 192 break; \ 193 case (sizeof (FbBits) - 3) | (2 << (FB_SHIFT - 3)): \ 194 FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ 195 FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ 196 break; \ 197 case (sizeof (FbBits) - 2) | (1 << (FB_SHIFT - 3)): \ 198 FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ 199 break; \ 200 case sizeof (FbBits) - 3: \ 201 FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ 202 case sizeof (FbBits) - 2: \ 203 FbStorePart(dst,sizeof (FbBits) - 2,CARD16,xor); \ 204 break; \ 205 case sizeof (FbBits) - 1: \ 206 FbStorePart(dst,sizeof (FbBits) - 1,CARD8,xor); \ 207 break; \ 208 default: \ 209 WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, l)); \ 210 break; \ 211 } \ 212} 213 214#define FbDoRightMaskByteRRop(dst,rb,r,and,xor) { \ 215 switch (rb) { \ 216 case 1: \ 217 FbStorePart(dst,0,CARD8,xor); \ 218 break; \ 219 case 2: \ 220 FbStorePart(dst,0,CARD16,xor); \ 221 break; \ 222 case 3: \ 223 FbStorePart(dst,0,CARD16,xor); \ 224 FbStorePart(dst,2,CARD8,xor); \ 225 break; \ 226 default: \ 227 WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, r)); \ 228 } \ 229} 230 231#define FbMaskStip(x,w,l,n,r) { \ 232 n = (w); \ 233 r = FbRightStipMask((x)+n); \ 234 l = FbLeftStipMask(x); \ 235 if (l) { \ 236 n -= FB_STIP_UNIT - ((x) & FB_STIP_MASK); \ 237 if (n < 0) { \ 238 n = 0; \ 239 l &= r; \ 240 r = 0; \ 241 } \ 242 } \ 243 n >>= FB_STIP_SHIFT; \ 244} 245 246/* 247 * These macros are used to transparently stipple 248 * in copy mode; the expected usage is with 'n' constant 249 * so all of the conditional parts collapse into a minimal 250 * sequence of partial word writes 251 * 252 * 'n' is the bytemask of which bytes to store, 'a' is the address 253 * of the FbBits base unit, 'o' is the offset within that unit 254 * 255 * The term "lane" comes from the hardware term "byte-lane" which 256 */ 257 258#define FbLaneCase1(n,a,o) \ 259 if ((n) == 0x01) { \ 260 WRITE((CARD8 *) ((a)+FbPatternOffset(o,CARD8)), fgxor); \ 261 } 262 263#define FbLaneCase2(n,a,o) \ 264 if ((n) == 0x03) { \ 265 WRITE((CARD16 *) ((a)+FbPatternOffset(o,CARD16)), fgxor); \ 266 } else { \ 267 FbLaneCase1((n)&1,a,o) \ 268 FbLaneCase1((n)>>1,a,(o)+1) \ 269 } 270 271#define FbLaneCase4(n,a,o) \ 272 if ((n) == 0x0f) { \ 273 WRITE((CARD32 *) ((a)+FbPatternOffset(o,CARD32)), fgxor); \ 274 } else { \ 275 FbLaneCase2((n)&3,a,o) \ 276 FbLaneCase2((n)>>2,a,(o)+2) \ 277 } 278 279#define FbLaneCase(n,a) FbLaneCase4(n,(CARD8 *) (a),0) 280 281typedef struct { 282 long changes; 283 long serial; 284 GCFuncs *old_funcs; 285 void *priv; 286 287 FbBits and, xor; /* reduced rop values */ 288 FbBits bgand, bgxor; /* for stipples */ 289 FbBits fg, bg, pm; /* expanded and filled */ 290 unsigned int dashLength; /* total of all dash elements */ 291 unsigned char evenStipple; /* stipple is even */ 292 unsigned char bpp; /* current drawable bpp */ 293} FbGCPrivate, *FbGCPrivPtr; 294 295extern DevPrivateKeyRec sna_gc_key; 296extern DevPrivateKeyRec sna_window_key; 297 298static inline FbGCPrivate *fb_gc(GCPtr gc) 299{ 300 return (FbGCPrivate *)__get_private(gc, sna_gc_key); 301} 302 303static inline PixmapPtr fbGetWindowPixmap(WindowPtr window) 304{ 305 return *(PixmapPtr *)__get_private(window, sna_window_key); 306} 307 308#ifdef ROOTLESS 309#define __fbPixDrawableX(p) ((p)->drawable.x) 310#define __fbPixDrawableY(p) ((p)->drawable.y) 311#else 312#define __fbPixDrawableX(p) 0 313#define __fbPixDrawableY(p) 0 314#endif 315 316#ifdef COMPOSITE 317#define __fbPixOffXWin(p) (__fbPixDrawableX(p) - (p)->screen_x) 318#define __fbPixOffYWin(p) (__fbPixDrawableY(p) - (p)->screen_y) 319#else 320#define __fbPixOffXWin(p) (__fbPixDrawableX(p)) 321#define __fbPixOffYWin(p) (__fbPixDrawableY(p)) 322#endif 323#define __fbPixOffXPix(p) (__fbPixDrawableX(p)) 324#define __fbPixOffYPix(p) (__fbPixDrawableY(p)) 325 326#define fbGetDrawablePixmap(drawable, pixmap, xoff, yoff) { \ 327 if ((drawable)->type != DRAWABLE_PIXMAP) { \ 328 (pixmap) = fbGetWindowPixmap((WindowPtr)drawable); \ 329 (xoff) = __fbPixOffXWin(pixmap); \ 330 (yoff) = __fbPixOffYWin(pixmap); \ 331 } else { \ 332 (pixmap) = (PixmapPtr) (drawable); \ 333 (xoff) = __fbPixOffXPix(pixmap); \ 334 (yoff) = __fbPixOffYPix(pixmap); \ 335 } \ 336} 337 338#define fbGetPixmapBitsData(pixmap, pointer, stride, bpp) { \ 339 (pointer) = (FbBits *) (pixmap)->devPrivate.ptr; \ 340 (stride) = ((int) (pixmap)->devKind) / sizeof (FbBits); (void)(stride);\ 341 (bpp) = (pixmap)->drawable.bitsPerPixel; (void)(bpp); \ 342} 343 344#define fbGetPixmapStipData(pixmap, pointer, stride, bpp) { \ 345 (pointer) = (FbStip *) (pixmap)->devPrivate.ptr; \ 346 (stride) = ((int) (pixmap)->devKind) / sizeof (FbStip); (void)(stride);\ 347 (bpp) = (pixmap)->drawable.bitsPerPixel; (void)(bpp); \ 348} 349 350#define fbGetDrawable(drawable, pointer, stride, bpp, xoff, yoff) { \ 351 PixmapPtr _pPix; \ 352 fbGetDrawablePixmap(drawable, _pPix, xoff, yoff); \ 353 fbGetPixmapBitsData(_pPix, pointer, stride, bpp); \ 354} 355 356#define fbGetStipDrawable(drawable, pointer, stride, bpp, xoff, yoff) { \ 357 PixmapPtr _pPix; \ 358 fbGetDrawablePixmap(drawable, _pPix, xoff, yoff); \ 359 fbGetPixmapStipData(_pPix, pointer, stride, bpp); \ 360} 361 362/* 363 * XFree86 empties the root BorderClip when the VT is inactive, 364 * here's a macro which uses that to disable GetImage and GetSpans 365 */ 366 367#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,10,0,0,0) 368#define fbWindowEnabled(pWin) \ 369 RegionNotEmpty(&(pWin)->drawable.pScreen->root->borderClip) 370#else 371#define fbWindowEnabled(pWin) \ 372 RegionNotEmpty(&WindowTable[(pWin)->drawable.pScreen->myNum]->borderClip) 373#endif 374#define fbDrawableEnabled(drawable) \ 375 ((drawable)->type == DRAWABLE_PIXMAP ? \ 376 TRUE : fbWindowEnabled((WindowPtr) drawable)) 377 378#define FbPowerOfTwo(w) (((w) & ((w) - 1)) == 0) 379/* 380 * Accelerated tiles are power of 2 width <= FB_UNIT 381 */ 382#define FbEvenTile(w) ((w) <= FB_UNIT && FbPowerOfTwo(w)) 383/* 384 * Accelerated stipples are power of 2 width and <= FB_UNIT/dstBpp 385 * with dstBpp a power of 2 as well 386 */ 387#define FbEvenStip(w,bpp) ((w) * (bpp) <= FB_UNIT && FbPowerOfTwo(w) && FbPowerOfTwo(bpp)) 388 389inline static int16_t fbBound(int16_t a, uint16_t b) 390{ 391 int v = (int)a + (int)b; 392 if (v > MAXSHORT) 393 return MAXSHORT; 394 return v; 395} 396 397extern void 398fbPolyArc(DrawablePtr drawable, GCPtr gc, int narcs, xArc * parcs); 399 400extern void 401fbBlt(FbBits *src, FbStride srcStride, int srcX, 402 FbBits *dst, FbStride dstStride, int dstX, 403 int width, int height, 404 int alu, FbBits pm, int bpp, 405 Bool reverse, Bool upsidedown); 406 407#if FB_STIP_SHIFT == FB_SHIFT 408static inline void 409fbBltStip(FbStip *src, FbStride srcStride, int srcX, 410 FbStip *dst, FbStride dstStride, int dstX, 411 int width, int height, int alu, FbBits pm, int bpp) 412{ 413 fbBlt((FbBits *)src, srcStride, srcX, 414 (FbBits *)dst, dstStride, dstX, 415 width, height, alu, pm, bpp, 416 FALSE, FALSE); 417} 418#else 419#error FB_STIP_SHIFT must equal FB_SHIFT 420#endif 421 422extern void 423fbBltOne(FbStip *src, FbStride srcStride, int srcX, 424 FbBits *dst, FbStride dstStride, int dstX, 425 int dstBpp, int width, int height, 426 FbBits fgand, FbBits fbxor, FbBits bgand, FbBits bgxor); 427 428extern void 429fbBltPlane(FbBits *src, FbStride srcStride, int srcX, int srcBpp, 430 FbStip *dst, FbStride dstStride, int dstX, 431 int width, int height, 432 FbStip fgand, FbStip fgxor, FbStip bgand, FbStip bgxor, 433 Pixel planeMask); 434 435extern void 436fbCopyNtoN(DrawablePtr src, DrawablePtr dst, GCPtr gc, 437 BoxPtr pbox, int nbox, 438 int dx, int dy, 439 Bool reverse, Bool upsidedown, Pixel bitplane, void *closure); 440 441extern void 442fbCopy1toN(DrawablePtr src, DrawablePtr dst, GCPtr gc, 443 BoxPtr pbox, int nbox, 444 int dx, int dy, 445 Bool reverse, Bool upsidedown, Pixel bitplane, void *closure); 446 447extern void 448fbCopyNto1(DrawablePtr src, DrawablePtr dst, GCPtr gc, 449 BoxPtr pbox, int nbox, 450 int dx, int dy, 451 Bool reverse, Bool upsidedown, Pixel bitplane, void *closure); 452 453extern RegionPtr 454fbCopyArea(DrawablePtr src, DrawablePtr dst, GCPtr gc, 455 int sx, int sy, 456 int width, int height, 457 int dx, int dy); 458 459extern RegionPtr 460fbCopyPlane(DrawablePtr src, DrawablePtr dst, GCPtr gc, 461 int sx, int sy, 462 int width, int height, 463 int dx, int dy, 464 unsigned long bitplane); 465 466extern void 467fbFill(DrawablePtr drawable, GCPtr gc, int x, int y, int width, int height); 468 469extern void 470fbSolidBoxClipped(DrawablePtr drawable, GCPtr gc, 471 int x1, int y1, int x2, int y2); 472 473extern void 474fbPolyFillRect(DrawablePtr drawable, GCPtr gc, int n, xRectangle *rec); 475 476extern void 477fbFillSpans(DrawablePtr drawable, GCPtr gc, 478 int n, DDXPointPtr pt, int *width, int fSorted); 479 480extern void 481fbPadPixmap(PixmapPtr pPixmap); 482 483extern void 484fbValidateGC(GCPtr gc, unsigned long changes, DrawablePtr drawable); 485 486extern void 487fbGetSpans(DrawablePtr drawable, int wMax, 488 DDXPointPtr pt, int *width, int n, char *dst); 489 490extern void 491fbPolyGlyphBlt(DrawablePtr drawable, GCPtr gc, int x, int y, 492 unsigned int n, CharInfoPtr *info, pointer glyphs); 493 494extern void 495fbImageGlyphBlt(DrawablePtr drawable, GCPtr gc, int x, int y, 496 unsigned int n, CharInfoPtr *info, pointer glyphs); 497 498extern void 499fbPutImage(DrawablePtr drawable, GCPtr gc, int depth, 500 int x, int y, int w, int h, 501 int leftPad, int format, char *image); 502 503extern void 504fbPutXYImage(DrawablePtr drawable, GCPtr gc, 505 FbBits fg, FbBits bg, FbBits pm, 506 int alu, Bool opaque, 507 int x, int y, int width, int height, 508 FbStip * src, FbStride srcStride, int srcX); 509 510extern void 511fbGetImage(DrawablePtr drawable, 512 int x, int y, int w, int h, 513 unsigned int format, unsigned long planeMask, char *d); 514 515extern void 516fbPolyLine(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt); 517 518extern void 519fbFixCoordModePrevious(int n, DDXPointPtr pt); 520 521extern void 522fbPolySegment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg); 523 524extern RegionPtr 525fbBitmapToRegion(PixmapPtr pixmap); 526 527extern void 528fbPolyPoint(DrawablePtr drawable, GCPtr gc, 529 int mode, int n, xPoint *pt, 530 unsigned flags); 531 532extern void 533fbPushImage(DrawablePtr drawable, GCPtr gc, 534 FbStip *src, FbStride srcStride, int srcX, 535 int x, int y, int width, int height); 536 537extern void 538fbPushPixels(GCPtr gc, PixmapPtr pBitmap, DrawablePtr drawable, 539 int dx, int dy, int xOrg, int yOrg); 540 541extern void 542fbSetSpans(DrawablePtr drawable, GCPtr gc, 543 char *src, DDXPointPtr pt, int *width, int n, int fSorted); 544 545extern void 546fbSegment(DrawablePtr drawable, GCPtr gc, 547 int xa, int ya, int xb, int yb, 548 bool drawLast, int *dashOffset); 549 550extern void 551fbSegment1(DrawablePtr drawable, GCPtr gc, const BoxRec *clip, 552 int xa, int ya, int xb, int yb, 553 bool drawLast, int *dashOffset); 554 555extern void 556fbTransparentSpan(FbBits * dst, FbBits stip, FbBits fgxor, int n); 557 558extern void 559fbStipple(FbBits *dst, FbStride dstStride, int dstX, int dstBpp, 560 int width, int height, 561 FbStip *stip, FbStride stipStride, 562 int stipWidth, int stipHeight, 563 Bool even, 564 FbBits fgand, FbBits fgxor, FbBits bgand, FbBits bgxor, 565 int xRot, int yRot); 566 567extern void 568fbTile(FbBits *dst, FbStride dstStride, int dstX, int width, int height, 569 FbBits *tile, FbStride tileStride, int tileWidth, int tileHeight, 570 int alu, FbBits pm, int bpp, 571 int xRot, int yRot); 572 573extern FbBits fbReplicatePixel(Pixel p, int bpp); 574 575#endif /* FB_H */ 576