summaryrefslogtreecommitdiff
path: root/exa/exa.h
blob: 9af098ebe8a4ecf0066275c8c1cd94ba7b9cd133 (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
/*
 *
 * 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"

#define EXA_VERSION_MAJOR   2
#define EXA_VERSION_MINOR   0
#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 set of a series of Solid()
     * calls following a PrepareSolid() that was called.  This allows drivers to
     * finish up emitting drawing commands that were buffered.
     *
     * This call is required if PrepareSolid() ever succeeds.
     */
    void        (*DoneSolid) (PixmapPtr      pPixmap);
    /** @} */

    /** @name Copy
     * @{
     */
    /**
     * PrepareCopy sets up the driver for doing a copy within offscreen 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 set of a series of Copy()
     * calls following a PrepareCopy() that was called.  This allows drivers to
     * finish up emitting drawing commands that were buffered.
     *
     * 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 pitches and offsets 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 operations
     * 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 PrepareCopy 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 set of a series of
     * Composite() calls following a PrepareCopy() that was called.  This allows
     * drivers to finish up emitting drawing commands that were buffered.
     *
     * 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 @param pSrc into
     * @param 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.
     *
     * UploadToScreen is not required, but is highly recommended.
     */
    Bool (*DownloadFromScreen)(PixmapPtr pSrc,
                               int x,  int y,
                               int w,  int h,
                               char *dst,  int dst_pitch);

    /* Should return a hrdware-dependent marker number which can
     * be waited for with WaitMarker(). It can be not implemented in which
     * case WaitMarker() must wait for idle on any given marker
     * number.
     */
    /**
     * MarkSync() requests that the driver mark a synchronization point, returning
     * an driver-devined 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.
     *
     * 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.
     *
     * 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).
     *
     * @return TRUE if PrepareAccess() successfully prepared the pixmap for CPU
     * drawing.  Failure means that EXA should migrate the pixmap out of
     * offscreen memory, but this code path is currently broken.  Note that
     * DownloadFromScreen() will be called in case of a PrepareAccess() failure.
     * Also, PrepareAccess() may not fail on a pixmap representing the front
     * buffer, because the front buffer may not be migrated.
     */
    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);

	/** @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);

unsigned long
exaGetPixmapOffset(PixmapPtr pPix);

unsigned long
exaGetPixmapPitch(PixmapPtr pPix);

unsigned long
exaGetPixmapSize(PixmapPtr pPix);

void
exaEnableDisableFBAccess (int index, Bool enable);

#endif /* EXA_H */