1428d7b3dSmrg/* 2428d7b3dSmrg * Copyright © 2001 Keith Packard 3428d7b3dSmrg * 4428d7b3dSmrg * Partly based on code that is Copyright © The XFree86 Project Inc. 5428d7b3dSmrg * 6428d7b3dSmrg * Permission to use, copy, modify, distribute, and sell this software and its 7428d7b3dSmrg * documentation for any purpose is hereby granted without fee, provided that 8428d7b3dSmrg * the above copyright notice appear in all copies and that both that 9428d7b3dSmrg * copyright notice and this permission notice appear in supporting 10428d7b3dSmrg * documentation, and that the name of Keith Packard not be used in 11428d7b3dSmrg * advertising or publicity pertaining to distribution of the software without 12428d7b3dSmrg * specific, written prior permission. Keith Packard makes no 13428d7b3dSmrg * representations about the suitability of this software for any purpose. It 14428d7b3dSmrg * is provided "as is" without express or implied warranty. 15428d7b3dSmrg * 16428d7b3dSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 17428d7b3dSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 18428d7b3dSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 19428d7b3dSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 20428d7b3dSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 21428d7b3dSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 22428d7b3dSmrg * PERFORMANCE OF THIS SOFTWARE. 23428d7b3dSmrg */ 24428d7b3dSmrg 25428d7b3dSmrg/** @file 26428d7b3dSmrg * This file covers the initialization and teardown of UXA, and has various 27428d7b3dSmrg * functions not responsible for performing rendering, pixmap migration, or 28428d7b3dSmrg * memory management. 29428d7b3dSmrg */ 30428d7b3dSmrg 31428d7b3dSmrg#ifdef HAVE_DIX_CONFIG_H 32428d7b3dSmrg#include <dix-config.h> 33428d7b3dSmrg#endif 34428d7b3dSmrg 35428d7b3dSmrg#include <stdlib.h> 36428d7b3dSmrg 37428d7b3dSmrg#include "uxa-priv.h" 38428d7b3dSmrg#include <X11/fonts/fontstruct.h> 39428d7b3dSmrg#include "dixfontstr.h" 40428d7b3dSmrg#include "uxa.h" 41428d7b3dSmrg 42428d7b3dSmrg#if HAS_DEVPRIVATEKEYREC 43428d7b3dSmrgDevPrivateKeyRec uxa_screen_index; 44428d7b3dSmrg#else 45428d7b3dSmrgint uxa_screen_index; 46428d7b3dSmrg#endif 47428d7b3dSmrg 48428d7b3dSmrg/** 49428d7b3dSmrg * uxa_get_drawable_pixmap() returns a backing pixmap for a given drawable. 50428d7b3dSmrg * 51428d7b3dSmrg * @param pDrawable the drawable being requested. 52428d7b3dSmrg * 53428d7b3dSmrg * This function returns the backing pixmap for a drawable, whether it is a 54428d7b3dSmrg * redirected window, unredirected window, or already a pixmap. Note that 55428d7b3dSmrg * coordinate translation is needed when drawing to the backing pixmap of a 56428d7b3dSmrg * redirected window, and the translation coordinates are provided by calling 57428d7b3dSmrg * uxa_get_drawable_pixmap() on the drawable. 58428d7b3dSmrg */ 59428d7b3dSmrgPixmapPtr uxa_get_drawable_pixmap(DrawablePtr pDrawable) 60428d7b3dSmrg{ 61428d7b3dSmrg if (pDrawable->type == DRAWABLE_WINDOW) 62428d7b3dSmrg return pDrawable->pScreen-> 63428d7b3dSmrg GetWindowPixmap((WindowPtr) pDrawable); 64428d7b3dSmrg else 65428d7b3dSmrg return (PixmapPtr) pDrawable; 66428d7b3dSmrg} 67428d7b3dSmrg 68428d7b3dSmrg/** 69428d7b3dSmrg * Sets the offsets to add to coordinates to make them address the same bits in 70428d7b3dSmrg * the backing drawable. These coordinates are nonzero only for redirected 71428d7b3dSmrg * windows. 72428d7b3dSmrg */ 73428d7b3dSmrgvoid 74428d7b3dSmrguxa_get_drawable_deltas(DrawablePtr pDrawable, PixmapPtr pPixmap, 75428d7b3dSmrg int *xp, int *yp) 76428d7b3dSmrg{ 77428d7b3dSmrg#ifdef COMPOSITE 78428d7b3dSmrg if (pDrawable->type == DRAWABLE_WINDOW) { 79428d7b3dSmrg *xp = -pPixmap->screen_x; 80428d7b3dSmrg *yp = -pPixmap->screen_y; 81428d7b3dSmrg return; 82428d7b3dSmrg } 83428d7b3dSmrg#endif 84428d7b3dSmrg 85428d7b3dSmrg *xp = 0; 86428d7b3dSmrg *yp = 0; 87428d7b3dSmrg} 88428d7b3dSmrg 89428d7b3dSmrg/** 90428d7b3dSmrg * uxa_pixmap_is_offscreen() is used to determine if a pixmap is in offscreen 91428d7b3dSmrg * memory, meaning that acceleration could probably be done to it, and that it 92428d7b3dSmrg * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it 93428d7b3dSmrg * with the CPU. 94428d7b3dSmrg * 95428d7b3dSmrg * Note that except for UploadToScreen()/DownloadFromScreen() (which explicitly 96428d7b3dSmrg * deal with moving pixmaps in and out of system memory), UXA will give drivers 97428d7b3dSmrg * pixmaps as arguments for which uxa_pixmap_is_offscreen() is TRUE. 98428d7b3dSmrg * 99428d7b3dSmrg * @return TRUE if the given drawable is in framebuffer memory. 100428d7b3dSmrg */ 101428d7b3dSmrgBool uxa_pixmap_is_offscreen(PixmapPtr p) 102428d7b3dSmrg{ 103428d7b3dSmrg ScreenPtr pScreen = p->drawable.pScreen; 104428d7b3dSmrg uxa_screen_t *uxa_screen = uxa_get_screen(pScreen); 105428d7b3dSmrg 106428d7b3dSmrg if (uxa_screen->info->pixmap_is_offscreen) 107428d7b3dSmrg return uxa_screen->info->pixmap_is_offscreen(p); 108428d7b3dSmrg 109428d7b3dSmrg return FALSE; 110428d7b3dSmrg} 111428d7b3dSmrg 112428d7b3dSmrg/** 113428d7b3dSmrg * uxa_drawable_is_offscreen() is a convenience wrapper for 114428d7b3dSmrg * uxa_pixmap_is_offscreen(). 115428d7b3dSmrg */ 116428d7b3dSmrgBool uxa_drawable_is_offscreen(DrawablePtr pDrawable) 117428d7b3dSmrg{ 118428d7b3dSmrg return uxa_pixmap_is_offscreen(uxa_get_drawable_pixmap(pDrawable)); 119428d7b3dSmrg} 120428d7b3dSmrg 121428d7b3dSmrg/** 122428d7b3dSmrg * Returns the pixmap which backs a drawable, and the offsets to add to 123428d7b3dSmrg * coordinates to make them address the same bits in the backing drawable. 124428d7b3dSmrg */ 125428d7b3dSmrgPixmapPtr uxa_get_offscreen_pixmap(DrawablePtr drawable, int *xp, int *yp) 126428d7b3dSmrg{ 127428d7b3dSmrg PixmapPtr pixmap = uxa_get_drawable_pixmap(drawable); 128428d7b3dSmrg 129428d7b3dSmrg uxa_get_drawable_deltas(drawable, pixmap, xp, yp); 130428d7b3dSmrg 131428d7b3dSmrg if (uxa_pixmap_is_offscreen(pixmap)) 132428d7b3dSmrg return pixmap; 133428d7b3dSmrg else 134428d7b3dSmrg return NULL; 135428d7b3dSmrg} 136428d7b3dSmrg 137428d7b3dSmrg/** 138428d7b3dSmrg * uxa_prepare_access() is UXA's wrapper for the driver's PrepareAccess() handler. 139428d7b3dSmrg * 140428d7b3dSmrg * It deals with waiting for synchronization with the card, determining if 141428d7b3dSmrg * PrepareAccess() is necessary, and working around PrepareAccess() failure. 142428d7b3dSmrg */ 143428d7b3dSmrgBool uxa_prepare_access(DrawablePtr pDrawable, uxa_access_t access) 144428d7b3dSmrg{ 145428d7b3dSmrg ScreenPtr pScreen = pDrawable->pScreen; 146428d7b3dSmrg uxa_screen_t *uxa_screen = uxa_get_screen(pScreen); 147428d7b3dSmrg PixmapPtr pPixmap = uxa_get_drawable_pixmap(pDrawable); 148428d7b3dSmrg Bool offscreen = uxa_pixmap_is_offscreen(pPixmap); 149428d7b3dSmrg 150428d7b3dSmrg if (!offscreen) 151428d7b3dSmrg return TRUE; 152428d7b3dSmrg 153428d7b3dSmrg if (uxa_screen->info->prepare_access) 154428d7b3dSmrg return (*uxa_screen->info->prepare_access) (pPixmap, access); 155428d7b3dSmrg return TRUE; 156428d7b3dSmrg} 157428d7b3dSmrg 158428d7b3dSmrg/** 159428d7b3dSmrg * uxa_finish_access() is UXA's wrapper for the driver's finish_access() handler. 160428d7b3dSmrg * 161428d7b3dSmrg * It deals with calling the driver's finish_access() only if necessary. 162428d7b3dSmrg */ 163428d7b3dSmrgvoid uxa_finish_access(DrawablePtr pDrawable, uxa_access_t access) 164428d7b3dSmrg{ 165428d7b3dSmrg ScreenPtr pScreen = pDrawable->pScreen; 166428d7b3dSmrg uxa_screen_t *uxa_screen = uxa_get_screen(pScreen); 167428d7b3dSmrg PixmapPtr pPixmap; 168428d7b3dSmrg 169428d7b3dSmrg if (uxa_screen->info->finish_access == NULL) 170428d7b3dSmrg return; 171428d7b3dSmrg 172428d7b3dSmrg pPixmap = uxa_get_drawable_pixmap(pDrawable); 173428d7b3dSmrg if (!uxa_pixmap_is_offscreen(pPixmap)) 174428d7b3dSmrg return; 175428d7b3dSmrg 176428d7b3dSmrg (*uxa_screen->info->finish_access) (pPixmap, access); 177428d7b3dSmrg} 178428d7b3dSmrg 179428d7b3dSmrg/** 180428d7b3dSmrg * uxa_validate_gc() sets the ops to UXA's implementations, which may be 181428d7b3dSmrg * accelerated or may sync the card and fall back to fb. 182428d7b3dSmrg */ 183428d7b3dSmrgstatic void 184428d7b3dSmrguxa_validate_gc(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) 185428d7b3dSmrg{ 186428d7b3dSmrg /* fbValidateGC will do direct access to pixmaps if the tiling has 187428d7b3dSmrg * changed. 188428d7b3dSmrg * Preempt fbValidateGC by doing its work and masking the change out, so 189428d7b3dSmrg * that we can do the Prepare/finish_access. 190428d7b3dSmrg */ 191428d7b3dSmrg 192428d7b3dSmrg#ifdef FB_24_32BIT 193428d7b3dSmrg if ((changes & GCTile) && fbGetRotatedPixmap(pGC)) { 194428d7b3dSmrg (*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC)); 195428d7b3dSmrg fbGetRotatedPixmap(pGC) = 0; 196428d7b3dSmrg } 197428d7b3dSmrg 198428d7b3dSmrg if (pGC->fillStyle == FillTiled) { 199428d7b3dSmrg PixmapPtr pOldTile, pNewTile; 200428d7b3dSmrg 201428d7b3dSmrg pOldTile = pGC->tile.pixmap; 202428d7b3dSmrg if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) { 203428d7b3dSmrg pNewTile = fbGetRotatedPixmap(pGC); 204428d7b3dSmrg if (!pNewTile || 205428d7b3dSmrg pNewTile->drawable.bitsPerPixel != 206428d7b3dSmrg pDrawable->bitsPerPixel) { 207428d7b3dSmrg if (pNewTile) 208428d7b3dSmrg (*pGC->pScreen-> 209428d7b3dSmrg DestroyPixmap) (pNewTile); 210428d7b3dSmrg /* fb24_32ReformatTile will do direct access 211428d7b3dSmrg * of a newly-allocated pixmap. This isn't a 212428d7b3dSmrg * problem yet, since we don't put pixmaps in 213428d7b3dSmrg * FB until at least one accelerated UXA op. 214428d7b3dSmrg */ 215428d7b3dSmrg if (uxa_prepare_access 216428d7b3dSmrg (&pOldTile->drawable, UXA_ACCESS_RO)) { 217428d7b3dSmrg pNewTile = 218428d7b3dSmrg fb24_32ReformatTile(pOldTile, 219428d7b3dSmrg pDrawable-> 220428d7b3dSmrg bitsPerPixel); 221428d7b3dSmrg uxa_finish_access(&pOldTile->drawable, UXA_ACCESS_RO); 222428d7b3dSmrg } 223428d7b3dSmrg } 224428d7b3dSmrg if (pNewTile) { 225428d7b3dSmrg fbGetRotatedPixmap(pGC) = pOldTile; 226428d7b3dSmrg pGC->tile.pixmap = pNewTile; 227428d7b3dSmrg changes |= GCTile; 228428d7b3dSmrg } 229428d7b3dSmrg } 230428d7b3dSmrg } 231428d7b3dSmrg#endif 232428d7b3dSmrg if (changes & GCTile) { 233428d7b3dSmrg if (!pGC->tileIsPixel 234428d7b3dSmrg && FbEvenTile(pGC->tile.pixmap->drawable.width * 235428d7b3dSmrg pDrawable->bitsPerPixel)) { 236428d7b3dSmrg if (uxa_prepare_access 237428d7b3dSmrg (&pGC->tile.pixmap->drawable, UXA_ACCESS_RW)) { 238428d7b3dSmrg fbPadPixmap(pGC->tile.pixmap); 239428d7b3dSmrg uxa_finish_access(&pGC->tile.pixmap->drawable, UXA_ACCESS_RW); 240428d7b3dSmrg } 241428d7b3dSmrg } 242428d7b3dSmrg /* Mask out the GCTile change notification, now that we've 243428d7b3dSmrg * done FB's job for it. 244428d7b3dSmrg */ 245428d7b3dSmrg changes &= ~GCTile; 246428d7b3dSmrg } 247428d7b3dSmrg 248428d7b3dSmrg if (changes & GCStipple && pGC->stipple) { 249428d7b3dSmrg /* We can't inline stipple handling like we do for GCTile 250428d7b3dSmrg * because it sets fbgc privates. 251428d7b3dSmrg */ 252428d7b3dSmrg if (uxa_prepare_access(&pGC->stipple->drawable, UXA_ACCESS_RW)) { 253428d7b3dSmrg fbValidateGC(pGC, changes, pDrawable); 254428d7b3dSmrg uxa_finish_access(&pGC->stipple->drawable, UXA_ACCESS_RW); 255428d7b3dSmrg } 256428d7b3dSmrg } else { 257428d7b3dSmrg fbValidateGC(pGC, changes, pDrawable); 258428d7b3dSmrg } 259428d7b3dSmrg 260428d7b3dSmrg pGC->ops = (GCOps *) & uxa_ops; 261428d7b3dSmrg} 262428d7b3dSmrg 263428d7b3dSmrgstatic GCFuncs uxaGCFuncs = { 264428d7b3dSmrg uxa_validate_gc, 265428d7b3dSmrg miChangeGC, 266428d7b3dSmrg miCopyGC, 267428d7b3dSmrg miDestroyGC, 268428d7b3dSmrg miChangeClip, 269428d7b3dSmrg miDestroyClip, 270428d7b3dSmrg miCopyClip 271428d7b3dSmrg}; 272428d7b3dSmrg 273428d7b3dSmrg/** 274428d7b3dSmrg * uxa_create_gc makes a new GC and hooks up its funcs handler, so that 275428d7b3dSmrg * uxa_validate_gc() will get called. 276428d7b3dSmrg */ 277428d7b3dSmrgstatic int uxa_create_gc(GCPtr pGC) 278428d7b3dSmrg{ 279428d7b3dSmrg if (!fbCreateGC(pGC)) 280428d7b3dSmrg return FALSE; 281428d7b3dSmrg 282428d7b3dSmrg pGC->funcs = &uxaGCFuncs; 283428d7b3dSmrg 284428d7b3dSmrg return TRUE; 285428d7b3dSmrg} 286428d7b3dSmrg 287428d7b3dSmrgBool uxa_prepare_access_window(WindowPtr pWin) 288428d7b3dSmrg{ 289428d7b3dSmrg if (pWin->backgroundState == BackgroundPixmap) { 290428d7b3dSmrg if (!uxa_prepare_access 291428d7b3dSmrg (&pWin->background.pixmap->drawable, UXA_ACCESS_RO)) 292428d7b3dSmrg return FALSE; 293428d7b3dSmrg } 294428d7b3dSmrg 295428d7b3dSmrg if (pWin->borderIsPixel == FALSE) { 296428d7b3dSmrg if (!uxa_prepare_access 297428d7b3dSmrg (&pWin->border.pixmap->drawable, UXA_ACCESS_RO)) { 298428d7b3dSmrg if (pWin->backgroundState == BackgroundPixmap) 299428d7b3dSmrg uxa_finish_access(&pWin->background.pixmap-> 300428d7b3dSmrg drawable, UXA_ACCESS_RO); 301428d7b3dSmrg return FALSE; 302428d7b3dSmrg } 303428d7b3dSmrg } 304428d7b3dSmrg return TRUE; 305428d7b3dSmrg} 306428d7b3dSmrg 307428d7b3dSmrgvoid uxa_finish_access_window(WindowPtr pWin) 308428d7b3dSmrg{ 309428d7b3dSmrg if (pWin->backgroundState == BackgroundPixmap) 310428d7b3dSmrg uxa_finish_access(&pWin->background.pixmap->drawable, UXA_ACCESS_RO); 311428d7b3dSmrg 312428d7b3dSmrg if (pWin->borderIsPixel == FALSE) 313428d7b3dSmrg uxa_finish_access(&pWin->border.pixmap->drawable, UXA_ACCESS_RO); 314428d7b3dSmrg} 315428d7b3dSmrg 316428d7b3dSmrgstatic Bool uxa_change_window_attributes(WindowPtr pWin, unsigned long mask) 317428d7b3dSmrg{ 318428d7b3dSmrg Bool ret; 319428d7b3dSmrg 320428d7b3dSmrg if (!uxa_prepare_access_window(pWin)) 321428d7b3dSmrg return FALSE; 322428d7b3dSmrg ret = fbChangeWindowAttributes(pWin, mask); 323428d7b3dSmrg uxa_finish_access_window(pWin); 324428d7b3dSmrg return ret; 325428d7b3dSmrg} 326428d7b3dSmrg 327428d7b3dSmrgstatic RegionPtr uxa_bitmap_to_region(PixmapPtr pPix) 328428d7b3dSmrg{ 329428d7b3dSmrg RegionPtr ret; 330428d7b3dSmrg if (!uxa_prepare_access(&pPix->drawable, UXA_ACCESS_RO)) 331428d7b3dSmrg return NULL; 332428d7b3dSmrg ret = fbPixmapToRegion(pPix); 333428d7b3dSmrg uxa_finish_access(&pPix->drawable, UXA_ACCESS_RO); 334428d7b3dSmrg return ret; 335428d7b3dSmrg} 336428d7b3dSmrg 337428d7b3dSmrgvoid uxa_set_fallback_debug(ScreenPtr screen, Bool enable) 338428d7b3dSmrg{ 339428d7b3dSmrg uxa_screen_t *uxa_screen = uxa_get_screen(screen); 340428d7b3dSmrg 341428d7b3dSmrg uxa_screen->fallback_debug = enable; 342428d7b3dSmrg} 343428d7b3dSmrg 344428d7b3dSmrgvoid uxa_set_force_fallback(ScreenPtr screen, Bool value) 345428d7b3dSmrg{ 346428d7b3dSmrg uxa_screen_t *uxa_screen = uxa_get_screen(screen); 347428d7b3dSmrg 348428d7b3dSmrg uxa_screen->force_fallback = value; 349428d7b3dSmrg} 350428d7b3dSmrg 351428d7b3dSmrg/** 352428d7b3dSmrg * uxa_close_screen() unwraps its wrapped screen functions and tears down UXA's 353428d7b3dSmrg * screen private, before calling down to the next CloseSccreen. 354428d7b3dSmrg */ 355428d7b3dSmrgstatic Bool uxa_close_screen(CLOSE_SCREEN_ARGS_DECL) 356428d7b3dSmrg{ 357428d7b3dSmrg uxa_screen_t *uxa_screen = uxa_get_screen(screen); 358428d7b3dSmrg#ifdef RENDER 359428d7b3dSmrg PictureScreenPtr ps = GetPictureScreenIfSet(screen); 360428d7b3dSmrg#endif 361428d7b3dSmrg int n; 362428d7b3dSmrg 363428d7b3dSmrg if (uxa_screen->solid_clear) 364428d7b3dSmrg FreePicture(uxa_screen->solid_clear, 0); 365428d7b3dSmrg if (uxa_screen->solid_black) 366428d7b3dSmrg FreePicture(uxa_screen->solid_black, 0); 367428d7b3dSmrg if (uxa_screen->solid_white) 368428d7b3dSmrg FreePicture(uxa_screen->solid_white, 0); 369428d7b3dSmrg for (n = 0; n < uxa_screen->solid_cache_size; n++) 370428d7b3dSmrg FreePicture(uxa_screen->solid_cache[n].picture, 0); 371428d7b3dSmrg 372428d7b3dSmrg uxa_glyphs_fini(screen); 373428d7b3dSmrg 374428d7b3dSmrg#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,15,99,903,0) 375428d7b3dSmrg if (screen->devPrivate) { 376428d7b3dSmrg /* Destroy the pixmap created by miScreenInit() *before* 377428d7b3dSmrg * chaining up as we finalize ourselves here and so this 378428d7b3dSmrg * is the last chance we have of releasing our resources 379428d7b3dSmrg * associated with the Pixmap. So do it first. 380428d7b3dSmrg */ 381428d7b3dSmrg (void) (*screen->DestroyPixmap) (screen->devPrivate); 382428d7b3dSmrg screen->devPrivate = NULL; 383428d7b3dSmrg } 384428d7b3dSmrg#endif 385428d7b3dSmrg 386428d7b3dSmrg screen->CreateGC = uxa_screen->SavedCreateGC; 387428d7b3dSmrg screen->CloseScreen = uxa_screen->SavedCloseScreen; 388428d7b3dSmrg screen->GetImage = uxa_screen->SavedGetImage; 389428d7b3dSmrg screen->GetSpans = uxa_screen->SavedGetSpans; 390428d7b3dSmrg screen->CreatePixmap = uxa_screen->SavedCreatePixmap; 391428d7b3dSmrg screen->DestroyPixmap = uxa_screen->SavedDestroyPixmap; 392428d7b3dSmrg screen->CopyWindow = uxa_screen->SavedCopyWindow; 393428d7b3dSmrg screen->ChangeWindowAttributes = 394428d7b3dSmrg uxa_screen->SavedChangeWindowAttributes; 395428d7b3dSmrg screen->BitmapToRegion = uxa_screen->SavedBitmapToRegion; 396428d7b3dSmrg#ifdef RENDER 397428d7b3dSmrg if (ps) { 398428d7b3dSmrg ps->Composite = uxa_screen->SavedComposite; 399428d7b3dSmrg ps->Glyphs = uxa_screen->SavedGlyphs; 400428d7b3dSmrg ps->Trapezoids = uxa_screen->SavedTrapezoids; 401428d7b3dSmrg ps->AddTraps = uxa_screen->SavedAddTraps; 402428d7b3dSmrg ps->Triangles = uxa_screen->SavedTriangles; 403428d7b3dSmrg 404428d7b3dSmrg ps->UnrealizeGlyph = uxa_screen->SavedUnrealizeGlyph; 405428d7b3dSmrg } 406428d7b3dSmrg#endif 407428d7b3dSmrg 408428d7b3dSmrg free(uxa_screen); 409428d7b3dSmrg 410428d7b3dSmrg return (*screen->CloseScreen) (CLOSE_SCREEN_ARGS); 411428d7b3dSmrg} 412428d7b3dSmrg 413428d7b3dSmrg/** 414428d7b3dSmrg * This function allocates a driver structure for UXA drivers to fill in. By 415428d7b3dSmrg * having UXA allocate the structure, the driver structure can be extended 416428d7b3dSmrg * without breaking ABI between UXA and the drivers. The driver's 417428d7b3dSmrg * responsibility is to check beforehand that the UXA module has a matching 418428d7b3dSmrg * major number and sufficient minor. Drivers are responsible for freeing the 419428d7b3dSmrg * driver structure using free(). 420428d7b3dSmrg * 421428d7b3dSmrg * @return a newly allocated, zero-filled driver structure 422428d7b3dSmrg */ 423428d7b3dSmrguxa_driver_t *uxa_driver_alloc(void) 424428d7b3dSmrg{ 425428d7b3dSmrg return calloc(1, sizeof(uxa_driver_t)); 426428d7b3dSmrg} 427428d7b3dSmrg 428428d7b3dSmrg/** 429428d7b3dSmrg * @param screen screen being initialized 430428d7b3dSmrg * @param pScreenInfo UXA driver record 431428d7b3dSmrg * 432428d7b3dSmrg * uxa_driver_init sets up UXA given a driver record filled in by the driver. 433428d7b3dSmrg * pScreenInfo should have been allocated by uxa_driver_alloc(). See the 434428d7b3dSmrg * comments in _UxaDriver for what must be filled in and what is optional. 435428d7b3dSmrg * 436428d7b3dSmrg * @return TRUE if UXA was successfully initialized. 437428d7b3dSmrg */ 438428d7b3dSmrgBool uxa_driver_init(ScreenPtr screen, uxa_driver_t * uxa_driver) 439428d7b3dSmrg{ 440428d7b3dSmrg uxa_screen_t *uxa_screen; 441428d7b3dSmrg 442428d7b3dSmrg if (!uxa_driver) 443428d7b3dSmrg return FALSE; 444428d7b3dSmrg 445428d7b3dSmrg if (uxa_driver->uxa_major != UXA_VERSION_MAJOR || 446428d7b3dSmrg uxa_driver->uxa_minor > UXA_VERSION_MINOR) { 447428d7b3dSmrg LogMessage(X_ERROR, 448428d7b3dSmrg "UXA(%d): driver's UXA version requirements " 449428d7b3dSmrg "(%d.%d) are incompatible with UXA version (%d.%d)\n", 450428d7b3dSmrg screen->myNum, uxa_driver->uxa_major, 451428d7b3dSmrg uxa_driver->uxa_minor, UXA_VERSION_MAJOR, 452428d7b3dSmrg UXA_VERSION_MINOR); 453428d7b3dSmrg return FALSE; 454428d7b3dSmrg } 455428d7b3dSmrg 456428d7b3dSmrg if (!uxa_driver->prepare_solid) { 457428d7b3dSmrg LogMessage(X_ERROR, 458428d7b3dSmrg "UXA(%d): uxa_driver_t::prepare_solid must be " 459428d7b3dSmrg "non-NULL\n", screen->myNum); 460428d7b3dSmrg return FALSE; 461428d7b3dSmrg } 462428d7b3dSmrg 463428d7b3dSmrg if (!uxa_driver->prepare_copy) { 464428d7b3dSmrg LogMessage(X_ERROR, 465428d7b3dSmrg "UXA(%d): uxa_driver_t::prepare_copy must be " 466428d7b3dSmrg "non-NULL\n", screen->myNum); 467428d7b3dSmrg return FALSE; 468428d7b3dSmrg } 469428d7b3dSmrg#if HAS_DIXREGISTERPRIVATEKEY 470428d7b3dSmrg if (!dixRegisterPrivateKey(&uxa_screen_index, PRIVATE_SCREEN, 0)) 471428d7b3dSmrg return FALSE; 472428d7b3dSmrg#endif 473428d7b3dSmrg uxa_screen = calloc(sizeof(uxa_screen_t), 1); 474428d7b3dSmrg 475428d7b3dSmrg if (!uxa_screen) { 476428d7b3dSmrg LogMessage(X_WARNING, 477428d7b3dSmrg "UXA(%d): Failed to allocate screen private\n", 478428d7b3dSmrg screen->myNum); 479428d7b3dSmrg return FALSE; 480428d7b3dSmrg } 481428d7b3dSmrg 482428d7b3dSmrg uxa_screen->info = uxa_driver; 483428d7b3dSmrg 484428d7b3dSmrg dixSetPrivate(&screen->devPrivates, &uxa_screen_index, uxa_screen); 485428d7b3dSmrg 486428d7b3dSmrg uxa_screen->force_fallback = FALSE; 487428d7b3dSmrg 488428d7b3dSmrg uxa_screen->solid_cache_size = 0; 489428d7b3dSmrg uxa_screen->solid_clear = 0; 490428d7b3dSmrg uxa_screen->solid_black = 0; 491428d7b3dSmrg uxa_screen->solid_white = 0; 492428d7b3dSmrg 493428d7b3dSmrg// exaDDXDriverInit(screen); 494428d7b3dSmrg 495428d7b3dSmrg /* 496428d7b3dSmrg * Replace various fb screen functions 497428d7b3dSmrg */ 498428d7b3dSmrg uxa_screen->SavedCloseScreen = screen->CloseScreen; 499428d7b3dSmrg screen->CloseScreen = uxa_close_screen; 500428d7b3dSmrg 501428d7b3dSmrg uxa_screen->SavedCreateGC = screen->CreateGC; 502428d7b3dSmrg screen->CreateGC = uxa_create_gc; 503428d7b3dSmrg 504428d7b3dSmrg uxa_screen->SavedGetImage = screen->GetImage; 505428d7b3dSmrg screen->GetImage = uxa_get_image; 506428d7b3dSmrg 507428d7b3dSmrg uxa_screen->SavedGetSpans = screen->GetSpans; 508428d7b3dSmrg screen->GetSpans = uxa_get_spans; 509428d7b3dSmrg 510428d7b3dSmrg uxa_screen->SavedCopyWindow = screen->CopyWindow; 511428d7b3dSmrg screen->CopyWindow = uxa_copy_window; 512428d7b3dSmrg 513428d7b3dSmrg uxa_screen->SavedChangeWindowAttributes = 514428d7b3dSmrg screen->ChangeWindowAttributes; 515428d7b3dSmrg screen->ChangeWindowAttributes = uxa_change_window_attributes; 516428d7b3dSmrg 517428d7b3dSmrg uxa_screen->SavedBitmapToRegion = screen->BitmapToRegion; 518428d7b3dSmrg screen->BitmapToRegion = uxa_bitmap_to_region; 519428d7b3dSmrg 520428d7b3dSmrg#ifdef RENDER 521428d7b3dSmrg { 522428d7b3dSmrg PictureScreenPtr ps = GetPictureScreenIfSet(screen); 523428d7b3dSmrg if (ps) { 524428d7b3dSmrg uxa_screen->SavedComposite = ps->Composite; 525428d7b3dSmrg ps->Composite = uxa_composite; 526428d7b3dSmrg 527428d7b3dSmrg uxa_screen->SavedGlyphs = ps->Glyphs; 528428d7b3dSmrg ps->Glyphs = uxa_glyphs; 529428d7b3dSmrg 530428d7b3dSmrg uxa_screen->SavedUnrealizeGlyph = ps->UnrealizeGlyph; 531428d7b3dSmrg ps->UnrealizeGlyph = uxa_glyph_unrealize; 532428d7b3dSmrg 533428d7b3dSmrg uxa_screen->SavedTriangles = ps->Triangles; 534428d7b3dSmrg ps->Triangles = uxa_triangles; 535428d7b3dSmrg 536428d7b3dSmrg uxa_screen->SavedTrapezoids = ps->Trapezoids; 537428d7b3dSmrg ps->Trapezoids = uxa_trapezoids; 538428d7b3dSmrg 539428d7b3dSmrg uxa_screen->SavedAddTraps = ps->AddTraps; 540428d7b3dSmrg ps->AddTraps = uxa_add_traps; 541428d7b3dSmrg } 542428d7b3dSmrg } 543428d7b3dSmrg#endif 544428d7b3dSmrg 545428d7b3dSmrg LogMessage(X_INFO, 546428d7b3dSmrg "UXA(%d): Driver registered support for the following" 547428d7b3dSmrg " operations:\n", screen->myNum); 548428d7b3dSmrg assert(uxa_driver->prepare_solid != NULL); 549428d7b3dSmrg LogMessage(X_INFO, " solid\n"); 550428d7b3dSmrg assert(uxa_driver->prepare_copy != NULL); 551428d7b3dSmrg LogMessage(X_INFO, " copy\n"); 552428d7b3dSmrg if (uxa_driver->prepare_composite != NULL) { 553428d7b3dSmrg LogMessage(X_INFO, " composite (RENDER acceleration)\n"); 554428d7b3dSmrg } 555428d7b3dSmrg if (uxa_driver->put_image != NULL) { 556428d7b3dSmrg LogMessage(X_INFO, " put_image\n"); 557428d7b3dSmrg } 558428d7b3dSmrg if (uxa_driver->get_image != NULL) { 559428d7b3dSmrg LogMessage(X_INFO, " get_image\n"); 560428d7b3dSmrg } 561428d7b3dSmrg 562428d7b3dSmrg return TRUE; 563428d7b3dSmrg} 564428d7b3dSmrg 565428d7b3dSmrgBool uxa_resources_init(ScreenPtr screen) 566428d7b3dSmrg{ 567428d7b3dSmrg if (!uxa_glyphs_init(screen)) 568428d7b3dSmrg return FALSE; 569428d7b3dSmrg 570428d7b3dSmrg return TRUE; 571428d7b3dSmrg} 572428d7b3dSmrg 573428d7b3dSmrg/** 574428d7b3dSmrg * uxa_driver_fini tears down UXA on a given screen. 575428d7b3dSmrg * 576428d7b3dSmrg * @param pScreen screen being torn down. 577428d7b3dSmrg */ 578428d7b3dSmrgvoid uxa_driver_fini(ScreenPtr pScreen) 579428d7b3dSmrg{ 580428d7b3dSmrg /*right now does nothing */ 581428d7b3dSmrg} 582