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