1fa225cbcSrjs/*
2fa225cbcSrjs * Copyright � 2001 Keith Packard
3fa225cbcSrjs *
4fa225cbcSrjs * Partly based on code that is Copyright � The XFree86 Project Inc.
5fa225cbcSrjs *
6fa225cbcSrjs * Permission to use, copy, modify, distribute, and sell this software and its
7fa225cbcSrjs * documentation for any purpose is hereby granted without fee, provided that
8fa225cbcSrjs * the above copyright notice appear in all copies and that both that
9fa225cbcSrjs * copyright notice and this permission notice appear in supporting
10fa225cbcSrjs * documentation, and that the name of Keith Packard not be used in
11fa225cbcSrjs * advertising or publicity pertaining to distribution of the software without
12fa225cbcSrjs * specific, written prior permission.  Keith Packard makes no
13fa225cbcSrjs * representations about the suitability of this software for any purpose.  It
14fa225cbcSrjs * is provided "as is" without express or implied warranty.
15fa225cbcSrjs *
16fa225cbcSrjs * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17fa225cbcSrjs * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18fa225cbcSrjs * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19fa225cbcSrjs * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20fa225cbcSrjs * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21fa225cbcSrjs * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22fa225cbcSrjs * PERFORMANCE OF THIS SOFTWARE.
23fa225cbcSrjs */
24fa225cbcSrjs
25fa225cbcSrjs/** @file
26fa225cbcSrjs * This file covers the initialization and teardown of UXA, and has various
27fa225cbcSrjs * functions not responsible for performing rendering, pixmap migration, or
28fa225cbcSrjs * memory management.
29fa225cbcSrjs */
30fa225cbcSrjs
31fa225cbcSrjs#ifdef HAVE_DIX_CONFIG_H
32fa225cbcSrjs#include <dix-config.h>
33fa225cbcSrjs#endif
34fa225cbcSrjs
35fa225cbcSrjs#include <stdlib.h>
36fa225cbcSrjs
37fa225cbcSrjs#include "uxa-priv.h"
38fa225cbcSrjs#include <X11/fonts/fontstruct.h>
39fa225cbcSrjs#include "dixfontstr.h"
40fa225cbcSrjs#include "uxa.h"
41fa225cbcSrjs
42be514f52SrjsDevPrivateKeyRec uxa_screen_index;
43fa225cbcSrjs
44fa225cbcSrjs/**
45fa225cbcSrjs * uxa_get_drawable_pixmap() returns a backing pixmap for a given drawable.
46fa225cbcSrjs *
47fa225cbcSrjs * @param pDrawable the drawable being requested.
48fa225cbcSrjs *
49fa225cbcSrjs * This function returns the backing pixmap for a drawable, whether it is a
50fa225cbcSrjs * redirected window, unredirected window, or already a pixmap.  Note that
51fa225cbcSrjs * coordinate translation is needed when drawing to the backing pixmap of a
52fa225cbcSrjs * redirected window, and the translation coordinates are provided by calling
53fa225cbcSrjs * uxa_get_drawable_pixmap() on the drawable.
54fa225cbcSrjs */
55fa225cbcSrjsPixmapPtr
56fa225cbcSrjsuxa_get_drawable_pixmap(DrawablePtr pDrawable)
57fa225cbcSrjs{
58fa225cbcSrjs     if (pDrawable->type == DRAWABLE_WINDOW)
59fa225cbcSrjs	return pDrawable->pScreen->GetWindowPixmap ((WindowPtr) pDrawable);
60fa225cbcSrjs     else
61fa225cbcSrjs	return (PixmapPtr) pDrawable;
62fa225cbcSrjs}
63fa225cbcSrjs
64fa225cbcSrjs/**
65fa225cbcSrjs * Sets the offsets to add to coordinates to make them address the same bits in
66fa225cbcSrjs * the backing drawable. These coordinates are nonzero only for redirected
67fa225cbcSrjs * windows.
68fa225cbcSrjs */
69fa225cbcSrjsvoid
70fa225cbcSrjsuxa_get_drawable_deltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
71fa225cbcSrjs			 int *xp, int *yp)
72fa225cbcSrjs{
73fa225cbcSrjs#ifdef COMPOSITE
74fa225cbcSrjs    if (pDrawable->type == DRAWABLE_WINDOW) {
75fa225cbcSrjs	*xp = -pPixmap->screen_x;
76fa225cbcSrjs	*yp = -pPixmap->screen_y;
77fa225cbcSrjs	return;
78fa225cbcSrjs    }
79fa225cbcSrjs#endif
80fa225cbcSrjs
81fa225cbcSrjs    *xp = 0;
82fa225cbcSrjs    *yp = 0;
83fa225cbcSrjs}
84fa225cbcSrjs
85fa225cbcSrjs/**
86fa225cbcSrjs * uxa_pixmap_is_offscreen() is used to determine if a pixmap is in offscreen
87fa225cbcSrjs * memory, meaning that acceleration could probably be done to it, and that it
88fa225cbcSrjs * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it
89fa225cbcSrjs * with the CPU.
90fa225cbcSrjs *
91fa225cbcSrjs * Note that except for UploadToScreen()/DownloadFromScreen() (which explicitly
92fa225cbcSrjs * deal with moving pixmaps in and out of system memory), UXA will give drivers
93fa225cbcSrjs * pixmaps as arguments for which uxa_pixmap_is_offscreen() is TRUE.
94fa225cbcSrjs *
95fa225cbcSrjs * @return TRUE if the given drawable is in framebuffer memory.
96fa225cbcSrjs */
97fa225cbcSrjsBool
98fa225cbcSrjsuxa_pixmap_is_offscreen(PixmapPtr p)
99fa225cbcSrjs{
100fa225cbcSrjs    ScreenPtr	    pScreen = p->drawable.pScreen;
101fa225cbcSrjs    uxa_screen_t    *uxa_screen = uxa_get_screen(pScreen);
102fa225cbcSrjs
103fa225cbcSrjs    if (uxa_screen->info->pixmap_is_offscreen)
104fa225cbcSrjs	return uxa_screen->info->pixmap_is_offscreen(p);
105fa225cbcSrjs
106fa225cbcSrjs    return FALSE;
107fa225cbcSrjs}
108fa225cbcSrjs
109fa225cbcSrjs/**
110fa225cbcSrjs * uxa_drawable_is_offscreen() is a convenience wrapper for uxa_pixmap_is_offscreen().
111fa225cbcSrjs */
112fa225cbcSrjsBool
113fa225cbcSrjsuxa_drawable_is_offscreen (DrawablePtr pDrawable)
114fa225cbcSrjs{
115fa225cbcSrjs    return uxa_pixmap_is_offscreen (uxa_get_drawable_pixmap (pDrawable));
116fa225cbcSrjs}
117fa225cbcSrjs
118fa225cbcSrjs/**
119fa225cbcSrjs  * Returns the pixmap which backs a drawable, and the offsets to add to
120fa225cbcSrjs  * coordinates to make them address the same bits in the backing drawable.
121fa225cbcSrjs  */
122fa225cbcSrjsPixmapPtr
123fa225cbcSrjsuxa_get_offscreen_pixmap (DrawablePtr drawable, int *xp, int *yp)
124fa225cbcSrjs{
125fa225cbcSrjs    PixmapPtr   pixmap = uxa_get_drawable_pixmap (drawable);
126fa225cbcSrjs
127fa225cbcSrjs    uxa_get_drawable_deltas (drawable, pixmap, xp, yp);
128fa225cbcSrjs
129fa225cbcSrjs    if (uxa_pixmap_is_offscreen (pixmap))
130fa225cbcSrjs	return pixmap;
131fa225cbcSrjs    else
132fa225cbcSrjs	return NULL;
133fa225cbcSrjs}
134fa225cbcSrjs
135fa225cbcSrjs
136fa225cbcSrjs
137fa225cbcSrjs/**
138fa225cbcSrjs * uxa_prepare_access() is UXA's wrapper for the driver's PrepareAccess() handler.
139fa225cbcSrjs *
140fa225cbcSrjs * It deals with waiting for synchronization with the card, determining if
141fa225cbcSrjs * PrepareAccess() is necessary, and working around PrepareAccess() failure.
142fa225cbcSrjs */
143fa225cbcSrjsBool
144fa225cbcSrjsuxa_prepare_access(DrawablePtr pDrawable, uxa_access_t access)
145fa225cbcSrjs{
146fa225cbcSrjs    ScreenPtr	    pScreen = pDrawable->pScreen;
147fa225cbcSrjs    uxa_screen_t    *uxa_screen = uxa_get_screen(pScreen);
148fa225cbcSrjs    PixmapPtr	    pPixmap = uxa_get_drawable_pixmap (pDrawable);
149fa225cbcSrjs    Bool	    offscreen = uxa_pixmap_is_offscreen(pPixmap);
150fa225cbcSrjs
151fa225cbcSrjs    if (!offscreen)
152fa225cbcSrjs	return TRUE;
153fa225cbcSrjs
154fa225cbcSrjs    if (uxa_screen->info->prepare_access)
155fa225cbcSrjs	return (*uxa_screen->info->prepare_access) (pPixmap, access);
156fa225cbcSrjs    return TRUE;
157fa225cbcSrjs}
158fa225cbcSrjs
159fa225cbcSrjs/**
160fa225cbcSrjs * uxa_finish_access() is UXA's wrapper for the driver's finish_access() handler.
161fa225cbcSrjs *
162fa225cbcSrjs * It deals with calling the driver's finish_access() only if necessary.
163fa225cbcSrjs */
164fa225cbcSrjsvoid
165fa225cbcSrjsuxa_finish_access(DrawablePtr pDrawable)
166fa225cbcSrjs{
167fa225cbcSrjs    ScreenPtr	    pScreen = pDrawable->pScreen;
168fa225cbcSrjs    uxa_screen_t    *uxa_screen = uxa_get_screen(pScreen);
169fa225cbcSrjs    PixmapPtr	    pPixmap = uxa_get_drawable_pixmap (pDrawable);
170fa225cbcSrjs
171fa225cbcSrjs    if (uxa_screen->info->finish_access == NULL)
172fa225cbcSrjs	return;
173fa225cbcSrjs
174fa225cbcSrjs    if (!uxa_pixmap_is_offscreen (pPixmap))
175fa225cbcSrjs	return;
176fa225cbcSrjs
177fa225cbcSrjs    (*uxa_screen->info->finish_access) (pPixmap);
178fa225cbcSrjs}
179fa225cbcSrjs
180fa225cbcSrjs/**
181fa225cbcSrjs * uxa_validate_gc() sets the ops to UXA's implementations, which may be
182fa225cbcSrjs * accelerated or may sync the card and fall back to fb.
183fa225cbcSrjs */
184fa225cbcSrjsstatic void
185fa225cbcSrjsuxa_validate_gc (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
186fa225cbcSrjs{
187fa225cbcSrjs    /* fbValidateGC will do direct access to pixmaps if the tiling has changed.
188fa225cbcSrjs     * Preempt fbValidateGC by doing its work and masking the change out, so
189fa225cbcSrjs     * that we can do the Prepare/finish_access.
190fa225cbcSrjs     */
191fa225cbcSrjs#ifdef FB_24_32BIT
192fa225cbcSrjs    if ((changes & GCTile) && fbGetRotatedPixmap(pGC)) {
193fa225cbcSrjs	(*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC));
194fa225cbcSrjs	fbGetRotatedPixmap(pGC) = 0;
195fa225cbcSrjs    }
196fa225cbcSrjs
197fa225cbcSrjs    if (pGC->fillStyle == FillTiled) {
198fa225cbcSrjs	PixmapPtr	pOldTile, pNewTile;
199fa225cbcSrjs
200fa225cbcSrjs	pOldTile = pGC->tile.pixmap;
201fa225cbcSrjs	if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel)
202fa225cbcSrjs	{
203fa225cbcSrjs	    pNewTile = fbGetRotatedPixmap(pGC);
204fa225cbcSrjs	    if (!pNewTile ||
205fa225cbcSrjs		pNewTile ->drawable.bitsPerPixel != pDrawable->bitsPerPixel)
206fa225cbcSrjs	    {
207fa225cbcSrjs		if (pNewTile)
208fa225cbcSrjs		    (*pGC->pScreen->DestroyPixmap) (pNewTile);
209fa225cbcSrjs		/* fb24_32ReformatTile will do direct access of a newly-
210fa225cbcSrjs		 * allocated pixmap.  This isn't a problem yet, since we don't
211fa225cbcSrjs		 * put pixmaps in FB until at least one accelerated UXA op.
212fa225cbcSrjs		 */
213fa225cbcSrjs		if (uxa_prepare_access(&pOldTile->drawable, UXA_ACCESS_RO)) {
214fa225cbcSrjs		    pNewTile = fb24_32ReformatTile (pOldTile,
215fa225cbcSrjs						    pDrawable->bitsPerPixel);
216fa225cbcSrjs		    uxa_finish_access(&pOldTile->drawable);
217fa225cbcSrjs		}
218fa225cbcSrjs	    }
219fa225cbcSrjs	    if (pNewTile)
220fa225cbcSrjs	    {
221fa225cbcSrjs		fbGetRotatedPixmap(pGC) = pOldTile;
222fa225cbcSrjs		pGC->tile.pixmap = pNewTile;
223fa225cbcSrjs		changes |= GCTile;
224fa225cbcSrjs	    }
225fa225cbcSrjs	}
226fa225cbcSrjs    }
227fa225cbcSrjs#endif
228fa225cbcSrjs    if (changes & GCTile) {
229fa225cbcSrjs	if (!pGC->tileIsPixel && FbEvenTile (pGC->tile.pixmap->drawable.width *
230fa225cbcSrjs					     pDrawable->bitsPerPixel))
231fa225cbcSrjs	{
232fa225cbcSrjs	    if (uxa_prepare_access(&pGC->tile.pixmap->drawable, UXA_ACCESS_RW)) {
233fa225cbcSrjs		fbPadPixmap (pGC->tile.pixmap);
234fa225cbcSrjs		uxa_finish_access(&pGC->tile.pixmap->drawable);
235fa225cbcSrjs	    }
236fa225cbcSrjs	}
237fa225cbcSrjs	/* Mask out the GCTile change notification, now that we've done FB's
238fa225cbcSrjs	 * job for it.
239fa225cbcSrjs	 */
240fa225cbcSrjs	changes &= ~GCTile;
241fa225cbcSrjs    }
242fa225cbcSrjs
243fa225cbcSrjs    if (changes & GCStipple && pGC->stipple) {
244fa225cbcSrjs	/* We can't inline stipple handling like we do for GCTile because it sets
245fa225cbcSrjs	 * fbgc privates.
246fa225cbcSrjs	 */
247fa225cbcSrjs	if (uxa_prepare_access(&pGC->stipple->drawable, UXA_ACCESS_RW)) {
248fa225cbcSrjs	    fbValidateGC (pGC, changes, pDrawable);
249fa225cbcSrjs	    uxa_finish_access(&pGC->stipple->drawable);
250fa225cbcSrjs	}
251fa225cbcSrjs    } else {
252fa225cbcSrjs	fbValidateGC (pGC, changes, pDrawable);
253fa225cbcSrjs    }
254fa225cbcSrjs
255fa225cbcSrjs    pGC->ops = (GCOps *) &uxa_ops;
256fa225cbcSrjs}
257fa225cbcSrjs
258fa225cbcSrjsstatic GCFuncs	uxaGCFuncs = {
259fa225cbcSrjs    uxa_validate_gc,
260fa225cbcSrjs    miChangeGC,
261fa225cbcSrjs    miCopyGC,
262fa225cbcSrjs    miDestroyGC,
263fa225cbcSrjs    miChangeClip,
264fa225cbcSrjs    miDestroyClip,
265fa225cbcSrjs    miCopyClip
266fa225cbcSrjs};
267fa225cbcSrjs
268fa225cbcSrjs/**
269fa225cbcSrjs * uxa_create_gc makes a new GC and hooks up its funcs handler, so that
270fa225cbcSrjs * uxa_validate_gc() will get called.
271fa225cbcSrjs */
272fa225cbcSrjsstatic int
273fa225cbcSrjsuxa_create_gc (GCPtr pGC)
274fa225cbcSrjs{
275fa225cbcSrjs    if (!fbCreateGC (pGC))
276fa225cbcSrjs	return FALSE;
277fa225cbcSrjs
278fa225cbcSrjs    pGC->funcs = &uxaGCFuncs;
279fa225cbcSrjs
280fa225cbcSrjs    return TRUE;
281fa225cbcSrjs}
282fa225cbcSrjs
283fa225cbcSrjsBool
284fa225cbcSrjsuxa_prepare_access_window(WindowPtr pWin)
285fa225cbcSrjs{
286fa225cbcSrjs    if (pWin->backgroundState == BackgroundPixmap) {
287fa225cbcSrjs        if (!uxa_prepare_access(&pWin->background.pixmap->drawable, UXA_ACCESS_RO))
288fa225cbcSrjs	    return FALSE;
289fa225cbcSrjs    }
290fa225cbcSrjs
291fa225cbcSrjs    if (pWin->borderIsPixel == FALSE) {
292fa225cbcSrjs        if (!uxa_prepare_access(&pWin->border.pixmap->drawable, UXA_ACCESS_RO)) {
293fa225cbcSrjs	    if (pWin->backgroundState == BackgroundPixmap)
294fa225cbcSrjs		uxa_finish_access(&pWin->background.pixmap->drawable);
295fa225cbcSrjs	    return FALSE;
296fa225cbcSrjs	}
297fa225cbcSrjs    }
298fa225cbcSrjs    return TRUE;
299fa225cbcSrjs}
300fa225cbcSrjs
301fa225cbcSrjsvoid
302fa225cbcSrjsuxa_finish_access_window(WindowPtr pWin)
303fa225cbcSrjs{
304fa225cbcSrjs    if (pWin->backgroundState == BackgroundPixmap)
305fa225cbcSrjs        uxa_finish_access(&pWin->background.pixmap->drawable);
306fa225cbcSrjs
307fa225cbcSrjs    if (pWin->borderIsPixel == FALSE)
308fa225cbcSrjs        uxa_finish_access(&pWin->border.pixmap->drawable);
309fa225cbcSrjs}
310fa225cbcSrjs
311fa225cbcSrjsstatic Bool
312fa225cbcSrjsuxa_change_window_attributes(WindowPtr pWin, unsigned long mask)
313fa225cbcSrjs{
314fa225cbcSrjs    Bool ret;
315fa225cbcSrjs
316fa225cbcSrjs    if (!uxa_prepare_access_window(pWin))
317fa225cbcSrjs	return FALSE;
318fa225cbcSrjs    ret = fbChangeWindowAttributes(pWin, mask);
319fa225cbcSrjs    uxa_finish_access_window(pWin);
320fa225cbcSrjs    return ret;
321fa225cbcSrjs}
322fa225cbcSrjs
323fa225cbcSrjsstatic RegionPtr
324fa225cbcSrjsuxa_bitmap_to_region(PixmapPtr pPix)
325fa225cbcSrjs{
326fa225cbcSrjs  RegionPtr ret;
327fa225cbcSrjs  if (!uxa_prepare_access(&pPix->drawable, UXA_ACCESS_RO))
328fa225cbcSrjs    return NULL;
329fa225cbcSrjs  ret = fbPixmapToRegion(pPix);
330fa225cbcSrjs  uxa_finish_access(&pPix->drawable);
331fa225cbcSrjs  return ret;
332fa225cbcSrjs}
333fa225cbcSrjs
334fa225cbcSrjsstatic void
335fa225cbcSrjsuxa_xorg_enable_disable_fb_access (int index, Bool enable)
336fa225cbcSrjs{
337fa225cbcSrjs    ScreenPtr screen = screenInfo.screens[index];
338fa225cbcSrjs    uxa_screen_t *uxa_screen = uxa_get_screen(screen);
339fa225cbcSrjs
340fa225cbcSrjs    if (!enable && uxa_screen->disableFbCount++ == 0)
341fa225cbcSrjs	uxa_screen->swappedOut = TRUE;
342fa225cbcSrjs
343fa225cbcSrjs    if (enable && --uxa_screen->disableFbCount == 0)
344fa225cbcSrjs	uxa_screen->swappedOut = FALSE;
345fa225cbcSrjs
346fa225cbcSrjs    if (uxa_screen->SavedEnableDisableFBAccess)
347fa225cbcSrjs       uxa_screen->SavedEnableDisableFBAccess(index, enable);
348fa225cbcSrjs}
349fa225cbcSrjs
350fa225cbcSrjsvoid
351fa225cbcSrjsuxa_set_fallback_debug (ScreenPtr screen, Bool enable)
352fa225cbcSrjs{
353fa225cbcSrjs    uxa_screen_t *uxa_screen = uxa_get_screen(screen);
354fa225cbcSrjs
355fa225cbcSrjs    uxa_screen->fallback_debug = enable;
356fa225cbcSrjs}
357fa225cbcSrjs
358fa225cbcSrjs/**
359fa225cbcSrjs * uxa_close_screen() unwraps its wrapped screen functions and tears down UXA's
360fa225cbcSrjs * screen private, before calling down to the next CloseSccreen.
361fa225cbcSrjs */
362fa225cbcSrjsstatic Bool
363fa225cbcSrjsuxa_close_screen(int i, ScreenPtr pScreen)
364fa225cbcSrjs{
365fa225cbcSrjs    uxa_screen_t	*uxa_screen = uxa_get_screen(pScreen);
366fa225cbcSrjs    ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
367fa225cbcSrjs#ifdef RENDER
368fa225cbcSrjs    PictureScreenPtr	ps = GetPictureScreenIfSet(pScreen);
369fa225cbcSrjs#endif
370fa225cbcSrjs
371fa225cbcSrjs    uxa_glyphs_fini(pScreen);
372fa225cbcSrjs
373fa225cbcSrjs    pScreen->CreateGC = uxa_screen->SavedCreateGC;
374fa225cbcSrjs    pScreen->CloseScreen = uxa_screen->SavedCloseScreen;
375fa225cbcSrjs    pScreen->GetImage = uxa_screen->SavedGetImage;
376fa225cbcSrjs    pScreen->GetSpans = uxa_screen->SavedGetSpans;
377fa225cbcSrjs    pScreen->CreatePixmap = uxa_screen->SavedCreatePixmap;
378fa225cbcSrjs    pScreen->DestroyPixmap = uxa_screen->SavedDestroyPixmap;
379fa225cbcSrjs    pScreen->CopyWindow = uxa_screen->SavedCopyWindow;
380fa225cbcSrjs    pScreen->ChangeWindowAttributes = uxa_screen->SavedChangeWindowAttributes;
381fa225cbcSrjs    pScreen->BitmapToRegion = uxa_screen->SavedBitmapToRegion;
382fa225cbcSrjs    scrn->EnableDisableFBAccess = uxa_screen->SavedEnableDisableFBAccess;
383fa225cbcSrjs#ifdef RENDER
384fa225cbcSrjs    if (ps) {
385fa225cbcSrjs	ps->Composite = uxa_screen->SavedComposite;
386fa225cbcSrjs	ps->Glyphs = uxa_screen->SavedGlyphs;
387fa225cbcSrjs	ps->Trapezoids = uxa_screen->SavedTrapezoids;
388fa225cbcSrjs	ps->AddTraps = uxa_screen->SavedAddTraps;
389fa225cbcSrjs	ps->Triangles = uxa_screen->SavedTriangles;
390fa225cbcSrjs    }
391fa225cbcSrjs#endif
392fa225cbcSrjs
393fa225cbcSrjs    xfree (uxa_screen);
394fa225cbcSrjs
395fa225cbcSrjs    return (*pScreen->CloseScreen) (i, pScreen);
396fa225cbcSrjs}
397fa225cbcSrjs
398fa225cbcSrjs/**
399fa225cbcSrjs * This function allocates a driver structure for UXA drivers to fill in.  By
400fa225cbcSrjs * having UXA allocate the structure, the driver structure can be extended
401fa225cbcSrjs * without breaking ABI between UXA and the drivers.  The driver's
402fa225cbcSrjs * responsibility is to check beforehand that the UXA module has a matching
403fa225cbcSrjs * major number and sufficient minor.  Drivers are responsible for freeing the
404fa225cbcSrjs * driver structure using xfree().
405fa225cbcSrjs *
406fa225cbcSrjs * @return a newly allocated, zero-filled driver structure
407fa225cbcSrjs */
408fa225cbcSrjsuxa_driver_t *
409fa225cbcSrjsuxa_driver_alloc(void)
410fa225cbcSrjs{
411fa225cbcSrjs    return xcalloc(1, sizeof(uxa_driver_t));
412fa225cbcSrjs}
413fa225cbcSrjs
414fa225cbcSrjs/**
415fa225cbcSrjs * @param pScreen screen being initialized
416fa225cbcSrjs * @param pScreenInfo UXA driver record
417fa225cbcSrjs *
418fa225cbcSrjs * uxa_driver_init sets up UXA given a driver record filled in by the driver.
419fa225cbcSrjs * pScreenInfo should have been allocated by uxa_driver_alloc().  See the
420fa225cbcSrjs * comments in _UxaDriver for what must be filled in and what is optional.
421fa225cbcSrjs *
422fa225cbcSrjs * @return TRUE if UXA was successfully initialized.
423fa225cbcSrjs */
424fa225cbcSrjsBool
425fa225cbcSrjsuxa_driver_init(ScreenPtr screen, uxa_driver_t *uxa_driver)
426fa225cbcSrjs{
427fa225cbcSrjs    uxa_screen_t	*uxa_screen;
428fa225cbcSrjs    ScrnInfoPtr scrn = xf86Screens[screen->myNum];
429fa225cbcSrjs#ifdef RENDER
430fa225cbcSrjs    PictureScreenPtr	ps;
431fa225cbcSrjs#endif
432fa225cbcSrjs
433fa225cbcSrjs    if (!uxa_driver)
434fa225cbcSrjs	return FALSE;
435fa225cbcSrjs
436fa225cbcSrjs    if (uxa_driver->uxa_major != UXA_VERSION_MAJOR ||
437fa225cbcSrjs	uxa_driver->uxa_minor > UXA_VERSION_MINOR)
438fa225cbcSrjs    {
439fa225cbcSrjs	LogMessage(X_ERROR, "UXA(%d): driver's UXA version requirements "
440fa225cbcSrjs		   "(%d.%d) are incompatible with UXA version (%d.%d)\n",
441fa225cbcSrjs		   screen->myNum,
442fa225cbcSrjs		   uxa_driver->uxa_major, uxa_driver->uxa_minor,
443fa225cbcSrjs		   UXA_VERSION_MAJOR, UXA_VERSION_MINOR);
444fa225cbcSrjs	return FALSE;
445fa225cbcSrjs    }
446fa225cbcSrjs
447fa225cbcSrjs    if (!uxa_driver->prepare_solid) {
448fa225cbcSrjs	LogMessage(X_ERROR, "UXA(%d): uxa_driver_t::prepare_solid must be "
449fa225cbcSrjs		   "non-NULL\n", screen->myNum);
450fa225cbcSrjs	return FALSE;
451fa225cbcSrjs    }
452fa225cbcSrjs
453fa225cbcSrjs    if (!uxa_driver->prepare_copy) {
454fa225cbcSrjs	LogMessage(X_ERROR, "UXA(%d): uxa_driver_t::prepare_copy must be "
455fa225cbcSrjs		   "non-NULL\n", screen->myNum);
456fa225cbcSrjs	return FALSE;
457fa225cbcSrjs    }
458fa225cbcSrjs
459fa225cbcSrjs#ifdef RENDER
460fa225cbcSrjs    ps = GetPictureScreenIfSet(screen);
461fa225cbcSrjs#endif
462fa225cbcSrjs
463be514f52Srjs#if HAS_DIXREGISTERPRIVATEKEY
464be514f52Srjs    if (!dixRegisterPrivateKey(&uxa_screen_index, PRIVATE_SCREEN, 0))
465be514f52Srjs	return FALSE;
466be514f52Srjs#endif
467fa225cbcSrjs    uxa_screen = xcalloc (sizeof (uxa_screen_t), 1);
468fa225cbcSrjs
469fa225cbcSrjs    if (!uxa_screen) {
470fa225cbcSrjs        LogMessage(X_WARNING, "UXA(%d): Failed to allocate screen private\n",
471fa225cbcSrjs		   screen->myNum);
472fa225cbcSrjs	return FALSE;
473fa225cbcSrjs    }
474fa225cbcSrjs
475fa225cbcSrjs    uxa_screen->info = uxa_driver;
476fa225cbcSrjs
477fa225cbcSrjs    dixSetPrivate(&screen->devPrivates, &uxa_screen_index, uxa_screen);
478fa225cbcSrjs
479fa225cbcSrjs//    exaDDXDriverInit(screen);
480fa225cbcSrjs
481fa225cbcSrjs    /*
482fa225cbcSrjs     * Replace various fb screen functions
483fa225cbcSrjs     */
484fa225cbcSrjs    uxa_screen->SavedCloseScreen = screen->CloseScreen;
485fa225cbcSrjs    screen->CloseScreen = uxa_close_screen;
486fa225cbcSrjs
487fa225cbcSrjs    uxa_screen->SavedCreateGC = screen->CreateGC;
488fa225cbcSrjs    screen->CreateGC = uxa_create_gc;
489fa225cbcSrjs
490fa225cbcSrjs    uxa_screen->SavedGetImage = screen->GetImage;
491fa225cbcSrjs    screen->GetImage = uxa_get_image;
492fa225cbcSrjs
493fa225cbcSrjs    uxa_screen->SavedGetSpans = screen->GetSpans;
494fa225cbcSrjs    screen->GetSpans = uxa_check_get_spans;
495fa225cbcSrjs
496fa225cbcSrjs    uxa_screen->SavedCopyWindow = screen->CopyWindow;
497fa225cbcSrjs    screen->CopyWindow = uxa_copy_window;
498fa225cbcSrjs
499fa225cbcSrjs    uxa_screen->SavedChangeWindowAttributes = screen->ChangeWindowAttributes;
500fa225cbcSrjs    screen->ChangeWindowAttributes = uxa_change_window_attributes;
501fa225cbcSrjs
502fa225cbcSrjs    uxa_screen->SavedBitmapToRegion = screen->BitmapToRegion;
503fa225cbcSrjs    screen->BitmapToRegion = uxa_bitmap_to_region;
504fa225cbcSrjs
505fa225cbcSrjs    uxa_screen->SavedEnableDisableFBAccess = scrn->EnableDisableFBAccess;
506fa225cbcSrjs    scrn->EnableDisableFBAccess = uxa_xorg_enable_disable_fb_access;
507fa225cbcSrjs
508fa225cbcSrjs#ifdef RENDER
509fa225cbcSrjs    if (ps) {
510fa225cbcSrjs        uxa_screen->SavedComposite = ps->Composite;
511fa225cbcSrjs	ps->Composite = uxa_composite;
512fa225cbcSrjs
513fa225cbcSrjs	uxa_screen->SavedGlyphs = ps->Glyphs;
514fa225cbcSrjs	ps->Glyphs = uxa_glyphs;
515fa225cbcSrjs
516fa225cbcSrjs	uxa_screen->SavedTriangles = ps->Triangles;
517fa225cbcSrjs	ps->Triangles = uxa_triangles;
518fa225cbcSrjs
519fa225cbcSrjs	uxa_screen->SavedTrapezoids = ps->Trapezoids;
520fa225cbcSrjs	ps->Trapezoids = uxa_trapezoids;
521fa225cbcSrjs
522fa225cbcSrjs	uxa_screen->SavedAddTraps = ps->AddTraps;
523fa225cbcSrjs	ps->AddTraps = uxa_check_add_traps;
524fa225cbcSrjs    }
525fa225cbcSrjs#endif
526fa225cbcSrjs
527fa225cbcSrjs#ifdef MITSHM
528fa225cbcSrjs    /* Re-register with the MI funcs, which don't allow shared pixmaps.
529fa225cbcSrjs     * Shared pixmaps are almost always a performance loss for us, but this
530fa225cbcSrjs     * still allows for SHM PutImage.
531fa225cbcSrjs     */
532fa225cbcSrjs    ShmRegisterFuncs(screen, &uxa_shm_funcs);
533fa225cbcSrjs#endif
534fa225cbcSrjs
535fa225cbcSrjs    uxa_glyphs_init(screen);
536fa225cbcSrjs
537fa225cbcSrjs    LogMessage(X_INFO, "UXA(%d): Driver registered support for the following"
538fa225cbcSrjs	       " operations:\n", screen->myNum);
539fa225cbcSrjs    assert(uxa_driver->prepare_solid != NULL);
540fa225cbcSrjs    LogMessage(X_INFO, "        solid\n");
541fa225cbcSrjs    assert(uxa_driver->prepare_copy != NULL);
542fa225cbcSrjs    LogMessage(X_INFO, "        copy\n");
543fa225cbcSrjs    if (uxa_driver->prepare_composite != NULL) {
544fa225cbcSrjs	LogMessage(X_INFO, "        composite (RENDER acceleration)\n");
545fa225cbcSrjs    }
546fa225cbcSrjs    if (uxa_driver->put_image != NULL) {
547fa225cbcSrjs	LogMessage(X_INFO, "        put_image\n");
548fa225cbcSrjs    }
549fa225cbcSrjs    if (uxa_driver->get_image != NULL) {
550fa225cbcSrjs	LogMessage(X_INFO, "        get_image\n");
551fa225cbcSrjs    }
552fa225cbcSrjs
553fa225cbcSrjs    return TRUE;
554fa225cbcSrjs}
555fa225cbcSrjs
556fa225cbcSrjs/**
557fa225cbcSrjs * uxa_driver_fini tears down UXA on a given screen.
558fa225cbcSrjs *
559fa225cbcSrjs * @param pScreen screen being torn down.
560fa225cbcSrjs */
561fa225cbcSrjsvoid
562fa225cbcSrjsuxa_driver_fini (ScreenPtr pScreen)
563fa225cbcSrjs{
564fa225cbcSrjs    /*right now does nothing*/
565fa225cbcSrjs}
566