uxa.c revision 03b705cf
103b705cfSriastradh/* 203b705cfSriastradh * Copyright © 2001 Keith Packard 303b705cfSriastradh * 403b705cfSriastradh * Partly based on code that is Copyright © The XFree86 Project Inc. 503b705cfSriastradh * 603b705cfSriastradh * Permission to use, copy, modify, distribute, and sell this software and its 703b705cfSriastradh * documentation for any purpose is hereby granted without fee, provided that 803b705cfSriastradh * the above copyright notice appear in all copies and that both that 903b705cfSriastradh * copyright notice and this permission notice appear in supporting 1003b705cfSriastradh * documentation, and that the name of Keith Packard not be used in 1103b705cfSriastradh * advertising or publicity pertaining to distribution of the software without 1203b705cfSriastradh * specific, written prior permission. Keith Packard makes no 1303b705cfSriastradh * representations about the suitability of this software for any purpose. It 1403b705cfSriastradh * is provided "as is" without express or implied warranty. 1503b705cfSriastradh * 1603b705cfSriastradh * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1703b705cfSriastradh * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1803b705cfSriastradh * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1903b705cfSriastradh * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2003b705cfSriastradh * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 2103b705cfSriastradh * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2203b705cfSriastradh * PERFORMANCE OF THIS SOFTWARE. 2303b705cfSriastradh */ 2403b705cfSriastradh 2503b705cfSriastradh/** @file 2603b705cfSriastradh * This file covers the initialization and teardown of UXA, and has various 2703b705cfSriastradh * functions not responsible for performing rendering, pixmap migration, or 2803b705cfSriastradh * memory management. 2903b705cfSriastradh */ 3003b705cfSriastradh 3103b705cfSriastradh#ifdef HAVE_DIX_CONFIG_H 3203b705cfSriastradh#include <dix-config.h> 3303b705cfSriastradh#endif 3403b705cfSriastradh 3503b705cfSriastradh#include <stdlib.h> 3603b705cfSriastradh 3703b705cfSriastradh#include "uxa-priv.h" 3803b705cfSriastradh#include <X11/fonts/fontstruct.h> 3903b705cfSriastradh#include "dixfontstr.h" 4003b705cfSriastradh#include "uxa.h" 4103b705cfSriastradh#include "uxa-glamor.h" 4203b705cfSriastradh 4303b705cfSriastradh#if HAS_DEVPRIVATEKEYREC 4403b705cfSriastradhDevPrivateKeyRec uxa_screen_index; 4503b705cfSriastradh#else 4603b705cfSriastradhint uxa_screen_index; 4703b705cfSriastradh#endif 4803b705cfSriastradh 4903b705cfSriastradh/** 5003b705cfSriastradh * uxa_get_drawable_pixmap() returns a backing pixmap for a given drawable. 5103b705cfSriastradh * 5203b705cfSriastradh * @param pDrawable the drawable being requested. 5303b705cfSriastradh * 5403b705cfSriastradh * This function returns the backing pixmap for a drawable, whether it is a 5503b705cfSriastradh * redirected window, unredirected window, or already a pixmap. Note that 5603b705cfSriastradh * coordinate translation is needed when drawing to the backing pixmap of a 5703b705cfSriastradh * redirected window, and the translation coordinates are provided by calling 5803b705cfSriastradh * uxa_get_drawable_pixmap() on the drawable. 5903b705cfSriastradh */ 6003b705cfSriastradhPixmapPtr uxa_get_drawable_pixmap(DrawablePtr pDrawable) 6103b705cfSriastradh{ 6203b705cfSriastradh if (pDrawable->type == DRAWABLE_WINDOW) 6303b705cfSriastradh return pDrawable->pScreen-> 6403b705cfSriastradh GetWindowPixmap((WindowPtr) pDrawable); 6503b705cfSriastradh else 6603b705cfSriastradh return (PixmapPtr) pDrawable; 6703b705cfSriastradh} 6803b705cfSriastradh 6903b705cfSriastradh/** 7003b705cfSriastradh * Sets the offsets to add to coordinates to make them address the same bits in 7103b705cfSriastradh * the backing drawable. These coordinates are nonzero only for redirected 7203b705cfSriastradh * windows. 7303b705cfSriastradh */ 7403b705cfSriastradhvoid 7503b705cfSriastradhuxa_get_drawable_deltas(DrawablePtr pDrawable, PixmapPtr pPixmap, 7603b705cfSriastradh int *xp, int *yp) 7703b705cfSriastradh{ 7803b705cfSriastradh#ifdef COMPOSITE 7903b705cfSriastradh if (pDrawable->type == DRAWABLE_WINDOW) { 8003b705cfSriastradh *xp = -pPixmap->screen_x; 8103b705cfSriastradh *yp = -pPixmap->screen_y; 8203b705cfSriastradh return; 8303b705cfSriastradh } 8403b705cfSriastradh#endif 8503b705cfSriastradh 8603b705cfSriastradh *xp = 0; 8703b705cfSriastradh *yp = 0; 8803b705cfSriastradh} 8903b705cfSriastradh 9003b705cfSriastradh/** 9103b705cfSriastradh * uxa_pixmap_is_offscreen() is used to determine if a pixmap is in offscreen 9203b705cfSriastradh * memory, meaning that acceleration could probably be done to it, and that it 9303b705cfSriastradh * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it 9403b705cfSriastradh * with the CPU. 9503b705cfSriastradh * 9603b705cfSriastradh * Note that except for UploadToScreen()/DownloadFromScreen() (which explicitly 9703b705cfSriastradh * deal with moving pixmaps in and out of system memory), UXA will give drivers 9803b705cfSriastradh * pixmaps as arguments for which uxa_pixmap_is_offscreen() is TRUE. 9903b705cfSriastradh * 10003b705cfSriastradh * @return TRUE if the given drawable is in framebuffer memory. 10103b705cfSriastradh */ 10203b705cfSriastradhBool uxa_pixmap_is_offscreen(PixmapPtr p) 10303b705cfSriastradh{ 10403b705cfSriastradh ScreenPtr pScreen = p->drawable.pScreen; 10503b705cfSriastradh uxa_screen_t *uxa_screen = uxa_get_screen(pScreen); 10603b705cfSriastradh 10703b705cfSriastradh if (uxa_screen->info->pixmap_is_offscreen) 10803b705cfSriastradh return uxa_screen->info->pixmap_is_offscreen(p); 10903b705cfSriastradh 11003b705cfSriastradh return FALSE; 11103b705cfSriastradh} 11203b705cfSriastradh 11303b705cfSriastradh/** 11403b705cfSriastradh * uxa_drawable_is_offscreen() is a convenience wrapper for 11503b705cfSriastradh * uxa_pixmap_is_offscreen(). 11603b705cfSriastradh */ 11703b705cfSriastradhBool uxa_drawable_is_offscreen(DrawablePtr pDrawable) 11803b705cfSriastradh{ 11903b705cfSriastradh return uxa_pixmap_is_offscreen(uxa_get_drawable_pixmap(pDrawable)); 12003b705cfSriastradh} 12103b705cfSriastradh 12203b705cfSriastradh/** 12303b705cfSriastradh * Returns the pixmap which backs a drawable, and the offsets to add to 12403b705cfSriastradh * coordinates to make them address the same bits in the backing drawable. 12503b705cfSriastradh */ 12603b705cfSriastradhPixmapPtr uxa_get_offscreen_pixmap(DrawablePtr drawable, int *xp, int *yp) 12703b705cfSriastradh{ 12803b705cfSriastradh PixmapPtr pixmap = uxa_get_drawable_pixmap(drawable); 12903b705cfSriastradh 13003b705cfSriastradh uxa_get_drawable_deltas(drawable, pixmap, xp, yp); 13103b705cfSriastradh 13203b705cfSriastradh if (uxa_pixmap_is_offscreen(pixmap)) 13303b705cfSriastradh return pixmap; 13403b705cfSriastradh else 13503b705cfSriastradh return NULL; 13603b705cfSriastradh} 13703b705cfSriastradh 13803b705cfSriastradh/** 13903b705cfSriastradh * uxa_prepare_access() is UXA's wrapper for the driver's PrepareAccess() handler. 14003b705cfSriastradh * 14103b705cfSriastradh * It deals with waiting for synchronization with the card, determining if 14203b705cfSriastradh * PrepareAccess() is necessary, and working around PrepareAccess() failure. 14303b705cfSriastradh */ 14403b705cfSriastradhBool uxa_prepare_access(DrawablePtr pDrawable, uxa_access_t access) 14503b705cfSriastradh{ 14603b705cfSriastradh ScreenPtr pScreen = pDrawable->pScreen; 14703b705cfSriastradh uxa_screen_t *uxa_screen = uxa_get_screen(pScreen); 14803b705cfSriastradh PixmapPtr pPixmap = uxa_get_drawable_pixmap(pDrawable); 14903b705cfSriastradh Bool offscreen = uxa_pixmap_is_offscreen(pPixmap); 15003b705cfSriastradh 15103b705cfSriastradh if (!offscreen) 15203b705cfSriastradh return TRUE; 15303b705cfSriastradh 15403b705cfSriastradh if (uxa_screen->info->prepare_access) 15503b705cfSriastradh return (*uxa_screen->info->prepare_access) (pPixmap, access); 15603b705cfSriastradh return TRUE; 15703b705cfSriastradh} 15803b705cfSriastradh 15903b705cfSriastradh/** 16003b705cfSriastradh * uxa_finish_access() is UXA's wrapper for the driver's finish_access() handler. 16103b705cfSriastradh * 16203b705cfSriastradh * It deals with calling the driver's finish_access() only if necessary. 16303b705cfSriastradh */ 16403b705cfSriastradhvoid uxa_finish_access(DrawablePtr pDrawable, uxa_access_t access) 16503b705cfSriastradh{ 16603b705cfSriastradh ScreenPtr pScreen = pDrawable->pScreen; 16703b705cfSriastradh uxa_screen_t *uxa_screen = uxa_get_screen(pScreen); 16803b705cfSriastradh PixmapPtr pPixmap; 16903b705cfSriastradh 17003b705cfSriastradh if (uxa_screen->info->finish_access == NULL) 17103b705cfSriastradh return; 17203b705cfSriastradh 17303b705cfSriastradh pPixmap = uxa_get_drawable_pixmap(pDrawable); 17403b705cfSriastradh if (!uxa_pixmap_is_offscreen(pPixmap)) 17503b705cfSriastradh return; 17603b705cfSriastradh 17703b705cfSriastradh (*uxa_screen->info->finish_access) (pPixmap, access); 17803b705cfSriastradh} 17903b705cfSriastradh 18003b705cfSriastradh/** 18103b705cfSriastradh * uxa_validate_gc() sets the ops to UXA's implementations, which may be 18203b705cfSriastradh * accelerated or may sync the card and fall back to fb. 18303b705cfSriastradh */ 18403b705cfSriastradhstatic void 18503b705cfSriastradhuxa_validate_gc(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) 18603b705cfSriastradh{ 18703b705cfSriastradh uxa_screen_t *uxa_screen = uxa_get_screen(pGC->pScreen); 18803b705cfSriastradh /* fbValidateGC will do direct access to pixmaps if the tiling has 18903b705cfSriastradh * changed. 19003b705cfSriastradh * Preempt fbValidateGC by doing its work and masking the change out, so 19103b705cfSriastradh * that we can do the Prepare/finish_access. 19203b705cfSriastradh */ 19303b705cfSriastradh 19403b705cfSriastradh /* If we are using GLAMOR, then the tile or stipple pixmap 19503b705cfSriastradh * may be pure GLAMOR pixmap, then we should let the glamor 19603b705cfSriastradh * to do the validation. 19703b705cfSriastradh */ 19803b705cfSriastradh if (uxa_screen->info->flags & UXA_USE_GLAMOR) { 19903b705cfSriastradh glamor_validate_gc(pGC, changes, pDrawable); 20003b705cfSriastradh goto set_ops; 20103b705cfSriastradh } 20203b705cfSriastradh#ifdef FB_24_32BIT 20303b705cfSriastradh if ((changes & GCTile) && fbGetRotatedPixmap(pGC)) { 20403b705cfSriastradh (*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC)); 20503b705cfSriastradh fbGetRotatedPixmap(pGC) = 0; 20603b705cfSriastradh } 20703b705cfSriastradh 20803b705cfSriastradh if (pGC->fillStyle == FillTiled) { 20903b705cfSriastradh PixmapPtr pOldTile, pNewTile; 21003b705cfSriastradh 21103b705cfSriastradh pOldTile = pGC->tile.pixmap; 21203b705cfSriastradh if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) { 21303b705cfSriastradh pNewTile = fbGetRotatedPixmap(pGC); 21403b705cfSriastradh if (!pNewTile || 21503b705cfSriastradh pNewTile->drawable.bitsPerPixel != 21603b705cfSriastradh pDrawable->bitsPerPixel) { 21703b705cfSriastradh if (pNewTile) 21803b705cfSriastradh (*pGC->pScreen-> 21903b705cfSriastradh DestroyPixmap) (pNewTile); 22003b705cfSriastradh /* fb24_32ReformatTile will do direct access 22103b705cfSriastradh * of a newly-allocated pixmap. This isn't a 22203b705cfSriastradh * problem yet, since we don't put pixmaps in 22303b705cfSriastradh * FB until at least one accelerated UXA op. 22403b705cfSriastradh */ 22503b705cfSriastradh if (uxa_prepare_access 22603b705cfSriastradh (&pOldTile->drawable, UXA_ACCESS_RO)) { 22703b705cfSriastradh pNewTile = 22803b705cfSriastradh fb24_32ReformatTile(pOldTile, 22903b705cfSriastradh pDrawable-> 23003b705cfSriastradh bitsPerPixel); 23103b705cfSriastradh uxa_finish_access(&pOldTile->drawable, UXA_ACCESS_RO); 23203b705cfSriastradh } 23303b705cfSriastradh } 23403b705cfSriastradh if (pNewTile) { 23503b705cfSriastradh fbGetRotatedPixmap(pGC) = pOldTile; 23603b705cfSriastradh pGC->tile.pixmap = pNewTile; 23703b705cfSriastradh changes |= GCTile; 23803b705cfSriastradh } 23903b705cfSriastradh } 24003b705cfSriastradh } 24103b705cfSriastradh#endif 24203b705cfSriastradh if (changes & GCTile) { 24303b705cfSriastradh if (!pGC->tileIsPixel 24403b705cfSriastradh && FbEvenTile(pGC->tile.pixmap->drawable.width * 24503b705cfSriastradh pDrawable->bitsPerPixel)) { 24603b705cfSriastradh if (uxa_prepare_access 24703b705cfSriastradh (&pGC->tile.pixmap->drawable, UXA_ACCESS_RW)) { 24803b705cfSriastradh fbPadPixmap(pGC->tile.pixmap); 24903b705cfSriastradh uxa_finish_access(&pGC->tile.pixmap->drawable, UXA_ACCESS_RW); 25003b705cfSriastradh } 25103b705cfSriastradh } 25203b705cfSriastradh /* Mask out the GCTile change notification, now that we've 25303b705cfSriastradh * done FB's job for it. 25403b705cfSriastradh */ 25503b705cfSriastradh changes &= ~GCTile; 25603b705cfSriastradh } 25703b705cfSriastradh 25803b705cfSriastradh if (changes & GCStipple && pGC->stipple) { 25903b705cfSriastradh /* We can't inline stipple handling like we do for GCTile 26003b705cfSriastradh * because it sets fbgc privates. 26103b705cfSriastradh */ 26203b705cfSriastradh if (uxa_prepare_access(&pGC->stipple->drawable, UXA_ACCESS_RW)) { 26303b705cfSriastradh fbValidateGC(pGC, changes, pDrawable); 26403b705cfSriastradh uxa_finish_access(&pGC->stipple->drawable, UXA_ACCESS_RW); 26503b705cfSriastradh } 26603b705cfSriastradh } else { 26703b705cfSriastradh fbValidateGC(pGC, changes, pDrawable); 26803b705cfSriastradh } 26903b705cfSriastradh 27003b705cfSriastradhset_ops: 27103b705cfSriastradh pGC->ops = (GCOps *) & uxa_ops; 27203b705cfSriastradh} 27303b705cfSriastradh 27403b705cfSriastradhstatic GCFuncs uxaGCFuncs = { 27503b705cfSriastradh uxa_validate_gc, 27603b705cfSriastradh miChangeGC, 27703b705cfSriastradh miCopyGC, 27803b705cfSriastradh miDestroyGC, 27903b705cfSriastradh miChangeClip, 28003b705cfSriastradh miDestroyClip, 28103b705cfSriastradh miCopyClip 28203b705cfSriastradh}; 28303b705cfSriastradh 28403b705cfSriastradh/** 28503b705cfSriastradh * uxa_create_gc makes a new GC and hooks up its funcs handler, so that 28603b705cfSriastradh * uxa_validate_gc() will get called. 28703b705cfSriastradh */ 28803b705cfSriastradhstatic int uxa_create_gc(GCPtr pGC) 28903b705cfSriastradh{ 29003b705cfSriastradh if (!fbCreateGC(pGC)) 29103b705cfSriastradh return FALSE; 29203b705cfSriastradh 29303b705cfSriastradh pGC->funcs = &uxaGCFuncs; 29403b705cfSriastradh 29503b705cfSriastradh return TRUE; 29603b705cfSriastradh} 29703b705cfSriastradh 29803b705cfSriastradhBool uxa_prepare_access_window(WindowPtr pWin) 29903b705cfSriastradh{ 30003b705cfSriastradh if (pWin->backgroundState == BackgroundPixmap) { 30103b705cfSriastradh if (!uxa_prepare_access 30203b705cfSriastradh (&pWin->background.pixmap->drawable, UXA_ACCESS_RO)) 30303b705cfSriastradh return FALSE; 30403b705cfSriastradh } 30503b705cfSriastradh 30603b705cfSriastradh if (pWin->borderIsPixel == FALSE) { 30703b705cfSriastradh if (!uxa_prepare_access 30803b705cfSriastradh (&pWin->border.pixmap->drawable, UXA_ACCESS_RO)) { 30903b705cfSriastradh if (pWin->backgroundState == BackgroundPixmap) 31003b705cfSriastradh uxa_finish_access(&pWin->background.pixmap-> 31103b705cfSriastradh drawable, UXA_ACCESS_RO); 31203b705cfSriastradh return FALSE; 31303b705cfSriastradh } 31403b705cfSriastradh } 31503b705cfSriastradh return TRUE; 31603b705cfSriastradh} 31703b705cfSriastradh 31803b705cfSriastradhvoid uxa_finish_access_window(WindowPtr pWin) 31903b705cfSriastradh{ 32003b705cfSriastradh if (pWin->backgroundState == BackgroundPixmap) 32103b705cfSriastradh uxa_finish_access(&pWin->background.pixmap->drawable, UXA_ACCESS_RO); 32203b705cfSriastradh 32303b705cfSriastradh if (pWin->borderIsPixel == FALSE) 32403b705cfSriastradh uxa_finish_access(&pWin->border.pixmap->drawable, UXA_ACCESS_RO); 32503b705cfSriastradh} 32603b705cfSriastradh 32703b705cfSriastradhstatic Bool uxa_change_window_attributes(WindowPtr pWin, unsigned long mask) 32803b705cfSriastradh{ 32903b705cfSriastradh Bool ret; 33003b705cfSriastradh 33103b705cfSriastradh if (!uxa_prepare_access_window(pWin)) 33203b705cfSriastradh return FALSE; 33303b705cfSriastradh ret = fbChangeWindowAttributes(pWin, mask); 33403b705cfSriastradh uxa_finish_access_window(pWin); 33503b705cfSriastradh return ret; 33603b705cfSriastradh} 33703b705cfSriastradh 33803b705cfSriastradhstatic RegionPtr uxa_bitmap_to_region(PixmapPtr pPix) 33903b705cfSriastradh{ 34003b705cfSriastradh RegionPtr ret; 34103b705cfSriastradh if (!uxa_prepare_access(&pPix->drawable, UXA_ACCESS_RO)) 34203b705cfSriastradh return NULL; 34303b705cfSriastradh ret = fbPixmapToRegion(pPix); 34403b705cfSriastradh uxa_finish_access(&pPix->drawable, UXA_ACCESS_RO); 34503b705cfSriastradh return ret; 34603b705cfSriastradh} 34703b705cfSriastradh 34803b705cfSriastradhvoid uxa_set_fallback_debug(ScreenPtr screen, Bool enable) 34903b705cfSriastradh{ 35003b705cfSriastradh uxa_screen_t *uxa_screen = uxa_get_screen(screen); 35103b705cfSriastradh 35203b705cfSriastradh uxa_screen->fallback_debug = enable; 35303b705cfSriastradh} 35403b705cfSriastradh 35503b705cfSriastradhvoid uxa_set_force_fallback(ScreenPtr screen, Bool value) 35603b705cfSriastradh{ 35703b705cfSriastradh uxa_screen_t *uxa_screen = uxa_get_screen(screen); 35803b705cfSriastradh 35903b705cfSriastradh uxa_screen->force_fallback = value; 36003b705cfSriastradh} 36103b705cfSriastradh 36203b705cfSriastradh/** 36303b705cfSriastradh * uxa_close_screen() unwraps its wrapped screen functions and tears down UXA's 36403b705cfSriastradh * screen private, before calling down to the next CloseSccreen. 36503b705cfSriastradh */ 36603b705cfSriastradhstatic Bool uxa_close_screen(CLOSE_SCREEN_ARGS_DECL) 36703b705cfSriastradh{ 36803b705cfSriastradh uxa_screen_t *uxa_screen = uxa_get_screen(screen); 36903b705cfSriastradh#ifdef RENDER 37003b705cfSriastradh PictureScreenPtr ps = GetPictureScreenIfSet(screen); 37103b705cfSriastradh#endif 37203b705cfSriastradh int n; 37303b705cfSriastradh 37403b705cfSriastradh if (uxa_screen->solid_clear) 37503b705cfSriastradh FreePicture(uxa_screen->solid_clear, 0); 37603b705cfSriastradh if (uxa_screen->solid_black) 37703b705cfSriastradh FreePicture(uxa_screen->solid_black, 0); 37803b705cfSriastradh if (uxa_screen->solid_white) 37903b705cfSriastradh FreePicture(uxa_screen->solid_white, 0); 38003b705cfSriastradh for (n = 0; n < uxa_screen->solid_cache_size; n++) 38103b705cfSriastradh FreePicture(uxa_screen->solid_cache[n].picture, 0); 38203b705cfSriastradh 38303b705cfSriastradh uxa_glyphs_fini(screen); 38403b705cfSriastradh 38503b705cfSriastradh if (screen->devPrivate) { 38603b705cfSriastradh /* Destroy the pixmap created by miScreenInit() *before* 38703b705cfSriastradh * chaining up as we finalize ourselves here and so this 38803b705cfSriastradh * is the last chance we have of releasing our resources 38903b705cfSriastradh * associated with the Pixmap. So do it first. 39003b705cfSriastradh */ 39103b705cfSriastradh (void) (*screen->DestroyPixmap) (screen->devPrivate); 39203b705cfSriastradh screen->devPrivate = NULL; 39303b705cfSriastradh } 39403b705cfSriastradh 39503b705cfSriastradh screen->CreateGC = uxa_screen->SavedCreateGC; 39603b705cfSriastradh screen->CloseScreen = uxa_screen->SavedCloseScreen; 39703b705cfSriastradh screen->GetImage = uxa_screen->SavedGetImage; 39803b705cfSriastradh screen->GetSpans = uxa_screen->SavedGetSpans; 39903b705cfSriastradh screen->CreatePixmap = uxa_screen->SavedCreatePixmap; 40003b705cfSriastradh screen->DestroyPixmap = uxa_screen->SavedDestroyPixmap; 40103b705cfSriastradh screen->CopyWindow = uxa_screen->SavedCopyWindow; 40203b705cfSriastradh screen->ChangeWindowAttributes = 40303b705cfSriastradh uxa_screen->SavedChangeWindowAttributes; 40403b705cfSriastradh screen->BitmapToRegion = uxa_screen->SavedBitmapToRegion; 40503b705cfSriastradh#ifdef RENDER 40603b705cfSriastradh if (ps) { 40703b705cfSriastradh ps->Composite = uxa_screen->SavedComposite; 40803b705cfSriastradh ps->Glyphs = uxa_screen->SavedGlyphs; 40903b705cfSriastradh ps->Trapezoids = uxa_screen->SavedTrapezoids; 41003b705cfSriastradh ps->AddTraps = uxa_screen->SavedAddTraps; 41103b705cfSriastradh ps->Triangles = uxa_screen->SavedTriangles; 41203b705cfSriastradh 41303b705cfSriastradh ps->UnrealizeGlyph = uxa_screen->SavedUnrealizeGlyph; 41403b705cfSriastradh } 41503b705cfSriastradh#endif 41603b705cfSriastradh 41703b705cfSriastradh free(uxa_screen); 41803b705cfSriastradh 41903b705cfSriastradh return (*screen->CloseScreen) (CLOSE_SCREEN_ARGS); 42003b705cfSriastradh} 42103b705cfSriastradh 42203b705cfSriastradh/** 42303b705cfSriastradh * This function allocates a driver structure for UXA drivers to fill in. By 42403b705cfSriastradh * having UXA allocate the structure, the driver structure can be extended 42503b705cfSriastradh * without breaking ABI between UXA and the drivers. The driver's 42603b705cfSriastradh * responsibility is to check beforehand that the UXA module has a matching 42703b705cfSriastradh * major number and sufficient minor. Drivers are responsible for freeing the 42803b705cfSriastradh * driver structure using free(). 42903b705cfSriastradh * 43003b705cfSriastradh * @return a newly allocated, zero-filled driver structure 43103b705cfSriastradh */ 43203b705cfSriastradhuxa_driver_t *uxa_driver_alloc(void) 43303b705cfSriastradh{ 43403b705cfSriastradh return calloc(1, sizeof(uxa_driver_t)); 43503b705cfSriastradh} 43603b705cfSriastradh 43703b705cfSriastradh/** 43803b705cfSriastradh * @param screen screen being initialized 43903b705cfSriastradh * @param pScreenInfo UXA driver record 44003b705cfSriastradh * 44103b705cfSriastradh * uxa_driver_init sets up UXA given a driver record filled in by the driver. 44203b705cfSriastradh * pScreenInfo should have been allocated by uxa_driver_alloc(). See the 44303b705cfSriastradh * comments in _UxaDriver for what must be filled in and what is optional. 44403b705cfSriastradh * 44503b705cfSriastradh * @return TRUE if UXA was successfully initialized. 44603b705cfSriastradh */ 44703b705cfSriastradhBool uxa_driver_init(ScreenPtr screen, uxa_driver_t * uxa_driver) 44803b705cfSriastradh{ 44903b705cfSriastradh uxa_screen_t *uxa_screen; 45003b705cfSriastradh 45103b705cfSriastradh if (!uxa_driver) 45203b705cfSriastradh return FALSE; 45303b705cfSriastradh 45403b705cfSriastradh if (uxa_driver->uxa_major != UXA_VERSION_MAJOR || 45503b705cfSriastradh uxa_driver->uxa_minor > UXA_VERSION_MINOR) { 45603b705cfSriastradh LogMessage(X_ERROR, 45703b705cfSriastradh "UXA(%d): driver's UXA version requirements " 45803b705cfSriastradh "(%d.%d) are incompatible with UXA version (%d.%d)\n", 45903b705cfSriastradh screen->myNum, uxa_driver->uxa_major, 46003b705cfSriastradh uxa_driver->uxa_minor, UXA_VERSION_MAJOR, 46103b705cfSriastradh UXA_VERSION_MINOR); 46203b705cfSriastradh return FALSE; 46303b705cfSriastradh } 46403b705cfSriastradh 46503b705cfSriastradh if (!uxa_driver->prepare_solid) { 46603b705cfSriastradh LogMessage(X_ERROR, 46703b705cfSriastradh "UXA(%d): uxa_driver_t::prepare_solid must be " 46803b705cfSriastradh "non-NULL\n", screen->myNum); 46903b705cfSriastradh return FALSE; 47003b705cfSriastradh } 47103b705cfSriastradh 47203b705cfSriastradh if (!uxa_driver->prepare_copy) { 47303b705cfSriastradh LogMessage(X_ERROR, 47403b705cfSriastradh "UXA(%d): uxa_driver_t::prepare_copy must be " 47503b705cfSriastradh "non-NULL\n", screen->myNum); 47603b705cfSriastradh return FALSE; 47703b705cfSriastradh } 47803b705cfSriastradh#if HAS_DIXREGISTERPRIVATEKEY 47903b705cfSriastradh if (!dixRegisterPrivateKey(&uxa_screen_index, PRIVATE_SCREEN, 0)) 48003b705cfSriastradh return FALSE; 48103b705cfSriastradh#endif 48203b705cfSriastradh uxa_screen = calloc(sizeof(uxa_screen_t), 1); 48303b705cfSriastradh 48403b705cfSriastradh if (!uxa_screen) { 48503b705cfSriastradh LogMessage(X_WARNING, 48603b705cfSriastradh "UXA(%d): Failed to allocate screen private\n", 48703b705cfSriastradh screen->myNum); 48803b705cfSriastradh return FALSE; 48903b705cfSriastradh } 49003b705cfSriastradh 49103b705cfSriastradh uxa_screen->info = uxa_driver; 49203b705cfSriastradh 49303b705cfSriastradh dixSetPrivate(&screen->devPrivates, &uxa_screen_index, uxa_screen); 49403b705cfSriastradh 49503b705cfSriastradh uxa_screen->force_fallback = FALSE; 49603b705cfSriastradh 49703b705cfSriastradh uxa_screen->solid_cache_size = 0; 49803b705cfSriastradh uxa_screen->solid_clear = 0; 49903b705cfSriastradh uxa_screen->solid_black = 0; 50003b705cfSriastradh uxa_screen->solid_white = 0; 50103b705cfSriastradh 50203b705cfSriastradh// exaDDXDriverInit(screen); 50303b705cfSriastradh 50403b705cfSriastradh /* 50503b705cfSriastradh * Replace various fb screen functions 50603b705cfSriastradh */ 50703b705cfSriastradh uxa_screen->SavedCloseScreen = screen->CloseScreen; 50803b705cfSriastradh screen->CloseScreen = uxa_close_screen; 50903b705cfSriastradh 51003b705cfSriastradh uxa_screen->SavedCreateGC = screen->CreateGC; 51103b705cfSriastradh screen->CreateGC = uxa_create_gc; 51203b705cfSriastradh 51303b705cfSriastradh uxa_screen->SavedGetImage = screen->GetImage; 51403b705cfSriastradh screen->GetImage = uxa_get_image; 51503b705cfSriastradh 51603b705cfSriastradh uxa_screen->SavedGetSpans = screen->GetSpans; 51703b705cfSriastradh screen->GetSpans = uxa_get_spans; 51803b705cfSriastradh 51903b705cfSriastradh uxa_screen->SavedCopyWindow = screen->CopyWindow; 52003b705cfSriastradh screen->CopyWindow = uxa_copy_window; 52103b705cfSriastradh 52203b705cfSriastradh uxa_screen->SavedChangeWindowAttributes = 52303b705cfSriastradh screen->ChangeWindowAttributes; 52403b705cfSriastradh screen->ChangeWindowAttributes = uxa_change_window_attributes; 52503b705cfSriastradh 52603b705cfSriastradh uxa_screen->SavedBitmapToRegion = screen->BitmapToRegion; 52703b705cfSriastradh screen->BitmapToRegion = uxa_bitmap_to_region; 52803b705cfSriastradh 52903b705cfSriastradh#ifdef RENDER 53003b705cfSriastradh { 53103b705cfSriastradh PictureScreenPtr ps = GetPictureScreenIfSet(screen); 53203b705cfSriastradh if (ps) { 53303b705cfSriastradh uxa_screen->SavedComposite = ps->Composite; 53403b705cfSriastradh ps->Composite = uxa_composite; 53503b705cfSriastradh 53603b705cfSriastradh uxa_screen->SavedGlyphs = ps->Glyphs; 53703b705cfSriastradh ps->Glyphs = uxa_glyphs; 53803b705cfSriastradh 53903b705cfSriastradh uxa_screen->SavedUnrealizeGlyph = ps->UnrealizeGlyph; 54003b705cfSriastradh ps->UnrealizeGlyph = uxa_glyph_unrealize; 54103b705cfSriastradh 54203b705cfSriastradh uxa_screen->SavedTriangles = ps->Triangles; 54303b705cfSriastradh ps->Triangles = uxa_triangles; 54403b705cfSriastradh 54503b705cfSriastradh uxa_screen->SavedTrapezoids = ps->Trapezoids; 54603b705cfSriastradh ps->Trapezoids = uxa_trapezoids; 54703b705cfSriastradh 54803b705cfSriastradh uxa_screen->SavedAddTraps = ps->AddTraps; 54903b705cfSriastradh ps->AddTraps = uxa_add_traps; 55003b705cfSriastradh } 55103b705cfSriastradh } 55203b705cfSriastradh#endif 55303b705cfSriastradh 55403b705cfSriastradh LogMessage(X_INFO, 55503b705cfSriastradh "UXA(%d): Driver registered support for the following" 55603b705cfSriastradh " operations:\n", screen->myNum); 55703b705cfSriastradh assert(uxa_driver->prepare_solid != NULL); 55803b705cfSriastradh LogMessage(X_INFO, " solid\n"); 55903b705cfSriastradh assert(uxa_driver->prepare_copy != NULL); 56003b705cfSriastradh LogMessage(X_INFO, " copy\n"); 56103b705cfSriastradh if (uxa_driver->prepare_composite != NULL) { 56203b705cfSriastradh LogMessage(X_INFO, " composite (RENDER acceleration)\n"); 56303b705cfSriastradh } 56403b705cfSriastradh if (uxa_driver->put_image != NULL) { 56503b705cfSriastradh LogMessage(X_INFO, " put_image\n"); 56603b705cfSriastradh } 56703b705cfSriastradh if (uxa_driver->get_image != NULL) { 56803b705cfSriastradh LogMessage(X_INFO, " get_image\n"); 56903b705cfSriastradh } 57003b705cfSriastradh 57103b705cfSriastradh return TRUE; 57203b705cfSriastradh} 57303b705cfSriastradh 57403b705cfSriastradhBool uxa_resources_init(ScreenPtr screen) 57503b705cfSriastradh{ 57603b705cfSriastradh if (!uxa_glyphs_init(screen)) 57703b705cfSriastradh return FALSE; 57803b705cfSriastradh 57903b705cfSriastradh return TRUE; 58003b705cfSriastradh} 58103b705cfSriastradh 58203b705cfSriastradh/** 58303b705cfSriastradh * uxa_driver_fini tears down UXA on a given screen. 58403b705cfSriastradh * 58503b705cfSriastradh * @param pScreen screen being torn down. 58603b705cfSriastradh */ 58703b705cfSriastradhvoid uxa_driver_fini(ScreenPtr pScreen) 58803b705cfSriastradh{ 58903b705cfSriastradh /*right now does nothing */ 59003b705cfSriastradh} 591