summaryrefslogtreecommitdiff
path: root/exa/exa.h
blob: 9ea593381c3a46b5cc24118ba3f54b64255096f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
/*
 *
 * Copyright (C) 2000 Keith Packard
 *               2004 Eric Anholt
 *               2005 Zack Rusin
 *
 * 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 copyright holders not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission. Copyright holders make no
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.
 *
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
 */

/** @file
 * This is the header containing the public API of EXA for exa drivers.
 */

#ifndef EXA_H
#define EXA_H

#include "scrnintstr.h"
#include "pixmapstr.h"
#include "windowstr.h"
#include "gcstruct.h"
#include "picturestr.h"
#include "fb.h"

#define EXA_VERSION_MAJOR   2
#define EXA_VERSION_MINOR   2
#define EXA_VERSION_RELEASE 0

typedef struct _ExaOffscreenArea ExaOffscreenArea;

typedef void (*ExaOffscreenSaveProc) (ScreenPtr pScreen, ExaOffscreenArea *area);

typedef enum _ExaOffscreenState {
    ExaOffscreenAvail,
    ExaOffscreenRemovable,
    ExaOffscreenLocked
} ExaOffscreenState;

struct _ExaOffscreenArea {
    int                 base_offset;	/* allocation base */
    int                 offset;         /* aligned offset */
    int                 size;           /* total allocation size */
    int                 score;
    pointer             privData;

    ExaOffscreenSaveProc save;

    ExaOffscreenState   state;

    ExaOffscreenArea    *next;
};

/**
 * The ExaDriver structure is allocated through exaDriverAlloc(), and then
 * fllled in by drivers.
 */
