summaryrefslogtreecommitdiff
path: root/saa/saa.c
diff options
context:
space:
mode:
Diffstat (limited to 'saa/saa.c')
-rw-r--r--saa/saa.c748
1 files changed, 748 insertions, 0 deletions
diff --git a/saa/saa.c b/saa/saa.c
new file mode 100644
index 0000000..173c090
--- /dev/null
+++ b/saa/saa.c
@@ -0,0 +1,748 @@
1/*
2 * Copyright © 2001 Keith Packard
3 *
4 * Partly based on code that is Copyright © The XFree86 Project Inc.
5 *
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of Keith Packard not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission. Keith Packard makes no
13 * representations about the suitability of this software for any purpose. It
14 * is provided "as is" without express or implied warranty.
15 *
16 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
23 */
24
25/** @file
26 * This file covers the initialization and teardown of SAA, and has various
27 * functions not responsible for performing rendering, pixmap migration, or
28 * memory management.
29 */
30
31#ifdef HAVE_DIX_CONFIG_H
32#include <dix-config.h>
33#endif
34
35#include <stdlib.h>
36
37#include "saa_priv.h"
38#include <X11/fonts/fontstruct.h>
39#include "regionstr.h"
40#include "saa.h"
41#include "saa_priv.h"
42
43#ifdef SAA_DEVPRIVATEKEYREC
44DevPrivateKeyRec saa_screen_index;
45DevPrivateKeyRec saa_pixmap_index;
46DevPrivateKeyRec saa_gc_index;
47#else
48int saa_screen_index = -1;
49int saa_pixmap_index = -1;
50int saa_gc_index = -1;
51#endif
52
53/**
54 * saa_get_drawable_pixmap() returns a backing pixmap for a given drawable.
55 *
56 * @param pDrawable the drawable being requested.
57 *
58 * This function returns the backing pixmap for a drawable, whether it is a
59 * redirected window, unredirected window, or already a pixmap. Note that
60 * coordinate translation is needed when drawing to the backing pixmap of a
61 * redirected window, and the translation coordinates are provided by calling
62 * saa_get_drawable_pixmap() on the drawable.
63 */
64PixmapPtr
65saa_get_drawable_pixmap(DrawablePtr pDrawable)
66{
67 if (pDrawable->type == DRAWABLE_WINDOW)
68 return pDrawable->pScreen->GetWindowPixmap((WindowPtr) pDrawable);
69 else
70 return (PixmapPtr) pDrawable;
71}
72
73/**
74 * Sets the offsets to add to coordinates to make them address the same bits in
75 * the backing drawable. These coordinates are nonzero only for redirected
76 * windows.
77 */
78void
79saa_get_drawable_deltas(DrawablePtr pDrawable, PixmapPtr pPixmap,
80 int *xp, int *yp)
81{
82#ifdef COMPOSITE
83 if (pDrawable->type == DRAWABLE_WINDOW) {
84 *xp = -pPixmap->screen_x;
85 *yp = -pPixmap->screen_y;
86 return;
87 }
88#endif
89
90 *xp = 0;
91 *yp = 0;
92}
93
94/**
95 * Returns the pixmap which backs a drawable, and the offsets to add to
96 * coordinates to make them address the same bits in the backing drawable.
97 */
98PixmapPtr
99saa_get_pixmap(DrawablePtr drawable, int *xp, int *yp)
100{
101 PixmapPtr pixmap = saa_get_drawable_pixmap(drawable);
102
103 saa_get_drawable_deltas(drawable, pixmap, xp, yp);
104
105 return pixmap;
106}
107
108static Bool
109saa_download_from_hw(PixmapPtr pix, RegionPtr readback)
110{
111 struct saa_screen_priv *sscreen = saa_screen(pix->drawable.pScreen);
112 struct saa_driver *driver = sscreen->driver;
113 struct saa_pixmap *spix = saa_pixmap(pix);
114 void *addr;
115 Bool ret;
116
117 if (spix->mapped_access)
118 driver->release_from_cpu(driver, pix, spix->mapped_access);
119
120 ret = driver->download_from_hw(driver, pix, readback);
121
122 if (spix->mapped_access) {
123 addr = driver->sync_for_cpu(driver, pix, spix->mapped_access);
124 if (addr != NULL)
125 spix->addr = addr;
126 }
127
128 return ret;
129}
130
131Bool
132saa_prepare_access_pixmap(PixmapPtr pix, saa_access_t access,
133 RegionPtr read_reg)
134{
135 ScreenPtr pScreen = pix->drawable.pScreen;
136 struct saa_screen_priv *sscreen = saa_screen(pScreen);
137 struct saa_driver *driver = sscreen->driver;
138 struct saa_pixmap *spix = saa_pixmap(pix);
139 saa_access_t map_access = 0;
140 Bool ret = TRUE;
141
142 if (read_reg && REGION_NOTEMPTY(pScreen, read_reg))
143 ret = saa_download_from_hw(pix, read_reg);
144
145 if (!ret) {
146 LogMessage(X_ERROR, "Prepare access pixmap failed.\n");
147 return ret;
148 }
149
150 if ((access & SAA_ACCESS_R) != 0 && spix->read_access++ == 0)
151 map_access = SAA_ACCESS_R;
152 if ((access & SAA_ACCESS_W) != 0 && spix->write_access++ == 0)
153 map_access |= SAA_ACCESS_W;
154
155 if (map_access) {
156 if (spix->auth_loc != saa_loc_override) {
157 (void)driver->sync_for_cpu(driver, pix, map_access);
158 spix->addr = driver->map(driver, pix, map_access);
159 } else
160 spix->addr = spix->override;
161 spix->mapped_access |= map_access;
162 }
163
164 pix->devPrivate.ptr = spix->addr;
165 return TRUE;
166}
167
168void
169saa_finish_access_pixmap(PixmapPtr pix, saa_access_t access)
170{
171 struct saa_screen_priv *sscreen = saa_screen(pix->drawable.pScreen);
172 struct saa_driver *driver = sscreen->driver;
173 struct saa_pixmap *spix = saa_pixmap(pix);
174 saa_access_t unmap_access = 0;
175
176 if ((access & SAA_ACCESS_R) != 0 && --spix->read_access == 0)
177 unmap_access = SAA_ACCESS_R;
178 if ((access & SAA_ACCESS_W) != 0 && --spix->write_access == 0)
179 unmap_access |= SAA_ACCESS_W;
180
181 if (spix->read_access < 0)
182 LogMessage(X_ERROR, "Incorrect read access.\n");
183 if (spix->write_access < 0)
184 LogMessage(X_ERROR, "Incorrect write access.\n");
185
186 if (unmap_access) {
187 if (spix->auth_loc != saa_loc_override) {
188 driver->unmap(driver, pix, unmap_access);
189 driver->release_from_cpu(driver, pix, unmap_access);
190 }
191 spix->mapped_access &= ~unmap_access;
192 }
193 if (!spix->mapped_access) {
194 spix->addr = NULL;
195 pix->devPrivate.ptr = SAA_INVALID_ADDRESS;
196 }
197}
198
199/*
200 * Callback that is called after a rendering operation. We try to
201 * determine whether it's a shadow damage or a hw damage and call the
202 * driver callback.
203 */
204
205static void
206saa_report_damage(DamagePtr damage, RegionPtr reg, void *closure)
207{
208 PixmapPtr pixmap = (PixmapPtr) closure;
209 struct saa_pixmap *spix = saa_get_saa_pixmap(pixmap);
210 struct saa_driver *driver = saa_screen(pixmap->drawable.pScreen)->driver;
211
212 if (spix->read_access || spix->write_access)
213 LogMessage(X_ERROR, "Damage report inside prepare access.\n");
214
215 driver->operation_complete(driver, pixmap);
216 DamageEmpty(damage);
217}
218
219Bool
220saa_add_damage(PixmapPtr pixmap)
221{
222 ScreenPtr pScreen = pixmap->drawable.pScreen;
223 struct saa_pixmap *spix = saa_get_saa_pixmap(pixmap);
224
225 if (spix->damage)
226 return TRUE;
227
228 spix->damage = DamageCreate(saa_report_damage, NULL,
229 DamageReportRawRegion, TRUE, pScreen, pixmap);
230 if (!spix->damage)
231 return FALSE;
232
233 DamageRegister(&pixmap->drawable, spix->damage);
234 DamageSetReportAfterOp(spix->damage, TRUE);
235
236 return TRUE;
237}
238
239static inline RegionPtr
240saa_pix_damage_region(struct saa_pixmap *spix)
241{
242 return (spix->damage ? DamageRegion(spix->damage) : NULL);
243}
244
245Bool
246saa_pad_read(DrawablePtr draw)
247{
248 ScreenPtr pScreen = draw->pScreen;
249 PixmapPtr pix;
250 int xp;
251 int yp;
252 BoxRec box;
253 RegionRec entire;
254 Bool ret;
255
256 (void)pScreen;
257 pix = saa_get_pixmap(draw, &xp, &yp);
258
259 box.x1 = draw->x + xp;
260 box.y1 = draw->y + yp;
261 box.x2 = box.x1 + draw->width;
262 box.y2 = box.y1 + draw->height;
263
264 REGION_INIT(pScreen, &entire, &box, 1);
265 ret = saa_prepare_access_pixmap(pix, SAA_ACCESS_R, &entire);
266 REGION_UNINIT(pScreen, &entire);
267 return ret;
268}
269
270Bool
271saa_pad_read_box(DrawablePtr draw, int x, int y, int w, int h)
272{
273 ScreenPtr pScreen = draw->pScreen;
274 PixmapPtr pix;
275 int xp;
276 int yp;
277 BoxRec box;
278 RegionRec entire;
279 Bool ret;
280
281 (void)pScreen;
282 pix = saa_get_pixmap(draw, &xp, &yp);
283
284 box.x1 = x + xp;
285 box.y1 = y + yp;
286 box.x2 = box.x1 + w;
287 box.y2 = box.y1 + h;
288
289 REGION_INIT(pScreen, &entire, &box, 1);
290 ret = saa_prepare_access_pixmap(pix, SAA_ACCESS_R, &entire);
291 REGION_UNINIT(pScreen, &entire);
292 return ret;
293}
294
295/**
296 * Prepares a drawable destination for access, and maps it read-write.
297 * If check_read is TRUE, pGC should point to a valid GC. The drawable
298 * may then be mapped write-only if the pending operation admits.
299 */
300
301Bool
302saa_pad_write(DrawablePtr draw, GCPtr pGC, Bool check_read,
303 saa_access_t * access)
304{
305 int xp;
306 int yp;
307 PixmapPtr pixmap = saa_get_pixmap(draw, &xp, &yp);
308 struct saa_pixmap *spix = saa_pixmap(pixmap);
309
310 *access = SAA_ACCESS_W;
311
312 /*
313 * If the to-be-damaged area doesn't depend at all on previous
314 * rendered contents, we don't need to do any readback.
315 */
316
317 if (check_read && !saa_gc_reads_destination(draw, pGC))
318 return saa_prepare_access_pixmap(pixmap, *access, NULL);
319
320 *access |= SAA_ACCESS_R;
321
322 /*
323 * Read back the area to be damaged.
324 */
325
326 return saa_prepare_access_pixmap(pixmap, *access,
327 saa_pix_damage_pending(spix));
328}
329
330void
331saa_fad_read(DrawablePtr draw)
332{
333 saa_finish_access_pixmap(saa_get_drawable_pixmap(draw), SAA_ACCESS_R);
334}
335
336void
337saa_fad_write(DrawablePtr draw, saa_access_t access)
338{
339 PixmapPtr pix = saa_get_drawable_pixmap(draw);
340 struct saa_pixmap *spix = saa_pixmap(pix);
341
342 saa_finish_access_pixmap(pix, access);
343 if (spix->damage)
344 saa_pixmap_dirty(pix, FALSE, saa_pix_damage_pending(spix));
345}
346
347Bool
348saa_gc_reads_destination(DrawablePtr pDrawable, GCPtr pGC)
349{
350 return ((pGC->alu != GXcopy && pGC->alu != GXclear && pGC->alu != GXset &&
351 pGC->alu != GXcopyInverted) || pGC->fillStyle == FillStippled ||
352 pGC->clientClipType != CT_NONE ||
353 !SAA_PM_IS_SOLID(pDrawable, pGC->planemask));
354}
355
356Bool
357saa_op_reads_destination(CARD8 op)
358{
359 /* FALSE (does not read destination) is the list of ops in the protocol
360 * document with "0" in the "Fb" column and no "Ab" in the "Fa" column.
361 * That's just Clear and Src. ReduceCompositeOp() will already have
362 * converted con/disjoint clear/src to Clear or Src.
363 */
364 switch (op) {
365 case PictOpClear:
366 case PictOpSrc:
367 return FALSE;
368 default:
369 return TRUE;
370 }
371}
372
373static void
374saa_validate_gc(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
375{
376 /* fbValidateGC will do direct access to pixmaps if the tiling has changed.
377 * Do a few smart things so fbValidateGC can do it's work.
378 */
379
380 ScreenPtr pScreen = pDrawable->pScreen;
381 struct saa_screen_priv *sscreen = saa_screen(pScreen);
382 struct saa_gc_priv *sgc = saa_gc(pGC);
383 PixmapPtr pTile = NULL;
384 Bool finish_current_tile = FALSE;
385
386 /* Either of these conditions is enough to trigger access to a tile pixmap. */
387 /* With pGC->tileIsPixel == 1, you run the risk of dereferencing an invalid tile pixmap pointer. */
388 if (pGC->fillStyle == FillTiled
389 || ((changes & GCTile) && !pGC->tileIsPixel)) {
390 pTile = pGC->tile.pixmap;
391
392 /* Sometimes tile pixmaps are swapped, you need access to:
393 * - The current tile if it depth matches.
394 * - Or the rotated tile if that one matches depth and !(changes & GCTile).
395 * - Or the current tile pixmap and a newly created one.
396 */
397 if (pTile && pTile->drawable.depth != pDrawable->depth
398 && !(changes & GCTile)) {
399 PixmapPtr pRotatedTile = fbGetRotatedPixmap(pGC);
400
401 if (pRotatedTile
402 && pRotatedTile->drawable.depth == pDrawable->depth)
403 pTile = pRotatedTile;
404 else
405 finish_current_tile = TRUE; /* CreatePixmap will be called. */
406 }
407 }
408
409 if (pGC->stipple && !saa_pad_read(&pGC->stipple->drawable)) {
410 LogMessage(X_ERROR, "Failed stipple prepareaccess.\n");
411 return;
412 }
413
414 if (pTile && !saa_pad_read(&pTile->drawable)) {
415 LogMessage(X_ERROR, "Failed stipple prepareaccess.\n");
416 goto out_no_tile;
417 }
418
419 /* Calls to Create/DestroyPixmap have to be identified as special, so
420 * up sscreen->fallback_count.
421 */
422
423 sscreen->fallback_count++;
424 saa_swap(sgc, pGC, funcs);
425 (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);
426 saa_swap(sgc, pGC, funcs);
427
428 if (finish_current_tile && pGC->tile.pixmap)
429 saa_fad_write(&pGC->tile.pixmap->drawable, SAA_ACCESS_W);
430 sscreen->fallback_count--;
431
432 if (pTile)
433 saa_fad_read(&pTile->drawable);
434 out_no_tile:
435 if (pGC->stipple)
436 saa_fad_read(&pGC->stipple->drawable);
437}
438
439static void
440saa_destroy_gc(GCPtr pGC)
441{
442 struct saa_gc_priv *sgc = saa_gc(pGC);
443
444 saa_swap(sgc, pGC, funcs);
445 (*pGC->funcs->DestroyGC) (pGC);
446 saa_swap(sgc, pGC, funcs);
447}
448
449static void
450saa_change_gc(GCPtr pGC, unsigned long mask)
451{
452 struct saa_gc_priv *sgc = saa_gc(pGC);
453
454 saa_swap(sgc, pGC, funcs);
455 (*pGC->funcs->ChangeGC) (pGC, mask);
456 saa_swap(sgc, pGC, funcs);
457}
458
459static void
460saa_copy_gc(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
461{
462 struct saa_gc_priv *sgc = saa_gc(pGCDst);
463
464 saa_swap(sgc, pGCDst, funcs);
465 (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
466 saa_swap(sgc, pGCDst, funcs);
467}
468
469static void
470saa_change_clip(GCPtr pGC, int type, pointer pvalue, int nrects)
471{
472 struct saa_gc_priv *sgc = saa_gc(pGC);
473
474 saa_swap(sgc, pGC, funcs);
475 (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
476 saa_swap(sgc, pGC, funcs);
477}
478
479static void
480saa_copy_clip(GCPtr pGCDst, GCPtr pGCSrc)
481{
482 struct saa_gc_priv *sgc = saa_gc(pGCDst);
483
484 saa_swap(sgc, pGCDst, funcs);
485 (*pGCDst->funcs->CopyClip) (pGCDst, pGCSrc);
486 saa_swap(sgc, pGCDst, funcs);
487}
488
489static void
490saa_destroy_clip(GCPtr pGC)
491{
492 struct saa_gc_priv *sgc = saa_gc(pGC);
493
494 saa_swap(sgc, pGC, funcs);
495 (*pGC->funcs->DestroyClip) (pGC);
496 saa_swap(sgc, pGC, funcs);
497}
498
499static GCFuncs saa_gc_funcs = {
500 saa_validate_gc,
501 saa_change_gc,
502 saa_copy_gc,
503 saa_destroy_gc,
504 saa_change_clip,
505 saa_destroy_clip,
506 saa_copy_clip
507};
508
509/**
510 * saa_create_gc makes a new GC and hooks up its funcs handler, so that
511 * saa_validate_gc() will get called.
512 */
513int
514saa_create_gc(GCPtr pGC)
515{
516 ScreenPtr pScreen = pGC->pScreen;
517 struct saa_screen_priv *sscreen = saa_screen(pScreen);
518 struct saa_gc_priv *sgc = saa_gc(pGC);
519 Bool ret;
520
521 saa_swap(sscreen, pScreen, CreateGC);
522 ret = pScreen->CreateGC(pGC);
523 if (ret) {
524 saa_wrap(sgc, pGC, funcs, &saa_gc_funcs);
525 saa_wrap(sgc, pGC, ops, &saa_gc_ops);
526 }
527 saa_swap(sscreen, pScreen, CreateGC);
528
529 return ret;
530}
531
532static Bool
533saa_prepare_access_window(WindowPtr pWin)
534{
535 if (pWin->backgroundState == BackgroundPixmap) {
536 if (!saa_pad_read(&pWin->background.pixmap->drawable))
537 return FALSE;
538 }
539
540 if (pWin->borderIsPixel == FALSE) {
541 if (!saa_pad_read(&pWin->border.pixmap->drawable)) {
542 if (pWin->backgroundState == BackgroundPixmap)
543 saa_fad_read(&pWin->background.pixmap->drawable);
544 return FALSE;
545 }
546 }
547 return TRUE;
548}
549
550static void
551saa_finish_access_window(WindowPtr pWin)
552{
553 if (pWin->backgroundState == BackgroundPixmap)
554 saa_fad_read(&pWin->background.pixmap->drawable);
555
556 if (pWin->borderIsPixel == FALSE)
557 saa_fad_read(&pWin->border.pixmap->drawable);
558}
559
560static Bool
561saa_change_window_attributes(WindowPtr pWin, unsigned long mask)
562{
563 Bool ret;
564
565 if (!saa_prepare_access_window(pWin))
566 return FALSE;
567 ret = fbChangeWindowAttributes(pWin, mask);
568 saa_finish_access_window(pWin);
569 return ret;
570}
571
572RegionPtr
573saa_bitmap_to_region(PixmapPtr pPix)
574{
575 RegionPtr ret;
576
577 if (!saa_pad_read(&pPix->drawable))
578 return NULL;
579 ret = fbPixmapToRegion(pPix);
580 saa_fad_read(&pPix->drawable);
581 return ret;
582}
583
584void
585saa_set_fallback_debug(ScreenPtr screen, Bool enable)
586{
587 struct saa_screen_priv *sscreen = saa_screen(screen);
588
589 sscreen->fallback_debug = enable;
590}
591
592/**
593 * saa_close_screen() unwraps its wrapped screen functions and tears down SAA's
594 * screen private, before calling down to the next CloseScreen.
595 */
596Bool
597saa_close_screen(int i, ScreenPtr pScreen)
598{
599 struct saa_screen_priv *sscreen = saa_screen(pScreen);
600 struct saa_driver *driver = sscreen->driver;
601
602 if (pScreen->devPrivate) {
603 /* Destroy the pixmap created by miScreenInit() *before*
604 * chaining up as we finalize ourselves here and so this
605 * is the last chance we have of releasing our resources
606 * associated with the Pixmap. So do it first.
607 */
608 (void)(*pScreen->DestroyPixmap) (pScreen->devPrivate);
609 pScreen->devPrivate = NULL;
610 }
611
612 saa_unwrap(sscreen, pScreen, CloseScreen);
613 saa_unwrap(sscreen, pScreen, CreateGC);
614 saa_unwrap(sscreen, pScreen, ChangeWindowAttributes);
615 saa_unwrap(sscreen, pScreen, CreatePixmap);
616 saa_unwrap(sscreen, pScreen, DestroyPixmap);
617 saa_unwrap(sscreen, pScreen, ModifyPixmapHeader);
618 saa_unwrap(sscreen, pScreen, BitmapToRegion);
619#ifdef RENDER
620 saa_render_takedown(pScreen);
621#endif
622 saa_unaccel_takedown(pScreen);
623 driver->takedown(driver);
624
625 free(sscreen);
626
627 return (*pScreen->CloseScreen) (i, pScreen);
628}
629
630struct saa_driver *
631saa_get_driver(ScreenPtr pScreen)
632{
633 return saa_screen(pScreen)->driver;
634}
635
636/**
637 * @param pScreen screen being initialized
638 * @param pScreenInfo SAA driver record
639 *
640 * saa_driver_init sets up SAA given a driver record filled in by the driver.
641 * pScreenInfo should have been allocated by saa_driver_alloc(). See the
642 * comments in _SaaDriver for what must be filled in and what is optional.
643 *
644 * @return TRUE if SAA was successfully initialized.
645 */
646Bool
647saa_driver_init(ScreenPtr screen, struct saa_driver * saa_driver)
648{
649 struct saa_screen_priv *sscreen;
650
651 if (!saa_driver)
652 return FALSE;
653
654 if (saa_driver->saa_major != SAA_VERSION_MAJOR ||
655 saa_driver->saa_minor > SAA_VERSION_MINOR) {
656 LogMessage(X_ERROR,
657 "SAA(%d): driver's SAA version requirements "
658 "(%d.%d) are incompatible with SAA version (%d.%d)\n",
659 screen->myNum, saa_driver->saa_major,
660 saa_driver->saa_minor, SAA_VERSION_MAJOR, SAA_VERSION_MINOR);
661 return FALSE;
662 }
663#if 0
664 if (!saa_driver->prepare_solid) {
665 LogMessage(X_ERROR,
666 "SAA(%d): saa_driver_t::prepare_solid must be "
667 "non-NULL\n", screen->myNum);
668 return FALSE;
669 }
670
671 if (!saa_driver->prepare_copy) {
672 LogMessage(X_ERROR,
673 "SAA(%d): saa_driver_t::prepare_copy must be "
674 "non-NULL\n", screen->myNum);
675 return FALSE;
676 }
677#endif
678#ifdef SAA_DEVPRIVATEKEYREC
679 if (!dixRegisterPrivateKey(&saa_screen_index, PRIVATE_SCREEN, 0)) {
680 LogMessage(X_ERROR, "Failed to register SAA screen private.\n");
681 return FALSE;
682 }
683 if (!dixRegisterPrivateKey(&saa_pixmap_index, PRIVATE_PIXMAP,
684 saa_driver->pixmap_size)) {
685 LogMessage(X_ERROR, "Failed to register SAA pixmap private.\n");
686 return FALSE;
687 }
688 if (!dixRegisterPrivateKey(&saa_gc_index, PRIVATE_GC,
689 sizeof(struct saa_gc_priv))) {
690 LogMessage(X_ERROR, "Failed to register SAA gc private.\n");
691 return FALSE;
692 }
693#else
694 if (!dixRequestPrivate(&saa_screen_index, 0)) {
695 LogMessage(X_ERROR, "Failed to register SAA screen private.\n");
696 return FALSE;
697 }
698 if (!dixRequestPrivate(&saa_pixmap_index, saa_driver->pixmap_size)) {
699 LogMessage(X_ERROR, "Failed to register SAA pixmap private.\n");
700 return FALSE;
701 }
702 if (!dixRequestPrivate(&saa_gc_index, sizeof(struct saa_gc_priv))) {
703 LogMessage(X_ERROR, "Failed to register SAA gc private.\n");
704 return FALSE;
705 }
706#endif
707
708 sscreen = calloc(1, sizeof(*sscreen));
709
710 if (!sscreen) {
711 LogMessage(X_WARNING,
712 "SAA(%d): Failed to allocate screen private\n",
713 screen->myNum);
714 return FALSE;
715 }
716
717 sscreen->driver = saa_driver;
718 dixSetPrivate(&screen->devPrivates, &saa_screen_index, sscreen);
719
720 /*
721 * Replace various fb screen functions
722 */
723
724 saa_wrap(sscreen, screen, CloseScreen, saa_close_screen);
725 saa_wrap(sscreen, screen, CreateGC, saa_create_gc);
726 saa_wrap(sscreen, screen, ChangeWindowAttributes,
727 saa_change_window_attributes);
728 saa_wrap(sscreen, screen, CreatePixmap, saa_create_pixmap);
729 saa_wrap(sscreen, screen, DestroyPixmap, saa_destroy_pixmap);
730 saa_wrap(sscreen, screen, ModifyPixmapHeader, saa_modify_pixmap_header);
731
732 saa_wrap(sscreen, screen, BitmapToRegion, saa_bitmap_to_region);
733 saa_unaccel_setup(screen);
734#ifdef RENDER
735 saa_render_setup(screen);
736#endif
737
738 return TRUE;
739}
740
741Bool
742saa_resources_init(ScreenPtr screen)
743{
744/* if (!saa_glyphs_init(screen))
745 return FALSE;
746*/
747 return TRUE;
748}