typedef struct _ExaDriver {
    /**
     * exa_major and exa_minor should be set by the driver to the version of
     * EXA which the driver was compiled for (or configures itself at runtime
     * to support).  This allows EXA to extend the structure for new features
     * without breaking ABI for drivers compiled against older versions.
     */
    int exa_major, exa_minor;

    /**
     * memoryBase is the address of the beginning of framebuffer memory.
     * The visible screen should be within memoryBase to memoryBase +
     * memorySize.
     */
    CARD8         *memoryBase;

    /**
     * offScreenBase is the offset from memoryBase of the beginning of the area
     * to be managed by EXA's linear offscreen memory manager.
     *
     * In XFree86 DDX drivers, this is probably:
     *   (pScrn->displayWidth * cpp * pScrn->virtualY)
     */
    unsigned long  offScreenBase;

    /**
     * memorySize is the length (in bytes) of framebuffer memory beginning
     * from memoryBase.
     *
     * The offscreen memory manager will manage the area beginning at
     * (memoryBase + offScreenBase), with a length of (memorySize -
     * offScreenBase)
     *
     * In XFree86 DDX drivers, this is probably (pScrn->videoRam * 1024)
     */
    unsigned long memorySize;

    /**
     * pixmapOffsetAlign is the byte alignment necessary for pixmap offsets
     * within framebuffer.
     *
     * Hardware typically has a required alignment of offsets, which may or may
     * not be a power of two.  EXA will ensure that pixmaps managed by the
     * offscreen memory manager meet this alignment requirement.
     */
    int pixmapOffsetAlign;

    /**
     * pixmapPitchAlign is the byte alignment necessary for pixmap pitches
     * within the framebuffer.
     *
     * Hardware typically has a required alignment of pitches for acceleration.
     * For 3D hardware, Composite acceleration often requires that source and
     * mask pixmaps (textures) have a power-of-two pitch, which can be demanded
     * using EXA_OFFSCREEN_ALIGN_POT.  These pitch requirements only apply to
     * pixmaps managed by the offscreen memory manager.  Thus, it is up to the
     * driver to ensure that the visible screen has an appropriate pitch for
     * acceleration.
     */
    int pixmapPitchAlign;

    /**
     * The flags field is bitfield of boolean values controlling EXA's behavior.
     *
     * The flags in clude EXA_OFFSCREEN_PIXMAPS, EXA_OFFSCREEN_ALIGN_POT, and
     * EXA_TWO_BITBLT_DIRECTIONS.
     */
    int flags;

    /** @{ */
    /**
     * maxX controls the X coordinate limitation for rendering from the card.
     * The driver should never receive a request for rendering beyond maxX
     * in the X direction from the origin of a pixmap.
     */
    int maxX;

    /**
     * maxY controls the Y coordinate limitation for rendering from the card.
     * The driver should never receive a request for rendering beyond maxY
     * in the Y direction from the origin of a pixmap.
     */
    int maxY;
    /** @} */

    /* private */
    ExaOffscreenArea *offScreenAreas;
    Bool              needsSync;
    int               lastMarker;

    /** @name Solid
     * @{
     */
    /**
     * PrepareSolid() sets up the driver for doing a solid fill.
     * @param pPixmap Destination pixmap
     * @param alu raster operation
     * @param planemask write mask for the fill
     * @param fg "foreground" color for the fill
     *
     * This call should set up the driver for doing a series of solid fills
     * through the Solid() call.  The alu raster op is one of the GX*
     * graphics functions listed in X.h, and typically maps to a similar
     * single-byte "ROP" setting in all hardware.  The planemask controls
     * which bits of the destination should be affected, and will only represent
     * the bits up to the depth of pPixmap.  The fg is the pixel value of the
     * foreground color referred to in ROP descriptions.
     *
     * Note that many drivers will need to store some of the data in the driver
     * private record, for sending to the hardware with each drawing command.
     *
     * The PrepareSolid() call is required of all drivers, but it may fail for any
     * reason.  Failure results in a fallback to software rendering.
     */
    Bool        (*PrepareSolid) (PixmapPtr      pPixmap,
                                 int            alu,
                                 Pixel          planemask,
                                 Pixel          fg);

    /**
     * Solid() performs a solid fill set up in the last PrepareSolid() call.
     *
     * @param pPixmap destination pixmap
     * @param x1 left coordinate
     * @param y1 top coordinate
     * @param x2 right coordinate
     * @param y2 bottom coordinate
     *
     * Performs the fill set up by the last PrepareSolid() call, covering the
     * area from (x1,y1) to (x2,y2) in pPixmap.  Note that the coordinates are
     * in the coordinate space of the destination pixmap, so the driver will
     * need to set up the hardware's offset and pitch for the destination
     * coordinates according to the pixmap's offset and pitch within
     * framebuffer.  This likely means using exaGetPixmapOffset() and
     * exaGetPixmapPitch().
     *
     * This call is required if PrepareSolid() ever succeeds.
     */
    void        (*Solid) (PixmapPtr      pPixmap, int x1, int y1, int x2, int y2);

    /**
     * DoneSolid() finishes a set of solid fills.
     *
     * @param pPixmap destination pixmap.
     *
     * The DoneSolid() call is called at the end of a series of consecutive
     * Solid() calls following a successful PrepareSolid().  This allows drivers
     * to finish up emitting drawing commands that were buffered, or clean up
     * state from PrepareSolid().
     *
     * This call is required if PrepareSolid() ever succeeds.
     */
    void        (*DoneSolid) (PixmapPtr      pPixmap);
    /** @} */

    /** @name Copy
     * @{
     */
    /**
     * PrepareCopy() sets up the driver for doing a copy within video 
     * memory.
     *
     * @param pSrcPixmap source pixmap
     * @param pDstPixmap destination pixmap
     * @param dx X copy direction
     * @param dy Y copy direction
     * @param alu raster operation
     * @param planemask write mask for the fill
     *
     * This call should set up the driver for doing a series of copies from the
     * the pSrcPixmap to the pDstPixmap.  The dx flag will be positive if the
     * hardware should do the copy from the left to the right, and dy will be
     * positive if the copy should be done from the top to the bottom.  This
     * is to deal with self-overlapping copies when pSrcPixmap == pDstPixmap.
     * If your hardware can only support blits that are (left to right, top to
     * bottom) or (right to left, bottom to top), then you should set
     * #EXA_TWO_BITBLT_DIRECTIONS, and EXA will break down Copy operations to
     * ones that meet those requirements.  The alu raster op is one of the GX*
     * graphics functions listed in X.h, and typically maps to a similar
     * single-byte "ROP" setting in all hardware.  The planemask controls which
     * bits of the destination should be affected, and will only represent the
     * bits up to the depth of pPixmap.
     *
     * Note that many drivers will need to store some of the data in the driver
     * private record, for sending to the hardware with each drawing command.
     *
     * The PrepareCopy() call is required of all drivers, but it may fail for any
     * reason.  Failure results in a fallback to software rendering.
     */
    Bool        (*PrepareCopy) (PixmapPtr       pSrcPixmap,
                                PixmapPtr       pDstPixmap,
                                int             dx,
                                int             dy,
                                int             alu,
                                Pixel           planemask);

    /**
     * Copy() performs a copy set up in the last PrepareCopy call.
     *
     * @param pDstPixmap destination pixmap
     * @param srcX source X coordinate
     * @param srcY source Y coordinate
     * @param dstX destination X coordinate
     * @param dstY destination Y coordinate
     * @param width width of the rectangle to be copied
     * @param height height of the rectangle to be copied.
     *
     * Performs the copy set up by the last PrepareCopy() call, copying the
     * rectangle from (srcX, srcY) to (srcX + width, srcY + width) in the source
     * pixmap to the same-sized rectangle at (dstX, dstY) in the destination
     * pixmap.  Those rectangles may overlap in memory, if
     * pSrcPixmap == pDstPixmap.  Note that this call does not receive the
     * pSrcPixmap as an argument -- if it's needed in this function, it should
     * be stored in the driver private during PrepareCopy().  As with Solid(),
     * the coordinates are in the coordinate space of each pixmap, so the driver
     * will need to set up source and destination pitches and offsets from those
     * pixmaps, probably using exaGetPixmapOffset() and exaGetPixmapPitch().
     *
     * This call is required if PrepareCopy ever succeeds.
     */
    void        (*Copy) (PixmapPtr       pDstPixmap,
                         int    srcX,
                         int    srcY,
                         int    dstX,
                         int    dstY,
                         int    width,
                         int    height);

    /**
     * DoneCopy() finishes a set of copies.
     *
     * @param pPixmap destination pixmap.
     *
     * The DoneCopy() call is called at the end of a series of consecutive
     * Copy() calls following a successful PrepareCopy().  This allows drivers
     * to finish up emitting drawing commands that were buffered, or clean up
     * state from PrepareCopy().
     *
     * This call is required if PrepareCopy() ever succeeds.
     */
    void        (*DoneCopy) (PixmapPtr       pDstPixmap);
    /** @} */

    /** @name Composite
     * @{
     */
    /**
     * CheckComposite() checks to see if a composite operation could be
     * accelerated.
     *
     * @param op Render operation
     * @param pSrcPicture source Picture
     * @param pMaskPicture mask picture
     * @param pDstPicture destination Picture
     *
     * The CheckComposite() call checks if the driver could handle acceleration
     * of op with the given source, mask, and destination pictures.  This allows
     * drivers to check source and destination formats, supported operations,
     * transformations, and component alpha state, and send operations it can't
     * support to software rendering early on.  This avoids costly pixmap
     * migration to the wrong places when the driver can't accelerate
     * operations.  Note that because migration hasn't happened, the driver
     * can't know during CheckComposite() what the offsets and pitches of the
     * pixmaps are going to be.
     *
     * See PrepareComposite() for more details on likely issues that drivers
     * will have in accelerating Composite operations.
     *
     * The CheckComposite() call is recommended if PrepareComposite() is
     * implemented, but is not required.
     */
    Bool        (*CheckComposite) (int          op,
                                   PicturePtr   pSrcPicture,
                                   PicturePtr   pMaskPicture,
                                   PicturePtr   pDstPicture);

    /**
     * PrepareComposite() sets up the driver for doing a Composite operation
     * described in the Render extension protocol spec.
     *
     * @param op Render operation
     * @param pSrcPicture source Picture
     * @param pMaskPicture mask picture
     * @param pDstPicture destination Picture
     * @param pSrc source pixmap
     * @param pMask mask pixmap
     * @param pDst destination pixmap
     *
     * This call should set up the driver for doing a series of Composite
     * operations, as described in the Render protocol spec, with the given
     * pSrcPicture, pMaskPicture, and pDstPicture.  The pSrc, pMask, and
     * pDst are the pixmaps containing the pixel data, and should be used for
     * setting the offset and pitch used for the coordinate spaces for each of
     * the Pictures.
     *
     * Notes on interpreting Picture structures:
     * - The Picture structures will always have a valid pDrawable.
     * - The Picture structures will never have alphaMap set.
     * - The mask Picture (and therefore pMask) may be NULL, in which case the
     *   operation is simply src OP dst instead of src IN mask OP dst, and
     *   mask coordinates should be ignored.
     * - pMarkPicture may have componentAlpha set, which greatly changes
     *   the behavior of the Composite operation.  componentAlpha has no effect
     *   when set on pSrcPicture or pDstPicture.
     * - The source and mask Pictures may have a transformation set
     *   (Picture->transform != NULL), which means that the source coordinates
     *   should be transformed by that transformation, resulting in scaling,
     *   rotation, etc.  The PictureTransformPoint() call can transform
     *   coordinates for you.  Transforms have no effect on Pictures when used
     *   as a destination.
     * - The source and mask pictures may have a filter set.  PictFilterNearest
     *   and PictFilterBilinear are defined in the Render protocol, but others
     *   may be encountered, and must be handled correctly (usually by
     *   PrepareComposite failing, and falling back to software).  Filters have
     *   no effect on Pictures when used as a destination.
     * - The source and mask Pictures may have repeating set, which must be
     *   respected.  Many chipsets will be unable to support repeating on
     *   pixmaps that have a width or height that is not a power of two.
     *
     * If your hardware can't support source pictures (textures) with
     * non-power-of-two pitches, you should set #EXA_OFFSCREEN_ALIGN_POT.
     *
     * Note that many drivers will need to store some of the data in the driver
     * private record, for sending to the hardware with each drawing command.
     *
     * The PrepareComposite() call is not required.  However, it is highly
     * recommended for performance of antialiased font rendering and performance
     * of cairo applications.  Failure results in a fallback to software
     * rendering.
     */
    Bool        (*PrepareComposite) (int                op,
                                     PicturePtr         pSrcPicture,
                                     PicturePtr         pMaskPicture,
                                     PicturePtr         pDstPicture,
                                     PixmapPtr          pSrc,
                                     PixmapPtr          pMask,
                                     PixmapPtr          pDst);

    /**
     * Composite() performs a Composite operation set up in the last
     * PrepareComposite() call.
     *
     * @param pDstPixmap destination pixmap
     * @param srcX source X coordinate
     * @param srcY source Y coordinate
     * @param maskX source X coordinate
     * @param maskY source Y coordinate
     * @param dstX destination X coordinate
     * @param dstY destination Y coordinate
     * @param width destination rectangle width
     * @param height destination rectangle height
     *
     * Performs the Composite operation set up by the last PrepareComposite()
     * call, to the rectangle from (dstX, dstY) to (dstX + width, dstY + height)
     * in the destination Pixmap.  Note that if a transformation was set on
     * the source or mask Pictures, the source rectangles may not be the same
     * size as the destination rectangles and filtering.  Getting the coordinate
     * transformation right at the subpixel level can be tricky, and rendercheck
     * can test this for you.
     *
     * This call is required if PrepareComposite() ever succeeds.
     */
    void        (*Composite) (PixmapPtr         pDst,
                              int       srcX,
                              int        srcY,
                              int        maskX,
                              int        maskY,
                              int        dstX,
                              int        dstY,
                              int        width,
                              int        height);

    /**
     * DoneComposite() finishes a set of Composite operations.
     *
     * @param pPixmap destination pixmap.
     *
     * The DoneComposite() call is called at the end of a series of consecutive
     * Composite() calls following a successful PrepareComposite().  This allows
     * drivers to finish up emitting drawing commands that were buffered, or
     * clean up state from PrepareComposite().
     *
     * This call is required if PrepareComposite() ever succeeds.
     */
    void        (*DoneComposite) (PixmapPtr         pDst);
    /** @} */

    /**
     * UploadToScreen() loads a rectangle of data from src into pDst.
     *
     * @param pDst destination pixmap
     * @param x destination X coordinate.
     * @param y destination Y coordinate
     * @param width width of the rectangle to be copied
     * @param height height of the rectangle to be copied
     * @param src pointer to the beginning of the source data
     * @param src_pitch pitch (in bytes) of the lines of source data.
     *
     * UploadToScreen() copies data in system memory beginning at src (with
     * pitch src_pitch) into the destination pixmap from (x, y) to
     * (x + width, y + height).  This is typically done with hostdata uploads,
     * where the CPU sets up a blit command on the hardware with instructions
     * that the blit data will be fed through some sort of aperture on the card.
     *
     * If UploadToScreen() is performed asynchronously, it is up to the driver
     * to call exaMarkSync().  This is in contrast to most other acceleration
     * calls in EXA.
     *
     * UploadToScreen() can aid in pixmap migration, but is most important for
     * the performance of exaGlyphs() (antialiased font drawing) by allowing
     * pipelining of data uploads, avoiding a sync of the card after each glyph.
     * 
     * @return TRUE if the driver successfully uploaded the data.  FALSE
     * indicates that EXA should fall back to doing the upload in software.
     *
     * UploadToScreen() is not required, but is recommended if Composite
     * acceleration is supported.
     */
    Bool        (*UploadToScreen) (PixmapPtr            pDst,
				   int                  x,
				   int                  y,
				   int                  w,
				   int                  h,
                                   char                 *src,
                                   int                  src_pitch);

    /**
     * UploadToScratch() is used to upload a pixmap to a scratch area for
     * acceleration.
     *
     * @param pSrc source pixmap in host memory
     * @param pDst fake, scratch pixmap to be set up in offscreen memory.
     *
     * The UploadToScratch() call was added to support Xati before Xati had
     * support for hostdata uploads and before exaGlyphs() was written.  It
     * behaves incorrectly (uses an invalid pixmap as pDst),
     * and UploadToScreen() should be implemented instead.
     *
     * Drivers implementing UploadToScratch() had to set up space (likely in a
     * statically allocated area) in offscreen memory, copy pSrc to that
     * scratch area, and adust pDst->devKind for the pitch and
     * pDst->devPrivate.ptr for the pointer to that scratch area.  The driver
     * was responsible for syncing (as it was implemented using memcpy() in
     * Xati), and only the data from the last UploadToScratch() was guaranteed
     * to be valid at any given time.
     *
     * UploadToScratch() should not be implemented by drivers, and will likely
     * be removed in a future version of EXA.
     */
    Bool        (*UploadToScratch) (PixmapPtr           pSrc,
                                    PixmapPtr           pDst);

    /**
     * DownloadFromScreen() loads a rectangle of data from pSrc into dst
     *
     * @param pSrc source pixmap
     * @param x source X coordinate.
     * @param y source Y coordinate
     * @param width width of the rectangle to be copied
     * @param height height of the rectangle to be copied
     * @param dst pointer to the beginning of the destination data
     * @param dst_pitch pitch (in bytes) of the lines of destination data.
     *
     * DownloadFromScreen() copies data from offscreen memory in pSrc from
     * (x, y) to (x + width, y + height), to system memory starting at
     * dst (with pitch dst_pitch).  This would usually be done
     * using scatter-gather DMA, supported by a DRM call, or by blitting to AGP
     * and then synchronously reading from AGP.  Because the implementation
     * might be synchronous, EXA leaves it up to the driver to call
     * exaMarkSync() if DownloadFromScreen() was asynchronous.  This is in
     * contrast to most other acceleration calls in EXA.
     *
     * DownloadFromScreen() can aid in the largest bottleneck in pixmap
     * migration, which is the read from framebuffer when evicting pixmaps from
     * framebuffer memory.  Thus, it is highly recommended, even though
     * implementations are typically complicated.
     * 
     * @return TRUE if the driver successfully downloaded the data.  FALSE
     * indicates that EXA should fall back to doing the download in software.
     *
     * DownloadFromScreen() is not required, but is highly recommended.
     */
    Bool (*DownloadFromScreen)(PixmapPtr pSrc,
                               int x,  int y,
                               int w,  int h,
                               char *dst,  int dst_pitch);

    /**
     * MarkSync() requests that the driver mark a synchronization point,
     * returning an driver-defined integer marker which could be requested for
     * synchronization to later in WaitMarker().  This might be used in the
     * future to avoid waiting for full hardware stalls before accessing pixmap
     * data with the CPU, but is not important in the current incarnation of
     * EXA.
     *
     * Note that drivers should call exaMarkSync() when they have done some
     * acceleration, rather than their own MarkSync() handler, as otherwise EXA
     * will be unaware of the driver's acceleration and not sync to it during
     * fallbacks.
     *
     * MarkSync() is optional.
     */
    int		(*MarkSync)   (ScreenPtr pScreen);

    /**
     * WaitMarker() waits for all rendering before the given marker to have
     * completed.  If the driver does not implement MarkSync(), marker is
     * meaningless, and all rendering by the hardware should be completed before
     * WaitMarker() returns.
     *
     * Note that drivers should call exaWaitSync() to wait for all acceleration
     * to finish, as otherwise EXA will be unaware of the driver having
     * synchronized, resulting in excessive WaitMarker() calls.
     *
     * WaitMarker() is required of all drivers.
     */
    void	(*WaitMarker) (ScreenPtr pScreen, int marker);

    /** @{ */
    /**
     * PrepareAccess() is called before CPU access to an offscreen pixmap.
     *
     * @param pPix the pixmap being accessed
     * @param index the index of the pixmap being accessed.
     *
     * PrepareAccess() will be called before CPU access to an offscreen pixmap.
     * This can be used to set up hardware surfaces for byteswapping or
     * untiling, or to adjust the pixmap's devPrivate.ptr for the purpose of
     * making CPU access use a different aperture.
     *
     * The index is one of #EXA_PREPARE_DEST, #EXA_PREPARE_SRC, or
     * #EXA_PREPARE_MASK, indicating which pixmap is in question.  Since only up
     * to three pixmaps will have PrepareAccess() called on them per operation,
     * drivers can have a small, statically-allocated space to maintain state
     * for PrepareAccess() and FinishAccess() in.  Note that the same pixmap may
     * have PrepareAccess() called on it more than once, for example when doing
     * a copy within the same pixmap (so it gets PrepareAccess as()
     * #EXA_PREPARE_DEST and then as #EXA_PREPARE_SRC).
     *
     * PrepareAccess() may fail.  An example might be the case of hardware that
     * can set up 1 or 2 surfaces for CPU access, but not 3.  If PrepareAccess()
     * fails, EXA will migrate the pixmap to system memory.
     * DownloadFromScreen() must be implemented and must not fail if a driver
     * wishes to fail in PrepareAccess().  PrepareAccess() must not fail when
     * pPix is the visible screen, because the visible screen can not be
     * migrated.
     *
     * @return TRUE if PrepareAccess() successfully prepared the pixmap for CPU
     * drawing.
     * @return FALSE if PrepareAccess() is unsuccessful and EXA should use
     * DownloadFromScreen() to migate the pixmap out.
     */
    Bool	(*PrepareAccess)(PixmapPtr pPix, int index);

    /**
     * FinishAccess() is called after CPU access to an offscreen pixmap.
     *
     * @param pPix the pixmap being accessed
     * @param index the index of the pixmap being accessed.
     *
     * FinishAccess() will be called after finishing CPU access of an offscreen
     * pixmap set up by PrepareAccess().  Note that the FinishAccess() will not be
     * called if PrepareAccess() failed and the pixmap was migrated out.
     */
    void	(*FinishAccess)(PixmapPtr pPix, int index);

    /**
     * PixmapIsOffscreen() is an optional driver replacement to
     * exaPixmapIsOffscreen(). Set to NULL if you want the standard behaviour
     * of exaPixmapIsOffscreen().
     *
     * @param pPix the pixmap
     * @return TRUE if the given drawable is in framebuffer memory.
     *
     * exaPixmapIsOffscreen() is used to determine if a pixmap is in offscreen
     * memory, meaning that acceleration could probably be done to it, and that it
     * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it
     * with the CPU.
     *
     *
     */
    Bool	(*PixmapIsOffscreen)(PixmapPtr pPix);

	/** @name PrepareAccess() and FinishAccess() indices
	 * @{
	 */
	/**
	 * EXA_PREPARE_DEST is the index for a pixmap that may be drawn to or
	 * read from.
	 */ 
	#define EXA_PREPARE_DEST	0
	/**
	 * EXA_PREPARE_SRC is the index for a pixmap that may be read from
	 */
	#define EXA_PREPARE_SRC		1
	/**
	 * EXA_PREPARE_SRC is the index for a second pixmap that may be read
	 * from.
	 */
	#define EXA_PREPARE_MASK	2
	/** @} */
    /** @} */
} ExaDriverRec, *ExaDriverPtr;

/** @name EXA driver flags
 * @{
 */
/**
 * EXA_OFFSCREEN_PIXMAPS indicates to EXA that the driver can support 
 * offscreen pixmaps.
 */
#define EXA_OFFSCREEN_PIXMAPS		(1 << 0)

/**
 * EXA_OFFSCREEN_ALIGN_POT indicates to EXA that the driver needs pixmaps
 * to have a power-of-two pitch.
 */
#define EXA_OFFSCREEN_ALIGN_POT		(1 << 1)

/**
 * EXA_TWO_BITBLT_DIRECTIONS indicates to EXA that the driver can only
 * support copies that are (left-to-right, top-to-bottom) or
 * (right-to-left, bottom-to-top).
 */
#define EXA_TWO_BITBLT_DIRECTIONS	(1 << 2)
/** @} */

ExaDriverPtr
exaDriverAlloc(void);

Bool
exaDriverInit(ScreenPtr                pScreen,
              ExaDriverPtr   pScreenInfo);

void
exaDriverFini(ScreenPtr                pScreen);

void
exaMarkSync(ScreenPtr pScreen);
void
exaWaitSync(ScreenPtr pScreen);

ExaOffscreenArea *
exaOffscreenAlloc(ScreenPtr pScreen, int size, int align,
                  Bool locked,
                  ExaOffscreenSaveProc save,
                  pointer privData);

ExaOffscreenArea *
exaOffscreenFree(ScreenPtr pScreen, ExaOffscreenArea *area);

void
ExaOffscreenMarkUsed (PixmapPtr pPixmap);

unsigned long
exaGetPixmapOffset(PixmapPtr pPix);

unsigned long
exaGetPixmapPitch(PixmapPtr pPix);

unsigned long
exaGetPixmapSize(PixmapPtr pPix);

void
exaEnableDisableFBAccess (int index, Bool enable);

void
exaMoveInPixmap (PixmapPtr pPixmap);

void
exaMoveOutPixmap (PixmapPtr pPixmap);

/**
 * Returns TRUE if the given planemask covers all the significant bits in the
 * pixel values for pDrawable.
 */
#define EXA_PM_IS_SOLID(_pDrawable, _pm) \
	(((_pm) & FbFullMask((_pDrawable)->depth)) == \
	 FbFullMask((_pDrawable)->depth))

#endif /* EXA_H */