summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <mdaenzer@redhat.com>2020-11-17 11:59:51 +0100
committerOlivier Fourdan <ofourdan@redhat.com>2022-01-18 12:09:52 +0100
commitcd080f721b0e253bb3cff32e1b206a056b2540e1 (patch)
tree35526b07c03555fa0d39c38ac30aabcb18696b62
parent09ce18292c36fa801424aa1c7cd1545db1d3a869 (diff)
Drop EXA code
Not used on this branch. (cherry picked from commit aa49cd5ab72fa9624e1a20750af542b3bbb1e988)
-rw-r--r--exa/exa.c1144
-rw-r--r--exa/exa.h820
-rw-r--r--exa/exa_accel.c1297
-rw-r--r--exa/exa_classic.c265
-rw-r--r--exa/exa_driver.c230
-rw-r--r--exa/exa_glyphs.c839
-rw-r--r--exa/exa_migration_classic.c761
-rw-r--r--exa/exa_migration_mixed.c270
-rw-r--r--exa/exa_mixed.c330
-rw-r--r--exa/exa_offscreen.c677
-rw-r--r--exa/exa_priv.h735
-rw-r--r--exa/exa_render.c1229
-rw-r--r--exa/exa_unaccel.c733
-rw-r--r--exa/meson.build19
-rw-r--r--meson.build1
15 files changed, 0 insertions, 9350 deletions
diff --git a/exa/exa.c b/exa/exa.c
deleted file mode 100644
index b16875845..000000000
--- a/exa/exa.c
+++ /dev/null
@@ -1,1144 +0,0 @@
-/*
- * Copyright © 2001 Keith Packard
- *
- * Partly based on code that is Copyright © The XFree86 Project Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/** @file
- * This file covers the initialization and teardown of EXA, and has various
- * functions not responsible for performing rendering, pixmap migration, or
- * memory management.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdlib.h>
-
-#include "exa_priv.h"
-#include "exa.h"
-
-DevPrivateKeyRec exaScreenPrivateKeyRec;
-
-#ifdef MITSHM
-static ShmFuncs exaShmFuncs = { NULL, NULL };
-#endif
-
-/**
- * exaGetPixmapOffset() returns the offset (in bytes) within the framebuffer of
- * the beginning of the given pixmap.
- *
- * Note that drivers are free to, and often do, munge this offset as necessary
- * for handing to the hardware -- for example, translating it into a different
- * aperture. This function may need to be extended in the future if we grow
- * support for having multiple card-accessible offscreen, such as an AGP memory
- * pool alongside the framebuffer pool.
- */
-unsigned long
-exaGetPixmapOffset(PixmapPtr pPix)
-{
- ExaScreenPriv(pPix->drawable.pScreen);
- ExaPixmapPriv(pPix);
-
- return (CARD8 *) pExaPixmap->fb_ptr - pExaScr->info->memoryBase;
-}
-
-void *
-exaGetPixmapDriverPrivate(PixmapPtr pPix)
-{
- ExaPixmapPriv(pPix);
-
- return pExaPixmap->driverPriv;
-}
-
-/**
- * exaGetPixmapPitch() returns the pitch (in bytes) of the given pixmap.
- *
- * This is a helper to make driver code more obvious, due to the rather obscure
- * naming of the pitch field in the pixmap.
- */
-unsigned long
-exaGetPixmapPitch(PixmapPtr pPix)
-{
- return pPix->devKind;
-}
-
-/**
- * exaGetPixmapSize() returns the size in bytes of the given pixmap in video
- * memory. Only valid when the pixmap is currently in framebuffer.
- */
-unsigned long
-exaGetPixmapSize(PixmapPtr pPix)
-{
- ExaPixmapPrivPtr pExaPixmap;
-
- pExaPixmap = ExaGetPixmapPriv(pPix);
- if (pExaPixmap != NULL)
- return pExaPixmap->fb_size;
- return 0;
-}
-
-/**
- * exaGetDrawablePixmap() returns a backing pixmap for a given drawable.
- *
- * @param pDrawable the drawable being requested.
- *
- * This function returns the backing pixmap for a drawable, whether it is a
- * redirected window, unredirected window, or already a pixmap. Note that
- * coordinate translation is needed when drawing to the backing pixmap of a
- * redirected window, and the translation coordinates are provided by calling
- * exaGetOffscreenPixmap() on the drawable.
- */
-PixmapPtr
-exaGetDrawablePixmap(DrawablePtr pDrawable)
-{
- if (pDrawable->type == DRAWABLE_WINDOW)
- return pDrawable->pScreen->GetWindowPixmap((WindowPtr) pDrawable);
- else
- return (PixmapPtr) pDrawable;
-}
-
-/**
- * Sets the offsets to add to coordinates to make them address the same bits in
- * the backing drawable. These coordinates are nonzero only for redirected
- * windows.
- */
-void
-exaGetDrawableDeltas(DrawablePtr pDrawable, PixmapPtr pPixmap, int *xp, int *yp)
-{
-#ifdef COMPOSITE
- if (pDrawable->type == DRAWABLE_WINDOW) {
- *xp = -pPixmap->screen_x;
- *yp = -pPixmap->screen_y;
- return;
- }
-#endif
-
- *xp = 0;
- *yp = 0;
-}
-
-/**
- * exaPixmapDirty() marks a pixmap as dirty, allowing for
- * optimizations in pixmap migration when no changes have occurred.
- */
-void
-exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2)
-{
- BoxRec box;
- RegionRec region;
-
- box.x1 = max(x1, 0);
- box.y1 = max(y1, 0);
- box.x2 = min(x2, pPix->drawable.width);
- box.y2 = min(y2, pPix->drawable.height);
-
- if (box.x1 >= box.x2 || box.y1 >= box.y2)
- return;
-
- RegionInit(&region, &box, 1);
- DamageDamageRegion(&pPix->drawable, &region);
- RegionUninit(&region);
-}
-
-static int
-exaLog2(int val)
-{
- int bits;
-
- if (val <= 0)
- return 0;
- for (bits = 0; val != 0; bits++)
- val >>= 1;
- return bits - 1;
-}
-
-void
-exaSetAccelBlock(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap,
- int w, int h, int bpp)
-{
- pExaPixmap->accel_blocked = 0;
-
- if (pExaScr->info->maxPitchPixels) {
- int max_pitch = pExaScr->info->maxPitchPixels * bits_to_bytes(bpp);
-
- if (pExaPixmap->fb_pitch > max_pitch)
- pExaPixmap->accel_blocked |= EXA_RANGE_PITCH;
- }
-
- if (pExaScr->info->maxPitchBytes &&
- pExaPixmap->fb_pitch > pExaScr->info->maxPitchBytes)
- pExaPixmap->accel_blocked |= EXA_RANGE_PITCH;
-
- if (w > pExaScr->info->maxX)
- pExaPixmap->accel_blocked |= EXA_RANGE_WIDTH;
-
- if (h > pExaScr->info->maxY)
- pExaPixmap->accel_blocked |= EXA_RANGE_HEIGHT;
-}
-
-void
-exaSetFbPitch(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap,
- int w, int h, int bpp)
-{
- if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1)
- pExaPixmap->fb_pitch = bits_to_bytes((1 << (exaLog2(w - 1) + 1)) * bpp);
- else
- pExaPixmap->fb_pitch = bits_to_bytes(w * bpp);
-
- pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch,
- pExaScr->info->pixmapPitchAlign);
-}
-
-/**
- * Returns TRUE if the pixmap is not movable. This is the case where it's a
- * pixmap which has no private (almost always bad) or it's a scratch pixmap created by
- * some X Server internal component (the score says it's pinned).
- */
-Bool
-exaPixmapIsPinned(PixmapPtr pPix)
-{
- ExaPixmapPriv(pPix);
-
- if (pExaPixmap == NULL)
- EXA_FatalErrorDebugWithRet(("EXA bug: exaPixmapIsPinned was called on a non-exa pixmap.\n"), TRUE);
-
- return pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED;
-}
-
-/**
- * exaPixmapHasGpuCopy() is used to determine if a pixmap is in offscreen
- * memory, meaning that acceleration could probably be done to it, and that it
- * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it
- * with the CPU.
- *
- * Note that except for UploadToScreen()/DownloadFromScreen() (which explicitly
- * deal with moving pixmaps in and out of system memory), EXA will give drivers
- * pixmaps as arguments for which exaPixmapHasGpuCopy() is TRUE.
- *
- * @return TRUE if the given drawable is in framebuffer memory.
- */
-Bool
-exaPixmapHasGpuCopy(PixmapPtr pPixmap)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
-
- ExaScreenPriv(pScreen);
-
- if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS))
- return FALSE;
-
- return (*pExaScr->pixmap_has_gpu_copy) (pPixmap);
-}
-
-/**
- * exaDrawableIsOffscreen() is a convenience wrapper for exaPixmapHasGpuCopy().
- */
-Bool
-exaDrawableIsOffscreen(DrawablePtr pDrawable)
-{
- return exaPixmapHasGpuCopy(exaGetDrawablePixmap(pDrawable));
-}
-
-/**
- * Returns the pixmap which backs a drawable, and the offsets to add to
- * coordinates to make them address the same bits in the backing drawable.
- */
-PixmapPtr
-exaGetOffscreenPixmap(DrawablePtr pDrawable, int *xp, int *yp)
-{
- PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
-
- exaGetDrawableDeltas(pDrawable, pPixmap, xp, yp);
-
- if (exaPixmapHasGpuCopy(pPixmap))
- return pPixmap;
- else
- return NULL;
-}
-
-/**
- * Returns TRUE if the pixmap GPU copy is being accessed.
- */
-Bool
-ExaDoPrepareAccess(PixmapPtr pPixmap, int index)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
-
- ExaScreenPriv(pScreen);
- ExaPixmapPriv(pPixmap);
- Bool has_gpu_copy, ret;
- int i;
-
- if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS))
- return FALSE;
-
- if (pExaPixmap == NULL)
- EXA_FatalErrorDebugWithRet(("EXA bug: ExaDoPrepareAccess was called on a non-exa pixmap.\n"), FALSE);
-
- /* Handle repeated / nested calls. */
- for (i = 0; i < EXA_NUM_PREPARE_INDICES; i++) {
- if (pExaScr->access[i].pixmap == pPixmap) {
- pExaScr->access[i].count++;
- return pExaScr->access[i].retval;
- }
- }
-
- /* If slot for this index is taken, find an empty slot */
- if (pExaScr->access[index].pixmap) {
- for (index = EXA_NUM_PREPARE_INDICES - 1; index >= 0; index--)
- if (!pExaScr->access[index].pixmap)
- break;
- }
-
- /* Access to this pixmap hasn't been prepared yet, so data pointer should be NULL. */
- if (pPixmap->devPrivate.ptr != NULL) {
- EXA_FatalErrorDebug(("EXA bug: pPixmap->devPrivate.ptr was %p, but should have been NULL.\n", pPixmap->devPrivate.ptr));
- }
-
- has_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
-
- if (has_gpu_copy && pExaPixmap->fb_ptr) {
- pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
- ret = TRUE;
- }
- else {
- pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
- ret = FALSE;
- }
-
- /* Store so we can handle repeated / nested calls. */
- pExaScr->access[index].pixmap = pPixmap;
- pExaScr->access[index].count = 1;
-
- if (!has_gpu_copy)
- goto out;
-
- exaWaitSync(pScreen);
-
- if (pExaScr->info->PrepareAccess == NULL)
- goto out;
-
- if (index >= EXA_PREPARE_AUX_DEST &&
- !(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) {
- if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED)
- FatalError("Unsupported AUX indices used on a pinned pixmap.\n");
- exaMoveOutPixmap(pPixmap);
- ret = FALSE;
- goto out;
- }
-
- if (!(*pExaScr->info->PrepareAccess) (pPixmap, index)) {
- if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED &&
- !(pExaScr->info->flags & EXA_MIXED_PIXMAPS))
- FatalError("Driver failed PrepareAccess on a pinned pixmap.\n");
- exaMoveOutPixmap(pPixmap);
- ret = FALSE;
- goto out;
- }
-
- ret = TRUE;
-
- out:
- pExaScr->access[index].retval = ret;
- return ret;
-}
-
-/**
- * exaPrepareAccess() is EXA's wrapper for the driver's PrepareAccess() handler.
- *
- * It deals with waiting for synchronization with the card, determining if
- * PrepareAccess() is necessary, and working around PrepareAccess() failure.
- */
-void
-exaPrepareAccess(DrawablePtr pDrawable, int index)
-{
- PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
-
- ExaScreenPriv(pDrawable->pScreen);
-
- if (pExaScr->prepare_access_reg)
- pExaScr->prepare_access_reg(pPixmap, index, NULL);
- else
- (void) ExaDoPrepareAccess(pPixmap, index);
-}
-
-/**
- * exaFinishAccess() is EXA's wrapper for the driver's FinishAccess() handler.
- *
- * It deals with calling the driver's FinishAccess() only if necessary.
- */
-void
-exaFinishAccess(DrawablePtr pDrawable, int index)
-{
- ScreenPtr pScreen = pDrawable->pScreen;
-
- ExaScreenPriv(pScreen);
- PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
-
- ExaPixmapPriv(pPixmap);
- int i;
-
- if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS))
- return;
-
- if (pExaPixmap == NULL)
- EXA_FatalErrorDebugWithRet(("EXA bug: exaFinishAccesss was called on a non-exa pixmap.\n"),);
-
- /* Handle repeated / nested calls. */
- for (i = 0; i < EXA_NUM_PREPARE_INDICES; i++) {
- if (pExaScr->access[i].pixmap == pPixmap) {
- if (--pExaScr->access[i].count > 0)
- return;
- break;
- }
- }
-
- /* Catch unbalanced Prepare/FinishAccess calls. */
- if (i == EXA_NUM_PREPARE_INDICES)
- EXA_FatalErrorDebugWithRet(("EXA bug: FinishAccess called without PrepareAccess for pixmap 0x%p.\n", pPixmap),);
-
- pExaScr->access[i].pixmap = NULL;
-
- /* We always hide the devPrivate.ptr. */
- pPixmap->devPrivate.ptr = NULL;
-
- /* Only call FinishAccess if PrepareAccess was called and succeeded. */
- if (!pExaScr->info->FinishAccess || !pExaScr->access[i].retval)
- return;
-
- if (i >= EXA_PREPARE_AUX_DEST &&
- !(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) {
- ErrorF("EXA bug: Trying to call driver FinishAccess hook with "
- "unsupported index EXA_PREPARE_AUX*\n");
- return;
- }
-
- (*pExaScr->info->FinishAccess) (pPixmap, i);
-}
-
-/**
- * Helper for things common to all schemes when a pixmap is destroyed
- */
-void
-exaDestroyPixmap(PixmapPtr pPixmap)
-{
- ExaScreenPriv(pPixmap->drawable.pScreen);
- int i;
-
- /* Finish access if it was prepared (e.g. pixmap created during
- * software fallback)
- */
- for (i = 0; i < EXA_NUM_PREPARE_INDICES; i++) {
- if (pExaScr->access[i].pixmap == pPixmap) {
- exaFinishAccess(&pPixmap->drawable, i);
- pExaScr->access[i].pixmap = NULL;
- break;
- }
- }
-}
-
-/**
- * Here begins EXA's GC code.
- * Do not ever access the fb/mi layer directly.
- */
-
-static void
- exaValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable);
-
-static void
- exaDestroyGC(GCPtr pGC);
-
-static void
- exaChangeGC(GCPtr pGC, unsigned long mask);
-
-static void
- exaCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
-
-static void
- exaChangeClip(GCPtr pGC, int type, void *pvalue, int nrects);
-
-static void
- exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc);
-
-static void
- exaDestroyClip(GCPtr pGC);
-
-const GCFuncs exaGCFuncs = {
- exaValidateGC,
- exaChangeGC,
- exaCopyGC,
- exaDestroyGC,
- exaChangeClip,
- exaDestroyClip,
- exaCopyClip
-};
-
-static void
-exaValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
-{
- /* fbValidateGC will do direct access to pixmaps if the tiling has changed.
- * Do a few smart things so fbValidateGC can do its work.
- */
-
- ScreenPtr pScreen = pDrawable->pScreen;
-
- ExaScreenPriv(pScreen);
- ExaGCPriv(pGC);
- PixmapPtr pTile = NULL;
-
- /* Either of these conditions is enough to trigger access to a tile pixmap.
- * With pGC->tileIsPixel == 1, you run the risk of dereferencing an invalid
- * tile pixmap pointer.
- */
- if (pGC->fillStyle == FillTiled ||
- ((changes & GCTile) && !pGC->tileIsPixel)) {
- pTile = pGC->tile.pixmap;
- }
-
- if (pGC->stipple)
- exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
- if (pTile)
- exaPrepareAccess(&pTile->drawable, EXA_PREPARE_SRC);
-
- /* Calls to Create/DestroyPixmap have to be identified as special. */
- pExaScr->fallback_counter++;
- swap(pExaGC, pGC, funcs);
- (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);
- swap(pExaGC, pGC, funcs);
- pExaScr->fallback_counter--;
-
- if (pTile)
- exaFinishAccess(&pTile->drawable, EXA_PREPARE_SRC);
- if (pGC->stipple)
- exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
-}
-
-/* Is exaPrepareAccessGC() needed? */
-static void
-exaDestroyGC(GCPtr pGC)
-{
- ExaGCPriv(pGC);
- swap(pExaGC, pGC, funcs);
- (*pGC->funcs->DestroyGC) (pGC);
- swap(pExaGC, pGC, funcs);
-}
-
-static void
-exaChangeGC(GCPtr pGC, unsigned long mask)
-{
- ExaGCPriv(pGC);
- swap(pExaGC, pGC, funcs);
- (*pGC->funcs->ChangeGC) (pGC, mask);
- swap(pExaGC, pGC, funcs);
-}
-
-static void
-exaCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
-{
- ExaGCPriv(pGCDst);
- swap(pExaGC, pGCDst, funcs);
- (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
- swap(pExaGC, pGCDst, funcs);
-}
-
-static void
-exaChangeClip(GCPtr pGC, int type, void *pvalue, int nrects)
-{
- ExaGCPriv(pGC);
- swap(pExaGC, pGC, funcs);
- (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
- swap(pExaGC, pGC, funcs);
-}
-
-static void
-exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
-{
- ExaGCPriv(pGCDst);
- swap(pExaGC, pGCDst, funcs);
- (*pGCDst->funcs->CopyClip) (pGCDst, pGCSrc);
- swap(pExaGC, pGCDst, funcs);
-}
-
-static void
-exaDestroyClip(GCPtr pGC)
-{
- ExaGCPriv(pGC);
- swap(pExaGC, pGC, funcs);
- (*pGC->funcs->DestroyClip) (pGC);
- swap(pExaGC, pGC, funcs);
-}
-
-/**
- * exaCreateGC makes a new GC and hooks up its funcs handler, so that
- * exaValidateGC() will get called.
- */
-static int
-exaCreateGC(GCPtr pGC)
-{
- ScreenPtr pScreen = pGC->pScreen;
-
- ExaScreenPriv(pScreen);
- ExaGCPriv(pGC);
- Bool ret;
-
- swap(pExaScr, pScreen, CreateGC);
- if ((ret = (*pScreen->CreateGC) (pGC))) {
- wrap(pExaGC, pGC, funcs, &exaGCFuncs);
- wrap(pExaGC, pGC, ops, &exaOps);
- }
- swap(pExaScr, pScreen, CreateGC);
-
- return ret;
-}
-
-static Bool
-exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
-{
- Bool ret;
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- ExaScreenPriv(pScreen);
-
- if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap)
- exaPrepareAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
-
- if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE)
- exaPrepareAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK);
-
- pExaScr->fallback_counter++;
- swap(pExaScr, pScreen, ChangeWindowAttributes);
- ret = pScreen->ChangeWindowAttributes(pWin, mask);
- swap(pExaScr, pScreen, ChangeWindowAttributes);
- pExaScr->fallback_counter--;
-
- if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap)
- exaFinishAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
- if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE)
- exaFinishAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK);
-
- return ret;
-}
-
-static RegionPtr
-exaBitmapToRegion(PixmapPtr pPix)
-{
- RegionPtr ret;
- ScreenPtr pScreen = pPix->drawable.pScreen;
-
- ExaScreenPriv(pScreen);
-
- exaPrepareAccess(&pPix->drawable, EXA_PREPARE_SRC);
- swap(pExaScr, pScreen, BitmapToRegion);
- ret = (*pScreen->BitmapToRegion) (pPix);
- swap(pExaScr, pScreen, BitmapToRegion);
- exaFinishAccess(&pPix->drawable, EXA_PREPARE_SRC);
-
- return ret;
-}
-
-static Bool
-exaCreateScreenResources(ScreenPtr pScreen)
-{
- ExaScreenPriv(pScreen);
- PixmapPtr pScreenPixmap;
- Bool b;
-
- swap(pExaScr, pScreen, CreateScreenResources);
- b = pScreen->CreateScreenResources(pScreen);
- swap(pExaScr, pScreen, CreateScreenResources);
-
- if (!b)
- return FALSE;
-
- pScreenPixmap = pScreen->GetScreenPixmap(pScreen);
-
- if (pScreenPixmap) {
- ExaPixmapPriv(pScreenPixmap);
-
- exaSetAccelBlock(pExaScr, pExaPixmap,
- pScreenPixmap->drawable.width,
- pScreenPixmap->drawable.height,
- pScreenPixmap->drawable.bitsPerPixel);
- }
-
- return TRUE;
-}
-
-static void
-ExaBlockHandler(ScreenPtr pScreen, void *pTimeout)
-{
- ExaScreenPriv(pScreen);
-
- /* Move any deferred results from a software fallback to the driver pixmap */
- if (pExaScr->deferred_mixed_pixmap)
- exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
-
- unwrap(pExaScr, pScreen, BlockHandler);
- (*pScreen->BlockHandler) (pScreen, pTimeout);
- wrap(pExaScr, pScreen, BlockHandler, ExaBlockHandler);
-
- /* The rest only applies to classic EXA */
- if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS)
- return;
-
- /* Try and keep the offscreen memory area tidy every now and then (at most
- * once per second) when the server has been idle for at least 100ms.
- */
- if (pExaScr->numOffscreenAvailable > 1) {
- CARD32 now = GetTimeInMillis();
-
- pExaScr->nextDefragment = now +
- max(100, (INT32) (pExaScr->lastDefragment + 1000 - now));
- AdjustWaitForDelay(pTimeout, pExaScr->nextDefragment - now);
- }
-}
-
-static void
-ExaWakeupHandler(ScreenPtr pScreen, int result)
-{
- ExaScreenPriv(pScreen);
-
- unwrap(pExaScr, pScreen, WakeupHandler);
- (*pScreen->WakeupHandler) (pScreen, result);
- wrap(pExaScr, pScreen, WakeupHandler, ExaWakeupHandler);
-
- if (result == 0 && pExaScr->numOffscreenAvailable > 1) {
- CARD32 now = GetTimeInMillis();
-
- if ((int) (now - pExaScr->nextDefragment) > 0) {
- ExaOffscreenDefragment(pScreen);
- pExaScr->lastDefragment = now;
- }
- }
-}
-
-/**
- * exaCloseScreen() unwraps its wrapped screen functions and tears down EXA's
- * screen private, before calling down to the next CloseSccreen.
- */
-static Bool
-exaCloseScreen(ScreenPtr pScreen)
-{
- ExaScreenPriv(pScreen);
- PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
-
- if (ps->Glyphs == exaGlyphs)
- exaGlyphsFini(pScreen);
-
- if (pScreen->BlockHandler == ExaBlockHandler)
- unwrap(pExaScr, pScreen, BlockHandler);
- if (pScreen->WakeupHandler == ExaWakeupHandler)
- unwrap(pExaScr, pScreen, WakeupHandler);
- unwrap(pExaScr, pScreen, CreateGC);
- unwrap(pExaScr, pScreen, CloseScreen);
- unwrap(pExaScr, pScreen, GetImage);
- unwrap(pExaScr, pScreen, GetSpans);
- if (pExaScr->SavedCreatePixmap)
- unwrap(pExaScr, pScreen, CreatePixmap);
- if (pExaScr->SavedDestroyPixmap)
- unwrap(pExaScr, pScreen, DestroyPixmap);
- if (pExaScr->SavedModifyPixmapHeader)
- unwrap(pExaScr, pScreen, ModifyPixmapHeader);
- unwrap(pExaScr, pScreen, CopyWindow);
- unwrap(pExaScr, pScreen, ChangeWindowAttributes);
- unwrap(pExaScr, pScreen, BitmapToRegion);
- unwrap(pExaScr, pScreen, CreateScreenResources);
- if (pExaScr->SavedSharePixmapBacking)
- unwrap(pExaScr, pScreen, SharePixmapBacking);
- if (pExaScr->SavedSetSharedPixmapBacking)
- unwrap(pExaScr, pScreen, SetSharedPixmapBacking);
- unwrap(pExaScr, ps, Composite);
- if (pExaScr->SavedGlyphs)
- unwrap(pExaScr, ps, Glyphs);
- unwrap(pExaScr, ps, Trapezoids);
- unwrap(pExaScr, ps, Triangles);
- unwrap(pExaScr, ps, AddTraps);
-
- free(pExaScr);
-
- return (*pScreen->CloseScreen) (pScreen);
-}
-
-/**
- * This function allocates a driver structure for EXA drivers to fill in. By
- * having EXA allocate the structure, the driver structure can be extended
- * without breaking ABI between EXA and the drivers. The driver's
- * responsibility is to check beforehand that the EXA module has a matching
- * major number and sufficient minor. Drivers are responsible for freeing the
- * driver structure using free().
- *
- * @return a newly allocated, zero-filled driver structure
- */
-ExaDriverPtr
-exaDriverAlloc(void)
-{
- return calloc(1, sizeof(ExaDriverRec));
-}
-
-/**
- * @param pScreen screen being initialized
- * @param pScreenInfo EXA driver record
- *
- * exaDriverInit sets up EXA given a driver record filled in by the driver.
- * pScreenInfo should have been allocated by exaDriverAlloc(). See the
- * comments in _ExaDriver for what must be filled in and what is optional.
- *
- * @return TRUE if EXA was successfully initialized.
- */
-Bool
-exaDriverInit(ScreenPtr pScreen, ExaDriverPtr pScreenInfo)
-{
- ExaScreenPrivPtr pExaScr;
- PictureScreenPtr ps;
-
- if (!pScreenInfo)
- return FALSE;
-
- if (pScreenInfo->exa_major != EXA_VERSION_MAJOR ||
- pScreenInfo->exa_minor > EXA_VERSION_MINOR) {
- LogMessage(X_ERROR, "EXA(%d): driver's EXA version requirements "
- "(%d.%d) are incompatible with EXA version (%d.%d)\n",
- pScreen->myNum,
- pScreenInfo->exa_major, pScreenInfo->exa_minor,
- EXA_VERSION_MAJOR, EXA_VERSION_MINOR);
- return FALSE;
- }
-
- if (!pScreenInfo->CreatePixmap && !pScreenInfo->CreatePixmap2) {
- if (!pScreenInfo->memoryBase) {
- LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memoryBase "
- "must be non-zero\n", pScreen->myNum);
- return FALSE;
- }
-
- if (!pScreenInfo->memorySize) {
- LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memorySize must be "
- "non-zero\n", pScreen->myNum);
- return FALSE;
- }
-
- if (pScreenInfo->offScreenBase > pScreenInfo->memorySize) {
- LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::offScreenBase must "
- "be <= ExaDriverRec::memorySize\n", pScreen->myNum);
- return FALSE;
- }
- }
-
- if (!pScreenInfo->PrepareSolid) {
- LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::PrepareSolid must be "
- "non-NULL\n", pScreen->myNum);
- return FALSE;
- }
-
- if (!pScreenInfo->PrepareCopy) {
- LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::PrepareCopy must be "
- "non-NULL\n", pScreen->myNum);
- return FALSE;
- }
-
- if (!pScreenInfo->WaitMarker) {
- LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::WaitMarker must be "
- "non-NULL\n", pScreen->myNum);
- return FALSE;
- }
-
- /* If the driver doesn't set any max pitch values, we'll just assume
- * that there's a limitation by pixels, and that it's the same as
- * maxX.
- *
- * We want maxPitchPixels or maxPitchBytes to be set so we can check
- * pixmaps against the max pitch in exaCreatePixmap() -- it matters
- * whether a pixmap is rejected because of its pitch or
- * because of its width.
- */
- if (!pScreenInfo->maxPitchPixels && !pScreenInfo->maxPitchBytes) {
- pScreenInfo->maxPitchPixels = pScreenInfo->maxX;
- }
-
- ps = GetPictureScreenIfSet(pScreen);
-
- if (!dixRegisterPrivateKey(&exaScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) {
- LogMessage(X_WARNING, "EXA(%d): Failed to register screen private\n",
- pScreen->myNum);
- return FALSE;
- }
-
- pExaScr = calloc(sizeof(ExaScreenPrivRec), 1);
- if (!pExaScr) {
- LogMessage(X_WARNING, "EXA(%d): Failed to allocate screen private\n",
- pScreen->myNum);
- return FALSE;
- }
-
- pExaScr->info = pScreenInfo;
-
- dixSetPrivate(&pScreen->devPrivates, exaScreenPrivateKey, pExaScr);
-
- pExaScr->migration = ExaMigrationAlways;
-
- exaDDXDriverInit(pScreen);
-
- if (!dixRegisterScreenSpecificPrivateKey
- (pScreen, &pExaScr->gcPrivateKeyRec, PRIVATE_GC, sizeof(ExaGCPrivRec))) {
- LogMessage(X_WARNING, "EXA(%d): Failed to allocate GC private\n",
- pScreen->myNum);
- return FALSE;
- }
-
- /*
- * Replace various fb screen functions
- */
- if ((pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) &&
- (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) ||
- (pExaScr->info->flags & EXA_MIXED_PIXMAPS)))
- wrap(pExaScr, pScreen, BlockHandler, ExaBlockHandler);
- if ((pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) &&
- !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS))
- wrap(pExaScr, pScreen, WakeupHandler, ExaWakeupHandler);
- wrap(pExaScr, pScreen, CreateGC, exaCreateGC);
- wrap(pExaScr, pScreen, CloseScreen, exaCloseScreen);
- wrap(pExaScr, pScreen, GetImage, exaGetImage);
- wrap(pExaScr, pScreen, GetSpans, ExaCheckGetSpans);
- wrap(pExaScr, pScreen, CopyWindow, exaCopyWindow);
- wrap(pExaScr, pScreen, ChangeWindowAttributes, exaChangeWindowAttributes);
- wrap(pExaScr, pScreen, BitmapToRegion, exaBitmapToRegion);
- wrap(pExaScr, pScreen, CreateScreenResources, exaCreateScreenResources);
-
- if (ps) {
- wrap(pExaScr, ps, Composite, exaComposite);
- if (pScreenInfo->PrepareComposite) {
- wrap(pExaScr, ps, Glyphs, exaGlyphs);
- }
- else {
- wrap(pExaScr, ps, Glyphs, ExaCheckGlyphs);
- }
- wrap(pExaScr, ps, Trapezoids, exaTrapezoids);
- wrap(pExaScr, ps, Triangles, exaTriangles);
- wrap(pExaScr, ps, AddTraps, ExaCheckAddTraps);
- }
-
-#ifdef MITSHM
- /*
- * Don't allow shared pixmaps.
- */
- ShmRegisterFuncs(pScreen, &exaShmFuncs);
-#endif
- /*
- * Hookup offscreen pixmaps
- */
- if (pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) {
- if (!dixRegisterScreenSpecificPrivateKey
- (pScreen, &pExaScr->pixmapPrivateKeyRec, PRIVATE_PIXMAP,
- sizeof(ExaPixmapPrivRec))) {
- LogMessage(X_WARNING,
- "EXA(%d): Failed to allocate pixmap private\n",
- pScreen->myNum);
- return FALSE;
- }
- if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS) {
- if (pExaScr->info->flags & EXA_MIXED_PIXMAPS) {
- wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_mixed);
- wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_mixed);
- wrap(pExaScr, pScreen, ModifyPixmapHeader,
- exaModifyPixmapHeader_mixed);
- wrap(pExaScr, pScreen, SharePixmapBacking, exaSharePixmapBacking_mixed);
- wrap(pExaScr, pScreen, SetSharedPixmapBacking, exaSetSharedPixmapBacking_mixed);
-
- pExaScr->do_migration = exaDoMigration_mixed;
- pExaScr->pixmap_has_gpu_copy = exaPixmapHasGpuCopy_mixed;
- pExaScr->do_move_in_pixmap = exaMoveInPixmap_mixed;
- pExaScr->do_move_out_pixmap = NULL;
- pExaScr->prepare_access_reg = exaPrepareAccessReg_mixed;
- }
- else {
- wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_driver);
- wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_driver);
- wrap(pExaScr, pScreen, ModifyPixmapHeader,
- exaModifyPixmapHeader_driver);
- pExaScr->do_migration = NULL;
- pExaScr->pixmap_has_gpu_copy = exaPixmapHasGpuCopy_driver;
- pExaScr->do_move_in_pixmap = NULL;
- pExaScr->do_move_out_pixmap = NULL;
- pExaScr->prepare_access_reg = NULL;
- }
- }
- else {
- wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_classic);
- wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_classic);
- wrap(pExaScr, pScreen, ModifyPixmapHeader,
- exaModifyPixmapHeader_classic);
- pExaScr->do_migration = exaDoMigration_classic;
- pExaScr->pixmap_has_gpu_copy = exaPixmapHasGpuCopy_classic;
- pExaScr->do_move_in_pixmap = exaMoveInPixmap_classic;
- pExaScr->do_move_out_pixmap = exaMoveOutPixmap_classic;
- pExaScr->prepare_access_reg = exaPrepareAccessReg_classic;
- }
- if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
- LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %lu bytes\n",
- pScreen->myNum,
- pExaScr->info->memorySize -
- pExaScr->info->offScreenBase);
- }
- else {
- LogMessage(X_INFO, "EXA(%d): Driver allocated offscreen pixmaps\n",
- pScreen->myNum);
-
- }
- }
- else
- LogMessage(X_INFO, "EXA(%d): No offscreen pixmaps\n", pScreen->myNum);
-
- if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
- DBG_PIXMAP(("============== %ld < %ld\n", pExaScr->info->offScreenBase,
- pExaScr->info->memorySize));
- if (pExaScr->info->offScreenBase < pExaScr->info->memorySize) {
- if (!exaOffscreenInit(pScreen)) {
- LogMessage(X_WARNING,
- "EXA(%d): Offscreen pixmap setup failed\n",
- pScreen->myNum);
- return FALSE;
- }
- }
- }
-
- if (ps->Glyphs == exaGlyphs)
- exaGlyphsInit(pScreen);
-
- LogMessage(X_INFO, "EXA(%d): Driver registered support for the following"
- " operations:\n", pScreen->myNum);
- assert(pScreenInfo->PrepareSolid != NULL);
- LogMessage(X_INFO, " Solid\n");
- assert(pScreenInfo->PrepareCopy != NULL);
- LogMessage(X_INFO, " Copy\n");
- if (pScreenInfo->PrepareComposite != NULL) {
- LogMessage(X_INFO, " Composite (RENDER acceleration)\n");
- }
- if (pScreenInfo->UploadToScreen != NULL) {
- LogMessage(X_INFO, " UploadToScreen\n");
- }
- if (pScreenInfo->DownloadFromScreen != NULL) {
- LogMessage(X_INFO, " DownloadFromScreen\n");
- }
-
- return TRUE;
-}
-
-/**
- * exaDriverFini tears down EXA on a given screen.
- *
- * @param pScreen screen being torn down.
- */
-void
-exaDriverFini(ScreenPtr pScreen)
-{
- /*right now does nothing */
-}
-
-/**
- * exaMarkSync() should be called after any asynchronous drawing by the hardware.
- *
- * @param pScreen screen which drawing occurred on
- *
- * exaMarkSync() sets a flag to indicate that some asynchronous drawing has
- * happened and a WaitSync() will be necessary before relying on the contents of
- * offscreen memory from the CPU's perspective. It also calls an optional
- * driver MarkSync() callback, the return value of which may be used to do partial
- * synchronization with the hardware in the future.
- */
-void
-exaMarkSync(ScreenPtr pScreen)
-{
- ExaScreenPriv(pScreen);
-
- pExaScr->info->needsSync = TRUE;
- if (pExaScr->info->MarkSync != NULL) {
- pExaScr->info->lastMarker = (*pExaScr->info->MarkSync) (pScreen);
- }
-}
-
-/**
- * exaWaitSync() ensures that all drawing has been completed.
- *
- * @param pScreen screen being synchronized.
- *
- * Calls down into the driver to ensure that all previous drawing has completed.
- * It should always be called before relying on the framebuffer contents
- * reflecting previous drawing, from a CPU perspective.
- */
-void
-exaWaitSync(ScreenPtr pScreen)
-{
- ExaScreenPriv(pScreen);
-
- if (pExaScr->info->needsSync && !pExaScr->swappedOut) {
- (*pExaScr->info->WaitMarker) (pScreen, pExaScr->info->lastMarker);
- pExaScr->info->needsSync = FALSE;
- }
-}
-
-/**
- * Performs migration of the pixmaps according to the operation information
- * provided in pixmaps and can_accel and the migration scheme chosen in the
- * config file.
- */
-void
-exaDoMigration(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
-{
- ScreenPtr pScreen = pixmaps[0].pPix->drawable.pScreen;
-
- ExaScreenPriv(pScreen);
-
- if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS))
- return;
-
- if (pExaScr->do_migration)
- (*pExaScr->do_migration) (pixmaps, npixmaps, can_accel);
-}
-
-void
-exaMoveInPixmap(PixmapPtr pPixmap)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
-
- ExaScreenPriv(pScreen);
-
- if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS))
- return;
-
- if (pExaScr->do_move_in_pixmap)
- (*pExaScr->do_move_in_pixmap) (pPixmap);
-}
-
-void
-exaMoveOutPixmap(PixmapPtr pPixmap)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
-
- ExaScreenPriv(pScreen);
-
- if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS))
- return;
-
- if (pExaScr->do_move_out_pixmap)
- (*pExaScr->do_move_out_pixmap) (pPixmap);
-}
diff --git a/exa/exa.h b/exa/exa.h
deleted file mode 100644
index fba06ca0f..000000000
--- a/exa/exa.h
+++ /dev/null
@@ -1,820 +0,0 @@
-/*
- *
- * Copyright (C) 2000 Keith Packard
- * 2004 Eric Anholt
- * 2005 Zack Rusin
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of copyright holders not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Copyright holders make no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-/** @file
- * This is the header containing the public API of EXA for exa drivers.
- */
-
-#ifndef EXA_H
-#define EXA_H
-
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "gcstruct.h"
-#include "picturestr.h"
-#include "fb.h"
-
-#define EXA_VERSION_MAJOR 2
-#define EXA_VERSION_MINOR 6
-#define EXA_VERSION_RELEASE 0
-
-typedef struct _ExaOffscreenArea ExaOffscreenArea;
-
-typedef void (*ExaOffscreenSaveProc) (ScreenPtr pScreen,
- ExaOffscreenArea * area);
-
-typedef enum _ExaOffscreenState {
- ExaOffscreenAvail,
- ExaOffscreenRemovable,
- ExaOffscreenLocked
-} ExaOffscreenState;
-
-struct _ExaOffscreenArea {
- int base_offset; /* allocation base */
- int offset; /* aligned offset */
- int size; /* total allocation size */
- unsigned last_use;
- void *privData;
-
- ExaOffscreenSaveProc save;
-
- ExaOffscreenState state;
-
- ExaOffscreenArea *next;
-
- unsigned eviction_cost;
-
- ExaOffscreenArea *prev; /* Double-linked list for defragmentation */
- int align; /* required alignment */
-};
-
-/**
- * The ExaDriver structure is allocated through exaDriverAlloc(), and then
- * fllled in by drivers.
- */
-typedef struct _ExaDriver {
- /**
- * exa_major and exa_minor should be set by the driver to the version of
- * EXA which the driver was compiled for (or configures itself at runtime
- * to support). This allows EXA to extend the structure for new features
- * without breaking ABI for drivers compiled against older versions.
- */
- int exa_major, exa_minor;
-
- /**
- * memoryBase is the address of the beginning of framebuffer memory.
- * The visible screen should be within memoryBase to memoryBase +
- * memorySize.
- */
- CARD8 *memoryBase;
-
- /**
- * offScreenBase is the offset from memoryBase of the beginning of the area
- * to be managed by EXA's linear offscreen memory manager.
- *
- * In XFree86 DDX drivers, this is probably:
- * (pScrn->displayWidth * cpp * pScrn->virtualY)
- */
- unsigned long offScreenBase;
-
- /**
- * memorySize is the length (in bytes) of framebuffer memory beginning
- * from memoryBase.
- *
- * The offscreen memory manager will manage the area beginning at
- * (memoryBase + offScreenBase), with a length of (memorySize -
- * offScreenBase)
- *
- * In XFree86 DDX drivers, this is probably (pScrn->videoRam * 1024)
- */
- unsigned long memorySize;
-
- /**
- * pixmapOffsetAlign is the byte alignment necessary for pixmap offsets
- * within framebuffer.
- *
- * Hardware typically has a required alignment of offsets, which may or may
- * not be a power of two. EXA will ensure that pixmaps managed by the
- * offscreen memory manager meet this alignment requirement.
- */
- int pixmapOffsetAlign;
-
- /**
- * pixmapPitchAlign is the byte alignment necessary for pixmap pitches
- * within the framebuffer.
- *
- * Hardware typically has a required alignment of pitches for acceleration.
- * For 3D hardware, Composite acceleration often requires that source and
- * mask pixmaps (textures) have a power-of-two pitch, which can be demanded
- * using EXA_OFFSCREEN_ALIGN_POT. These pitch requirements only apply to
- * pixmaps managed by the offscreen memory manager. Thus, it is up to the
- * driver to ensure that the visible screen has an appropriate pitch for
- * acceleration.
- */
- int pixmapPitchAlign;
-
- /**
- * The flags field is bitfield of boolean values controlling EXA's behavior.
- *
- * The flags include EXA_OFFSCREEN_PIXMAPS, EXA_OFFSCREEN_ALIGN_POT, and
- * EXA_TWO_BITBLT_DIRECTIONS.
- */
- int flags;
-
- /** @{ */
- /**
- * maxX controls the X coordinate limitation for rendering from the card.
- * The driver should never receive a request for rendering beyond maxX
- * in the X direction from the origin of a pixmap.
- */
- int maxX;
-
- /**
- * maxY controls the Y coordinate limitation for rendering from the card.
- * The driver should never receive a request for rendering beyond maxY
- * in the Y direction from the origin of a pixmap.
- */
- int maxY;
- /** @} */
-
- /* private */
- ExaOffscreenArea *offScreenAreas;
- Bool needsSync;
- int lastMarker;
-
- /** @name Solid
- * @{
- */
- /**
- * PrepareSolid() sets up the driver for doing a solid fill.
- * @param pPixmap Destination pixmap
- * @param alu raster operation
- * @param planemask write mask for the fill
- * @param fg "foreground" color for the fill
- *
- * This call should set up the driver for doing a series of solid fills
- * through the Solid() call. The alu raster op is one of the GX*
- * graphics functions listed in X.h, and typically maps to a similar
- * single-byte "ROP" setting in all hardware. The planemask controls
- * which bits of the destination should be affected, and will only represent
- * the bits up to the depth of pPixmap. The fg is the pixel value of the
- * foreground color referred to in ROP descriptions.
- *
- * Note that many drivers will need to store some of the data in the driver
- * private record, for sending to the hardware with each drawing command.
- *
- * The PrepareSolid() call is required of all drivers, but it may fail for any
- * reason. Failure results in a fallback to software rendering.
- */
- Bool (*PrepareSolid) (PixmapPtr pPixmap,
- int alu, Pixel planemask, Pixel fg);
-
- /**
- * Solid() performs a solid fill set up in the last PrepareSolid() call.
- *
- * @param pPixmap destination pixmap
- * @param x1 left coordinate
- * @param y1 top coordinate
- * @param x2 right coordinate
- * @param y2 bottom coordinate
- *
- * Performs the fill set up by the last PrepareSolid() call, covering the
- * area from (x1,y1) to (x2,y2) in pPixmap. Note that the coordinates are
- * in the coordinate space of the destination pixmap, so the driver will
- * need to set up the hardware's offset and pitch for the destination
- * coordinates according to the pixmap's offset and pitch within
- * framebuffer. This likely means using exaGetPixmapOffset() and
- * exaGetPixmapPitch().
- *
- * This call is required if PrepareSolid() ever succeeds.
- */
- void (*Solid) (PixmapPtr pPixmap, int x1, int y1, int x2, int y2);
-
- /**
- * DoneSolid() finishes a set of solid fills.
- *
- * @param pPixmap destination pixmap.
- *
- * The DoneSolid() call is called at the end of a series of consecutive
- * Solid() calls following a successful PrepareSolid(). This allows drivers
- * to finish up emitting drawing commands that were buffered, or clean up
- * state from PrepareSolid().
- *
- * This call is required if PrepareSolid() ever succeeds.
- */
- void (*DoneSolid) (PixmapPtr pPixmap);
- /** @} */
-
- /** @name Copy
- * @{
- */
- /**
- * PrepareCopy() sets up the driver for doing a copy within video
- * memory.
- *
- * @param pSrcPixmap source pixmap
- * @param pDstPixmap destination pixmap
- * @param dx X copy direction
- * @param dy Y copy direction
- * @param alu raster operation
- * @param planemask write mask for the fill
- *
- * This call should set up the driver for doing a series of copies from the
- * the pSrcPixmap to the pDstPixmap. The dx flag will be positive if the
- * hardware should do the copy from the left to the right, and dy will be
- * positive if the copy should be done from the top to the bottom. This
- * is to deal with self-overlapping copies when pSrcPixmap == pDstPixmap.
- * If your hardware can only support blits that are (left to right, top to
- * bottom) or (right to left, bottom to top), then you should set
- * #EXA_TWO_BITBLT_DIRECTIONS, and EXA will break down Copy operations to
- * ones that meet those requirements. The alu raster op is one of the GX*
- * graphics functions listed in X.h, and typically maps to a similar
- * single-byte "ROP" setting in all hardware. The planemask controls which
- * bits of the destination should be affected, and will only represent the
- * bits up to the depth of pPixmap.
- *
- * Note that many drivers will need to store some of the data in the driver
- * private record, for sending to the hardware with each drawing command.
- *
- * The PrepareCopy() call is required of all drivers, but it may fail for any
- * reason. Failure results in a fallback to software rendering.
- */
- Bool (*PrepareCopy) (PixmapPtr pSrcPixmap,
- PixmapPtr pDstPixmap,
- int dx, int dy, int alu, Pixel planemask);
-
- /**
- * Copy() performs a copy set up in the last PrepareCopy call.
- *
- * @param pDstPixmap destination pixmap
- * @param srcX source X coordinate
- * @param srcY source Y coordinate
- * @param dstX destination X coordinate
- * @param dstY destination Y coordinate
- * @param width width of the rectangle to be copied
- * @param height height of the rectangle to be copied.
- *
- * Performs the copy set up by the last PrepareCopy() call, copying the
- * rectangle from (srcX, srcY) to (srcX + width, srcY + width) in the source
- * pixmap to the same-sized rectangle at (dstX, dstY) in the destination
- * pixmap. Those rectangles may overlap in memory, if
- * pSrcPixmap == pDstPixmap. Note that this call does not receive the
- * pSrcPixmap as an argument -- if it's needed in this function, it should
- * be stored in the driver private during PrepareCopy(). As with Solid(),
- * the coordinates are in the coordinate space of each pixmap, so the driver
- * will need to set up source and destination pitches and offsets from those
- * pixmaps, probably using exaGetPixmapOffset() and exaGetPixmapPitch().
- *
- * This call is required if PrepareCopy ever succeeds.
- */
- void (*Copy) (PixmapPtr pDstPixmap,
- int srcX,
- int srcY, int dstX, int dstY, int width, int height);
-
- /**
- * DoneCopy() finishes a set of copies.
- *
- * @param pPixmap destination pixmap.
- *
- * The DoneCopy() call is called at the end of a series of consecutive
- * Copy() calls following a successful PrepareCopy(). This allows drivers
- * to finish up emitting drawing commands that were buffered, or clean up
- * state from PrepareCopy().
- *
- * This call is required if PrepareCopy() ever succeeds.
- */
- void (*DoneCopy) (PixmapPtr pDstPixmap);
- /** @} */
-
- /** @name Composite
- * @{
- */
- /**
- * CheckComposite() checks to see if a composite operation could be
- * accelerated.
- *
- * @param op Render operation
- * @param pSrcPicture source Picture
- * @param pMaskPicture mask picture
- * @param pDstPicture destination Picture
- *
- * The CheckComposite() call checks if the driver could handle acceleration
- * of op with the given source, mask, and destination pictures. This allows
- * drivers to check source and destination formats, supported operations,
- * transformations, and component alpha state, and send operations it can't
- * support to software rendering early on. This avoids costly pixmap
- * migration to the wrong places when the driver can't accelerate
- * operations. Note that because migration hasn't happened, the driver
- * can't know during CheckComposite() what the offsets and pitches of the
- * pixmaps are going to be.
- *
- * See PrepareComposite() for more details on likely issues that drivers
- * will have in accelerating Composite operations.
- *
- * The CheckComposite() call is recommended if PrepareComposite() is
- * implemented, but is not required.
- */
- Bool (*CheckComposite) (int op,
- PicturePtr pSrcPicture,
- PicturePtr pMaskPicture, PicturePtr pDstPicture);
-
- /**
- * PrepareComposite() sets up the driver for doing a Composite operation
- * described in the Render extension protocol spec.
- *
- * @param op Render operation
- * @param pSrcPicture source Picture
- * @param pMaskPicture mask picture
- * @param pDstPicture destination Picture
- * @param pSrc source pixmap
- * @param pMask mask pixmap
- * @param pDst destination pixmap
- *
- * This call should set up the driver for doing a series of Composite
- * operations, as described in the Render protocol spec, with the given
- * pSrcPicture, pMaskPicture, and pDstPicture. The pSrc, pMask, and
- * pDst are the pixmaps containing the pixel data, and should be used for
- * setting the offset and pitch used for the coordinate spaces for each of
- * the Pictures.
- *
- * Notes on interpreting Picture structures:
- * - The Picture structures will always have a valid pDrawable.
- * - The Picture structures will never have alphaMap set.
- * - The mask Picture (and therefore pMask) may be NULL, in which case the
- * operation is simply src OP dst instead of src IN mask OP dst, and
- * mask coordinates should be ignored.
- * - pMarkPicture may have componentAlpha set, which greatly changes
- * the behavior of the Composite operation. componentAlpha has no effect
- * when set on pSrcPicture or pDstPicture.
- * - The source and mask Pictures may have a transformation set
- * (Picture->transform != NULL), which means that the source coordinates
- * should be transformed by that transformation, resulting in scaling,
- * rotation, etc. The PictureTransformPoint() call can transform
- * coordinates for you. Transforms have no effect on Pictures when used
- * as a destination.
- * - The source and mask pictures may have a filter set. PictFilterNearest
- * and PictFilterBilinear are defined in the Render protocol, but others
- * may be encountered, and must be handled correctly (usually by
- * PrepareComposite failing, and falling back to software). Filters have
- * no effect on Pictures when used as a destination.
- * - The source and mask Pictures may have repeating set, which must be
- * respected. Many chipsets will be unable to support repeating on
- * pixmaps that have a width or height that is not a power of two.
- *
- * If your hardware can't support source pictures (textures) with
- * non-power-of-two pitches, you should set #EXA_OFFSCREEN_ALIGN_POT.
- *
- * Note that many drivers will need to store some of the data in the driver
- * private record, for sending to the hardware with each drawing command.
- *
- * The PrepareComposite() call is not required. However, it is highly
- * recommended for performance of antialiased font rendering and performance
- * of cairo applications. Failure results in a fallback to software
- * rendering.
- */
- Bool (*PrepareComposite) (int op,
- PicturePtr pSrcPicture,
- PicturePtr pMaskPicture,
- PicturePtr pDstPicture,
- PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst);
-
- /**
- * Composite() performs a Composite operation set up in the last
- * PrepareComposite() call.
- *
- * @param pDstPixmap destination pixmap
- * @param srcX source X coordinate
- * @param srcY source Y coordinate
- * @param maskX source X coordinate
- * @param maskY source Y coordinate
- * @param dstX destination X coordinate
- * @param dstY destination Y coordinate
- * @param width destination rectangle width
- * @param height destination rectangle height
- *
- * Performs the Composite operation set up by the last PrepareComposite()
- * call, to the rectangle from (dstX, dstY) to (dstX + width, dstY + height)
- * in the destination Pixmap. Note that if a transformation was set on
- * the source or mask Pictures, the source rectangles may not be the same
- * size as the destination rectangles and filtering. Getting the coordinate
- * transformation right at the subpixel level can be tricky, and rendercheck
- * can test this for you.
- *
- * This call is required if PrepareComposite() ever succeeds.
- */
- void (*Composite) (PixmapPtr pDst,
- int srcX,
- int srcY,
- int maskX,
- int maskY, int dstX, int dstY, int width, int height);
-
- /**
- * DoneComposite() finishes a set of Composite operations.
- *
- * @param pPixmap destination pixmap.
- *
- * The DoneComposite() call is called at the end of a series of consecutive
- * Composite() calls following a successful PrepareComposite(). This allows
- * drivers to finish up emitting drawing commands that were buffered, or
- * clean up state from PrepareComposite().
- *
- * This call is required if PrepareComposite() ever succeeds.
- */
- void (*DoneComposite) (PixmapPtr pDst);
- /** @} */
-
- /**
- * UploadToScreen() loads a rectangle of data from src into pDst.
- *
- * @param pDst destination pixmap
- * @param x destination X coordinate.
- * @param y destination Y coordinate
- * @param width width of the rectangle to be copied
- * @param height height of the rectangle to be copied
- * @param src pointer to the beginning of the source data
- * @param src_pitch pitch (in bytes) of the lines of source data.
- *
- * UploadToScreen() copies data in system memory beginning at src (with
- * pitch src_pitch) into the destination pixmap from (x, y) to
- * (x + width, y + height). This is typically done with hostdata uploads,
- * where the CPU sets up a blit command on the hardware with instructions
- * that the blit data will be fed through some sort of aperture on the card.
- *
- * If UploadToScreen() is performed asynchronously, it is up to the driver
- * to call exaMarkSync(). This is in contrast to most other acceleration
- * calls in EXA.
- *
- * UploadToScreen() can aid in pixmap migration, but is most important for
- * the performance of exaGlyphs() (antialiased font drawing) by allowing
- * pipelining of data uploads, avoiding a sync of the card after each glyph.
- *
- * @return TRUE if the driver successfully uploaded the data. FALSE
- * indicates that EXA should fall back to doing the upload in software.
- *
- * UploadToScreen() is not required, but is recommended if Composite
- * acceleration is supported.
- */
- Bool (*UploadToScreen) (PixmapPtr pDst,
- int x,
- int y, int w, int h, char *src, int src_pitch);
-
- /**
- * UploadToScratch() is no longer used and will be removed next time the EXA
- * major version needs to be bumped.
- */
- Bool (*UploadToScratch) (PixmapPtr pSrc, PixmapPtr pDst);
-
- /**
- * DownloadFromScreen() loads a rectangle of data from pSrc into dst
- *
- * @param pSrc source pixmap
- * @param x source X coordinate.
- * @param y source Y coordinate
- * @param width width of the rectangle to be copied
- * @param height height of the rectangle to be copied
- * @param dst pointer to the beginning of the destination data
- * @param dst_pitch pitch (in bytes) of the lines of destination data.
- *
- * DownloadFromScreen() copies data from offscreen memory in pSrc from
- * (x, y) to (x + width, y + height), to system memory starting at
- * dst (with pitch dst_pitch). This would usually be done
- * using scatter-gather DMA, supported by a DRM call, or by blitting to AGP
- * and then synchronously reading from AGP. Because the implementation
- * might be synchronous, EXA leaves it up to the driver to call
- * exaMarkSync() if DownloadFromScreen() was asynchronous. This is in
- * contrast to most other acceleration calls in EXA.
- *
- * DownloadFromScreen() can aid in the largest bottleneck in pixmap
- * migration, which is the read from framebuffer when evicting pixmaps from
- * framebuffer memory. Thus, it is highly recommended, even though
- * implementations are typically complicated.
- *
- * @return TRUE if the driver successfully downloaded the data. FALSE
- * indicates that EXA should fall back to doing the download in software.
- *
- * DownloadFromScreen() is not required, but is highly recommended.
- */
- Bool (*DownloadFromScreen) (PixmapPtr pSrc,
- int x, int y,
- int w, int h, char *dst, int dst_pitch);
-
- /**
- * MarkSync() requests that the driver mark a synchronization point,
- * returning an driver-defined integer marker which could be requested for
- * synchronization to later in WaitMarker(). This might be used in the
- * future to avoid waiting for full hardware stalls before accessing pixmap
- * data with the CPU, but is not important in the current incarnation of
- * EXA.
- *
- * Note that drivers should call exaMarkSync() when they have done some
- * acceleration, rather than their own MarkSync() handler, as otherwise EXA
- * will be unaware of the driver's acceleration and not sync to it during
- * fallbacks.
- *
- * MarkSync() is optional.
- */
- int (*MarkSync) (ScreenPtr pScreen);
-
- /**
- * WaitMarker() waits for all rendering before the given marker to have
- * completed. If the driver does not implement MarkSync(), marker is
- * meaningless, and all rendering by the hardware should be completed before
- * WaitMarker() returns.
- *
- * Note that drivers should call exaWaitSync() to wait for all acceleration
- * to finish, as otherwise EXA will be unaware of the driver having
- * synchronized, resulting in excessive WaitMarker() calls.
- *
- * WaitMarker() is required of all drivers.
- */
- void (*WaitMarker) (ScreenPtr pScreen, int marker);
-
- /** @{ */
- /**
- * PrepareAccess() is called before CPU access to an offscreen pixmap.
- *
- * @param pPix the pixmap being accessed
- * @param index the index of the pixmap being accessed.
- *
- * PrepareAccess() will be called before CPU access to an offscreen pixmap.
- * This can be used to set up hardware surfaces for byteswapping or
- * untiling, or to adjust the pixmap's devPrivate.ptr for the purpose of
- * making CPU access use a different aperture.
- *
- * The index is one of #EXA_PREPARE_DEST, #EXA_PREPARE_SRC,
- * #EXA_PREPARE_MASK, #EXA_PREPARE_AUX_DEST, #EXA_PREPARE_AUX_SRC, or
- * #EXA_PREPARE_AUX_MASK. Since only up to #EXA_NUM_PREPARE_INDICES pixmaps
- * will have PrepareAccess() called on them per operation, drivers can have
- * a small, statically-allocated space to maintain state for PrepareAccess()
- * and FinishAccess() in. Note that PrepareAccess() is only called once per
- * pixmap and operation, regardless of whether the pixmap is used as a
- * destination and/or source, and the index may not reflect the usage.
- *
- * PrepareAccess() may fail. An example might be the case of hardware that
- * can set up 1 or 2 surfaces for CPU access, but not 3. If PrepareAccess()
- * fails, EXA will migrate the pixmap to system memory.
- * DownloadFromScreen() must be implemented and must not fail if a driver
- * wishes to fail in PrepareAccess(). PrepareAccess() must not fail when
- * pPix is the visible screen, because the visible screen can not be
- * migrated.
- *
- * @return TRUE if PrepareAccess() successfully prepared the pixmap for CPU
- * drawing.
- * @return FALSE if PrepareAccess() is unsuccessful and EXA should use
- * DownloadFromScreen() to migate the pixmap out.
- */
- Bool (*PrepareAccess) (PixmapPtr pPix, int index);
-
- /**
- * FinishAccess() is called after CPU access to an offscreen pixmap.
- *
- * @param pPix the pixmap being accessed
- * @param index the index of the pixmap being accessed.
- *
- * FinishAccess() will be called after finishing CPU access of an offscreen
- * pixmap set up by PrepareAccess(). Note that the FinishAccess() will not be
- * called if PrepareAccess() failed and the pixmap was migrated out.
- */
- void (*FinishAccess) (PixmapPtr pPix, int index);
-
- /**
- * PixmapIsOffscreen() is an optional driver replacement to
- * exaPixmapHasGpuCopy(). Set to NULL if you want the standard behaviour
- * of exaPixmapHasGpuCopy().
- *
- * @param pPix the pixmap
- * @return TRUE if the given drawable is in framebuffer memory.
- *
- * exaPixmapHasGpuCopy() is used to determine if a pixmap is in offscreen
- * memory, meaning that acceleration could probably be done to it, and that it
- * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it
- * with the CPU.
- *
- *
- */
- Bool (*PixmapIsOffscreen) (PixmapPtr pPix);
-
- /** @name PrepareAccess() and FinishAccess() indices
- * @{
- */
- /**
- * EXA_PREPARE_DEST is the index for a pixmap that may be drawn to or
- * read from.
- */
-#define EXA_PREPARE_DEST 0
- /**
- * EXA_PREPARE_SRC is the index for a pixmap that may be read from
- */
-#define EXA_PREPARE_SRC 1
- /**
- * EXA_PREPARE_SRC is the index for a second pixmap that may be read
- * from.
- */
-#define EXA_PREPARE_MASK 2
- /**
- * EXA_PREPARE_AUX* are additional indices for other purposes, e.g.
- * separate alpha maps with Composite operations.
- */
-#define EXA_PREPARE_AUX_DEST 3
-#define EXA_PREPARE_AUX_SRC 4
-#define EXA_PREPARE_AUX_MASK 5
-#define EXA_NUM_PREPARE_INDICES 6
- /** @} */
-
- /**
- * maxPitchPixels controls the pitch limitation for rendering from
- * the card.
- * The driver should never receive a request for rendering a pixmap
- * that has a pitch (in pixels) beyond maxPitchPixels.
- *
- * Setting this field is optional -- if your hardware doesn't have
- * a pitch limitation in pixels, don't set this. If neither this value
- * nor maxPitchBytes is set, then maxPitchPixels is set to maxX.
- * If set, it must not be smaller than maxX.
- *
- * @sa maxPitchBytes
- */
- int maxPitchPixels;
-
- /**
- * maxPitchBytes controls the pitch limitation for rendering from
- * the card.
- * The driver should never receive a request for rendering a pixmap
- * that has a pitch (in bytes) beyond maxPitchBytes.
- *
- * Setting this field is optional -- if your hardware doesn't have
- * a pitch limitation in bytes, don't set this.
- * If set, it must not be smaller than maxX * 4.
- * There's no default value for maxPitchBytes.
- *
- * @sa maxPitchPixels
- */
- int maxPitchBytes;
-
- /* Hooks to allow driver to its own pixmap memory management */
- void *(*CreatePixmap) (ScreenPtr pScreen, int size, int align);
- void (*DestroyPixmap) (ScreenPtr pScreen, void *driverPriv);
- /**
- * Returning a pixmap with non-NULL devPrivate.ptr implies a pixmap which is
- * not offscreen, which will never be accelerated and Prepare/FinishAccess won't
- * be called.
- */
- Bool (*ModifyPixmapHeader) (PixmapPtr pPixmap, int width, int height,
- int depth, int bitsPerPixel, int devKind,
- void *pPixData);
-
- /* hooks for drivers with tiling support:
- * driver MUST fill out new_fb_pitch with valid pitch of pixmap
- */
- void *(*CreatePixmap2) (ScreenPtr pScreen, int width, int height,
- int depth, int usage_hint, int bitsPerPixel,
- int *new_fb_pitch);
- /** @} */
- Bool (*SharePixmapBacking)(PixmapPtr pPixmap, ScreenPtr secondary, void **handle_p);
-
- Bool (*SetSharedPixmapBacking)(PixmapPtr pPixmap, void *handle);
-
-} ExaDriverRec, *ExaDriverPtr;
-
-/** @name EXA driver flags
- * @{
- */
-/**
- * EXA_OFFSCREEN_PIXMAPS indicates to EXA that the driver can support
- * offscreen pixmaps.
- */
-#define EXA_OFFSCREEN_PIXMAPS (1 << 0)
-
-/**
- * EXA_OFFSCREEN_ALIGN_POT indicates to EXA that the driver needs pixmaps
- * to have a power-of-two pitch.
- */
-#define EXA_OFFSCREEN_ALIGN_POT (1 << 1)
-
-/**
- * EXA_TWO_BITBLT_DIRECTIONS indicates to EXA that the driver can only
- * support copies that are (left-to-right, top-to-bottom) or
- * (right-to-left, bottom-to-top).
- */
-#define EXA_TWO_BITBLT_DIRECTIONS (1 << 2)
-
-/**
- * EXA_HANDLES_PIXMAPS indicates to EXA that the driver can handle
- * all pixmap addressing and migration.
- */
-#define EXA_HANDLES_PIXMAPS (1 << 3)
-
-/**
- * EXA_SUPPORTS_PREPARE_AUX indicates to EXA that the driver can handle the
- * EXA_PREPARE_AUX* indices in the Prepare/FinishAccess hooks. If there are no
- * such hooks, this flag has no effect.
- */
-#define EXA_SUPPORTS_PREPARE_AUX (1 << 4)
-
-/**
- * EXA_SUPPORTS_OFFSCREEN_OVERLAPS indicates to EXA that the driver Copy hooks
- * can handle the source and destination occupying overlapping offscreen memory
- * areas. This allows the offscreen memory defragmentation code to defragment
- * areas where the defragmented position overlaps the fragmented position.
- *
- * Typically this is supported by traditional 2D engines but not by 3D engines.
- */
-#define EXA_SUPPORTS_OFFSCREEN_OVERLAPS (1 << 5)
-
-/**
- * EXA_MIXED_PIXMAPS will hide unacceleratable pixmaps from drivers and manage the
- * problem known software fallbacks like trapezoids. This only migrates pixmaps one way
- * into a driver pixmap and then pins it.
- */
-#define EXA_MIXED_PIXMAPS (1 << 6)
-
-/** @} */
-
-/* in exa.c */
-extern _X_EXPORT ExaDriverPtr exaDriverAlloc(void);
-
-extern _X_EXPORT Bool
- exaDriverInit(ScreenPtr pScreen, ExaDriverPtr pScreenInfo);
-
-extern _X_EXPORT void
- exaDriverFini(ScreenPtr pScreen);
-
-extern _X_EXPORT void
- exaMarkSync(ScreenPtr pScreen);
-extern _X_EXPORT void
- exaWaitSync(ScreenPtr pScreen);
-
-extern _X_EXPORT unsigned long
- exaGetPixmapOffset(PixmapPtr pPix);
-
-extern _X_EXPORT unsigned long
- exaGetPixmapPitch(PixmapPtr pPix);
-
-extern _X_EXPORT unsigned long
- exaGetPixmapSize(PixmapPtr pPix);
-
-extern _X_EXPORT void *exaGetPixmapDriverPrivate(PixmapPtr p);
-
-/* in exa_offscreen.c */
-extern _X_EXPORT ExaOffscreenArea *exaOffscreenAlloc(ScreenPtr pScreen,
- int size, int align,
- Bool locked,
- ExaOffscreenSaveProc save,
- void *privData);
-
-extern _X_EXPORT ExaOffscreenArea *exaOffscreenFree(ScreenPtr pScreen,
- ExaOffscreenArea * area);
-
-extern _X_EXPORT void
- ExaOffscreenMarkUsed(PixmapPtr pPixmap);
-
-extern _X_EXPORT void
- exaEnableDisableFBAccess(ScreenPtr pScreen, Bool enable);
-
-extern _X_EXPORT Bool
- exaDrawableIsOffscreen(DrawablePtr pDrawable);
-
-/* in exa.c */
-extern _X_EXPORT void
- exaMoveInPixmap(PixmapPtr pPixmap);
-
-extern _X_EXPORT void
- exaMoveOutPixmap(PixmapPtr pPixmap);
-
-/* in exa_unaccel.c */
-extern _X_EXPORT CARD32
- exaGetPixmapFirstPixel(PixmapPtr pPixmap);
-
-/**
- * Returns TRUE if the given planemask covers all the significant bits in the
- * pixel values for pDrawable.
- */
-#define EXA_PM_IS_SOLID(_pDrawable, _pm) \
- (((_pm) & FbFullMask((_pDrawable)->depth)) == \
- FbFullMask((_pDrawable)->depth))
-
-#endif /* EXA_H */
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
deleted file mode 100644
index e632331da..000000000
--- a/exa/exa_accel.c
+++ /dev/null
@@ -1,1297 +0,0 @@
-/*
- * Copyright © 2001 Keith Packard
- *
- * Partly based on code that is Copyright © The XFree86 Project Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Authors:
- * Eric Anholt <eric@anholt.net>
- * Michel Dänzer <michel@tungstengraphics.com>
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-#include "exa_priv.h"
-#include <X11/fonts/fontstruct.h>
-#include "dixfontstr.h"
-#include "exa.h"
-
-static void
-exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
- DDXPointPtr ppt, int *pwidth, int fSorted)
-{
- ScreenPtr pScreen = pDrawable->pScreen;
-
- ExaScreenPriv(pScreen);
- RegionPtr pClip = fbGetCompositeClip(pGC);
- PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
-
- ExaPixmapPriv(pPixmap);
- BoxPtr pextent, pbox;
- int nbox;
- int extentX1, extentX2, extentY1, extentY2;
- int fullX1, fullX2, fullY1;
- int partX1, partX2;
- int off_x, off_y;
-
- if (pExaScr->fallback_counter ||
- pExaScr->swappedOut ||
- pGC->fillStyle != FillSolid || pExaPixmap->accel_blocked) {
- ExaCheckFillSpans(pDrawable, pGC, n, ppt, pwidth, fSorted);
- return;
- }
-
- if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[1];
-
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pPixmap;
- pixmaps[0].pReg = NULL;
-
- exaDoMigration(pixmaps, 1, TRUE);
- }
-
- if (!(pPixmap = exaGetOffscreenPixmap(pDrawable, &off_x, &off_y)) ||
- !(*pExaScr->info->PrepareSolid) (pPixmap,
- pGC->alu,
- pGC->planemask, pGC->fgPixel)) {
- ExaCheckFillSpans(pDrawable, pGC, n, ppt, pwidth, fSorted);
- return;
- }
-
- pextent = RegionExtents(pClip);
- extentX1 = pextent->x1;
- extentY1 = pextent->y1;
- extentX2 = pextent->x2;
- extentY2 = pextent->y2;
- while (n--) {
- fullX1 = ppt->x;
- fullY1 = ppt->y;
- fullX2 = fullX1 + (int) *pwidth;
- ppt++;
- pwidth++;
-
- if (fullY1 < extentY1 || extentY2 <= fullY1)
- continue;
-
- if (fullX1 < extentX1)
- fullX1 = extentX1;
-
- if (fullX2 > extentX2)
- fullX2 = extentX2;
-
- if (fullX1 >= fullX2)
- continue;
-
- nbox = RegionNumRects(pClip);
- if (nbox == 1) {
- (*pExaScr->info->Solid) (pPixmap,
- fullX1 + off_x, fullY1 + off_y,
- fullX2 + off_x, fullY1 + 1 + off_y);
- }
- else {
- pbox = RegionRects(pClip);
- while (nbox--) {
- if (pbox->y1 <= fullY1 && fullY1 < pbox->y2) {
- partX1 = pbox->x1;
- if (partX1 < fullX1)
- partX1 = fullX1;
- partX2 = pbox->x2;
- if (partX2 > fullX2)
- partX2 = fullX2;
- if (partX2 > partX1) {
- (*pExaScr->info->Solid) (pPixmap,
- partX1 + off_x, fullY1 + off_y,
- partX2 + off_x,
- fullY1 + 1 + off_y);
- }
- }
- pbox++;
- }
- }
- }
- (*pExaScr->info->DoneSolid) (pPixmap);
- exaMarkSync(pScreen);
-}
-
-static Bool
-exaDoPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
- int w, int h, int format, char *bits, int src_stride)
-{
- ExaScreenPriv(pDrawable->pScreen);
- PixmapPtr pPix = exaGetDrawablePixmap(pDrawable);
-
- ExaPixmapPriv(pPix);
- RegionPtr pClip;
- BoxPtr pbox;
- int nbox;
- int xoff, yoff;
- int bpp = pDrawable->bitsPerPixel;
- Bool ret = TRUE;
-
- if (pExaScr->fallback_counter || pExaPixmap->accel_blocked ||
- !pExaScr->info->UploadToScreen)
- return FALSE;
-
- /* If there's a system copy, we want to save the result there */
- if (pExaPixmap->pDamage)
- return FALSE;
-
- /* Don't bother with under 8bpp, XYPixmaps. */
- if (format != ZPixmap || bpp < 8)
- return FALSE;
-
- /* Only accelerate copies: no rop or planemask. */
- if (!EXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy)
- return FALSE;
-
- if (pExaScr->swappedOut)
- return FALSE;
-
- if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[1];
-
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pPix;
- pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage);
-
- exaDoMigration(pixmaps, 1, TRUE);
- }
-
- pPix = exaGetOffscreenPixmap(pDrawable, &xoff, &yoff);
-
- if (!pPix)
- return FALSE;
-
- x += pDrawable->x;
- y += pDrawable->y;
-
- pClip = fbGetCompositeClip(pGC);
- for (nbox = RegionNumRects(pClip),
- pbox = RegionRects(pClip); nbox--; pbox++) {
- int x1 = x;
- int y1 = y;
- int x2 = x + w;
- int y2 = y + h;
- char *src;
- Bool ok;
-
- if (x1 < pbox->x1)
- x1 = pbox->x1;
- if (y1 < pbox->y1)
- y1 = pbox->y1;
- if (x2 > pbox->x2)
- x2 = pbox->x2;
- if (y2 > pbox->y2)
- y2 = pbox->y2;
- if (x1 >= x2 || y1 >= y2)
- continue;
-
- src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8);
- ok = pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff,
- x2 - x1, y2 - y1, src, src_stride);
- /* We have to fall back completely, and ignore what has already been completed.
- * Messing with the fb layer directly like we used to is completely unacceptable.
- */
- if (!ok) {
- ret = FALSE;
- break;
- }
- }
-
- if (ret)
- exaMarkSync(pDrawable->pScreen);
-
- return ret;
-}
-
-static void
-exaPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
- int w, int h, int leftPad, int format, char *bits)
-{
- if (!exaDoPutImage(pDrawable, pGC, depth, x, y, w, h, format, bits,
- PixmapBytePad(w, pDrawable->depth)))
- ExaCheckPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format,
- bits);
-}
-
-static Bool inline
-exaCopyNtoNTwoDir(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
- GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy)
-{
- ExaScreenPriv(pDstDrawable->pScreen);
- PixmapPtr pSrcPixmap, pDstPixmap;
- int src_off_x, src_off_y, dst_off_x, dst_off_y;
- int dirsetup;
-
- /* Need to get both pixmaps to call the driver routines */
- pSrcPixmap = exaGetOffscreenPixmap(pSrcDrawable, &src_off_x, &src_off_y);
- pDstPixmap = exaGetOffscreenPixmap(pDstDrawable, &dst_off_x, &dst_off_y);
- if (!pSrcPixmap || !pDstPixmap)
- return FALSE;
-
- /*
- * Now the case of a chip that only supports xdir = ydir = 1 or
- * xdir = ydir = -1, but we have xdir != ydir.
- */
- dirsetup = 0; /* No direction set up yet. */
- for (; nbox; pbox++, nbox--) {
- if (dx >= 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) {
- /* Do a xdir = ydir = -1 blit instead. */
- if (dirsetup != -1) {
- if (dirsetup != 0)
- pExaScr->info->DoneCopy(pDstPixmap);
- dirsetup = -1;
- if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap,
- pDstPixmap,
- -1, -1,
- pGC ? pGC->alu : GXcopy,
- pGC ? pGC->planemask :
- FB_ALLONES))
- return FALSE;
- }
- (*pExaScr->info->Copy) (pDstPixmap,
- src_off_x + pbox->x1 + dx,
- src_off_y + pbox->y1 + dy,
- dst_off_x + pbox->x1,
- dst_off_y + pbox->y1,
- pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
- }
- else if (dx < 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) {
- /* Do a xdir = ydir = 1 blit instead. */
- if (dirsetup != 1) {
- if (dirsetup != 0)
- pExaScr->info->DoneCopy(pDstPixmap);
- dirsetup = 1;
- if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap,
- pDstPixmap,
- 1, 1,
- pGC ? pGC->alu : GXcopy,
- pGC ? pGC->planemask :
- FB_ALLONES))
- return FALSE;
- }
- (*pExaScr->info->Copy) (pDstPixmap,
- src_off_x + pbox->x1 + dx,
- src_off_y + pbox->y1 + dy,
- dst_off_x + pbox->x1,
- dst_off_y + pbox->y1,
- pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
- }
- else if (dx >= 0) {
- /*
- * xdir = 1, ydir = -1.
- * Perform line-by-line xdir = ydir = 1 blits, going up.
- */
- int i;
-
- if (dirsetup != 1) {
- if (dirsetup != 0)
- pExaScr->info->DoneCopy(pDstPixmap);
- dirsetup = 1;
- if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap,
- pDstPixmap,
- 1, 1,
- pGC ? pGC->alu : GXcopy,
- pGC ? pGC->planemask :
- FB_ALLONES))
- return FALSE;
- }
- for (i = pbox->y2 - pbox->y1 - 1; i >= 0; i--)
- (*pExaScr->info->Copy) (pDstPixmap,
- src_off_x + pbox->x1 + dx,
- src_off_y + pbox->y1 + dy + i,
- dst_off_x + pbox->x1,
- dst_off_y + pbox->y1 + i,
- pbox->x2 - pbox->x1, 1);
- }
- else {
- /*
- * xdir = -1, ydir = 1.
- * Perform line-by-line xdir = ydir = -1 blits, going down.
- */
- int i;
-
- if (dirsetup != -1) {
- if (dirsetup != 0)
- pExaScr->info->DoneCopy(pDstPixmap);
- dirsetup = -1;
- if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap,
- pDstPixmap,
- -1, -1,
- pGC ? pGC->alu : GXcopy,
- pGC ? pGC->planemask :
- FB_ALLONES))
- return FALSE;
- }
- for (i = 0; i < pbox->y2 - pbox->y1; i++)
- (*pExaScr->info->Copy) (pDstPixmap,
- src_off_x + pbox->x1 + dx,
- src_off_y + pbox->y1 + dy + i,
- dst_off_x + pbox->x1,
- dst_off_y + pbox->y1 + i,
- pbox->x2 - pbox->x1, 1);
- }
- }
- if (dirsetup != 0)
- pExaScr->info->DoneCopy(pDstPixmap);
- exaMarkSync(pDstDrawable->pScreen);
- return TRUE;
-}
-
-Bool
-exaHWCopyNtoN(DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GCPtr pGC,
- BoxPtr pbox,
- int nbox, int dx, int dy, Bool reverse, Bool upsidedown)
-{
- ExaScreenPriv(pDstDrawable->pScreen);
- PixmapPtr pSrcPixmap, pDstPixmap;
- ExaPixmapPrivPtr pSrcExaPixmap, pDstExaPixmap;
- int src_off_x, src_off_y;
- int dst_off_x, dst_off_y;
- RegionPtr srcregion = NULL, dstregion = NULL;
- xRectangle *rects;
- Bool ret = TRUE;
-
- /* avoid doing copy operations if no boxes */
- if (nbox == 0)
- return TRUE;
-
- pSrcPixmap = exaGetDrawablePixmap(pSrcDrawable);
- pDstPixmap = exaGetDrawablePixmap(pDstDrawable);
-
- exaGetDrawableDeltas(pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y);
- exaGetDrawableDeltas(pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y);
-
- rects = xallocarray(nbox, sizeof(xRectangle));
-
- if (rects) {
- int i;
- int ordering;
-
- for (i = 0; i < nbox; i++) {
- rects[i].x = pbox[i].x1 + dx + src_off_x;
- rects[i].y = pbox[i].y1 + dy + src_off_y;
- rects[i].width = pbox[i].x2 - pbox[i].x1;
- rects[i].height = pbox[i].y2 - pbox[i].y1;
- }
-
- /* This must match the RegionCopy() logic for reversing rect order */
- if (nbox == 1 || (dx > 0 && dy > 0) ||
- (pDstDrawable != pSrcDrawable &&
- (pDstDrawable->type != DRAWABLE_WINDOW ||
- pSrcDrawable->type != DRAWABLE_WINDOW)))
- ordering = CT_YXBANDED;
- else
- ordering = CT_UNSORTED;
-
- srcregion = RegionFromRects(nbox, rects, ordering);
- free(rects);
-
- if (!pGC || !exaGCReadsDestination(pDstDrawable, pGC->planemask,
- pGC->fillStyle, pGC->alu,
- pGC->clientClip != NULL)) {
- dstregion = RegionCreate(NullBox, 0);
- RegionCopy(dstregion, srcregion);
- RegionTranslate(dstregion, dst_off_x - dx - src_off_x,
- dst_off_y - dy - src_off_y);
- }
- }
-
- pSrcExaPixmap = ExaGetPixmapPriv(pSrcPixmap);
- pDstExaPixmap = ExaGetPixmapPriv(pDstPixmap);
-
- /* Check whether the accelerator can use this pixmap.
- * If the pitch of the pixmaps is out of range, there's nothing
- * we can do but fall back to software rendering.
- */
- if (pSrcExaPixmap->accel_blocked & EXA_RANGE_PITCH ||
- pDstExaPixmap->accel_blocked & EXA_RANGE_PITCH)
- goto fallback;
-
- /* If the width or the height of either of the pixmaps
- * is out of range, check whether the boxes are actually out of the
- * addressable range as well. If they aren't, we can still do
- * the copying in hardware.
- */
- if (pSrcExaPixmap->accel_blocked || pDstExaPixmap->accel_blocked) {
- int i;
-
- for (i = 0; i < nbox; i++) {
- /* src */
- if ((pbox[i].x2 + dx + src_off_x) >= pExaScr->info->maxX ||
- (pbox[i].y2 + dy + src_off_y) >= pExaScr->info->maxY)
- goto fallback;
-
- /* dst */
- if ((pbox[i].x2 + dst_off_x) >= pExaScr->info->maxX ||
- (pbox[i].y2 + dst_off_y) >= pExaScr->info->maxY)
- goto fallback;
- }
- }
-
- if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[2];
-
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pDstPixmap;
- pixmaps[0].pReg = dstregion;
- pixmaps[1].as_dst = FALSE;
- pixmaps[1].as_src = TRUE;
- pixmaps[1].pPix = pSrcPixmap;
- pixmaps[1].pReg = srcregion;
-
- exaDoMigration(pixmaps, 2, TRUE);
- }
-
- /* Mixed directions must be handled specially if the card is lame */
- if ((pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) &&
- reverse != upsidedown) {
- if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
- dx, dy))
- goto out;
- goto fallback;
- }
-
- if (exaPixmapHasGpuCopy(pDstPixmap)) {
- /* Normal blitting. */
- if (exaPixmapHasGpuCopy(pSrcPixmap)) {
- if (!(*pExaScr->info->PrepareCopy)
- (pSrcPixmap, pDstPixmap, reverse ? -1 : 1, upsidedown ? -1 : 1,
- pGC ? pGC->alu : GXcopy, pGC ? pGC->planemask : FB_ALLONES)) {
- goto fallback;
- }
-
- while (nbox--) {
- (*pExaScr->info->Copy) (pDstPixmap,
- pbox->x1 + dx + src_off_x,
- pbox->y1 + dy + src_off_y,
- pbox->x1 + dst_off_x,
- pbox->y1 + dst_off_y,
- pbox->x2 - pbox->x1,
- pbox->y2 - pbox->y1);
- pbox++;
- }
-
- (*pExaScr->info->DoneCopy) (pDstPixmap);
- exaMarkSync(pDstDrawable->pScreen);
- /* UTS: mainly for SHM PutImage's secondary path.
- *
- * Only taking this path for directly accessible pixmaps.
- */
- }
- else if (!pDstExaPixmap->pDamage && pSrcExaPixmap->sys_ptr) {
- int bpp = pSrcDrawable->bitsPerPixel;
- int src_stride = exaGetPixmapPitch(pSrcPixmap);
- CARD8 *src = NULL;
-
- if (!pExaScr->info->UploadToScreen)
- goto fallback;
-
- if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel)
- goto fallback;
-
- if (pSrcDrawable->bitsPerPixel < 8)
- goto fallback;
-
- if (pGC &&
- !(pGC->alu == GXcopy &&
- EXA_PM_IS_SOLID(pSrcDrawable, pGC->planemask)))
- goto fallback;
-
- while (nbox--) {
- src =
- pSrcExaPixmap->sys_ptr + (pbox->y1 + dy +
- src_off_y) * src_stride +
- (pbox->x1 + dx + src_off_x) * (bpp / 8);
- if (!pExaScr->info->
- UploadToScreen(pDstPixmap, pbox->x1 + dst_off_x,
- pbox->y1 + dst_off_y, pbox->x2 - pbox->x1,
- pbox->y2 - pbox->y1, (char *) src,
- src_stride))
- goto fallback;
-
- pbox++;
- }
- }
- else
- goto fallback;
- }
- else
- goto fallback;
-
- goto out;
-
- fallback:
- ret = FALSE;
-
- out:
- if (dstregion) {
- RegionUninit(dstregion);
- RegionDestroy(dstregion);
- }
- if (srcregion) {
- RegionUninit(srcregion);
- RegionDestroy(srcregion);
- }
-
- return ret;
-}
-
-void
-exaCopyNtoN(DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GCPtr pGC,
- BoxPtr pbox,
- int nbox,
- int dx,
- int dy,
- Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
-{
- ExaScreenPriv(pDstDrawable->pScreen);
-
- if (pExaScr->fallback_counter ||
- (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW))
- return;
-
- if (exaHWCopyNtoN
- (pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse,
- upsidedown))
- return;
-
- /* This is a CopyWindow, it's cleaner to fallback at the original call. */
- if (pExaScr->fallback_flags & EXA_ACCEL_COPYWINDOW) {
- pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW;
- return;
- }
-
- /* fallback */
- ExaCheckCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy,
- reverse, upsidedown, bitplane, closure);
-}
-
-RegionPtr
-exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
- int srcx, int srcy, int width, int height, int dstx, int dsty)
-{
- ExaScreenPriv(pDstDrawable->pScreen);
-
- if (pExaScr->fallback_counter || pExaScr->swappedOut) {
- return ExaCheckCopyArea(pSrcDrawable, pDstDrawable, pGC,
- srcx, srcy, width, height, dstx, dsty);
- }
-
- return miDoCopy(pSrcDrawable, pDstDrawable, pGC,
- srcx, srcy, width, height,
- dstx, dsty, exaCopyNtoN, 0, NULL);
-}
-
-static void
-exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
- DDXPointPtr ppt)
-{
- ExaScreenPriv(pDrawable->pScreen);
- int i;
- xRectangle *prect;
-
- /* If we can't reuse the current GC as is, don't bother accelerating the
- * points.
- */
- if (pExaScr->fallback_counter || pGC->fillStyle != FillSolid) {
- ExaCheckPolyPoint(pDrawable, pGC, mode, npt, ppt);
- return;
- }
-
- prect = xallocarray(npt, sizeof(xRectangle));
- for (i = 0; i < npt; i++) {
- prect[i].x = ppt[i].x;
- prect[i].y = ppt[i].y;
- if (i > 0 && mode == CoordModePrevious) {
- prect[i].x += prect[i - 1].x;
- prect[i].y += prect[i - 1].y;
- }
- prect[i].width = 1;
- prect[i].height = 1;
- }
- pGC->ops->PolyFillRect(pDrawable, pGC, npt, prect);
- free(prect);
-}
-
-/**
- * exaPolylines() checks if it can accelerate the lines as a group of
- * horizontal or vertical lines (rectangles), and uses existing rectangle fill
- * acceleration if so.
- */
-static void
-exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
- DDXPointPtr ppt)
-{
- ExaScreenPriv(pDrawable->pScreen);
- xRectangle *prect;
- int x1, x2, y1, y2;
- int i;
-
- if (pExaScr->fallback_counter) {
- ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
- return;
- }
-
- /* Don't try to do wide lines or non-solid fill style. */
- if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid ||
- pGC->fillStyle != FillSolid) {
- ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
- return;
- }
-
- prect = xallocarray(npt - 1, sizeof(xRectangle));
- x1 = ppt[0].x;
- y1 = ppt[0].y;
- /* If we have any non-horizontal/vertical, fall back. */
- for (i = 0; i < npt - 1; i++) {
- if (mode == CoordModePrevious) {
- x2 = x1 + ppt[i + 1].x;
- y2 = y1 + ppt[i + 1].y;
- }
- else {
- x2 = ppt[i + 1].x;
- y2 = ppt[i + 1].y;
- }
-
- if (x1 != x2 && y1 != y2) {
- free(prect);
- ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
- return;
- }
-
- if (x1 < x2) {
- prect[i].x = x1;
- prect[i].width = x2 - x1 + 1;
- }
- else {
- prect[i].x = x2;
- prect[i].width = x1 - x2 + 1;
- }
- if (y1 < y2) {
- prect[i].y = y1;
- prect[i].height = y2 - y1 + 1;
- }
- else {
- prect[i].y = y2;
- prect[i].height = y1 - y2 + 1;
- }
-
- x1 = x2;
- y1 = y2;
- }
- pGC->ops->PolyFillRect(pDrawable, pGC, npt - 1, prect);
- free(prect);
-}
-
-/**
- * exaPolySegment() checks if it can accelerate the lines as a group of
- * horizontal or vertical lines (rectangles), and uses existing rectangle fill
- * acceleration if so.
- */
-static void
-exaPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSeg)
-{
- ExaScreenPriv(pDrawable->pScreen);
- xRectangle *prect;
- int i;
-
- /* Don't try to do wide lines or non-solid fill style. */
- if (pExaScr->fallback_counter || pGC->lineWidth != 0 ||
- pGC->lineStyle != LineSolid || pGC->fillStyle != FillSolid) {
- ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
- return;
- }
-
- /* If we have any non-horizontal/vertical, fall back. */
- for (i = 0; i < nseg; i++) {
- if (pSeg[i].x1 != pSeg[i].x2 && pSeg[i].y1 != pSeg[i].y2) {
- ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
- return;
- }
- }
-
- prect = xallocarray((unsigned int)nseg, sizeof(xRectangle));
- for (i = 0; i < nseg; i++) {
- if (pSeg[i].x1 < pSeg[i].x2) {
- prect[i].x = pSeg[i].x1;
- prect[i].width = pSeg[i].x2 - pSeg[i].x1 + 1;
- }
- else {
- prect[i].x = pSeg[i].x2;
- prect[i].width = pSeg[i].x1 - pSeg[i].x2 + 1;
- }
- if (pSeg[i].y1 < pSeg[i].y2) {
- prect[i].y = pSeg[i].y1;
- prect[i].height = pSeg[i].y2 - pSeg[i].y1 + 1;
- }
- else {
- prect[i].y = pSeg[i].y2;
- prect[i].height = pSeg[i].y1 - pSeg[i].y2 + 1;
- }
-
- /* don't paint last pixel */
- if (pGC->capStyle == CapNotLast) {
- if (prect[i].width == 1)
- prect[i].height--;
- else
- prect[i].width--;
- }
- }
- pGC->ops->PolyFillRect(pDrawable, pGC, nseg, prect);
- free(prect);
-}
-
-static Bool exaFillRegionSolid(DrawablePtr pDrawable, RegionPtr pRegion,
- Pixel pixel, CARD32 planemask, CARD32 alu,
- Bool hasClientClip);
-
-static void
-exaPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrect, xRectangle *prect)
-{
- ExaScreenPriv(pDrawable->pScreen);
- RegionPtr pClip = fbGetCompositeClip(pGC);
- PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
-
- ExaPixmapPriv(pPixmap);
- register BoxPtr pbox;
- BoxPtr pextent;
- int extentX1, extentX2, extentY1, extentY2;
- int fullX1, fullX2, fullY1, fullY2;
- int partX1, partX2, partY1, partY2;
- int xoff, yoff;
- int xorg, yorg;
- int n;
- RegionPtr pReg = RegionFromRects(nrect, prect, CT_UNSORTED);
-
- /* Compute intersection of rects and clip region */
- RegionTranslate(pReg, pDrawable->x, pDrawable->y);
- RegionIntersect(pReg, pClip, pReg);
-
- if (!RegionNumRects(pReg)) {
- goto out;
- }
-
- exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
-
- if (pExaScr->fallback_counter || pExaScr->swappedOut ||
- pExaPixmap->accel_blocked) {
- goto fallback;
- }
-
- /* For ROPs where overlaps don't matter, convert rectangles to region and
- * call exaFillRegion{Solid,Tiled}.
- */
- if ((pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) &&
- (nrect == 1 || pGC->alu == GXcopy || pGC->alu == GXclear ||
- pGC->alu == GXnoop || pGC->alu == GXcopyInverted ||
- pGC->alu == GXset)) {
- if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) &&
- exaFillRegionSolid(pDrawable, pReg, pGC->fillStyle == FillSolid ?
- pGC->fgPixel : pGC->tile.pixel, pGC->planemask,
- pGC->alu, pGC->clientClip != NULL)) ||
- (pGC->fillStyle == FillTiled && !pGC->tileIsPixel &&
- exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg,
- pGC->planemask, pGC->alu,
- pGC->clientClip != NULL))) {
- goto out;
- }
- }
-
- if (pGC->fillStyle != FillSolid &&
- !(pGC->tileIsPixel && pGC->fillStyle == FillTiled)) {
- goto fallback;
- }
-
- if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[1];
-
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pPixmap;
- pixmaps[0].pReg = NULL;
-
- exaDoMigration(pixmaps, 1, TRUE);
- }
-
- if (!exaPixmapHasGpuCopy(pPixmap) ||
- !(*pExaScr->info->PrepareSolid) (pPixmap,
- pGC->alu,
- pGC->planemask, pGC->fgPixel)) {
- fallback:
- ExaCheckPolyFillRect(pDrawable, pGC, nrect, prect);
- goto out;
- }
-
- xorg = pDrawable->x;
- yorg = pDrawable->y;
-
- pextent = RegionExtents(pClip);
- extentX1 = pextent->x1;
- extentY1 = pextent->y1;
- extentX2 = pextent->x2;
- extentY2 = pextent->y2;
- while (nrect--) {
- fullX1 = prect->x + xorg;
- fullY1 = prect->y + yorg;
- fullX2 = fullX1 + (int) prect->width;
- fullY2 = fullY1 + (int) prect->height;
- prect++;
-
- if (fullX1 < extentX1)
- fullX1 = extentX1;
-
- if (fullY1 < extentY1)
- fullY1 = extentY1;
-
- if (fullX2 > extentX2)
- fullX2 = extentX2;
-
- if (fullY2 > extentY2)
- fullY2 = extentY2;
-
- if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
- continue;
- n = RegionNumRects(pClip);
- if (n == 1) {
- (*pExaScr->info->Solid) (pPixmap,
- fullX1 + xoff, fullY1 + yoff,
- fullX2 + xoff, fullY2 + yoff);
- }
- else {
- pbox = RegionRects(pClip);
- /*
- * clip the rectangle to each box in the clip region
- * this is logically equivalent to calling Intersect(),
- * but rectangles may overlap each other here.
- */
- while (n--) {
- partX1 = pbox->x1;
- if (partX1 < fullX1)
- partX1 = fullX1;
- partY1 = pbox->y1;
- if (partY1 < fullY1)
- partY1 = fullY1;
- partX2 = pbox->x2;
- if (partX2 > fullX2)
- partX2 = fullX2;
- partY2 = pbox->y2;
- if (partY2 > fullY2)
- partY2 = fullY2;
-
- pbox++;
-
- if (partX1 < partX2 && partY1 < partY2) {
- (*pExaScr->info->Solid) (pPixmap,
- partX1 + xoff, partY1 + yoff,
- partX2 + xoff, partY2 + yoff);
- }
- }
- }
- }
- (*pExaScr->info->DoneSolid) (pPixmap);
- exaMarkSync(pDrawable->pScreen);
-
- out:
- RegionUninit(pReg);
- RegionDestroy(pReg);
-}
-
-const GCOps exaOps = {
- exaFillSpans,
- ExaCheckSetSpans,
- exaPutImage,
- exaCopyArea,
- ExaCheckCopyPlane,
- exaPolyPoint,
- exaPolylines,
- exaPolySegment,
- miPolyRectangle,
- ExaCheckPolyArc,
- miFillPolygon,
- exaPolyFillRect,
- miPolyFillArc,
- miPolyText8,
- miPolyText16,
- miImageText8,
- miImageText16,
- ExaCheckImageGlyphBlt,
- ExaCheckPolyGlyphBlt,
- ExaCheckPushPixels,
-};
-
-void
-exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
-{
- RegionRec rgnDst;
- int dx, dy;
- PixmapPtr pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
-
- ExaScreenPriv(pWin->drawable.pScreen);
-
- dx = ptOldOrg.x - pWin->drawable.x;
- dy = ptOldOrg.y - pWin->drawable.y;
- RegionTranslate(prgnSrc, -dx, -dy);
-
- RegionInit(&rgnDst, NullBox, 0);
-
- RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc);
-#ifdef COMPOSITE
- if (pPixmap->screen_x || pPixmap->screen_y)
- RegionTranslate(&rgnDst, -pPixmap->screen_x, -pPixmap->screen_y);
-#endif
-
- if (pExaScr->fallback_counter) {
- pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW;
- goto fallback;
- }
-
- pExaScr->fallback_flags |= EXA_ACCEL_COPYWINDOW;
- miCopyRegion(&pPixmap->drawable, &pPixmap->drawable,
- NULL, &rgnDst, dx, dy, exaCopyNtoN, 0, NULL);
- pExaScr->fallback_flags &= ~EXA_ACCEL_COPYWINDOW;
-
- fallback:
- RegionUninit(&rgnDst);
-
- if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW) {
- pExaScr->fallback_flags &= ~EXA_FALLBACK_COPYWINDOW;
- RegionTranslate(prgnSrc, dx, dy);
- ExaCheckCopyWindow(pWin, ptOldOrg, prgnSrc);
- }
-}
-
-static Bool
-exaFillRegionSolid(DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel,
- CARD32 planemask, CARD32 alu, Bool hasClientClip)
-{
- ExaScreenPriv(pDrawable->pScreen);
- PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
-
- ExaPixmapPriv(pPixmap);
- int xoff, yoff;
- Bool ret = FALSE;
-
- exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
- RegionTranslate(pRegion, xoff, yoff);
-
- if (pExaScr->fallback_counter || pExaPixmap->accel_blocked)
- goto out;
-
- if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[1];
-
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pPixmap;
- pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillSolid,
- alu,
- hasClientClip) ? NULL : pRegion;
-
- exaDoMigration(pixmaps, 1, TRUE);
- }
-
- if (exaPixmapHasGpuCopy(pPixmap) &&
- (*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel)) {
- int nbox;
- BoxPtr pBox;
-
- nbox = RegionNumRects(pRegion);
- pBox = RegionRects(pRegion);
-
- while (nbox--) {
- (*pExaScr->info->Solid) (pPixmap, pBox->x1, pBox->y1, pBox->x2,
- pBox->y2);
- pBox++;
- }
- (*pExaScr->info->DoneSolid) (pPixmap);
- exaMarkSync(pDrawable->pScreen);
-
- if (pExaPixmap->pDamage &&
- pExaPixmap->sys_ptr && pDrawable->type == DRAWABLE_PIXMAP &&
- pDrawable->width == 1 && pDrawable->height == 1 &&
- pDrawable->bitsPerPixel != 24 && alu == GXcopy) {
- RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
-
- switch (pDrawable->bitsPerPixel) {
- case 32:
- *(CARD32 *) pExaPixmap->sys_ptr = pixel;
- break;
- case 16:
- *(CARD16 *) pExaPixmap->sys_ptr = pixel;
- break;
- case 8:
- case 4:
- case 1:
- *(CARD8 *) pExaPixmap->sys_ptr = pixel;
- }
-
- RegionUnion(&pExaPixmap->validSys, &pExaPixmap->validSys, pRegion);
- RegionUnion(&pExaPixmap->validFB, &pExaPixmap->validFB, pRegion);
- RegionSubtract(pending_damage, pending_damage, pRegion);
- }
-
- ret = TRUE;
- }
-
- out:
- RegionTranslate(pRegion, -xoff, -yoff);
-
- return ret;
-}
-
-/* Try to do an accelerated tile of the pTile into pRegion of pDrawable.
- * Based on fbFillRegionTiled(), fbTile().
- */
-Bool
-exaFillRegionTiled(DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
- DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu,
- Bool hasClientClip)
-{
- ExaScreenPriv(pDrawable->pScreen);
- PixmapPtr pPixmap;
- ExaPixmapPrivPtr pExaPixmap;
- ExaPixmapPrivPtr pTileExaPixmap = ExaGetPixmapPriv(pTile);
- int xoff, yoff;
- int tileWidth, tileHeight;
- int nbox = RegionNumRects(pRegion);
- BoxPtr pBox = RegionRects(pRegion);
- Bool ret = FALSE;
- int i;
-
- tileWidth = pTile->drawable.width;
- tileHeight = pTile->drawable.height;
-
- /* If we're filling with a solid color, grab it out and go to
- * FillRegionSolid, saving numerous copies.
- */
- if (tileWidth == 1 && tileHeight == 1)
- return exaFillRegionSolid(pDrawable, pRegion,
- exaGetPixmapFirstPixel(pTile), planemask,
- alu, hasClientClip);
-
- pPixmap = exaGetDrawablePixmap(pDrawable);
- pExaPixmap = ExaGetPixmapPriv(pPixmap);
-
- if (pExaScr->fallback_counter || pExaPixmap->accel_blocked ||
- pTileExaPixmap->accel_blocked)
- return FALSE;
-
- if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[2];
-
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pPixmap;
- pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillTiled,
- alu,
- hasClientClip) ? NULL : pRegion;
- pixmaps[1].as_dst = FALSE;
- pixmaps[1].as_src = TRUE;
- pixmaps[1].pPix = pTile;
- pixmaps[1].pReg = NULL;
-
- exaDoMigration(pixmaps, 2, TRUE);
- }
-
- pPixmap = exaGetOffscreenPixmap(pDrawable, &xoff, &yoff);
-
- if (!pPixmap || !exaPixmapHasGpuCopy(pTile))
- return FALSE;
-
- if ((*pExaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu, planemask)) {
- if (xoff || yoff)
- RegionTranslate(pRegion, xoff, yoff);
-
- for (i = 0; i < nbox; i++) {
- int height = pBox[i].y2 - pBox[i].y1;
- int dstY = pBox[i].y1;
- int tileY;
-
- if (alu == GXcopy)
- height = min(height, tileHeight);
-
- modulus(dstY - yoff - pDrawable->y - pPatOrg->y, tileHeight, tileY);
-
- while (height > 0) {
- int width = pBox[i].x2 - pBox[i].x1;
- int dstX = pBox[i].x1;
- int tileX;
- int h = tileHeight - tileY;
-
- if (alu == GXcopy)
- width = min(width, tileWidth);
-
- if (h > height)
- h = height;
- height -= h;
-
- modulus(dstX - xoff - pDrawable->x - pPatOrg->x, tileWidth,
- tileX);
-
- while (width > 0) {
- int w = tileWidth - tileX;
-
- if (w > width)
- w = width;
- width -= w;
-
- (*pExaScr->info->Copy) (pPixmap, tileX, tileY, dstX, dstY,
- w, h);
- dstX += w;
- tileX = 0;
- }
- dstY += h;
- tileY = 0;
- }
- }
- (*pExaScr->info->DoneCopy) (pPixmap);
-
- /* With GXcopy, we only need to do the basic algorithm up to the tile
- * size; then, we can just keep doubling the destination in each
- * direction until it fills the box. This way, the number of copy
- * operations is O(log(rx)) + O(log(ry)) instead of O(rx * ry), where
- * rx/ry is the ratio between box and tile width/height. This can make
- * a big difference if each driver copy incurs a significant constant
- * overhead.
- */
- if (alu != GXcopy)
- ret = TRUE;
- else {
- Bool more_copy = FALSE;
-
- for (i = 0; i < nbox; i++) {
- int dstX = pBox[i].x1 + tileWidth;
- int dstY = pBox[i].y1 + tileHeight;
-
- if ((dstX < pBox[i].x2) || (dstY < pBox[i].y2)) {
- more_copy = TRUE;
- break;
- }
- }
-
- if (more_copy == FALSE)
- ret = TRUE;
-
- if (more_copy && (*pExaScr->info->PrepareCopy) (pPixmap, pPixmap,
- 1, 1, alu,
- planemask)) {
- for (i = 0; i < nbox; i++) {
- int dstX = pBox[i].x1 + tileWidth;
- int dstY = pBox[i].y1 + tileHeight;
- int width = min(pBox[i].x2 - dstX, tileWidth);
- int height = min(pBox[i].y2 - pBox[i].y1, tileHeight);
-
- while (dstX < pBox[i].x2) {
- (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1,
- dstX, pBox[i].y1, width,
- height);
- dstX += width;
- width = min(pBox[i].x2 - dstX, width * 2);
- }
-
- width = pBox[i].x2 - pBox[i].x1;
- height = min(pBox[i].y2 - dstY, tileHeight);
-
- while (dstY < pBox[i].y2) {
- (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1,
- pBox[i].x1, dstY, width,
- height);
- dstY += height;
- height = min(pBox[i].y2 - dstY, height * 2);
- }
- }
-
- (*pExaScr->info->DoneCopy) (pPixmap);
-
- ret = TRUE;
- }
- }
-
- exaMarkSync(pDrawable->pScreen);
-
- if (xoff || yoff)
- RegionTranslate(pRegion, -xoff, -yoff);
- }
-
- return ret;
-}
-
-/**
- * Accelerates GetImage for solid ZPixmap downloads from framebuffer memory.
- *
- * This is probably the only case we actually care about. The rest fall through
- * to migration and fbGetImage, which hopefully will result in migration pushing
- * the pixmap out of framebuffer.
- */
-void
-exaGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
- unsigned int format, unsigned long planeMask, char *d)
-{
- ExaScreenPriv(pDrawable->pScreen);
- PixmapPtr pPix = exaGetDrawablePixmap(pDrawable);
-
- ExaPixmapPriv(pPix);
- int xoff, yoff;
- Bool ok;
-
- if (pExaScr->fallback_counter || pExaScr->swappedOut)
- goto fallback;
-
- /* If there's a system copy, we want to save the result there */
- if (pExaPixmap->pDamage)
- goto fallback;
-
- pPix = exaGetOffscreenPixmap(pDrawable, &xoff, &yoff);
-
- if (pPix == NULL || pExaScr->info->DownloadFromScreen == NULL)
- goto fallback;
-
- /* Only cover the ZPixmap, solid copy case. */
- if (format != ZPixmap || !EXA_PM_IS_SOLID(pDrawable, planeMask))
- goto fallback;
-
- /* Only try to handle the 8bpp and up cases, since we don't want to think
- * about <8bpp.
- */
- if (pDrawable->bitsPerPixel < 8)
- goto fallback;
-
- ok = pExaScr->info->DownloadFromScreen(pPix, pDrawable->x + x + xoff,
- pDrawable->y + y + yoff, w, h, d,
- PixmapBytePad(w, pDrawable->depth));
- if (ok) {
- exaWaitSync(pDrawable->pScreen);
- return;
- }
-
- fallback:
- ExaCheckGetImage(pDrawable, x, y, w, h, format, planeMask, d);
-}
diff --git a/exa/exa_classic.c b/exa/exa_classic.c
deleted file mode 100644
index a6a60e50c..000000000
--- a/exa/exa_classic.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright © 2009 Maarten Maathuis
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <string.h>
-
-#include "exa_priv.h"
-#include "exa.h"
-
-/* This file holds the classic exa specific implementation. */
-
-static _X_INLINE void *
-ExaGetPixmapAddress(PixmapPtr p)
-{
- ExaPixmapPriv(p);
-
- if (pExaPixmap->use_gpu_copy && pExaPixmap->fb_ptr)
- return pExaPixmap->fb_ptr;
- else
- return pExaPixmap->sys_ptr;
-}
-
-/**
- * exaCreatePixmap() creates a new pixmap.
- *
- * If width and height are 0, this won't be a full-fledged pixmap and it will
- * get ModifyPixmapHeader() called on it later. So, we mark it as pinned, because
- * ModifyPixmapHeader() would break migration. These types of pixmaps are used
- * for scratch pixmaps, or to represent the visible screen.
- */
-PixmapPtr
-exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
- unsigned usage_hint)
-{
- PixmapPtr pPixmap;
- ExaPixmapPrivPtr pExaPixmap;
- BoxRec box;
- int bpp;
-
- ExaScreenPriv(pScreen);
-
- if (w > 32767 || h > 32767)
- return NullPixmap;
-
- swap(pExaScr, pScreen, CreatePixmap);
- pPixmap = pScreen->CreatePixmap(pScreen, w, h, depth, usage_hint);
- swap(pExaScr, pScreen, CreatePixmap);
-
- if (!pPixmap)
- return NULL;
-
- pExaPixmap = ExaGetPixmapPriv(pPixmap);
- pExaPixmap->driverPriv = NULL;
-
- bpp = pPixmap->drawable.bitsPerPixel;
-
- pExaPixmap->driverPriv = NULL;
- /* Scratch pixmaps may have w/h equal to zero, and may not be
- * migrated.
- */
- if (!w || !h)
- pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
- else
- pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;
-
- pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
- pExaPixmap->sys_pitch = pPixmap->devKind;
-
- pPixmap->devPrivate.ptr = NULL;
- pExaPixmap->use_gpu_copy = FALSE;
-
- pExaPixmap->fb_ptr = NULL;
- exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp);
- pExaPixmap->fb_size = pExaPixmap->fb_pitch * h;
-
- if (pExaPixmap->fb_pitch > 131071) {
- swap(pExaScr, pScreen, DestroyPixmap);
- pScreen->DestroyPixmap(pPixmap);
- swap(pExaScr, pScreen, DestroyPixmap);
- return NULL;
- }
-
- /* Set up damage tracking */
- pExaPixmap->pDamage = DamageCreate(NULL, NULL,
- DamageReportNone, TRUE,
- pScreen, pPixmap);
-
- if (pExaPixmap->pDamage == NULL) {
- swap(pExaScr, pScreen, DestroyPixmap);
- pScreen->DestroyPixmap(pPixmap);
- swap(pExaScr, pScreen, DestroyPixmap);
- return NULL;
- }
-
- DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
- /* This ensures that pending damage reflects the current operation. */
- /* This is used by exa to optimize migration. */
- DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);
-
- pExaPixmap->area = NULL;
-
- /* We set the initial pixmap as completely valid for a simple reason.
- * Imagine a 1000x1000 pixmap, it has 1 million pixels, 250000 of which
- * could form single pixel rects as part of a region. Setting the complete region
- * as valid is a natural defragmentation of the region.
- */
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = w;
- box.y2 = h;
- RegionInit(&pExaPixmap->validSys, &box, 0);
- RegionInit(&pExaPixmap->validFB, &box, 0);
-
- exaSetAccelBlock(pExaScr, pExaPixmap, w, h, bpp);
-
- /* During a fallback we must prepare access. */
- if (pExaScr->fallback_counter)
- exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
-
- return pPixmap;
-}
-
-Bool
-exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height,
- int depth, int bitsPerPixel, int devKind,
- void *pPixData)
-{
- ScreenPtr pScreen;
- ExaScreenPrivPtr pExaScr;
- ExaPixmapPrivPtr pExaPixmap;
- Bool ret;
-
- if (!pPixmap)
- return FALSE;
-
- pScreen = pPixmap->drawable.pScreen;
- pExaScr = ExaGetScreenPriv(pScreen);
- pExaPixmap = ExaGetPixmapPriv(pPixmap);
-
- if (pExaPixmap) {
- if (pPixData)
- pExaPixmap->sys_ptr = pPixData;
-
- if (devKind > 0)
- pExaPixmap->sys_pitch = devKind;
-
- /* Classic EXA:
- * - Framebuffer.
- * - Scratch pixmap with gpu memory.
- */
- if (pExaScr->info->memoryBase && pPixData) {
- if ((CARD8 *) pPixData >= pExaScr->info->memoryBase &&
- ((CARD8 *) pPixData - pExaScr->info->memoryBase) <
- pExaScr->info->memorySize) {
- pExaPixmap->fb_ptr = pPixData;
- pExaPixmap->fb_pitch = devKind;
- pExaPixmap->use_gpu_copy = TRUE;
- }
- }
-
- if (width > 0 && height > 0 && bitsPerPixel > 0) {
- exaSetFbPitch(pExaScr, pExaPixmap, width, height, bitsPerPixel);
-
- exaSetAccelBlock(pExaScr, pExaPixmap, width, height, bitsPerPixel);
- }
-
- /* Pixmaps subject to ModifyPixmapHeader will be pinned to system or
- * gpu memory, so there's no need to track damage.
- */
- if (pExaPixmap->pDamage) {
- DamageDestroy(pExaPixmap->pDamage);
- pExaPixmap->pDamage = NULL;
- }
- }
-
- swap(pExaScr, pScreen, ModifyPixmapHeader);
- ret = pScreen->ModifyPixmapHeader(pPixmap, width, height, depth,
- bitsPerPixel, devKind, pPixData);
- swap(pExaScr, pScreen, ModifyPixmapHeader);
-
- /* Always NULL this, we don't want lingering pointers. */
- pPixmap->devPrivate.ptr = NULL;
-
- return ret;
-}
-
-Bool
-exaDestroyPixmap_classic(PixmapPtr pPixmap)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
-
- ExaScreenPriv(pScreen);
- Bool ret;
-
- if (pPixmap->refcnt == 1) {
- ExaPixmapPriv(pPixmap);
-
- exaDestroyPixmap(pPixmap);
-
- if (pExaPixmap->area) {
- DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n",
- (void *) pPixmap->drawable.id,
- ExaGetPixmapPriv(pPixmap)->area->offset,
- pPixmap->drawable.width, pPixmap->drawable.height));
- /* Free the offscreen area */
- exaOffscreenFree(pPixmap->drawable.pScreen, pExaPixmap->area);
- pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
- pPixmap->devKind = pExaPixmap->sys_pitch;
- }
- RegionUninit(&pExaPixmap->validSys);
- RegionUninit(&pExaPixmap->validFB);
- }
-
- swap(pExaScr, pScreen, DestroyPixmap);
- ret = pScreen->DestroyPixmap(pPixmap);
- swap(pExaScr, pScreen, DestroyPixmap);
-
- return ret;
-}
-
-Bool
-exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
-
- ExaScreenPriv(pScreen);
- ExaPixmapPriv(pPixmap);
- Bool ret;
-
- if (pExaScr->info->PixmapIsOffscreen) {
- void *old_ptr = pPixmap->devPrivate.ptr;
-
- pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap);
- ret = pExaScr->info->PixmapIsOffscreen(pPixmap);
- pPixmap->devPrivate.ptr = old_ptr;
- }
- else
- ret = (pExaPixmap->use_gpu_copy && pExaPixmap->fb_ptr);
-
- return ret;
-}
diff --git a/exa/exa_driver.c b/exa/exa_driver.c
deleted file mode 100644
index 8799a798e..000000000
--- a/exa/exa_driver.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright © 2009 Maarten Maathuis
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <string.h>
-
-#include "exa_priv.h"
-#include "exa.h"
-
-/* This file holds the driver allocated pixmaps specific implementation. */
-
-static _X_INLINE void *
-ExaGetPixmapAddress(PixmapPtr p)
-{
- ExaPixmapPriv(p);
-
- return pExaPixmap->sys_ptr;
-}
-
-/**
- * exaCreatePixmap() creates a new pixmap.
- *
- * Pixmaps are always marked as pinned, because exa has no control over them.
- */
-PixmapPtr
-exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth,
- unsigned usage_hint)
-{
- PixmapPtr pPixmap;
- ExaPixmapPrivPtr pExaPixmap;
- int bpp;
- size_t paddedWidth, datasize;
-
- ExaScreenPriv(pScreen);
-
- if (w > 32767 || h > 32767)
- return NullPixmap;
-
- swap(pExaScr, pScreen, CreatePixmap);
- pPixmap = pScreen->CreatePixmap(pScreen, 0, 0, depth, usage_hint);
- swap(pExaScr, pScreen, CreatePixmap);
-
- if (!pPixmap)
- return NULL;
-
- pExaPixmap = ExaGetPixmapPriv(pPixmap);
- pExaPixmap->driverPriv = NULL;
-
- bpp = pPixmap->drawable.bitsPerPixel;
-
- /* Set this before driver hooks, to allow for driver pixmaps without gpu
- * memory to back it. These pixmaps have a valid pointer at all times.
- */
- pPixmap->devPrivate.ptr = NULL;
-
- if (pExaScr->info->CreatePixmap2) {
- int new_pitch = 0;
-
- pExaPixmap->driverPriv =
- pExaScr->info->CreatePixmap2(pScreen, w, h, depth, usage_hint, bpp,
- &new_pitch);
- paddedWidth = pExaPixmap->fb_pitch = new_pitch;
- }
- else {
- paddedWidth = ((w * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
- if (paddedWidth / 4 > 32767 || h > 32767)
- return NullPixmap;
-
- exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp);
-
- if (paddedWidth < pExaPixmap->fb_pitch)
- paddedWidth = pExaPixmap->fb_pitch;
- datasize = h * paddedWidth;
- pExaPixmap->driverPriv =
- pExaScr->info->CreatePixmap(pScreen, datasize, 0);
- }
-
- if (!pExaPixmap->driverPriv) {
- swap(pExaScr, pScreen, DestroyPixmap);
- pScreen->DestroyPixmap(pPixmap);
- swap(pExaScr, pScreen, DestroyPixmap);
- return NULL;
- }
-
- /* Allow ModifyPixmapHeader to set sys_ptr appropriately. */
- pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
- pExaPixmap->fb_ptr = NULL;
- pExaPixmap->pDamage = NULL;
- pExaPixmap->sys_ptr = NULL;
-
- (*pScreen->ModifyPixmapHeader) (pPixmap, w, h, 0, 0, paddedWidth, NULL);
-
- pExaPixmap->area = NULL;
-
- exaSetAccelBlock(pExaScr, pExaPixmap, w, h, bpp);
-
- pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
-
- /* During a fallback we must prepare access. */
- if (pExaScr->fallback_counter)
- exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
-
- return pPixmap;
-}
-
-Bool
-exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height,
- int depth, int bitsPerPixel, int devKind,
- void *pPixData)
-{
- ScreenPtr pScreen;
- ExaScreenPrivPtr pExaScr;
- ExaPixmapPrivPtr pExaPixmap;
- Bool ret;
-
- if (!pPixmap)
- return FALSE;
-
- pScreen = pPixmap->drawable.pScreen;
- pExaScr = ExaGetScreenPriv(pScreen);
- pExaPixmap = ExaGetPixmapPriv(pPixmap);
-
- if (pExaPixmap) {
- if (pPixData)
- pExaPixmap->sys_ptr = pPixData;
-
- if (devKind > 0)
- pExaPixmap->sys_pitch = devKind;
-
- if (width > 0 && height > 0 && bitsPerPixel > 0) {
- exaSetFbPitch(pExaScr, pExaPixmap, width, height, bitsPerPixel);
-
- exaSetAccelBlock(pExaScr, pExaPixmap, width, height, bitsPerPixel);
- }
- }
-
- if (pExaScr->info->ModifyPixmapHeader) {
- ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth,
- bitsPerPixel, devKind,
- pPixData);
- /* For EXA_HANDLES_PIXMAPS, we set pPixData to NULL.
- * If pPixmap->devPrivate.ptr is non-NULL, then we've got a
- * !has_gpu_copy pixmap. We need to store the pointer,
- * because PrepareAccess won't be called.
- */
- if (!pPixData && pPixmap->devPrivate.ptr && pPixmap->devKind) {
- pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
- pExaPixmap->sys_pitch = pPixmap->devKind;
- }
- if (ret == TRUE)
- goto out;
- }
-
- swap(pExaScr, pScreen, ModifyPixmapHeader);
- ret = pScreen->ModifyPixmapHeader(pPixmap, width, height, depth,
- bitsPerPixel, devKind, pPixData);
- swap(pExaScr, pScreen, ModifyPixmapHeader);
-
- out:
- /* Always NULL this, we don't want lingering pointers. */
- pPixmap->devPrivate.ptr = NULL;
-
- return ret;
-}
-
-Bool
-exaDestroyPixmap_driver(PixmapPtr pPixmap)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
-
- ExaScreenPriv(pScreen);
- Bool ret;
-
- if (pPixmap->refcnt == 1) {
- ExaPixmapPriv(pPixmap);
-
- exaDestroyPixmap(pPixmap);
-
- if (pExaPixmap->driverPriv)
- pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
- pExaPixmap->driverPriv = NULL;
- }
-
- swap(pExaScr, pScreen, DestroyPixmap);
- ret = pScreen->DestroyPixmap(pPixmap);
- swap(pExaScr, pScreen, DestroyPixmap);
-
- return ret;
-}
-
-Bool
-exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
-
- ExaScreenPriv(pScreen);
- void *saved_ptr;
- Bool ret;
-
- saved_ptr = pPixmap->devPrivate.ptr;
- pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap);
- ret = pExaScr->info->PixmapIsOffscreen(pPixmap);
- pPixmap->devPrivate.ptr = saved_ptr;
-
- return ret;
-}
diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c
deleted file mode 100644
index 192a643cc..000000000
--- a/exa/exa_glyphs.c
+++ /dev/null
@@ -1,839 +0,0 @@
-/*
- * Copyright © 2008 Red Hat, Inc.
- * Partly based on code Copyright © 2000 SuSE, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Red Hat not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. Red Hat makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * Red Hat DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Red Hat
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of SuSE not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. SuSE makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: Owen Taylor <otaylor@fishsoup.net>
- * Based on code by: Keith Packard
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdlib.h>
-
-#include "exa_priv.h"
-
-#include "mipict.h"
-
-#if DEBUG_GLYPH_CACHE
-#define DBG_GLYPH_CACHE(a) ErrorF a
-#else
-#define DBG_GLYPH_CACHE(a)
-#endif
-
-/* Width of the pixmaps we use for the caches; this should be less than
- * max texture size of the driver; this may need to actually come from
- * the driver.
- */
-#define CACHE_PICTURE_WIDTH 1024
-
-/* Maximum number of glyphs we buffer on the stack before flushing
- * rendering to the mask or destination surface.
- */
-#define GLYPH_BUFFER_SIZE 256
-
-typedef struct {
- PicturePtr mask;
- ExaCompositeRectRec rects[GLYPH_BUFFER_SIZE];
- int count;
-} ExaGlyphBuffer, *ExaGlyphBufferPtr;
-
-typedef enum {
- ExaGlyphSuccess, /* Glyph added to render buffer */
- ExaGlyphFail, /* out of memory, etc */
- ExaGlyphNeedFlush, /* would evict a glyph already in the buffer */
-} ExaGlyphCacheResult;
-
-void
-exaGlyphsInit(ScreenPtr pScreen)
-{
- ExaScreenPriv(pScreen);
- int i = 0;
-
- memset(pExaScr->glyphCaches, 0, sizeof(pExaScr->glyphCaches));
-
- pExaScr->glyphCaches[i].format = PICT_a8;
- pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight =
- 16;
- i++;
- pExaScr->glyphCaches[i].format = PICT_a8;
- pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight =
- 32;
- i++;
- pExaScr->glyphCaches[i].format = PICT_a8r8g8b8;
- pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight =
- 16;
- i++;
- pExaScr->glyphCaches[i].format = PICT_a8r8g8b8;
- pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight =
- 32;
- i++;
-
- assert(i == EXA_NUM_GLYPH_CACHES);
-
- for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
- pExaScr->glyphCaches[i].columns =
- CACHE_PICTURE_WIDTH / pExaScr->glyphCaches[i].glyphWidth;
- pExaScr->glyphCaches[i].size = 256;
- pExaScr->glyphCaches[i].hashSize = 557;
- }
-}
-
-static void
-exaUnrealizeGlyphCaches(ScreenPtr pScreen, unsigned int format)
-{
- ExaScreenPriv(pScreen);
- int i;
-
- for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
- ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];
-
- if (cache->format != format)
- continue;
-
- if (cache->picture) {
- FreePicture((void *) cache->picture, (XID) 0);
- cache->picture = NULL;
- }
-
- free(cache->hashEntries);
- cache->hashEntries = NULL;
-
- free(cache->glyphs);
- cache->glyphs = NULL;
- cache->glyphCount = 0;
- }
-}
-
-#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
-
-/* All caches for a single format share a single pixmap for glyph storage,
- * allowing mixing glyphs of different sizes without paying a penalty
- * for switching between mask pixmaps. (Note that for a size of font
- * right at the border between two sizes, we might be switching for almost
- * every glyph.)
- *
- * This function allocates the storage pixmap, and then fills in the
- * rest of the allocated structures for all caches with the given format.
- */
-static Bool
-exaRealizeGlyphCaches(ScreenPtr pScreen, unsigned int format)
-{
- ExaScreenPriv(pScreen);
-
- int depth = PIXMAN_FORMAT_DEPTH(format);
- PictFormatPtr pPictFormat;
- PixmapPtr pPixmap;
- PicturePtr pPicture;
- CARD32 component_alpha;
- int height;
- int i;
- int error;
-
- pPictFormat = PictureMatchFormat(pScreen, depth, format);
- if (!pPictFormat)
- return FALSE;
-
- /* Compute the total vertical size needed for the format */
-
- height = 0;
- for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
- ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];
- int rows;
-
- if (cache->format != format)
- continue;
-
- cache->yOffset = height;
-
- rows = (cache->size + cache->columns - 1) / cache->columns;
- height += rows * cache->glyphHeight;
- }
-
- /* Now allocate the pixmap and picture */
- pPixmap = (*pScreen->CreatePixmap) (pScreen,
- CACHE_PICTURE_WIDTH, height, depth, 0);
- if (!pPixmap)
- return FALSE;
-
- component_alpha = NeedsComponent(pPictFormat->format);
- pPicture = CreatePicture(0, &pPixmap->drawable, pPictFormat,
- CPComponentAlpha, &component_alpha, serverClient,
- &error);
-
- (*pScreen->DestroyPixmap) (pPixmap); /* picture holds a refcount */
-
- if (!pPicture)
- return FALSE;
-
- /* And store the picture in all the caches for the format */
- for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
- ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];
- int j;
-
- if (cache->format != format)
- continue;
-
- cache->picture = pPicture;
- cache->picture->refcnt++;
- cache->hashEntries = xallocarray(cache->hashSize, sizeof(int));
- cache->glyphs = xallocarray(cache->size, sizeof(ExaCachedGlyphRec));
- cache->glyphCount = 0;
-
- if (!cache->hashEntries || !cache->glyphs)
- goto bail;
-
- for (j = 0; j < cache->hashSize; j++)
- cache->hashEntries[j] = -1;
-
- cache->evictionPosition = rand() % cache->size;
- }
-
- /* Each cache references the picture individually */
- FreePicture((void *) pPicture, (XID) 0);
- return TRUE;
-
- bail:
- exaUnrealizeGlyphCaches(pScreen, format);
- return FALSE;
-}
-
-void
-exaGlyphsFini(ScreenPtr pScreen)
-{
- ExaScreenPriv(pScreen);
- int i;
-
- for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
- ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];
-
- if (cache->picture)
- exaUnrealizeGlyphCaches(pScreen, cache->format);
- }
-}
-
-static int
-exaGlyphCacheHashLookup(ExaGlyphCachePtr cache, GlyphPtr pGlyph)
-{
- int slot;
-
- slot = (*(CARD32 *) pGlyph->sha1) % cache->hashSize;
-
- while (TRUE) { /* hash table can never be full */
- int entryPos = cache->hashEntries[slot];
-
- if (entryPos == -1)
- return -1;
-
- if (memcmp
- (pGlyph->sha1, cache->glyphs[entryPos].sha1,
- sizeof(pGlyph->sha1)) == 0) {
- return entryPos;
- }
-
- slot--;
- if (slot < 0)
- slot = cache->hashSize - 1;
- }
-}
-
-static void
-exaGlyphCacheHashInsert(ExaGlyphCachePtr cache, GlyphPtr pGlyph, int pos)
-{
- int slot;
-
- memcpy(cache->glyphs[pos].sha1, pGlyph->sha1, sizeof(pGlyph->sha1));
-
- slot = (*(CARD32 *) pGlyph->sha1) % cache->hashSize;
-
- while (TRUE) { /* hash table can never be full */
- if (cache->hashEntries[slot] == -1) {
- cache->hashEntries[slot] = pos;
- return;
- }
-
- slot--;
- if (slot < 0)
- slot = cache->hashSize - 1;
- }
-}
-
-static void
-exaGlyphCacheHashRemove(ExaGlyphCachePtr cache, int pos)
-{
- int slot;
- int emptiedSlot = -1;
-
- slot = (*(CARD32 *) cache->glyphs[pos].sha1) % cache->hashSize;
-
- while (TRUE) { /* hash table can never be full */
- int entryPos = cache->hashEntries[slot];
-
- if (entryPos == -1)
- return;
-
- if (entryPos == pos) {
- cache->hashEntries[slot] = -1;
- emptiedSlot = slot;
- }
- else if (emptiedSlot != -1) {
- /* See if we can move this entry into the emptied slot, we can't
- * do that if if entry would have hashed between the current position
- * and the emptied slot. (taking wrapping into account). Bad positions
- * are:
- *
- * | XXXXXXXXXX |
- * i j
- *
- * |XXX XXXX|
- * j i
- *
- * i - slot, j - emptiedSlot
- *
- * (Knuth 6.4R)
- */
-
- int entrySlot =
- (*(CARD32 *) cache->glyphs[entryPos].sha1) % cache->hashSize;
-
- if (!((entrySlot >= slot && entrySlot < emptiedSlot) ||
- (emptiedSlot < slot &&
- (entrySlot < emptiedSlot || entrySlot >= slot)))) {
- cache->hashEntries[emptiedSlot] = entryPos;
- cache->hashEntries[slot] = -1;
- emptiedSlot = slot;
- }
- }
-
- slot--;
- if (slot < 0)
- slot = cache->hashSize - 1;
- }
-}
-
-#define CACHE_X(pos) (((pos) % cache->columns) * cache->glyphWidth)
-#define CACHE_Y(pos) (cache->yOffset + ((pos) / cache->columns) * cache->glyphHeight)
-
-/* The most efficient thing to way to upload the glyph to the screen
- * is to use the UploadToScreen() driver hook; this allows us to
- * pipeline glyph uploads and to avoid creating gpu backed pixmaps for
- * glyphs that we'll never use again.
- *
- * If we can't do it with UploadToScreen (because the glyph has a gpu copy,
- * etc), we fall back to CompositePicture.
- *
- * We need to damage the cache pixmap manually in either case because the damage
- * layer unwrapped the picture screen before calling exaGlyphs.
- */
-static void
-exaGlyphCacheUploadGlyph(ScreenPtr pScreen,
- ExaGlyphCachePtr cache, int x, int y, GlyphPtr pGlyph)
-{
- ExaScreenPriv(pScreen);
- PicturePtr pGlyphPicture = GetGlyphPicture(pGlyph, pScreen);
- PixmapPtr pGlyphPixmap = (PixmapPtr) pGlyphPicture->pDrawable;
-
- ExaPixmapPriv(pGlyphPixmap);
- PixmapPtr pCachePixmap = (PixmapPtr) cache->picture->pDrawable;
-
- if (!pExaScr->info->UploadToScreen || pExaScr->swappedOut ||
- pExaPixmap->accel_blocked)
- goto composite;
-
- /* If the glyph pixmap is already uploaded, no point in doing
- * things this way */
- if (exaPixmapHasGpuCopy(pGlyphPixmap))
- goto composite;
-
- /* UploadToScreen only works if bpp match */
- if (pGlyphPixmap->drawable.bitsPerPixel !=
- pCachePixmap->drawable.bitsPerPixel)
- goto composite;
-
- if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[1];
-
- /* cache pixmap must have a gpu copy. */
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pCachePixmap;
- pixmaps[0].pReg = NULL;
- exaDoMigration(pixmaps, 1, TRUE);
- }
-
- if (!exaPixmapHasGpuCopy(pCachePixmap))
- goto composite;
-
- /* x,y are in pixmap coordinates, no need for cache{X,Y}off */
- if (pExaScr->info->UploadToScreen(pCachePixmap,
- x,
- y,
- pGlyph->info.width,
- pGlyph->info.height,
- (char *) pExaPixmap->sys_ptr,
- pExaPixmap->sys_pitch))
- goto damage;
-
- composite:
- CompositePicture(PictOpSrc,
- pGlyphPicture,
- None,
- cache->picture,
- 0, 0, 0, 0, x, y, pGlyph->info.width, pGlyph->info.height);
-
- damage:
- /* The cache pixmap isn't a window, so no need to offset coordinates. */
- exaPixmapDirty(pCachePixmap,
- x, y, x + cache->glyphWidth, y + cache->glyphHeight);
-}
-
-static ExaGlyphCacheResult
-exaGlyphCacheBufferGlyph(ScreenPtr pScreen,
- ExaGlyphCachePtr cache,
- ExaGlyphBufferPtr buffer,
- GlyphPtr pGlyph,
- PicturePtr pSrc,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst)
-{
- ExaCompositeRectPtr rect;
- int pos;
- int x, y;
-
- if (buffer->mask && buffer->mask != cache->picture)
- return ExaGlyphNeedFlush;
-
- if (!cache->picture) {
- if (!exaRealizeGlyphCaches(pScreen, cache->format))
- return ExaGlyphFail;
- }
-
- DBG_GLYPH_CACHE(("(%d,%d,%s): buffering glyph %lx\n",
- cache->glyphWidth, cache->glyphHeight,
- cache->format == PICT_a8 ? "A" : "ARGB",
- (long) *(CARD32 *) pGlyph->sha1));
-
- pos = exaGlyphCacheHashLookup(cache, pGlyph);
- if (pos != -1) {
- DBG_GLYPH_CACHE((" found existing glyph at %d\n", pos));
- x = CACHE_X(pos);
- y = CACHE_Y(pos);
- }
- else {
- if (cache->glyphCount < cache->size) {
- /* Space remaining; we fill from the start */
- pos = cache->glyphCount;
- x = CACHE_X(pos);
- y = CACHE_Y(pos);
- cache->glyphCount++;
- DBG_GLYPH_CACHE((" storing glyph in free space at %d\n", pos));
-
- exaGlyphCacheHashInsert(cache, pGlyph, pos);
-
- }
- else {
- /* Need to evict an entry. We have to see if any glyphs
- * already in the output buffer were at this position in
- * the cache
- */
- pos = cache->evictionPosition;
- x = CACHE_X(pos);
- y = CACHE_Y(pos);
- DBG_GLYPH_CACHE((" evicting glyph at %d\n", pos));
- if (buffer->count) {
- int i;
-
- for (i = 0; i < buffer->count; i++) {
- if (pSrc ?
- (buffer->rects[i].xMask == x &&
- buffer->rects[i].yMask ==
- y) : (buffer->rects[i].xSrc == x &&
- buffer->rects[i].ySrc == y)) {
- DBG_GLYPH_CACHE((" must flush buffer\n"));
- return ExaGlyphNeedFlush;
- }
- }
- }
-
- /* OK, we're all set, swap in the new glyph */
- exaGlyphCacheHashRemove(cache, pos);
- exaGlyphCacheHashInsert(cache, pGlyph, pos);
-
- /* And pick a new eviction position */
- cache->evictionPosition = rand() % cache->size;
- }
-
- exaGlyphCacheUploadGlyph(pScreen, cache, x, y, pGlyph);
- }
-
- buffer->mask = cache->picture;
-
- rect = &buffer->rects[buffer->count];
-
- if (pSrc) {
- rect->xSrc = xSrc;
- rect->ySrc = ySrc;
- rect->xMask = x;
- rect->yMask = y;
- }
- else {
- rect->xSrc = x;
- rect->ySrc = y;
- rect->xMask = 0;
- rect->yMask = 0;
- }
-
- rect->pDst = pDst;
- rect->xDst = xDst;
- rect->yDst = yDst;
- rect->width = pGlyph->info.width;
- rect->height = pGlyph->info.height;
-
- buffer->count++;
-
- return ExaGlyphSuccess;
-}
-
-#undef CACHE_X
-#undef CACHE_Y
-
-static ExaGlyphCacheResult
-exaBufferGlyph(ScreenPtr pScreen,
- ExaGlyphBufferPtr buffer,
- GlyphPtr pGlyph,
- PicturePtr pSrc,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst)
-{
- ExaScreenPriv(pScreen);
- unsigned int format = (GetGlyphPicture(pGlyph, pScreen))->format;
- int width = pGlyph->info.width;
- int height = pGlyph->info.height;
- ExaCompositeRectPtr rect;
- PicturePtr mask;
- int i;
-
- if (buffer->count == GLYPH_BUFFER_SIZE)
- return ExaGlyphNeedFlush;
-
- if (PICT_FORMAT_BPP(format) == 1)
- format = PICT_a8;
-
- for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
- ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];
-
- if (format == cache->format &&
- width <= cache->glyphWidth && height <= cache->glyphHeight) {
- ExaGlyphCacheResult result = exaGlyphCacheBufferGlyph(pScreen,
- &pExaScr->
- glyphCaches
- [i],
- buffer,
- pGlyph,
- pSrc,
- pDst,
- xSrc, ySrc,
- xMask, yMask,
- xDst, yDst);
-
- switch (result) {
- case ExaGlyphFail:
- break;
- case ExaGlyphSuccess:
- case ExaGlyphNeedFlush:
- return result;
- }
- }
- }
-
- /* Couldn't find the glyph in the cache, use the glyph picture directly */
-
- mask = GetGlyphPicture(pGlyph, pScreen);
- if (buffer->mask && buffer->mask != mask)
- return ExaGlyphNeedFlush;
-
- buffer->mask = mask;
-
- rect = &buffer->rects[buffer->count];
- rect->xSrc = xSrc;
- rect->ySrc = ySrc;
- rect->xMask = xMask;
- rect->yMask = yMask;
- rect->xDst = xDst;
- rect->yDst = yDst;
- rect->width = width;
- rect->height = height;
-
- buffer->count++;
-
- return ExaGlyphSuccess;
-}
-
-static void
-exaGlyphsToMask(PicturePtr pMask, ExaGlyphBufferPtr buffer)
-{
- exaCompositeRects(PictOpAdd, buffer->mask, NULL, pMask,
- buffer->count, buffer->rects);
-
- buffer->count = 0;
- buffer->mask = NULL;
-}
-
-static void
-exaGlyphsToDst(CARD8 op, PicturePtr pSrc, PicturePtr pDst, ExaGlyphBufferPtr buffer)
-{
- exaCompositeRects(op, pSrc, buffer->mask, pDst, buffer->count,
- buffer->rects);
-
- buffer->count = 0;
- buffer->mask = NULL;
-}
-
-/* Cut and paste from render/glyph.c - probably should export it instead */
-static void
-GlyphExtents(int nlist, GlyphListPtr list, GlyphPtr * glyphs, BoxPtr extents)
-{
- int x1, x2, y1, y2;
- int n;
- GlyphPtr glyph;
- int x, y;
-
- x = 0;
- y = 0;
- extents->x1 = MAXSHORT;
- extents->x2 = MINSHORT;
- extents->y1 = MAXSHORT;
- extents->y2 = MINSHORT;
- while (nlist--) {
- x += list->xOff;
- y += list->yOff;
- n = list->len;
- list++;
- while (n--) {
- glyph = *glyphs++;
- x1 = x - glyph->info.x;
- if (x1 < MINSHORT)
- x1 = MINSHORT;
- y1 = y - glyph->info.y;
- if (y1 < MINSHORT)
- y1 = MINSHORT;
- x2 = x1 + glyph->info.width;
- if (x2 > MAXSHORT)
- x2 = MAXSHORT;
- y2 = y1 + glyph->info.height;
- if (y2 > MAXSHORT)
- y2 = MAXSHORT;
- if (x1 < extents->x1)
- extents->x1 = x1;
- if (x2 > extents->x2)
- extents->x2 = x2;
- if (y1 < extents->y1)
- extents->y1 = y1;
- if (y2 > extents->y2)
- extents->y2 = y2;
- x += glyph->info.xOff;
- y += glyph->info.yOff;
- }
- }
-}
-
-void
-exaGlyphs(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
-{
- PixmapPtr pMaskPixmap = 0;
- PicturePtr pMask = NULL;
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- int width = 0, height = 0;
- int x, y;
- int first_xOff = list->xOff, first_yOff = list->yOff;
- int n;
- GlyphPtr glyph;
- int error;
- BoxRec extents = { 0, 0, 0, 0 };
- CARD32 component_alpha;
- ExaGlyphBuffer buffer;
-
- if (maskFormat) {
- ExaScreenPriv(pScreen);
- GCPtr pGC;
- xRectangle rect;
-
- GlyphExtents(nlist, list, glyphs, &extents);
-
- if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
- return;
- width = extents.x2 - extents.x1;
- height = extents.y2 - extents.y1;
-
- if (maskFormat->depth == 1) {
- PictFormatPtr a8Format = PictureMatchFormat(pScreen, 8, PICT_a8);
-
- if (a8Format)
- maskFormat = a8Format;
- }
-
- pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
- maskFormat->depth,
- CREATE_PIXMAP_USAGE_SCRATCH);
- if (!pMaskPixmap)
- return;
- component_alpha = NeedsComponent(maskFormat->format);
- pMask = CreatePicture(0, &pMaskPixmap->drawable,
- maskFormat, CPComponentAlpha, &component_alpha,
- serverClient, &error);
- if (!pMask ||
- (!component_alpha && pExaScr->info->CheckComposite &&
- !(*pExaScr->info->CheckComposite) (PictOpAdd, pSrc, NULL, pMask)))
- {
- PictFormatPtr argbFormat;
-
- (*pScreen->DestroyPixmap) (pMaskPixmap);
-
- if (!pMask)
- return;
-
- /* The driver can't seem to composite to a8, let's try argb (but
- * without component-alpha) */
- FreePicture((void *) pMask, (XID) 0);
-
- argbFormat = PictureMatchFormat(pScreen, 32, PICT_a8r8g8b8);
-
- if (argbFormat)
- maskFormat = argbFormat;
-
- pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
- maskFormat->depth,
- CREATE_PIXMAP_USAGE_SCRATCH);
- if (!pMaskPixmap)
- return;
-
- pMask = CreatePicture(0, &pMaskPixmap->drawable, maskFormat, 0, 0,
- serverClient, &error);
- if (!pMask) {
- (*pScreen->DestroyPixmap) (pMaskPixmap);
- return;
- }
- }
- pGC = GetScratchGC(pMaskPixmap->drawable.depth, pScreen);
- ValidateGC(&pMaskPixmap->drawable, pGC);
- rect.x = 0;
- rect.y = 0;
- rect.width = width;
- rect.height = height;
- (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
- FreeScratchGC(pGC);
- x = -extents.x1;
- y = -extents.y1;
- }
- else {
- x = 0;
- y = 0;
- }
- buffer.count = 0;
- buffer.mask = NULL;
- while (nlist--) {
- x += list->xOff;
- y += list->yOff;
- n = list->len;
- while (n--) {
- glyph = *glyphs++;
-
- if (glyph->info.width > 0 && glyph->info.height > 0) {
- /* pGlyph->info.{x,y} compensate for empty space in the glyph. */
- if (maskFormat) {
- if (exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask,
- 0, 0, 0, 0, x - glyph->info.x,
- y - glyph->info.y) ==
- ExaGlyphNeedFlush) {
- exaGlyphsToMask(pMask, &buffer);
- exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask,
- 0, 0, 0, 0, x - glyph->info.x,
- y - glyph->info.y);
- }
- }
- else {
- if (exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst,
- xSrc + (x - glyph->info.x) - first_xOff,
- ySrc + (y - glyph->info.y) - first_yOff,
- 0, 0, x - glyph->info.x,
- y - glyph->info.y)
- == ExaGlyphNeedFlush) {
- exaGlyphsToDst(op, pSrc, pDst, &buffer);
- exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst,
- xSrc + (x - glyph->info.x) - first_xOff,
- ySrc + (y - glyph->info.y) - first_yOff,
- 0, 0, x - glyph->info.x,
- y - glyph->info.y);
- }
- }
- }
-
- x += glyph->info.xOff;
- y += glyph->info.yOff;
- }
- list++;
- }
-
- if (buffer.count) {
- if (maskFormat)
- exaGlyphsToMask(pMask, &buffer);
- else
- exaGlyphsToDst(op, pSrc, pDst, &buffer);
- }
-
- if (maskFormat) {
- x = extents.x1;
- y = extents.y1;
- CompositePicture(op,
- pSrc,
- pMask,
- pDst,
- xSrc + x - first_xOff,
- ySrc + y - first_yOff, 0, 0, x, y, width, height);
- FreePicture((void *) pMask, (XID) 0);
- (*pScreen->DestroyPixmap) (pMaskPixmap);
- }
-}
diff --git a/exa/exa_migration_classic.c b/exa/exa_migration_classic.c
deleted file mode 100644
index f712e1914..000000000
--- a/exa/exa_migration_classic.c
+++ /dev/null
@@ -1,761 +0,0 @@
-/*
- * Copyright © 2006 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Eric Anholt <eric@anholt.net>
- * Michel Dänzer <michel@tungstengraphics.com>
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <string.h>
-
-#include "exa_priv.h"
-#include "exa.h"
-
-#if DEBUG_MIGRATE
-#define DBG_MIGRATE(a) ErrorF a
-#else
-#define DBG_MIGRATE(a)
-#endif
-
-/**
- * The fallback path for UTS/DFS failing is to just memcpy. exaCopyDirtyToSys
- * and exaCopyDirtyToFb both needed to do this loop.
- */
-static void
-exaMemcpyBox(PixmapPtr pPixmap, BoxPtr pbox, CARD8 *src, int src_pitch,
- CARD8 *dst, int dst_pitch)
-{
- int i, cpp = pPixmap->drawable.bitsPerPixel / 8;
- int bytes = (pbox->x2 - pbox->x1) * cpp;
-
- src += pbox->y1 * src_pitch + pbox->x1 * cpp;
- dst += pbox->y1 * dst_pitch + pbox->x1 * cpp;
-
- for (i = pbox->y2 - pbox->y1; i; i--) {
- memcpy(dst, src, bytes);
- src += src_pitch;
- dst += dst_pitch;
- }
-}
-
-/**
- * Returns TRUE if the pixmap is dirty (has been modified in its current
- * location compared to the other), or lacks a private for tracking
- * dirtiness.
- */
-static Bool
-exaPixmapIsDirty(PixmapPtr pPix)
-{
- ExaPixmapPriv(pPix);
-
- if (pExaPixmap == NULL)
- EXA_FatalErrorDebugWithRet(("EXA bug: exaPixmapIsDirty was called on a non-exa pixmap.\n"), TRUE);
-
- if (!pExaPixmap->pDamage)
- return FALSE;
-
- return RegionNotEmpty(DamageRegion(pExaPixmap->pDamage)) ||
- !RegionEqual(&pExaPixmap->validSys, &pExaPixmap->validFB);
-}
-
-/**
- * Returns TRUE if the pixmap is either pinned in FB, or has a sufficient score
- * to be considered "should be in framebuffer". That's just anything that has
- * had more acceleration than fallbacks, or has no score yet.
- *
- * Only valid if using a migration scheme that tracks score.
- */
-static Bool
-exaPixmapShouldBeInFB(PixmapPtr pPix)
-{
- ExaPixmapPriv(pPix);
-
- if (exaPixmapIsPinned(pPix))
- return TRUE;
-
- return pExaPixmap->score >= 0;
-}
-
-/**
- * If the pixmap is currently dirty, this copies at least the dirty area from
- * FB to system or vice versa. Both areas must be allocated.
- */
-static void
-exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
- Bool (*transfer) (PixmapPtr pPix, int x, int y, int w, int h,
- char *sys, int sys_pitch), int fallback_index,
- void (*sync) (ScreenPtr pScreen))
-{
- PixmapPtr pPixmap = migrate->pPix;
-
- ExaPixmapPriv(pPixmap);
- RegionPtr damage = DamageRegion(pExaPixmap->pDamage);
- RegionRec CopyReg;
- Bool save_use_gpu_copy;
- int save_pitch;
- BoxPtr pBox;
- int nbox;
- Bool access_prepared = FALSE;
- Bool need_sync = FALSE;
-
- /* Damaged bits are valid in current copy but invalid in other one */
- if (pExaPixmap->use_gpu_copy) {
- RegionUnion(&pExaPixmap->validFB, &pExaPixmap->validFB, damage);
- RegionSubtract(&pExaPixmap->validSys, &pExaPixmap->validSys, damage);
- }
- else {
- RegionUnion(&pExaPixmap->validSys, &pExaPixmap->validSys, damage);
- RegionSubtract(&pExaPixmap->validFB, &pExaPixmap->validFB, damage);
- }
-
- RegionEmpty(damage);
-
- /* Copy bits valid in source but not in destination */
- RegionNull(&CopyReg);
- RegionSubtract(&CopyReg, pValidSrc, pValidDst);
-
- if (migrate->as_dst) {
- ExaScreenPriv(pPixmap->drawable.pScreen);
-
- /* XXX: The pending damage region will be marked as damaged after the
- * operation, so it should serve as an upper bound for the region that
- * needs to be synchronized for the operation. Unfortunately, this
- * causes corruption in some cases, e.g. when starting compiz. See
- * https://bugs.freedesktop.org/show_bug.cgi?id=12916 .
- */
- if (pExaScr->optimize_migration) {
- RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
-
-#if DEBUG_MIGRATE
- if (RegionNil(pending_damage)) {
- static Bool firsttime = TRUE;
-
- if (firsttime) {
- ErrorF("%s: Pending damage region empty!\n", __func__);
- firsttime = FALSE;
- }
- }
-#endif
-
- /* Try to prevent destination valid region from growing too many
- * rects by filling it up to the extents of the union of the
- * destination valid region and the pending damage region.
- */
- if (RegionNumRects(pValidDst) > 10) {
- BoxRec box;
- BoxPtr pValidExt, pDamageExt;
- RegionRec closure;
-
- pValidExt = RegionExtents(pValidDst);
- pDamageExt = RegionExtents(pending_damage);
-
- box.x1 = min(pValidExt->x1, pDamageExt->x1);
- box.y1 = min(pValidExt->y1, pDamageExt->y1);
- box.x2 = max(pValidExt->x2, pDamageExt->x2);
- box.y2 = max(pValidExt->y2, pDamageExt->y2);
-
- RegionInit(&closure, &box, 0);
- RegionIntersect(&CopyReg, &CopyReg, &closure);
- }
- else
- RegionIntersect(&CopyReg, &CopyReg, pending_damage);
- }
-
- /* The caller may provide a region to be subtracted from the calculated
- * dirty region. This is to avoid migration of bits that don't
- * contribute to the result of the operation.
- */
- if (migrate->pReg)
- RegionSubtract(&CopyReg, &CopyReg, migrate->pReg);
- }
- else {
- /* The caller may restrict the region to be migrated for source pixmaps
- * to what's relevant for the operation.
- */
- if (migrate->pReg)
- RegionIntersect(&CopyReg, &CopyReg, migrate->pReg);
- }
-
- pBox = RegionRects(&CopyReg);
- nbox = RegionNumRects(&CopyReg);
-
- save_use_gpu_copy = pExaPixmap->use_gpu_copy;
- save_pitch = pPixmap->devKind;
- pExaPixmap->use_gpu_copy = TRUE;
- pPixmap->devKind = pExaPixmap->fb_pitch;
-
- while (nbox--) {
- pBox->x1 = max(pBox->x1, 0);
- pBox->y1 = max(pBox->y1, 0);
- pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
- pBox->y2 = min(pBox->y2, pPixmap->drawable.height);
-
- if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
- continue;
-
- if (!transfer || !transfer(pPixmap,
- pBox->x1, pBox->y1,
- pBox->x2 - pBox->x1,
- pBox->y2 - pBox->y1,
- (char *) (pExaPixmap->sys_ptr
- + pBox->y1 * pExaPixmap->sys_pitch
- +
- pBox->x1 *
- pPixmap->drawable.bitsPerPixel /
- 8), pExaPixmap->sys_pitch)) {
- if (!access_prepared) {
- ExaDoPrepareAccess(pPixmap, fallback_index);
- access_prepared = TRUE;
- }
- if (fallback_index == EXA_PREPARE_DEST) {
- exaMemcpyBox(pPixmap, pBox,
- pExaPixmap->sys_ptr, pExaPixmap->sys_pitch,
- pPixmap->devPrivate.ptr, pPixmap->devKind);
- }
- else {
- exaMemcpyBox(pPixmap, pBox,
- pPixmap->devPrivate.ptr, pPixmap->devKind,
- pExaPixmap->sys_ptr, pExaPixmap->sys_pitch);
- }
- }
- else
- need_sync = TRUE;
-
- pBox++;
- }
-
- pExaPixmap->use_gpu_copy = save_use_gpu_copy;
- pPixmap->devKind = save_pitch;
-
- /* Try to prevent source valid region from growing too many rects by
- * removing parts of it which are also in the destination valid region.
- * Removing anything beyond that would lead to data loss.
- */
- if (RegionNumRects(pValidSrc) > 20)
- RegionSubtract(pValidSrc, pValidSrc, pValidDst);
-
- /* The copied bits are now valid in destination */
- RegionUnion(pValidDst, pValidDst, &CopyReg);
-
- RegionUninit(&CopyReg);
-
- if (access_prepared)
- exaFinishAccess(&pPixmap->drawable, fallback_index);
- else if (need_sync && sync)
- sync(pPixmap->drawable.pScreen);
-}
-
-/**
- * If the pixmap is currently dirty, this copies at least the dirty area from
- * the framebuffer memory copy to the system memory copy. Both areas must be
- * allocated.
- */
-void
-exaCopyDirtyToSys(ExaMigrationPtr migrate)
-{
- PixmapPtr pPixmap = migrate->pPix;
-
- ExaScreenPriv(pPixmap->drawable.pScreen);
- ExaPixmapPriv(pPixmap);
-
- exaCopyDirty(migrate, &pExaPixmap->validSys, &pExaPixmap->validFB,
- pExaScr->info->DownloadFromScreen, EXA_PREPARE_SRC,
- exaWaitSync);
-}
-
-/**
- * If the pixmap is currently dirty, this copies at least the dirty area from
- * the system memory copy to the framebuffer memory copy. Both areas must be
- * allocated.
- */
-void
-exaCopyDirtyToFb(ExaMigrationPtr migrate)
-{
- PixmapPtr pPixmap = migrate->pPix;
-
- ExaScreenPriv(pPixmap->drawable.pScreen);
- ExaPixmapPriv(pPixmap);
-
- exaCopyDirty(migrate, &pExaPixmap->validFB, &pExaPixmap->validSys,
- pExaScr->info->UploadToScreen, EXA_PREPARE_DEST, NULL);
-}
-
-/**
- * Allocates a framebuffer copy of the pixmap if necessary, and then copies
- * any necessary pixmap data into the framebuffer copy and points the pixmap at
- * it.
- *
- * Note that when first allocated, a pixmap will have FALSE dirty flag.
- * This is intentional because pixmap data starts out undefined. So if we move
- * it in due to the first operation against it being accelerated, it will have
- * undefined framebuffer contents that we didn't have to upload. If we do
- * moveouts (and moveins) after the first movein, then we will only have to copy
- * back and forth if the pixmap was written to after the last synchronization of
- * the two copies. Then, at exaPixmapSave (when the framebuffer copy goes away)
- * we mark the pixmap dirty, so that the next exaMoveInPixmap will actually move
- * all the data, since it's almost surely all valid now.
- */
-static void
-exaDoMoveInPixmap(ExaMigrationPtr migrate)
-{
- PixmapPtr pPixmap = migrate->pPix;
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
-
- ExaScreenPriv(pScreen);
- ExaPixmapPriv(pPixmap);
-
- /* If we're VT-switched away, no touching card memory allowed. */
- if (pExaScr->swappedOut)
- return;
-
- /* If we're not allowed to move, then fail. */
- if (exaPixmapIsPinned(pPixmap))
- return;
-
- /* Don't migrate in pixmaps which are less than 8bpp. This avoids a lot of
- * fragility in EXA, and <8bpp is probably not used enough any more to care
- * (at least, not in acceleratd paths).
- */
- if (pPixmap->drawable.bitsPerPixel < 8)
- return;
-
- if (pExaPixmap->accel_blocked)
- return;
-
- if (pExaPixmap->area == NULL) {
- pExaPixmap->area =
- exaOffscreenAlloc(pScreen, pExaPixmap->fb_size,
- pExaScr->info->pixmapOffsetAlign, FALSE,
- exaPixmapSave, (void *) pPixmap);
- if (pExaPixmap->area == NULL)
- return;
-
- pExaPixmap->fb_ptr = (CARD8 *) pExaScr->info->memoryBase +
- pExaPixmap->area->offset;
- }
-
- exaCopyDirtyToFb(migrate);
-
- if (exaPixmapHasGpuCopy(pPixmap))
- return;
-
- DBG_MIGRATE(("-> %p (0x%x) (%dx%d) (%c)\n", pPixmap,
- (ExaGetPixmapPriv(pPixmap)->area ?
- ExaGetPixmapPriv(pPixmap)->area->offset : 0),
- pPixmap->drawable.width,
- pPixmap->drawable.height,
- exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
-
- pExaPixmap->use_gpu_copy = TRUE;
-
- pPixmap->devKind = pExaPixmap->fb_pitch;
- pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
-}
-
-void
-exaMoveInPixmap_classic(PixmapPtr pPixmap)
-{
- static ExaMigrationRec migrate = {.as_dst = FALSE,.as_src = TRUE,
- .pReg = NULL
- };
-
- migrate.pPix = pPixmap;
- exaDoMoveInPixmap(&migrate);
-}
-
-/**
- * Switches the current active location of the pixmap to system memory, copying
- * updated data out if necessary.
- */
-static void
-exaDoMoveOutPixmap(ExaMigrationPtr migrate)
-{
- PixmapPtr pPixmap = migrate->pPix;
-
- ExaPixmapPriv(pPixmap);
-
- if (!pExaPixmap->area || exaPixmapIsPinned(pPixmap))
- return;
-
- exaCopyDirtyToSys(migrate);
-
- if (exaPixmapHasGpuCopy(pPixmap)) {
-
- DBG_MIGRATE(("<- %p (%p) (%dx%d) (%c)\n", pPixmap,
- (void *) (ExaGetPixmapPriv(pPixmap)->area ?
- ExaGetPixmapPriv(pPixmap)->area->offset : 0),
- pPixmap->drawable.width,
- pPixmap->drawable.height,
- exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
-
- pExaPixmap->use_gpu_copy = FALSE;
-
- pPixmap->devKind = pExaPixmap->sys_pitch;
- pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- }
-}
-
-void
-exaMoveOutPixmap_classic(PixmapPtr pPixmap)
-{
- static ExaMigrationRec migrate = {.as_dst = FALSE,.as_src = TRUE,
- .pReg = NULL
- };
-
- migrate.pPix = pPixmap;
- exaDoMoveOutPixmap(&migrate);
-}
-
-/**
- * Copies out important pixmap data and removes references to framebuffer area.
- * Called when the memory manager decides it's time to kick the pixmap out of
- * framebuffer entirely.
- */
-void
-exaPixmapSave(ScreenPtr pScreen, ExaOffscreenArea * area)
-{
- PixmapPtr pPixmap = area->privData;
-
- ExaPixmapPriv(pPixmap);
-
- exaMoveOutPixmap(pPixmap);
-
- pExaPixmap->fb_ptr = NULL;
- pExaPixmap->area = NULL;
-
- /* Mark all FB bits as invalid, so all valid system bits get copied to FB
- * next time */
- RegionEmpty(&pExaPixmap->validFB);
-}
-
-/**
- * For the "greedy" migration scheme, pushes the pixmap toward being located in
- * framebuffer memory.
- */
-static void
-exaMigrateTowardFb(ExaMigrationPtr migrate)
-{
- PixmapPtr pPixmap = migrate->pPix;
-
- ExaPixmapPriv(pPixmap);
-
- if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) {
- DBG_MIGRATE(("UseScreen: not migrating pinned pixmap %p\n",
- (void *) pPixmap));
- return;
- }
-
- DBG_MIGRATE(("UseScreen %p score %d\n",
- (void *) pPixmap, pExaPixmap->score));
-
- if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) {
- exaDoMoveInPixmap(migrate);
- pExaPixmap->score = 0;
- }
-
- if (pExaPixmap->score < EXA_PIXMAP_SCORE_MAX)
- pExaPixmap->score++;
-
- if (pExaPixmap->score >= EXA_PIXMAP_SCORE_MOVE_IN &&
- !exaPixmapHasGpuCopy(pPixmap)) {
- exaDoMoveInPixmap(migrate);
- }
-
- if (exaPixmapHasGpuCopy(pPixmap)) {
- exaCopyDirtyToFb(migrate);
- ExaOffscreenMarkUsed(pPixmap);
- }
- else
- exaCopyDirtyToSys(migrate);
-}
-
-/**
- * For the "greedy" migration scheme, pushes the pixmap toward being located in
- * system memory.
- */
-static void
-exaMigrateTowardSys(ExaMigrationPtr migrate)
-{
- PixmapPtr pPixmap = migrate->pPix;
-
- ExaPixmapPriv(pPixmap);
-
- DBG_MIGRATE(("UseMem: %p score %d\n", (void *) pPixmap,
- pExaPixmap->score));
-
- if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED)
- return;
-
- if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT)
- pExaPixmap->score = 0;
-
- if (pExaPixmap->score > EXA_PIXMAP_SCORE_MIN)
- pExaPixmap->score--;
-
- if (pExaPixmap->score <= EXA_PIXMAP_SCORE_MOVE_OUT && pExaPixmap->area)
- exaDoMoveOutPixmap(migrate);
-
- if (exaPixmapHasGpuCopy(pPixmap)) {
- exaCopyDirtyToFb(migrate);
- ExaOffscreenMarkUsed(pPixmap);
- }
- else
- exaCopyDirtyToSys(migrate);
-}
-
-/**
- * If the pixmap has both a framebuffer and system memory copy, this function
- * asserts that both of them are the same.
- */
-static Bool
-exaAssertNotDirty(PixmapPtr pPixmap)
-{
- ExaPixmapPriv(pPixmap);
- CARD8 *dst, *src;
- RegionRec ValidReg;
- int dst_pitch, src_pitch, cpp, y, nbox, save_pitch;
- BoxPtr pBox;
- Bool ret = TRUE, save_use_gpu_copy;
-
- if (exaPixmapIsPinned(pPixmap) || pExaPixmap->area == NULL)
- return ret;
-
- RegionNull(&ValidReg);
- RegionIntersect(&ValidReg, &pExaPixmap->validFB, &pExaPixmap->validSys);
- nbox = RegionNumRects(&ValidReg);
-
- if (!nbox)
- goto out;
-
- pBox = RegionRects(&ValidReg);
-
- dst_pitch = pExaPixmap->sys_pitch;
- src_pitch = pExaPixmap->fb_pitch;
- cpp = pPixmap->drawable.bitsPerPixel / 8;
-
- save_use_gpu_copy = pExaPixmap->use_gpu_copy;
- save_pitch = pPixmap->devKind;
- pExaPixmap->use_gpu_copy = TRUE;
- pPixmap->devKind = pExaPixmap->fb_pitch;
-
- if (!ExaDoPrepareAccess(pPixmap, EXA_PREPARE_SRC))
- goto skip;
-
- while (nbox--) {
- int rowbytes;
-
- pBox->x1 = max(pBox->x1, 0);
- pBox->y1 = max(pBox->y1, 0);
- pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
- pBox->y2 = min(pBox->y2, pPixmap->drawable.height);
-
- if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
- continue;
-
- rowbytes = (pBox->x2 - pBox->x1) * cpp;
- src =
- (CARD8 *) pPixmap->devPrivate.ptr + pBox->y1 * src_pitch +
- pBox->x1 * cpp;
- dst = pExaPixmap->sys_ptr + pBox->y1 * dst_pitch + pBox->x1 * cpp;
-
- for (y = pBox->y1; y < pBox->y2;
- y++, src += src_pitch, dst += dst_pitch) {
- if (memcmp(dst, src, rowbytes) != 0) {
- ret = FALSE;
- exaPixmapDirty(pPixmap, pBox->x1, pBox->y1, pBox->x2, pBox->y2);
- break;
- }
- }
- }
-
- skip:
- exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
-
- pExaPixmap->use_gpu_copy = save_use_gpu_copy;
- pPixmap->devKind = save_pitch;
-
- out:
- RegionUninit(&ValidReg);
- return ret;
-}
-
-/**
- * Performs migration of the pixmaps according to the operation information
- * provided in pixmaps and can_accel and the migration scheme chosen in the
- * config file.
- */
-void
-exaDoMigration_classic(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
-{
- ScreenPtr pScreen = pixmaps[0].pPix->drawable.pScreen;
-
- ExaScreenPriv(pScreen);
- int i, j;
-
- /* If this debugging flag is set, check each pixmap for whether it is marked
- * as clean, and if so, actually check if that's the case. This should help
- * catch issues with failing to mark a drawable as dirty. While it will
- * catch them late (after the operation happened), it at least explains what
- * went wrong, and instrumenting the code to find what operation happened
- * to the pixmap last shouldn't be hard.
- */
- if (pExaScr->checkDirtyCorrectness) {
- for (i = 0; i < npixmaps; i++) {
- if (!exaPixmapIsDirty(pixmaps[i].pPix) &&
- !exaAssertNotDirty(pixmaps[i].pPix))
- ErrorF("%s: Pixmap %d dirty but not marked as such!\n",
- __func__, i);
- }
- }
- /* If anything is pinned in system memory, we won't be able to
- * accelerate.
- */
- for (i = 0; i < npixmaps; i++) {
- if (exaPixmapIsPinned(pixmaps[i].pPix) &&
- !exaPixmapHasGpuCopy(pixmaps[i].pPix)) {
- EXA_FALLBACK(("Pixmap %p (%dx%d) pinned in sys\n", pixmaps[i].pPix,
- pixmaps[i].pPix->drawable.width,
- pixmaps[i].pPix->drawable.height));
- can_accel = FALSE;
- break;
- }
- }
-
- if (pExaScr->migration == ExaMigrationSmart) {
- /* If we've got something as a destination that we shouldn't cause to
- * become newly dirtied, take the unaccelerated route.
- */
- for (i = 0; i < npixmaps; i++) {
- if (pixmaps[i].as_dst && !exaPixmapShouldBeInFB(pixmaps[i].pPix) &&
- !exaPixmapIsDirty(pixmaps[i].pPix)) {
- for (i = 0; i < npixmaps; i++) {
- if (!exaPixmapIsDirty(pixmaps[i].pPix))
- exaDoMoveOutPixmap(pixmaps + i);
- }
- return;
- }
- }
-
- /* If we aren't going to accelerate, then we migrate everybody toward
- * system memory, and kick out if it's free.
- */
- if (!can_accel) {
- for (i = 0; i < npixmaps; i++) {
- exaMigrateTowardSys(pixmaps + i);
- if (!exaPixmapIsDirty(pixmaps[i].pPix))
- exaDoMoveOutPixmap(pixmaps + i);
- }
- return;
- }
-
- /* Finally, the acceleration path. Move them all in. */
- for (i = 0; i < npixmaps; i++) {
- exaMigrateTowardFb(pixmaps + i);
- exaDoMoveInPixmap(pixmaps + i);
- }
- }
- else if (pExaScr->migration == ExaMigrationGreedy) {
- /* If we can't accelerate, either because the driver can't or because one of
- * the pixmaps is pinned in system memory, then we migrate everybody toward
- * system memory.
- *
- * We also migrate toward system if all pixmaps involved are currently in
- * system memory -- this can mitigate thrashing when there are significantly
- * more pixmaps active than would fit in memory.
- *
- * If not, then we migrate toward FB so that hopefully acceleration can
- * happen.
- */
- if (!can_accel) {
- for (i = 0; i < npixmaps; i++)
- exaMigrateTowardSys(pixmaps + i);
- return;
- }
-
- for (i = 0; i < npixmaps; i++) {
- if (exaPixmapHasGpuCopy(pixmaps[i].pPix)) {
- /* Found one in FB, so move all to FB. */
- for (j = 0; j < npixmaps; j++)
- exaMigrateTowardFb(pixmaps + i);
- return;
- }
- }
-
- /* Nobody's in FB, so move all away from FB. */
- for (i = 0; i < npixmaps; i++)
- exaMigrateTowardSys(pixmaps + i);
- }
- else if (pExaScr->migration == ExaMigrationAlways) {
- /* Always move the pixmaps out if we can't accelerate. If we can
- * accelerate, try to move them all in. If that fails, then move them
- * back out.
- */
- if (!can_accel) {
- for (i = 0; i < npixmaps; i++)
- exaDoMoveOutPixmap(pixmaps + i);
- return;
- }
-
- /* Now, try to move them all into FB */
- for (i = 0; i < npixmaps; i++) {
- exaDoMoveInPixmap(pixmaps + i);
- }
-
- /* If we couldn't fit everything in, abort */
- for (i = 0; i < npixmaps; i++) {
- if (!exaPixmapHasGpuCopy(pixmaps[i].pPix)) {
- return;
- }
- }
-
- /* Yay, everything has a gpu copy, mark memory as used */
- for (i = 0; i < npixmaps; i++) {
- ExaOffscreenMarkUsed(pixmaps[i].pPix);
- }
- }
-}
-
-void
-exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg)
-{
- ExaMigrationRec pixmaps[1];
-
- if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) {
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- }
- else {
- pixmaps[0].as_dst = FALSE;
- pixmaps[0].as_src = TRUE;
- }
- pixmaps[0].pPix = pPixmap;
- pixmaps[0].pReg = pReg;
-
- exaDoMigration(pixmaps, 1, FALSE);
-
- (void) ExaDoPrepareAccess(pPixmap, index);
-}
diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c
deleted file mode 100644
index 7d3fca7c0..000000000
--- a/exa/exa_migration_mixed.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright © 2009 Maarten Maathuis
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <string.h>
-
-#include "exa_priv.h"
-#include "exa.h"
-
-void
-exaCreateDriverPixmap_mixed(PixmapPtr pPixmap)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
-
- ExaScreenPriv(pScreen);
- ExaPixmapPriv(pPixmap);
- int w = pPixmap->drawable.width, h = pPixmap->drawable.height;
- int depth = pPixmap->drawable.depth, bpp = pPixmap->drawable.bitsPerPixel;
- int usage_hint = pPixmap->usage_hint;
- int paddedWidth = pExaPixmap->sys_pitch;
-
- /* Already done. */
- if (pExaPixmap->driverPriv)
- return;
-
- if (exaPixmapIsPinned(pPixmap))
- return;
-
- /* Can't accel 1/4 bpp. */
- if (pExaPixmap->accel_blocked || bpp < 8)
- return;
-
- if (pExaScr->info->CreatePixmap2) {
- int new_pitch = 0;
-
- pExaPixmap->driverPriv =
- pExaScr->info->CreatePixmap2(pScreen, w, h, depth, usage_hint, bpp,
- &new_pitch);
- paddedWidth = pExaPixmap->fb_pitch = new_pitch;
- }
- else {
- if (paddedWidth < pExaPixmap->fb_pitch)
- paddedWidth = pExaPixmap->fb_pitch;
- pExaPixmap->driverPriv =
- pExaScr->info->CreatePixmap(pScreen, paddedWidth * h, 0);
- }
-
- if (!pExaPixmap->driverPriv)
- return;
-
- (*pScreen->ModifyPixmapHeader) (pPixmap, w, h, 0, 0, paddedWidth, NULL);
-}
-
-void
-exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
-{
- int i;
-
- /* If anything is pinned in system memory, we won't be able to
- * accelerate.
- */
- for (i = 0; i < npixmaps; i++) {
- if (exaPixmapIsPinned(pixmaps[i].pPix) &&
- !exaPixmapHasGpuCopy(pixmaps[i].pPix)) {
- can_accel = FALSE;
- break;
- }
- }
-
- /* We can do nothing. */
- if (!can_accel)
- return;
-
- for (i = 0; i < npixmaps; i++) {
- PixmapPtr pPixmap = pixmaps[i].pPix;
-
- ExaPixmapPriv(pPixmap);
-
- if (!pExaPixmap->driverPriv)
- exaCreateDriverPixmap_mixed(pPixmap);
-
- if (pExaPixmap->pDamage && exaPixmapHasGpuCopy(pPixmap)) {
- ExaScreenPriv(pPixmap->drawable.pScreen);
-
- /* This pitch is needed for proper acceleration. For some reason
- * there are pixmaps without pDamage and a bad fb_pitch value.
- * So setting devKind when only exaPixmapHasGpuCopy() is true
- * causes corruption. Pixmaps without pDamage are not migrated
- * and should have a valid devKind at all times, so that's why this
- * isn't causing problems. Pixmaps have their gpu pitch set the
- * first time in the MPH call from exaCreateDriverPixmap_mixed().
- */
- pPixmap->devKind = pExaPixmap->fb_pitch;
- exaCopyDirtyToFb(pixmaps + i);
-
- if (pExaScr->deferred_mixed_pixmap == pPixmap &&
- !pixmaps[i].as_dst && !pixmaps[i].pReg)
- pExaScr->deferred_mixed_pixmap = NULL;
- }
-
- pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
- }
-}
-
-void
-exaMoveInPixmap_mixed(PixmapPtr pPixmap)
-{
- ExaMigrationRec pixmaps[1];
-
- pixmaps[0].as_dst = FALSE;
- pixmaps[0].as_src = TRUE;
- pixmaps[0].pPix = pPixmap;
- pixmaps[0].pReg = NULL;
-
- exaDoMigration(pixmaps, 1, TRUE);
-}
-
-void
-exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure)
-{
- PixmapPtr pPixmap = closure;
-
- ExaPixmapPriv(pPixmap);
-
- /* Move back results of software rendering on system memory copy of mixed driver
- * pixmap (see exaPrepareAccessReg_mixed).
- *
- * Defer moving the destination back into the driver pixmap, to try and save
- * overhead on multiple subsequent software fallbacks.
- */
- if (!pExaPixmap->use_gpu_copy && exaPixmapHasGpuCopy(pPixmap)) {
- ExaScreenPriv(pPixmap->drawable.pScreen);
-
- if (pExaScr->deferred_mixed_pixmap &&
- pExaScr->deferred_mixed_pixmap != pPixmap)
- exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
- pExaScr->deferred_mixed_pixmap = pPixmap;
- }
-}
-
-/* With mixed pixmaps, if we fail to get direct access to the driver pixmap, we
- * use the DownloadFromScreen hook to retrieve contents to a copy in system
- * memory, perform software rendering on that and move back the results with the
- * UploadToScreen hook (see exaDamageReport_mixed).
- */
-void
-exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
-{
- ExaPixmapPriv(pPixmap);
- Bool has_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
- Bool success;
-
- success = ExaDoPrepareAccess(pPixmap, index);
-
- if (success && has_gpu_copy && pExaPixmap->pDamage) {
- /* You cannot do accelerated operations while a buffer is mapped. */
- exaFinishAccess(&pPixmap->drawable, index);
- /* Update the gpu view of both deferred destination pixmaps and of
- * source pixmaps that were migrated with a bounding region.
- */
- exaMoveInPixmap_mixed(pPixmap);
- success = ExaDoPrepareAccess(pPixmap, index);
-
- if (success) {
- /* We have a gpu pixmap that can be accessed, we don't need the cpu
- * copy anymore. Drivers that prefer DFS, should fail prepare
- * access.
- */
- DamageDestroy(pExaPixmap->pDamage);
- pExaPixmap->pDamage = NULL;
-
- free(pExaPixmap->sys_ptr);
- pExaPixmap->sys_ptr = NULL;
-
- return;
- }
- }
-
- if (!success) {
- ExaMigrationRec pixmaps[1];
-
- /* Do we need to allocate our system buffer? */
- if (!pExaPixmap->sys_ptr) {
- pExaPixmap->sys_ptr = xallocarray(pExaPixmap->sys_pitch,
- pPixmap->drawable.height);
- if (!pExaPixmap->sys_ptr)
- FatalError("EXA: malloc failed for size %d bytes\n",
- pExaPixmap->sys_pitch * pPixmap->drawable.height);
- }
-
- if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) {
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- }
- else {
- pixmaps[0].as_dst = FALSE;
- pixmaps[0].as_src = TRUE;
- }
- pixmaps[0].pPix = pPixmap;
- pixmaps[0].pReg = pReg;
-
- if (!pExaPixmap->pDamage &&
- (has_gpu_copy || !exaPixmapIsPinned(pPixmap))) {
- Bool as_dst = pixmaps[0].as_dst;
-
- /* Set up damage tracking */
- pExaPixmap->pDamage = DamageCreate(exaDamageReport_mixed, NULL,
- DamageReportNonEmpty, TRUE,
- pPixmap->drawable.pScreen,
- pPixmap);
-
- if (pExaPixmap->pDamage) {
- DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
- /* This ensures that pending damage reflects the current
- * operation. This is used by exa to optimize migration.
- */
- DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);
- }
-
- if (has_gpu_copy) {
- exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width,
- pPixmap->drawable.height);
-
- /* We don't know which region of the destination will be damaged,
- * have to assume all of it
- */
- if (as_dst) {
- pixmaps[0].as_dst = FALSE;
- pixmaps[0].as_src = TRUE;
- pixmaps[0].pReg = NULL;
- }
- exaCopyDirtyToSys(pixmaps);
- }
-
- if (as_dst)
- exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width,
- pPixmap->drawable.height);
- }
- else if (has_gpu_copy)
- exaCopyDirtyToSys(pixmaps);
-
- pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
- pPixmap->devKind = pExaPixmap->sys_pitch;
- pExaPixmap->use_gpu_copy = FALSE;
- }
-}
diff --git a/exa/exa_mixed.c b/exa/exa_mixed.c
deleted file mode 100644
index 1e67ec23a..000000000
--- a/exa/exa_mixed.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * Copyright © 2009 Maarten Maathuis
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <string.h>
-
-#include "exa_priv.h"
-#include "exa.h"
-
-/* This file holds the driver allocated pixmaps + better initial placement code.
- */
-
-static _X_INLINE void *
-ExaGetPixmapAddress(PixmapPtr p)
-{
- ExaPixmapPriv(p);
-
- return pExaPixmap->sys_ptr;
-}
-
-/**
- * exaCreatePixmap() creates a new pixmap.
- */
-PixmapPtr
-exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
- unsigned usage_hint)
-{
- PixmapPtr pPixmap;
- ExaPixmapPrivPtr pExaPixmap;
- int bpp;
- size_t paddedWidth;
-
- ExaScreenPriv(pScreen);
-
- if (w > 32767 || h > 32767)
- return NullPixmap;
-
- swap(pExaScr, pScreen, CreatePixmap);
- pPixmap = pScreen->CreatePixmap(pScreen, 0, 0, depth, usage_hint);
- swap(pExaScr, pScreen, CreatePixmap);
-
- if (!pPixmap)
- return NULL;
-
- pExaPixmap = ExaGetPixmapPriv(pPixmap);
- pExaPixmap->driverPriv = NULL;
-
- bpp = pPixmap->drawable.bitsPerPixel;
-
- paddedWidth = ((w * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
- if (paddedWidth / 4 > 32767 || h > 32767)
- return NullPixmap;
-
- /* We will allocate the system pixmap later if needed. */
- pPixmap->devPrivate.ptr = NULL;
- pExaPixmap->sys_ptr = NULL;
- pExaPixmap->sys_pitch = paddedWidth;
-
- pExaPixmap->area = NULL;
- pExaPixmap->fb_ptr = NULL;
- pExaPixmap->pDamage = NULL;
-
- exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp);
- exaSetAccelBlock(pExaScr, pExaPixmap, w, h, bpp);
-
- (*pScreen->ModifyPixmapHeader) (pPixmap, w, h, 0, 0, paddedWidth, NULL);
-
- /* A scratch pixmap will become a driver pixmap right away. */
- if (!w || !h) {
- exaCreateDriverPixmap_mixed(pPixmap);
- pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
- }
- else {
- pExaPixmap->use_gpu_copy = FALSE;
-
- if (w == 1 && h == 1) {
- pExaPixmap->sys_ptr = malloc(paddedWidth);
-
- /* Set up damage tracking */
- pExaPixmap->pDamage = DamageCreate(exaDamageReport_mixed, NULL,
- DamageReportNonEmpty, TRUE,
- pPixmap->drawable.pScreen,
- pPixmap);
-
- if (pExaPixmap->pDamage) {
- DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
- /* This ensures that pending damage reflects the current
- * operation. This is used by exa to optimize migration.
- */
- DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);
- }
- }
- }
-
- /* During a fallback we must prepare access. */
- if (pExaScr->fallback_counter)
- exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
-
- return pPixmap;
-}
-
-Bool
-exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
- int bitsPerPixel, int devKind, void *pPixData)
-{
- ScreenPtr pScreen;
- ExaScreenPrivPtr pExaScr;
- ExaPixmapPrivPtr pExaPixmap;
- Bool ret, has_gpu_copy;
-
- if (!pPixmap)
- return FALSE;
-
- pScreen = pPixmap->drawable.pScreen;
- pExaScr = ExaGetScreenPriv(pScreen);
- pExaPixmap = ExaGetPixmapPriv(pPixmap);
-
- if (pPixData) {
- if (pExaPixmap->driverPriv) {
- if (pExaPixmap->pDamage) {
- DamageDestroy(pExaPixmap->pDamage);
- pExaPixmap->pDamage = NULL;
- }
-
- pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
- pExaPixmap->driverPriv = NULL;
- }
-
- pExaPixmap->use_gpu_copy = FALSE;
- pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
- }
-
- has_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
-
- if (width <= 0)
- width = pPixmap->drawable.width;
-
- if (height <= 0)
- height = pPixmap->drawable.height;
-
- if (bitsPerPixel <= 0) {
- if (depth <= 0)
- bitsPerPixel = pPixmap->drawable.bitsPerPixel;
- else
- bitsPerPixel = BitsPerPixel(depth);
- }
-
- if (depth <= 0)
- depth = pPixmap->drawable.depth;
-
- if (width != pPixmap->drawable.width ||
- height != pPixmap->drawable.height ||
- depth != pPixmap->drawable.depth ||
- bitsPerPixel != pPixmap->drawable.bitsPerPixel) {
- if (pExaPixmap->driverPriv) {
- if (devKind > 0)
- pExaPixmap->fb_pitch = devKind;
- else
- exaSetFbPitch(pExaScr, pExaPixmap, width, height, bitsPerPixel);
-
- exaSetAccelBlock(pExaScr, pExaPixmap, width, height, bitsPerPixel);
- RegionEmpty(&pExaPixmap->validFB);
- }
-
- /* Need to re-create system copy if there's also a GPU copy */
- if (has_gpu_copy) {
- if (pExaPixmap->sys_ptr) {
- free(pExaPixmap->sys_ptr);
- pExaPixmap->sys_ptr = NULL;
- DamageDestroy(pExaPixmap->pDamage);
- pExaPixmap->pDamage = NULL;
- RegionEmpty(&pExaPixmap->validSys);
-
- if (pExaScr->deferred_mixed_pixmap == pPixmap)
- pExaScr->deferred_mixed_pixmap = NULL;
- }
-
- pExaPixmap->sys_pitch = PixmapBytePad(width, depth);
- }
- }
-
- if (has_gpu_copy) {
- pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
- pPixmap->devKind = pExaPixmap->fb_pitch;
- }
- else {
- pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
- pPixmap->devKind = pExaPixmap->sys_pitch;
- }
-
- /* Only pass driver pixmaps to the driver. */
- if (pExaScr->info->ModifyPixmapHeader && pExaPixmap->driverPriv) {
- ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth,
- bitsPerPixel, devKind,
- pPixData);
- if (ret == TRUE)
- goto out;
- }
-
- swap(pExaScr, pScreen, ModifyPixmapHeader);
- ret = pScreen->ModifyPixmapHeader(pPixmap, width, height, depth,
- bitsPerPixel, devKind, pPixData);
- swap(pExaScr, pScreen, ModifyPixmapHeader);
-
- out:
- if (has_gpu_copy) {
- pExaPixmap->fb_ptr = pPixmap->devPrivate.ptr;
- pExaPixmap->fb_pitch = pPixmap->devKind;
- }
- else {
- pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
- pExaPixmap->sys_pitch = pPixmap->devKind;
- }
- /* Always NULL this, we don't want lingering pointers. */
- pPixmap->devPrivate.ptr = NULL;
-
- return ret;
-}
-
-Bool
-exaDestroyPixmap_mixed(PixmapPtr pPixmap)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
-
- ExaScreenPriv(pScreen);
- Bool ret;
-
- if (pPixmap->refcnt == 1) {
- ExaPixmapPriv(pPixmap);
-
- exaDestroyPixmap(pPixmap);
-
- if (pExaScr->deferred_mixed_pixmap == pPixmap)
- pExaScr->deferred_mixed_pixmap = NULL;
-
- if (pExaPixmap->driverPriv)
- pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
- pExaPixmap->driverPriv = NULL;
-
- if (pExaPixmap->pDamage) {
- free(pExaPixmap->sys_ptr);
- pExaPixmap->sys_ptr = NULL;
- pExaPixmap->pDamage = NULL;
- }
- }
-
- swap(pExaScr, pScreen, DestroyPixmap);
- ret = pScreen->DestroyPixmap(pPixmap);
- swap(pExaScr, pScreen, DestroyPixmap);
-
- return ret;
-}
-
-Bool
-exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
-
- ExaScreenPriv(pScreen);
- ExaPixmapPriv(pPixmap);
- void *saved_ptr;
- Bool ret;
-
- if (!pExaPixmap->driverPriv)
- return FALSE;
-
- saved_ptr = pPixmap->devPrivate.ptr;
- pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap);
- ret = pExaScr->info->PixmapIsOffscreen(pPixmap);
- pPixmap->devPrivate.ptr = saved_ptr;
-
- return ret;
-}
-
-Bool
-exaSharePixmapBacking_mixed(PixmapPtr pPixmap, ScreenPtr secondary, void **handle_p)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
- ExaScreenPriv(pScreen);
- Bool ret = FALSE;
-
- exaMoveInPixmap(pPixmap);
- /* get the driver to give us a handle */
- if (pExaScr->info->SharePixmapBacking)
- ret = pExaScr->info->SharePixmapBacking(pPixmap, secondary, handle_p);
-
- return ret;
-}
-
-Bool
-exaSetSharedPixmapBacking_mixed(PixmapPtr pPixmap, void *handle)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
- ExaScreenPriv(pScreen);
- Bool ret = FALSE;
-
- if (pExaScr->info->SetSharedPixmapBacking)
- ret = pExaScr->info->SetSharedPixmapBacking(pPixmap, handle);
-
- if (ret == TRUE)
- exaMoveInPixmap(pPixmap);
-
- return ret;
-}
-
-
diff --git a/exa/exa_offscreen.c b/exa/exa_offscreen.c
deleted file mode 100644
index c77e36261..000000000
--- a/exa/exa_offscreen.c
+++ /dev/null
@@ -1,677 +0,0 @@
-/*
- * Copyright © 2003 Anders Carlsson
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Anders Carlsson not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Anders Carlsson makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * ANDERS CARLSSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL ANDERS CARLSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/** @file
- * This allocator allocates blocks of memory by maintaining a list of areas.
- * When allocating, the contiguous block of areas with the minimum eviction
- * cost is found and evicted in order to make room for the new allocation.
- */
-
-#include "exa_priv.h"
-
-#include <limits.h>
-#include <assert.h>
-#include <stdlib.h>
-
-#if DEBUG_OFFSCREEN
-#define DBG_OFFSCREEN(a) ErrorF a
-#else
-#define DBG_OFFSCREEN(a)
-#endif
-
-#if DEBUG_OFFSCREEN
-static void
-ExaOffscreenValidate(ScreenPtr pScreen)
-{
- ExaScreenPriv(pScreen);
- ExaOffscreenArea *prev = 0, *area;
-
- assert(pExaScr->info->offScreenAreas->base_offset ==
- pExaScr->info->offScreenBase);
- for (area = pExaScr->info->offScreenAreas; area; area = area->next) {
- assert(area->offset >= area->base_offset);
- assert(area->offset < (area->base_offset + area->size));
- if (prev)
- assert(prev->base_offset + prev->size == area->base_offset);
- prev = area;
- }
- assert(prev->base_offset + prev->size == pExaScr->info->memorySize);
-}
-#else
-#define ExaOffscreenValidate(s)
-#endif
-
-static ExaOffscreenArea *
-ExaOffscreenKickOut(ScreenPtr pScreen, ExaOffscreenArea * area)
-{
- if (area->save)
- (*area->save) (pScreen, area);
- return exaOffscreenFree(pScreen, area);
-}
-
-static void
-exaUpdateEvictionCost(ExaOffscreenArea * area, unsigned offScreenCounter)
-{
- unsigned age;
-
- if (area->state == ExaOffscreenAvail)
- return;
-
- age = offScreenCounter - area->last_use;
-
- /* This is unlikely to happen, but could result in a division by zero... */
- if (age > (UINT_MAX / 2)) {
- age = UINT_MAX / 2;
- area->last_use = offScreenCounter - age;
- }
-
- area->eviction_cost = area->size / age;
-}
-
-static ExaOffscreenArea *
-exaFindAreaToEvict(ExaScreenPrivPtr pExaScr, int size, int align)
-{
- ExaOffscreenArea *begin, *end, *best;
- unsigned cost, best_cost;
- int avail, real_size;
-
- best_cost = UINT_MAX;
- begin = end = pExaScr->info->offScreenAreas;
- avail = 0;
- cost = 0;
- best = 0;
-
- while (end != NULL) {
- restart:
- while (begin != NULL && begin->state == ExaOffscreenLocked)
- begin = end = begin->next;
-
- if (begin == NULL)
- break;
-
- /* adjust size needed to account for alignment loss for this area */
- real_size = size + (begin->base_offset + begin->size - size) % align;
-
- while (avail < real_size && end != NULL) {
- if (end->state == ExaOffscreenLocked) {
- /* Can't more room here, restart after this locked area */
- avail = 0;
- cost = 0;
- begin = end;
- goto restart;
- }
- avail += end->size;
- exaUpdateEvictionCost(end, pExaScr->offScreenCounter);
- cost += end->eviction_cost;
- end = end->next;
- }
-
- /* Check the cost, update best */
- if (avail >= real_size && cost < best_cost) {
- best = begin;
- best_cost = cost;
- }
-
- avail -= begin->size;
- cost -= begin->eviction_cost;
- begin = begin->next;
- }
-
- return best;
-}
-
-/**
- * exaOffscreenAlloc allocates offscreen memory
- *
- * @param pScreen current screen
- * @param size size in bytes of the allocation
- * @param align byte alignment requirement for the offset of the allocated area
- * @param locked whether the allocated area is locked and can't be kicked out
- * @param save callback for when the area is evicted from memory
- * @param privdata private data for the save callback.
- *
- * Allocates offscreen memory from the device associated with pScreen. size
- * and align determine where and how large the allocated area is, and locked
- * will mark whether it should be held in card memory. privdata may be any
- * pointer for the save callback when the area is removed.
- *
- * Note that locked areas do get evicted on VT switch unless the driver
- * requested version 2.1 or newer behavior. In that case, the save callback is
- * still called.
- */
-ExaOffscreenArea *
-exaOffscreenAlloc(ScreenPtr pScreen, int size, int align,
- Bool locked, ExaOffscreenSaveProc save, void *privData)
-{
- ExaOffscreenArea *area;
-
- ExaScreenPriv(pScreen);
- int real_size = 0, largest_avail = 0;
-
-#if DEBUG_OFFSCREEN
- static int number = 0;
-
- ErrorF("================= ============ allocating a new pixmap %d\n",
- ++number);
-#endif
-
- ExaOffscreenValidate(pScreen);
- if (!align)
- align = 1;
-
- if (!size) {
- DBG_OFFSCREEN(("Alloc 0x%x -> EMPTY\n", size));
- return NULL;
- }
-
- /* throw out requests that cannot fit */
- if (size > (pExaScr->info->memorySize - pExaScr->info->offScreenBase)) {
- DBG_OFFSCREEN(("Alloc 0x%x vs (0x%lx) -> TOBIG\n", size,
- pExaScr->info->memorySize -
- pExaScr->info->offScreenBase));
- return NULL;
- }
-
- /* Try to find a free space that'll fit. */
- for (area = pExaScr->info->offScreenAreas; area; area = area->next) {
- /* skip allocated areas */
- if (area->state != ExaOffscreenAvail)
- continue;
-
- /* adjust size to match alignment requirement */
- real_size = size + (area->base_offset + area->size - size) % align;
-
- /* does it fit? */
- if (real_size <= area->size)
- break;
-
- if (area->size > largest_avail)
- largest_avail = area->size;
- }
-
- if (!area) {
- area = exaFindAreaToEvict(pExaScr, size, align);
-
- if (!area) {
- DBG_OFFSCREEN(("Alloc 0x%x -> NOSPACE\n", size));
- /* Could not allocate memory */
- ExaOffscreenValidate(pScreen);
- return NULL;
- }
-
- /* adjust size needed to account for alignment loss for this area */
- real_size = size + (area->base_offset + area->size - size) % align;
-
- /*
- * Kick out first area if in use
- */
- if (area->state != ExaOffscreenAvail)
- area = ExaOffscreenKickOut(pScreen, area);
- /*
- * Now get the system to merge the other needed areas together
- */
- while (area->size < real_size) {
- assert(area->next);
- assert(area->next->state == ExaOffscreenRemovable);
- (void) ExaOffscreenKickOut(pScreen, area->next);
- }
- }
-
- /* save extra space in new area */
- if (real_size < area->size) {
- ExaOffscreenArea *new_area = malloc(sizeof(ExaOffscreenArea));
-
- if (!new_area)
- return NULL;
- new_area->base_offset = area->base_offset;
-
- new_area->offset = new_area->base_offset;
- new_area->align = 0;
- new_area->size = area->size - real_size;
- new_area->state = ExaOffscreenAvail;
- new_area->save = NULL;
- new_area->last_use = 0;
- new_area->eviction_cost = 0;
- new_area->next = area;
- new_area->prev = area->prev;
- if (area->prev->next)
- area->prev->next = new_area;
- else
- pExaScr->info->offScreenAreas = new_area;
- area->prev = new_area;
- area->base_offset = new_area->base_offset + new_area->size;
- area->size = real_size;
- }
- else
- pExaScr->numOffscreenAvailable--;
-
- /*
- * Mark this area as in use
- */
- if (locked)
- area->state = ExaOffscreenLocked;
- else
- area->state = ExaOffscreenRemovable;
- area->privData = privData;
- area->save = save;
- area->last_use = pExaScr->offScreenCounter++;
- area->offset = (area->base_offset + align - 1);
- area->offset -= area->offset % align;
- area->align = align;
-
- ExaOffscreenValidate(pScreen);
-
- DBG_OFFSCREEN(("Alloc 0x%x -> 0x%x (0x%x)\n", size,
- area->base_offset, area->offset));
- return area;
-}
-
-/**
- * Ejects all offscreen areas, and uninitializes the offscreen memory manager.
- */
-void
-ExaOffscreenSwapOut(ScreenPtr pScreen)
-{
- ExaScreenPriv(pScreen);
-
- ExaOffscreenValidate(pScreen);
- /* loop until a single free area spans the space */
- for (;;) {
- ExaOffscreenArea *area = pExaScr->info->offScreenAreas;
-
- if (!area)
- break;
- if (area->state == ExaOffscreenAvail) {
- area = area->next;
- if (!area)
- break;
- }
- assert(area->state != ExaOffscreenAvail);
- (void) ExaOffscreenKickOut(pScreen, area);
- ExaOffscreenValidate(pScreen);
- }
- ExaOffscreenValidate(pScreen);
- ExaOffscreenFini(pScreen);
-}
-
-/** Ejects all pixmaps managed by EXA. */
-static void
-ExaOffscreenEjectPixmaps(ScreenPtr pScreen)
-{
- ExaScreenPriv(pScreen);
-
- ExaOffscreenValidate(pScreen);
- /* loop until a single free area spans the space */
- for (;;) {
- ExaOffscreenArea *area;
-
- for (area = pExaScr->info->offScreenAreas; area != NULL;
- area = area->next) {
- if (area->state == ExaOffscreenRemovable &&
- area->save == exaPixmapSave) {
- (void) ExaOffscreenKickOut(pScreen, area);
- ExaOffscreenValidate(pScreen);
- break;
- }
- }
- if (area == NULL)
- break;
- }
- ExaOffscreenValidate(pScreen);
-}
-
-void
-ExaOffscreenSwapIn(ScreenPtr pScreen)
-{
- exaOffscreenInit(pScreen);
-}
-
-/**
- * Prepares EXA for disabling of FB access, or restoring it.
- *
- * In version 2.1, the disabling results in pixmaps being ejected, while other
- * allocations remain. With this plus the prevention of migration while
- * swappedOut is set, EXA by itself should not cause any access of the
- * framebuffer to occur while swapped out. Any remaining issues are the
- * responsibility of the driver.
- *
- * Prior to version 2.1, all allocations, including locked ones, are ejected
- * when access is disabled, and the allocator is torn down while swappedOut
- * is set. This is more drastic, and caused implementation difficulties for
- * many drivers that could otherwise handle the lack of FB access while
- * swapped out.
- */
-void
-exaEnableDisableFBAccess(ScreenPtr pScreen, Bool enable)
-{
- ExaScreenPriv(pScreen);
-
- if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS)
- return;
-
- if (!enable && pExaScr->disableFbCount++ == 0) {
- if (pExaScr->info->exa_minor < 1)
- ExaOffscreenSwapOut(pScreen);
- else
- ExaOffscreenEjectPixmaps(pScreen);
- pExaScr->swappedOut = TRUE;
- }
-
- if (enable && --pExaScr->disableFbCount == 0) {
- if (pExaScr->info->exa_minor < 1)
- ExaOffscreenSwapIn(pScreen);
- pExaScr->swappedOut = FALSE;
- }
-}
-
-/* merge the next free area into this one */
-static void
-ExaOffscreenMerge(ExaScreenPrivPtr pExaScr, ExaOffscreenArea * area)
-{
- ExaOffscreenArea *next = area->next;
-
- /* account for space */
- area->size += next->size;
- /* frob pointer */
- area->next = next->next;
- if (area->next)
- area->next->prev = area;
- else
- pExaScr->info->offScreenAreas->prev = area;
- free(next);
-
- pExaScr->numOffscreenAvailable--;
-}
-
-/**
- * exaOffscreenFree frees an allocation.
- *
- * @param pScreen current screen
- * @param area offscreen area to free
- *
- * exaOffscreenFree frees an allocation created by exaOffscreenAlloc. Note that
- * the save callback of the area is not called, and it is up to the driver to
- * do any cleanup necessary as a result.
- *
- * @return pointer to the newly freed area. This behavior should not be relied
- * on.
- */
-ExaOffscreenArea *
-exaOffscreenFree(ScreenPtr pScreen, ExaOffscreenArea * area)
-{
- ExaScreenPriv(pScreen);
- ExaOffscreenArea *next = area->next;
- ExaOffscreenArea *prev;
-
- DBG_OFFSCREEN(("Free 0x%x -> 0x%x (0x%x)\n", area->size,
- area->base_offset, area->offset));
- ExaOffscreenValidate(pScreen);
-
- area->state = ExaOffscreenAvail;
- area->save = NULL;
- area->last_use = 0;
- area->eviction_cost = 0;
- /*
- * Find previous area
- */
- if (area == pExaScr->info->offScreenAreas)
- prev = NULL;
- else
- prev = area->prev;
-
- pExaScr->numOffscreenAvailable++;
-
- /* link with next area if free */
- if (next && next->state == ExaOffscreenAvail)
- ExaOffscreenMerge(pExaScr, area);
-
- /* link with prev area if free */
- if (prev && prev->state == ExaOffscreenAvail) {
- area = prev;
- ExaOffscreenMerge(pExaScr, area);
- }
-
- ExaOffscreenValidate(pScreen);
- DBG_OFFSCREEN(("\tdone freeing\n"));
- return area;
-}
-
-void
-ExaOffscreenMarkUsed(PixmapPtr pPixmap)
-{
- ExaPixmapPriv(pPixmap);
- ExaScreenPriv(pPixmap->drawable.pScreen);
-
- if (!pExaPixmap || !pExaPixmap->area)
- return;
-
- pExaPixmap->area->last_use = pExaScr->offScreenCounter++;
-}
-
-/**
- * Defragment offscreen memory by compacting allocated areas at the end of it,
- * leaving the total amount of memory available as a single area at the
- * beginning (when there are no pinned allocations).
- */
-_X_HIDDEN ExaOffscreenArea *
-ExaOffscreenDefragment(ScreenPtr pScreen)
-{
- ExaScreenPriv(pScreen);
- ExaOffscreenArea *area, *largest_available = NULL;
- int largest_size = 0;
- PixmapPtr pDstPix;
- ExaPixmapPrivPtr pExaDstPix;
-
- pDstPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, 0, 0);
-
- if (!pDstPix)
- return NULL;
-
- pExaDstPix = ExaGetPixmapPriv(pDstPix);
- pExaDstPix->use_gpu_copy = TRUE;
-
- for (area = pExaScr->info->offScreenAreas->prev;
- area != pExaScr->info->offScreenAreas;) {
- ExaOffscreenArea *prev = area->prev;
- PixmapPtr pSrcPix;
- ExaPixmapPrivPtr pExaSrcPix;
- Bool save_use_gpu_copy;
- int save_pitch;
-
- if (area->state != ExaOffscreenAvail ||
- prev->state == ExaOffscreenLocked ||
- (prev->state == ExaOffscreenRemovable &&
- prev->save != exaPixmapSave)) {
- area = prev;
- continue;
- }
-
- if (prev->state == ExaOffscreenAvail) {
- if (area == largest_available) {
- largest_available = prev;
- largest_size += prev->size;
- }
- area = prev;
- ExaOffscreenMerge(pExaScr, area);
- continue;
- }
-
- if (area->size > largest_size) {
- largest_available = area;
- largest_size = area->size;
- }
-
- pSrcPix = prev->privData;
- pExaSrcPix = ExaGetPixmapPriv(pSrcPix);
-
- pExaDstPix->fb_ptr = pExaScr->info->memoryBase +
- area->base_offset + area->size - prev->size + prev->base_offset -
- prev->offset;
- pExaDstPix->fb_ptr -= (unsigned long) pExaDstPix->fb_ptr % prev->align;
-
- if (pExaDstPix->fb_ptr <= pExaSrcPix->fb_ptr) {
- area = prev;
- continue;
- }
-
- if (!(pExaScr->info->flags & EXA_SUPPORTS_OFFSCREEN_OVERLAPS) &&
- (pExaSrcPix->fb_ptr + prev->size) > pExaDstPix->fb_ptr) {
- area = prev;
- continue;
- }
-
- save_use_gpu_copy = pExaSrcPix->use_gpu_copy;
- save_pitch = pSrcPix->devKind;
-
- pExaSrcPix->use_gpu_copy = TRUE;
- pSrcPix->devKind = pExaSrcPix->fb_pitch;
-
- pDstPix->drawable.width = pSrcPix->drawable.width;
- pDstPix->devKind = pSrcPix->devKind;
- pDstPix->drawable.height = pSrcPix->drawable.height;
- pDstPix->drawable.depth = pSrcPix->drawable.depth;
- pDstPix->drawable.bitsPerPixel = pSrcPix->drawable.bitsPerPixel;
-
- if (!pExaScr->info->PrepareCopy(pSrcPix, pDstPix, -1, -1, GXcopy, ~0)) {
- pExaSrcPix->use_gpu_copy = save_use_gpu_copy;
- pSrcPix->devKind = save_pitch;
- area = prev;
- continue;
- }
-
- pExaScr->info->Copy(pDstPix, 0, 0, 0, 0, pDstPix->drawable.width,
- pDstPix->drawable.height);
- pExaScr->info->DoneCopy(pDstPix);
- exaMarkSync(pScreen);
-
- DBG_OFFSCREEN(("Before swap: prev=0x%08x-0x%08x-0x%08x area=0x%08x-0x%08x-0x%08x\n", prev->base_offset, prev->offset, prev->base_offset + prev->size, area->base_offset, area->offset, area->base_offset + area->size));
-
- /* Calculate swapped area offsets and sizes */
- area->base_offset = prev->base_offset;
- area->offset = area->base_offset;
- prev->offset += pExaDstPix->fb_ptr - pExaSrcPix->fb_ptr;
- assert(prev->offset >= pExaScr->info->offScreenBase);
- assert(prev->offset < pExaScr->info->memorySize);
- prev->base_offset = prev->offset;
- if (area->next)
- prev->size = area->next->base_offset - prev->base_offset;
- else
- prev->size = pExaScr->info->memorySize - prev->base_offset;
- area->size = prev->base_offset - area->base_offset;
-
- DBG_OFFSCREEN(("After swap: area=0x%08x-0x%08x-0x%08x prev=0x%08x-0x%08x-0x%08x\n", area->base_offset, area->offset, area->base_offset + area->size, prev->base_offset, prev->offset, prev->base_offset + prev->size));
-
- /* Swap areas in list */
- if (area->next)
- area->next->prev = prev;
- else
- pExaScr->info->offScreenAreas->prev = prev;
- if (prev->prev->next)
- prev->prev->next = area;
- else
- pExaScr->info->offScreenAreas = area;
- prev->next = area->next;
- area->next = prev;
- area->prev = prev->prev;
- prev->prev = area;
- if (!area->prev->next)
- pExaScr->info->offScreenAreas = area;
-
-#if DEBUG_OFFSCREEN
- if (prev->prev == prev || prev->next == prev)
- ErrorF("Whoops, prev points to itself!\n");
-
- if (area->prev == area || area->next == area)
- ErrorF("Whoops, area points to itself!\n");
-#endif
-
- pExaSrcPix->fb_ptr = pExaDstPix->fb_ptr;
- pExaSrcPix->use_gpu_copy = save_use_gpu_copy;
- pSrcPix->devKind = save_pitch;
- }
-
- pDstPix->drawable.width = 0;
- pDstPix->drawable.height = 0;
- pDstPix->drawable.depth = 0;
- pDstPix->drawable.bitsPerPixel = 0;
-
- (*pScreen->DestroyPixmap) (pDstPix);
-
- if (area->state == ExaOffscreenAvail && area->size > largest_size)
- return area;
-
- return largest_available;
-}
-
-/**
- * exaOffscreenInit initializes the offscreen memory manager.
- *
- * @param pScreen current screen
- *
- * exaOffscreenInit is called by exaDriverInit to set up the memory manager for
- * the screen, if any offscreen memory is available.
- */
-Bool
-exaOffscreenInit(ScreenPtr pScreen)
-{
- ExaScreenPriv(pScreen);
- ExaOffscreenArea *area;
-
- /* Allocate a big free area */
- area = malloc(sizeof(ExaOffscreenArea));
-
- if (!area)
- return FALSE;
-
- area->state = ExaOffscreenAvail;
- area->base_offset = pExaScr->info->offScreenBase;
- area->offset = area->base_offset;
- area->align = 0;
- area->size = pExaScr->info->memorySize - area->base_offset;
- area->save = NULL;
- area->next = NULL;
- area->prev = area;
- area->last_use = 0;
- area->eviction_cost = 0;
-
- /* Add it to the free areas */
- pExaScr->info->offScreenAreas = area;
- pExaScr->offScreenCounter = 1;
- pExaScr->numOffscreenAvailable = 1;
-
- ExaOffscreenValidate(pScreen);
-
- return TRUE;
-}
-
-void
-ExaOffscreenFini(ScreenPtr pScreen)
-{
- ExaScreenPriv(pScreen);
- ExaOffscreenArea *area;
-
- /* just free all of the area records */
- while ((area = pExaScr->info->offScreenAreas)) {
- pExaScr->info->offScreenAreas = area->next;
- free(area);
- }
-}
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
deleted file mode 100644
index 4468487e6..000000000
--- a/exa/exa_priv.h
+++ /dev/null
@@ -1,735 +0,0 @@
-/*
- *
- * Copyright (C) 2000 Keith Packard, member of The XFree86 Project, Inc.
- * 2005 Zack Rusin, Trolltech
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-#ifndef EXAPRIV_H
-#define EXAPRIV_H
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "exa.h"
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#ifdef MITSHM
-#include "shmint.h"
-#endif
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "servermd.h"
-#include "colormapst.h"
-#include "gcstruct.h"
-#include "input.h"
-#include "mipointer.h"
-#include "mi.h"
-#include "dix.h"
-#include "fb.h"
-#include "fboverlay.h"
-#include "fbpict.h"
-#include "glyphstr.h"
-#include "damage.h"
-
-#define DEBUG_TRACE_FALL 0
-#define DEBUG_MIGRATE 0
-#define DEBUG_PIXMAP 0
-#define DEBUG_OFFSCREEN 0
-#define DEBUG_GLYPH_CACHE 0
-
-#if DEBUG_TRACE_FALL
-#define EXA_FALLBACK(x) \
-do { \
- ErrorF("EXA fallback at %s: ", __FUNCTION__); \
- ErrorF x; \
-} while (0)
-
-char
- exaDrawableLocation(DrawablePtr pDrawable);
-#else
-#define EXA_FALLBACK(x)
-#endif
-
-#if DEBUG_PIXMAP
-#define DBG_PIXMAP(a) ErrorF a
-#else
-#define DBG_PIXMAP(a)
-#endif
-
-#ifndef EXA_MAX_FB
-#define EXA_MAX_FB FB_OVERLAY_MAX
-#endif
-
-#ifdef DEBUG
-#define EXA_FatalErrorDebug(x) FatalError x
-#define EXA_FatalErrorDebugWithRet(x, ret) FatalError x
-#else
-#define EXA_FatalErrorDebug(x) ErrorF x
-#define EXA_FatalErrorDebugWithRet(x, ret) \
-do { \
- ErrorF x; \
- return ret; \
-} while (0)
-#endif
-
-/**
- * This is the list of migration heuristics supported by EXA. See
- * exaDoMigration() for what their implementations do.
- */
-enum ExaMigrationHeuristic {
- ExaMigrationGreedy,
- ExaMigrationAlways,
- ExaMigrationSmart
-};
-
-typedef struct {
- unsigned char sha1[20];
-} ExaCachedGlyphRec, *ExaCachedGlyphPtr;
-
-typedef struct {
- /* The identity of the cache, statically configured at initialization */
- unsigned int format;
- int glyphWidth;
- int glyphHeight;
-
- int size; /* Size of cache; eventually this should be dynamically determined */
-
- /* Hash table mapping from glyph sha1 to position in the glyph; we use
- * open addressing with a hash table size determined based on size and large
- * enough so that we always have a good amount of free space, so we can
- * use linear probing. (Linear probing is preferable to double hashing
- * here because it allows us to easily remove entries.)
- */
- int *hashEntries;
- int hashSize;
-
- ExaCachedGlyphPtr glyphs;
- int glyphCount; /* Current number of glyphs */
-
- PicturePtr picture; /* Where the glyphs of the cache are stored */
- int yOffset; /* y location within the picture where the cache starts */
- int columns; /* Number of columns the glyphs are laid out in */
- int evictionPosition; /* Next random position to evict a glyph */
-} ExaGlyphCacheRec, *ExaGlyphCachePtr;
-
-#define EXA_NUM_GLYPH_CACHES 4
-
-#define EXA_FALLBACK_COPYWINDOW (1 << 0)
-#define EXA_ACCEL_COPYWINDOW (1 << 1)
-
-typedef struct _ExaMigrationRec {
- Bool as_dst;
- Bool as_src;
- PixmapPtr pPix;
- RegionPtr pReg;
-} ExaMigrationRec, *ExaMigrationPtr;
-
-typedef void (*EnableDisableFBAccessProcPtr) (ScreenPtr, Bool);
-typedef struct {
- ExaDriverPtr info;
- ScreenBlockHandlerProcPtr SavedBlockHandler;
- ScreenWakeupHandlerProcPtr SavedWakeupHandler;
- CreateGCProcPtr SavedCreateGC;
- CloseScreenProcPtr SavedCloseScreen;
- GetImageProcPtr SavedGetImage;
- GetSpansProcPtr SavedGetSpans;
- CreatePixmapProcPtr SavedCreatePixmap;
- DestroyPixmapProcPtr SavedDestroyPixmap;
- CopyWindowProcPtr SavedCopyWindow;
- ChangeWindowAttributesProcPtr SavedChangeWindowAttributes;
- BitmapToRegionProcPtr SavedBitmapToRegion;
- CreateScreenResourcesProcPtr SavedCreateScreenResources;
- ModifyPixmapHeaderProcPtr SavedModifyPixmapHeader;
- SharePixmapBackingProcPtr SavedSharePixmapBacking;
- SetSharedPixmapBackingProcPtr SavedSetSharedPixmapBacking;
- SourceValidateProcPtr SavedSourceValidate;
- CompositeProcPtr SavedComposite;
- TrianglesProcPtr SavedTriangles;
- GlyphsProcPtr SavedGlyphs;
- TrapezoidsProcPtr SavedTrapezoids;
- AddTrapsProcPtr SavedAddTraps;
- void (*do_migration) (ExaMigrationPtr pixmaps, int npixmaps,
- Bool can_accel);
- Bool (*pixmap_has_gpu_copy) (PixmapPtr pPixmap);
- void (*do_move_in_pixmap) (PixmapPtr pPixmap);
- void (*do_move_out_pixmap) (PixmapPtr pPixmap);
- void (*prepare_access_reg) (PixmapPtr pPixmap, int index, RegionPtr pReg);
-
- Bool swappedOut;
- enum ExaMigrationHeuristic migration;
- Bool checkDirtyCorrectness;
- unsigned disableFbCount;
- Bool optimize_migration;
- unsigned offScreenCounter;
- unsigned numOffscreenAvailable;
- CARD32 lastDefragment;
- CARD32 nextDefragment;
- PixmapPtr deferred_mixed_pixmap;
-
- /* Reference counting for accessed pixmaps */
- struct {
- PixmapPtr pixmap;
- int count;
- Bool retval;
- } access[EXA_NUM_PREPARE_INDICES];
-
- /* Holds information on fallbacks that cannot be relayed otherwise. */
- unsigned int fallback_flags;
- unsigned int fallback_counter;
-
- ExaGlyphCacheRec glyphCaches[EXA_NUM_GLYPH_CACHES];
-
- /**
- * Regions affected by fallback composite source / mask operations.
- */
-
- RegionRec srcReg;
- RegionRec maskReg;
- PixmapPtr srcPix;
- PixmapPtr maskPix;
-
- DevPrivateKeyRec pixmapPrivateKeyRec;
- DevPrivateKeyRec gcPrivateKeyRec;
-} ExaScreenPrivRec, *ExaScreenPrivPtr;
-
-extern DevPrivateKeyRec exaScreenPrivateKeyRec;
-
-#define exaScreenPrivateKey (&exaScreenPrivateKeyRec)
-
-#define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)dixGetPrivate(&(s)->devPrivates, exaScreenPrivateKey))
-#define ExaScreenPriv(s) ExaScreenPrivPtr pExaScr = ExaGetScreenPriv(s)
-
-#define ExaGetGCPriv(gc) ((ExaGCPrivPtr)dixGetPrivateAddr(&(gc)->devPrivates, &ExaGetScreenPriv(gc->pScreen)->gcPrivateKeyRec))
-#define ExaGCPriv(gc) ExaGCPrivPtr pExaGC = ExaGetGCPriv(gc)
-
-/*
- * Some macros to deal with function wrapping.
- */
-#define wrap(priv, real, mem, func) {\
- priv->Saved##mem = real->mem; \
- real->mem = func; \
-}
-
-#define unwrap(priv, real, mem) {\
- real->mem = priv->Saved##mem; \
-}
-
-#ifdef HAVE_TYPEOF
-#define swap(priv, real, mem) {\
- typeof(real->mem) tmp = priv->Saved##mem; \
- priv->Saved##mem = real->mem; \
- real->mem = tmp; \
-}
-#else
-#define swap(priv, real, mem) {\
- const void *tmp = priv->Saved##mem; \
- priv->Saved##mem = real->mem; \
- real->mem = tmp; \
-}
-#endif
-
-#define EXA_PRE_FALLBACK(_screen_) \
- ExaScreenPriv(_screen_); \
- pExaScr->fallback_counter++;
-
-#define EXA_POST_FALLBACK(_screen_) \
- pExaScr->fallback_counter--;
-
-#define EXA_PRE_FALLBACK_GC(_gc_) \
- ExaScreenPriv(_gc_->pScreen); \
- ExaGCPriv(_gc_); \
- pExaScr->fallback_counter++; \
- swap(pExaGC, _gc_, ops);
-
-#define EXA_POST_FALLBACK_GC(_gc_) \
- pExaScr->fallback_counter--; \
- swap(pExaGC, _gc_, ops);
-
-/** Align an offset to an arbitrary alignment */
-#define EXA_ALIGN(offset, align) (((offset) + (align) - 1) - \
- (((offset) + (align) - 1) % (align)))
-/** Align an offset to a power-of-two alignment */
-#define EXA_ALIGN2(offset, align) (((offset) + (align) - 1) & ~((align) - 1))
-
-#define EXA_PIXMAP_SCORE_MOVE_IN 10
-#define EXA_PIXMAP_SCORE_MAX 20
-#define EXA_PIXMAP_SCORE_MOVE_OUT -10
-#define EXA_PIXMAP_SCORE_MIN -20
-#define EXA_PIXMAP_SCORE_PINNED 1000
-#define EXA_PIXMAP_SCORE_INIT 1001
-
-#define ExaGetPixmapPriv(p) ((ExaPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &ExaGetScreenPriv((p)->drawable.pScreen)->pixmapPrivateKeyRec))
-#define ExaPixmapPriv(p) ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p)
-
-#define EXA_RANGE_PITCH (1 << 0)
-#define EXA_RANGE_WIDTH (1 << 1)
-#define EXA_RANGE_HEIGHT (1 << 2)
-
-typedef struct {
- ExaOffscreenArea *area;
- int score; /**< score for the move-in vs move-out heuristic */
- Bool use_gpu_copy;
-
- CARD8 *sys_ptr; /**< pointer to pixmap data in system memory */
- int sys_pitch; /**< pitch of pixmap in system memory */
-
- CARD8 *fb_ptr; /**< pointer to pixmap data in framebuffer memory */
- int fb_pitch; /**< pitch of pixmap in framebuffer memory */
- unsigned int fb_size; /**< size of pixmap in framebuffer memory */
-
- /**
- * Holds information about whether this pixmap can be used for
- * acceleration (== 0) or not (> 0).
- *
- * Contains a OR'ed combination of the following values:
- * EXA_RANGE_PITCH - set if the pixmap's pitch is out of range
- * EXA_RANGE_WIDTH - set if the pixmap's width is out of range
- * EXA_RANGE_HEIGHT - set if the pixmap's height is out of range
- */
- unsigned int accel_blocked;
-
- /**
- * The damage record contains the areas of the pixmap's current location
- * (framebuffer or system) that have been damaged compared to the other
- * location.
- */
- DamagePtr pDamage;
- /**
- * The valid regions mark the valid bits (at least, as they're derived from
- * damage, which may be overreported) of a pixmap's system and FB copies.
- */
- RegionRec validSys, validFB;
- /**
- * Driver private storage per EXA pixmap
- */
- void *driverPriv;
-} ExaPixmapPrivRec, *ExaPixmapPrivPtr;
-
-typedef struct {
- /* GC values from the layer below. */
- const GCOps *Savedops;
- const GCFuncs *Savedfuncs;
-} ExaGCPrivRec, *ExaGCPrivPtr;
-
-typedef struct {
- PicturePtr pDst;
- INT16 xSrc;
- INT16 ySrc;
- INT16 xMask;
- INT16 yMask;
- INT16 xDst;
- INT16 yDst;
- INT16 width;
- INT16 height;
-} ExaCompositeRectRec, *ExaCompositeRectPtr;
-
-/**
- * exaDDXDriverInit must be implemented by the DDX using EXA, and is the place
- * to set EXA options or hook in screen functions to handle using EXA as the AA.
- */
-void exaDDXDriverInit(ScreenPtr pScreen);
-
-/* exa_unaccel.c */
-void
- exaPrepareAccessGC(GCPtr pGC);
-
-void
- exaFinishAccessGC(GCPtr pGC);
-
-void
-
-ExaCheckFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nspans,
- DDXPointPtr ppt, int *pwidth, int fSorted);
-
-void
-
-ExaCheckSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
- DDXPointPtr ppt, int *pwidth, int nspans, int fSorted);
-
-void
-
-ExaCheckPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
- int x, int y, int w, int h, int leftPad, int format,
- char *bits);
-
-void
-
-ExaCheckCopyNtoN(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- BoxPtr pbox, int nbox, int dx, int dy, Bool reverse,
- Bool upsidedown, Pixel bitplane, void *closure);
-
-RegionPtr
-
-ExaCheckCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int w, int h, int dstx, int dsty);
-
-RegionPtr
-
-ExaCheckCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int w, int h, int dstx, int dsty,
- unsigned long bitPlane);
-
-void
-
-ExaCheckPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
- DDXPointPtr pptInit);
-
-void
-
-ExaCheckPolylines(DrawablePtr pDrawable, GCPtr pGC,
- int mode, int npt, DDXPointPtr ppt);
-
-void
-
-ExaCheckPolySegment(DrawablePtr pDrawable, GCPtr pGC,
- int nsegInit, xSegment * pSegInit);
-
-void
- ExaCheckPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * pArcs);
-
-void
-
-ExaCheckPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
- int nrect, xRectangle *prect);
-
-void
-
-ExaCheckImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr * ppci, void *pglyphBase);
-
-void
-
-ExaCheckPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr * ppci, void *pglyphBase);
-
-void
-
-ExaCheckPushPixels(GCPtr pGC, PixmapPtr pBitmap,
- DrawablePtr pDrawable, int w, int h, int x, int y);
-
-void
- ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
-
-void
-
-ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
- unsigned int format, unsigned long planeMask, char *d);
-
-void
-
-ExaCheckGetSpans(DrawablePtr pDrawable,
- int wMax,
- DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart);
-
-void
-
-ExaCheckAddTraps(PicturePtr pPicture,
- INT16 x_off, INT16 y_off, int ntrap, xTrap * traps);
-
-/* exa_accel.c */
-
-static _X_INLINE Bool
-exaGCReadsDestination(DrawablePtr pDrawable, unsigned long planemask,
- unsigned int fillStyle, unsigned char alu,
- Bool clientClip)
-{
- return ((alu != GXcopy && alu != GXclear && alu != GXset &&
- alu != GXcopyInverted) || fillStyle == FillStippled ||
- clientClip != FALSE || !EXA_PM_IS_SOLID(pDrawable, planemask));
-}
-
-void
- exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
-
-Bool
-
-exaFillRegionTiled(DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
- DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu,
- Bool clientClip);
-
-void
-
-exaGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
- unsigned int format, unsigned long planeMask, char *d);
-
-RegionPtr
-
-exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
- int srcx, int srcy, int width, int height, int dstx, int dsty);
-
-Bool
-
-exaHWCopyNtoN(DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GCPtr pGC,
- BoxPtr pbox,
- int nbox, int dx, int dy, Bool reverse, Bool upsidedown);
-
-void
-
-exaCopyNtoN(DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GCPtr pGC,
- BoxPtr pbox,
- int nbox,
- int dx,
- int dy,
- Bool reverse, Bool upsidedown, Pixel bitplane, void *closure);
-
-extern const GCOps exaOps;
-
-void
-
-ExaCheckComposite(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
-
-void
-
-ExaCheckGlyphs(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs);
-
-/* exa_offscreen.c */
-void
- ExaOffscreenSwapOut(ScreenPtr pScreen);
-
-void
- ExaOffscreenSwapIn(ScreenPtr pScreen);
-
-ExaOffscreenArea *ExaOffscreenDefragment(ScreenPtr pScreen);
-
-Bool
- exaOffscreenInit(ScreenPtr pScreen);
-
-void
- ExaOffscreenFini(ScreenPtr pScreen);
-
-/* exa.c */
-Bool
- ExaDoPrepareAccess(PixmapPtr pPixmap, int index);
-
-void
- exaPrepareAccess(DrawablePtr pDrawable, int index);
-
-void
- exaFinishAccess(DrawablePtr pDrawable, int index);
-
-void
- exaDestroyPixmap(PixmapPtr pPixmap);
-
-void
- exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2);
-
-void
-
-exaGetDrawableDeltas(DrawablePtr pDrawable, PixmapPtr pPixmap,
- int *xp, int *yp);
-
-Bool
- exaPixmapHasGpuCopy(PixmapPtr p);
-
-PixmapPtr
- exaGetOffscreenPixmap(DrawablePtr pDrawable, int *xp, int *yp);
-
-PixmapPtr
- exaGetDrawablePixmap(DrawablePtr pDrawable);
-
-void
-
-exaSetFbPitch(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap,
- int w, int h, int bpp);
-
-void
-
-exaSetAccelBlock(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap,
- int w, int h, int bpp);
-
-void
- exaDoMigration(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
-
-Bool
- exaPixmapIsPinned(PixmapPtr pPix);
-
-extern const GCFuncs exaGCFuncs;
-
-/* exa_classic.c */
-PixmapPtr
-
-exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
- unsigned usage_hint);
-
-Bool
-
-exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height,
- int depth, int bitsPerPixel, int devKind,
- void *pPixData);
-
-Bool
- exaDestroyPixmap_classic(PixmapPtr pPixmap);
-
-Bool
- exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap);
-
-/* exa_driver.c */
-PixmapPtr
-
-exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth,
- unsigned usage_hint);
-
-Bool
-
-exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height,
- int depth, int bitsPerPixel, int devKind,
- void *pPixData);
-
-Bool
- exaDestroyPixmap_driver(PixmapPtr pPixmap);
-
-Bool
- exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap);
-
-/* exa_mixed.c */
-PixmapPtr
-
-exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
- unsigned usage_hint);
-
-Bool
-
-exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
- int bitsPerPixel, int devKind, void *pPixData);
-
-Bool
- exaDestroyPixmap_mixed(PixmapPtr pPixmap);
-
-Bool
- exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap);
-
-/* exa_migration_mixed.c */
-void
- exaCreateDriverPixmap_mixed(PixmapPtr pPixmap);
-
-void
- exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
-
-void
- exaMoveInPixmap_mixed(PixmapPtr pPixmap);
-
-void
- exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure);
-
-void
- exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg);
-
-Bool
-exaSetSharedPixmapBacking_mixed(PixmapPtr pPixmap, void *handle);
-Bool
-exaSharePixmapBacking_mixed(PixmapPtr pPixmap, ScreenPtr secondary, void **handle_p);
-
-/* exa_render.c */
-Bool
- exaOpReadsDestination(CARD8 op);
-
-void
-
-exaComposite(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
-
-void
-
-exaCompositeRects(CARD8 op,
- PicturePtr Src,
- PicturePtr pMask,
- PicturePtr pDst, int nrect, ExaCompositeRectPtr rects);
-
-void
-
-exaTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
- PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
- int ntrap, xTrapezoid * traps);
-
-void
-
-exaTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
- PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
- int ntri, xTriangle * tris);
-
-/* exa_glyph.c */
-void
- exaGlyphsInit(ScreenPtr pScreen);
-
-void
- exaGlyphsFini(ScreenPtr pScreen);
-
-void
-
-exaGlyphs(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs);
-
-/* exa_migration_classic.c */
-void
- exaCopyDirtyToSys(ExaMigrationPtr migrate);
-
-void
- exaCopyDirtyToFb(ExaMigrationPtr migrate);
-
-void
- exaDoMigration_classic(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
-
-void
- exaPixmapSave(ScreenPtr pScreen, ExaOffscreenArea * area);
-
-void
- exaMoveOutPixmap_classic(PixmapPtr pPixmap);
-
-void
- exaMoveInPixmap_classic(PixmapPtr pPixmap);
-
-void
- exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg);
-
-#endif /* EXAPRIV_H */
diff --git a/exa/exa_render.c b/exa/exa_render.c
deleted file mode 100644
index 9fbfdfca2..000000000
--- a/exa/exa_render.c
+++ /dev/null
@@ -1,1229 +0,0 @@
-/*
- * Copyright © 2001 Keith Packard
- *
- * Partly based on code that is Copyright © The XFree86 Project Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdlib.h>
-
-#include "exa_priv.h"
-
-#include "mipict.h"
-
-#if DEBUG_TRACE_FALL
-static void
-exaCompositeFallbackPictDesc(PicturePtr pict, char *string, int n)
-{
- char format[20];
- char size[20];
- char loc;
- int temp;
-
- if (!pict) {
- snprintf(string, n, "None");
- return;
- }
-
- switch (pict->format) {
- case PICT_a8r8g8b8:
- snprintf(format, 20, "ARGB8888");
- break;
- case PICT_x8r8g8b8:
- snprintf(format, 20, "XRGB8888");
- break;
- case PICT_b8g8r8a8:
- snprintf(format, 20, "BGRA8888");
- break;
- case PICT_b8g8r8x8:
- snprintf(format, 20, "BGRX8888");
- break;
- case PICT_r5g6b5:
- snprintf(format, 20, "RGB565 ");
- break;
- case PICT_x1r5g5b5:
- snprintf(format, 20, "RGB555 ");
- break;
- case PICT_a8:
- snprintf(format, 20, "A8 ");
- break;
- case PICT_a1:
- snprintf(format, 20, "A1 ");
- break;
- default:
- snprintf(format, 20, "0x%x", (int) pict->format);
- break;
- }
-
- if (pict->pDrawable) {
- loc = exaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm';
-
- snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
- pict->pDrawable->height, pict->repeat ? " R" : "");
- }
- else {
- loc = '-';
-
- snprintf(size, 20, "%s", pict->repeat ? " R" : "");
- }
-
- snprintf(string, n, "%p:%c fmt %s (%s)", pict->pDrawable, loc, format,
- size);
-}
-
-static void
-exaPrintCompositeFallback(CARD8 op,
- PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst)
-{
- char sop[20];
- char srcdesc[40], maskdesc[40], dstdesc[40];
-
- switch (op) {
- case PictOpSrc:
- snprintf(sop, sizeof(sop), "Src");
- break;
- case PictOpOver:
- snprintf(sop, sizeof(sop), "Over");
- break;
- default:
- snprintf(sop, sizeof(sop), "0x%x", (int) op);
- break;
- }
-
- exaCompositeFallbackPictDesc(pSrc, srcdesc, 40);
- exaCompositeFallbackPictDesc(pMask, maskdesc, 40);
- exaCompositeFallbackPictDesc(pDst, dstdesc, 40);
-
- ErrorF("Composite fallback: op %s, \n"
- " src %s, \n"
- " mask %s, \n"
- " dst %s, \n", sop, srcdesc, maskdesc, dstdesc);
-}
-#endif /* DEBUG_TRACE_FALL */
-
-Bool
-exaOpReadsDestination(CARD8 op)
-{
- /* FALSE (does not read destination) is the list of ops in the protocol
- * document with "0" in the "Fb" column and no "Ab" in the "Fa" column.
- * That's just Clear and Src. ReduceCompositeOp() will already have
- * converted con/disjoint clear/src to Clear or Src.
- */
- switch (op) {
- case PictOpClear:
- case PictOpSrc:
- return FALSE;
- default:
- return TRUE;
- }
-}
-
-static Bool
-exaGetPixelFromRGBA(CARD32 *pixel,
- CARD16 red,
- CARD16 green,
- CARD16 blue, CARD16 alpha, PictFormatPtr pFormat)
-{
- int rbits, bbits, gbits, abits;
- int rshift, bshift, gshift, ashift;
-
- *pixel = 0;
-
- if (!PICT_FORMAT_COLOR(pFormat->format) &&
- PICT_FORMAT_TYPE(pFormat->format) != PICT_TYPE_A)
- return FALSE;
-
- rbits = PICT_FORMAT_R(pFormat->format);
- gbits = PICT_FORMAT_G(pFormat->format);
- bbits = PICT_FORMAT_B(pFormat->format);
- abits = PICT_FORMAT_A(pFormat->format);
-
- rshift = pFormat->direct.red;
- gshift = pFormat->direct.green;
- bshift = pFormat->direct.blue;
- ashift = pFormat->direct.alpha;
-
- *pixel |= (blue >> (16 - bbits)) << bshift;
- *pixel |= (red >> (16 - rbits)) << rshift;
- *pixel |= (green >> (16 - gbits)) << gshift;
- *pixel |= (alpha >> (16 - abits)) << ashift;
-
- return TRUE;
-}
-
-static Bool
-exaGetRGBAFromPixel(CARD32 pixel,
- CARD16 *red,
- CARD16 *green,
- CARD16 *blue,
- CARD16 *alpha,
- PictFormatPtr pFormat, PictFormatShort format)
-{
- int rbits, bbits, gbits, abits;
- int rshift, bshift, gshift, ashift;
-
- if (!PICT_FORMAT_COLOR(format) && PICT_FORMAT_TYPE(format) != PICT_TYPE_A)
- return FALSE;
-
- rbits = PICT_FORMAT_R(format);
- gbits = PICT_FORMAT_G(format);
- bbits = PICT_FORMAT_B(format);
- abits = PICT_FORMAT_A(format);
-
- if (pFormat) {
- rshift = pFormat->direct.red;
- gshift = pFormat->direct.green;
- bshift = pFormat->direct.blue;
- ashift = pFormat->direct.alpha;
- }
- else if (format == PICT_a8r8g8b8) {
- rshift = 16;
- gshift = 8;
- bshift = 0;
- ashift = 24;
- }
- else
- FatalError("EXA bug: exaGetRGBAFromPixel() doesn't match "
- "createSourcePicture()\n");
-
- if (rbits) {
- *red = ((pixel >> rshift) & ((1 << rbits) - 1)) << (16 - rbits);
- while (rbits < 16) {
- *red |= *red >> rbits;
- rbits <<= 1;
- }
-
- *green = ((pixel >> gshift) & ((1 << gbits) - 1)) << (16 - gbits);
- while (gbits < 16) {
- *green |= *green >> gbits;
- gbits <<= 1;
- }
-
- *blue = ((pixel >> bshift) & ((1 << bbits) - 1)) << (16 - bbits);
- while (bbits < 16) {
- *blue |= *blue >> bbits;
- bbits <<= 1;
- }
- }
- else {
- *red = 0x0000;
- *green = 0x0000;
- *blue = 0x0000;
- }
-
- if (abits) {
- *alpha = ((pixel >> ashift) & ((1 << abits) - 1)) << (16 - abits);
- while (abits < 16) {
- *alpha |= *alpha >> abits;
- abits <<= 1;
- }
- }
- else
- *alpha = 0xffff;
-
- return TRUE;
-}
-
-static int
-exaTryDriverSolidFill(PicturePtr pSrc,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
-{
- ExaScreenPriv(pDst->pDrawable->pScreen);
- RegionRec region;
- BoxPtr pbox;
- int nbox;
- int dst_off_x, dst_off_y;
- PixmapPtr pSrcPix, pDstPix;
- ExaPixmapPrivPtr pDstExaPix;
- CARD32 pixel;
- CARD16 red, green, blue, alpha;
-
- pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
- pDstExaPix = ExaGetPixmapPriv(pDstPix);
-
- /* Check whether the accelerator can use the destination pixmap.
- */
- if (pDstExaPix->accel_blocked) {
- return -1;
- }
-
- xDst += pDst->pDrawable->x;
- yDst += pDst->pDrawable->y;
- if (pSrc->pDrawable) {
- xSrc += pSrc->pDrawable->x;
- ySrc += pSrc->pDrawable->y;
- }
-
- if (!miComputeCompositeRegion(&region, pSrc, NULL, pDst,
- xSrc, ySrc, 0, 0, xDst, yDst, width, height))
- return 1;
-
- exaGetDrawableDeltas(pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
-
- RegionTranslate(&region, dst_off_x, dst_off_y);
-
- if (pSrc->pDrawable) {
- pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
- pixel = exaGetPixmapFirstPixel(pSrcPix);
- }
- else
- miRenderColorToPixel(PictureMatchFormat(pDst->pDrawable->pScreen, 32,
- pSrc->format),
- &pSrc->pSourcePict->solidFill.fullcolor,
- &pixel);
-
- if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
- pSrc->pFormat, pSrc->format) ||
- !exaGetPixelFromRGBA(&pixel, red, green, blue, alpha, pDst->pFormat)) {
- RegionUninit(&region);
- return -1;
- }
-
- if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[1];
-
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pDstPix;
- pixmaps[0].pReg = &region;
- exaDoMigration(pixmaps, 1, TRUE);
- }
-
- if (!exaPixmapHasGpuCopy(pDstPix)) {
- RegionUninit(&region);
- return 0;
- }
-
- if (!(*pExaScr->info->PrepareSolid) (pDstPix, GXcopy, 0xffffffff, pixel)) {
- RegionUninit(&region);
- return -1;
- }
-
- nbox = RegionNumRects(&region);
- pbox = RegionRects(&region);
-
- while (nbox--) {
- (*pExaScr->info->Solid) (pDstPix, pbox->x1, pbox->y1, pbox->x2,
- pbox->y2);
- pbox++;
- }
-
- (*pExaScr->info->DoneSolid) (pDstPix);
- exaMarkSync(pDst->pDrawable->pScreen);
-
- RegionUninit(&region);
- return 1;
-}
-
-static int
-exaTryDriverCompositeRects(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- int nrect, ExaCompositeRectPtr rects)
-{
- ExaScreenPriv(pDst->pDrawable->pScreen);
- int src_off_x = 0, src_off_y = 0, mask_off_x = 0, mask_off_y = 0;
- int dst_off_x, dst_off_y;
- PixmapPtr pSrcPix = NULL, pMaskPix = NULL, pDstPix;
- ExaPixmapPrivPtr pSrcExaPix = NULL, pMaskExaPix = NULL, pDstExaPix;
-
- if (!pExaScr->info->PrepareComposite)
- return -1;
-
- if (pSrc->pDrawable) {
- pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
- pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
- }
-
- if (pMask && pMask->pDrawable) {
- pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
- pMaskExaPix = ExaGetPixmapPriv(pMaskPix);
- }
-
- pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
- pDstExaPix = ExaGetPixmapPriv(pDstPix);
-
- /* Check whether the accelerator can use these pixmaps.
- * FIXME: If it cannot, use temporary pixmaps so that the drawing
- * happens within limits.
- */
- if (pDstExaPix->accel_blocked ||
- (pSrcExaPix && pSrcExaPix->accel_blocked) ||
- (pMaskExaPix && pMaskExaPix->accel_blocked)) {
- return -1;
- }
-
- if (pExaScr->info->CheckComposite &&
- !(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst)) {
- return -1;
- }
-
- if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[3];
- int i = 0;
-
- pixmaps[i].as_dst = TRUE;
- pixmaps[i].as_src = exaOpReadsDestination(op);
- pixmaps[i].pPix = pDstPix;
- pixmaps[i].pReg = NULL;
- i++;
-
- if (pSrcPix) {
- pixmaps[i].as_dst = FALSE;
- pixmaps[i].as_src = TRUE;
- pixmaps[i].pPix = pSrcPix;
- pixmaps[i].pReg = NULL;
- i++;
- }
-
- if (pMaskPix) {
- pixmaps[i].as_dst = FALSE;
- pixmaps[i].as_src = TRUE;
- pixmaps[i].pPix = pMaskPix;
- pixmaps[i].pReg = NULL;
- i++;
- }
-
- exaDoMigration(pixmaps, i, TRUE);
- }
-
- pDstPix = exaGetOffscreenPixmap(pDst->pDrawable, &dst_off_x, &dst_off_y);
- if (!pDstPix)
- return 0;
-
- if (pSrcPix) {
- pSrcPix =
- exaGetOffscreenPixmap(pSrc->pDrawable, &src_off_x, &src_off_y);
- if (!pSrcPix)
- return 0;
- }
-
- if (pMaskPix) {
- pMaskPix =
- exaGetOffscreenPixmap(pMask->pDrawable, &mask_off_x, &mask_off_y);
- if (!pMaskPix)
- return 0;
- }
-
- if (!(*pExaScr->info->PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix,
- pMaskPix, pDstPix))
- return -1;
-
- while (nrect--) {
- INT16 xDst = rects->xDst + pDst->pDrawable->x;
- INT16 yDst = rects->yDst + pDst->pDrawable->y;
- INT16 xMask = rects->xMask;
- INT16 yMask = rects->yMask;
- INT16 xSrc = rects->xSrc;
- INT16 ySrc = rects->ySrc;
- RegionRec region;
- BoxPtr pbox;
- int nbox;
-
- if (pMaskPix) {
- xMask += pMask->pDrawable->x;
- yMask += pMask->pDrawable->y;
- }
-
- if (pSrcPix) {
- xSrc += pSrc->pDrawable->x;
- ySrc += pSrc->pDrawable->y;
- }
-
- if (!miComputeCompositeRegion(&region, pSrc, pMask, pDst,
- xSrc, ySrc, xMask, yMask, xDst, yDst,
- rects->width, rects->height))
- goto next_rect;
-
- RegionTranslate(&region, dst_off_x, dst_off_y);
-
- nbox = RegionNumRects(&region);
- pbox = RegionRects(&region);
-
- xMask = xMask + mask_off_x - xDst - dst_off_x;
- yMask = yMask + mask_off_y - yDst - dst_off_y;
- xSrc = xSrc + src_off_x - xDst - dst_off_x;
- ySrc = ySrc + src_off_y - yDst - dst_off_y;
-
- while (nbox--) {
- (*pExaScr->info->Composite) (pDstPix,
- pbox->x1 + xSrc,
- pbox->y1 + ySrc,
- pbox->x1 + xMask,
- pbox->y1 + yMask,
- pbox->x1,
- pbox->y1,
- pbox->x2 - pbox->x1,
- pbox->y2 - pbox->y1);
- pbox++;
- }
-
- next_rect:
- RegionUninit(&region);
-
- rects++;
- }
-
- (*pExaScr->info->DoneComposite) (pDstPix);
- exaMarkSync(pDst->pDrawable->pScreen);
-
- return 1;
-}
-
-/**
- * Copy a number of rectangles from source to destination in a single
- * operation. This is specialized for glyph rendering: we don't have the
- * special-case fallbacks found in exaComposite() - if the driver can support
- * it, we use the driver functionality, otherwise we fall back straight to
- * software.
- */
-void
-exaCompositeRects(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst, int nrect, ExaCompositeRectPtr rects)
-{
- ExaScreenPriv(pDst->pDrawable->pScreen);
- int n;
- ExaCompositeRectPtr r;
- int ret;
-
- /* If we get a mask, that means we're rendering to the exaGlyphs
- * destination directly, so the damage layer takes care of this.
- */
- if (!pMask) {
- RegionRec region;
- int x1 = MAXSHORT;
- int y1 = MAXSHORT;
- int x2 = MINSHORT;
- int y2 = MINSHORT;
- BoxRec box;
-
- /* We have to manage the damage ourselves, since CompositeRects isn't
- * something in the screen that can be managed by the damage extension,
- * and EXA depends on damage to track what needs to be migrated between
- * the gpu and the cpu.
- */
-
- /* Compute the overall extents of the composited region - we're making
- * the assumption here that we are compositing a bunch of glyphs that
- * cluster closely together and damaging each glyph individually would
- * be a loss compared to damaging the bounding box.
- */
- n = nrect;
- r = rects;
- while (n--) {
- int rect_x2 = r->xDst + r->width;
- int rect_y2 = r->yDst + r->height;
-
- if (r->xDst < x1)
- x1 = r->xDst;
- if (r->yDst < y1)
- y1 = r->yDst;
- if (rect_x2 > x2)
- x2 = rect_x2;
- if (rect_y2 > y2)
- y2 = rect_y2;
-
- r++;
- }
-
- if (x2 <= x1 || y2 <= y1)
- return;
-
- box.x1 = x1;
- box.x2 = x2 < MAXSHORT ? x2 : MAXSHORT;
- box.y1 = y1;
- box.y2 = y2 < MAXSHORT ? y2 : MAXSHORT;
-
- /* The pixmap migration code relies on pendingDamage indicating
- * the bounds of the current rendering, so we need to force
- * the actual damage into that region before we do anything, and
- * (see use of DamagePendingRegion in exaCopyDirty)
- */
-
- RegionInit(&region, &box, 1);
-
- DamageRegionAppend(pDst->pDrawable, &region);
-
- RegionUninit(&region);
- }
-
- /************************************************************/
-
- ValidatePicture(pSrc);
- if (pMask)
- ValidatePicture(pMask);
- ValidatePicture(pDst);
-
- ret = exaTryDriverCompositeRects(op, pSrc, pMask, pDst, nrect, rects);
-
- if (ret != 1) {
- if (ret == -1 && op == PictOpOver && pMask && pMask->componentAlpha &&
- (!pExaScr->info->CheckComposite ||
- ((*pExaScr->info->CheckComposite) (PictOpOutReverse, pSrc, pMask,
- pDst) &&
- (*pExaScr->info->CheckComposite) (PictOpAdd, pSrc, pMask,
- pDst)))) {
- ret =
- exaTryDriverCompositeRects(PictOpOutReverse, pSrc, pMask, pDst,
- nrect, rects);
- if (ret == 1) {
- op = PictOpAdd;
- ret = exaTryDriverCompositeRects(op, pSrc, pMask, pDst, nrect,
- rects);
- }
- }
-
- if (ret != 1) {
- n = nrect;
- r = rects;
- while (n--) {
- ExaCheckComposite(op, pSrc, pMask, pDst,
- r->xSrc, r->ySrc,
- r->xMask, r->yMask,
- r->xDst, r->yDst, r->width, r->height);
- r++;
- }
- }
- }
-
- /************************************************************/
-
- if (!pMask) {
- /* Now we have to flush the damage out from pendingDamage => damage
- * Calling DamageRegionProcessPending has that effect.
- */
-
- DamageRegionProcessPending(pDst->pDrawable);
- }
-}
-
-static int
-exaTryDriverComposite(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
-{
- ExaScreenPriv(pDst->pDrawable->pScreen);
- RegionRec region;
- BoxPtr pbox;
- int nbox;
- int src_off_x, src_off_y, mask_off_x = 0, mask_off_y = 0, dst_off_x, dst_off_y;
- PixmapPtr pSrcPix = NULL, pMaskPix = NULL, pDstPix;
- ExaPixmapPrivPtr pSrcExaPix = NULL, pMaskExaPix = NULL, pDstExaPix;
-
- if (pSrc->pDrawable) {
- pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
- pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
- }
-
- pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
- pDstExaPix = ExaGetPixmapPriv(pDstPix);
-
- if (pMask && pMask->pDrawable) {
- pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
- pMaskExaPix = ExaGetPixmapPriv(pMaskPix);
- }
-
- /* Check whether the accelerator can use these pixmaps.
- * FIXME: If it cannot, use temporary pixmaps so that the drawing
- * happens within limits.
- */
- if (pDstExaPix->accel_blocked ||
- (pSrcExaPix && pSrcExaPix->accel_blocked) ||
- (pMaskExaPix && (pMaskExaPix->accel_blocked))) {
- return -1;
- }
-
- xDst += pDst->pDrawable->x;
- yDst += pDst->pDrawable->y;
-
- if (pMaskPix) {
- xMask += pMask->pDrawable->x;
- yMask += pMask->pDrawable->y;
- }
-
- if (pSrcPix) {
- xSrc += pSrc->pDrawable->x;
- ySrc += pSrc->pDrawable->y;
- }
-
- if (pExaScr->info->CheckComposite &&
- !(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst)) {
- return -1;
- }
-
- if (!miComputeCompositeRegion(&region, pSrc, pMask, pDst,
- xSrc, ySrc, xMask, yMask, xDst, yDst,
- width, height))
- return 1;
-
- exaGetDrawableDeltas(pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
-
- RegionTranslate(&region, dst_off_x, dst_off_y);
-
- if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[3];
- int i = 0;
-
- pixmaps[i].as_dst = TRUE;
- pixmaps[i].as_src = exaOpReadsDestination(op);
- pixmaps[i].pPix = pDstPix;
- pixmaps[i].pReg = pixmaps[0].as_src ? NULL : &region;
- i++;
-
- if (pSrcPix) {
- pixmaps[i].as_dst = FALSE;
- pixmaps[i].as_src = TRUE;
- pixmaps[i].pPix = pSrcPix;
- pixmaps[i].pReg = NULL;
- i++;
- }
-
- if (pMaskPix) {
- pixmaps[i].as_dst = FALSE;
- pixmaps[i].as_src = TRUE;
- pixmaps[i].pPix = pMaskPix;
- pixmaps[i].pReg = NULL;
- i++;
- }
-
- exaDoMigration(pixmaps, i, TRUE);
- }
-
- if (pSrcPix) {
- pSrcPix =
- exaGetOffscreenPixmap(pSrc->pDrawable, &src_off_x, &src_off_y);
- if (!pSrcPix) {
- RegionUninit(&region);
- return 0;
- }
- }
-
- if (pMaskPix) {
- pMaskPix = exaGetOffscreenPixmap(pMask->pDrawable, &mask_off_x,
- &mask_off_y);
- if (!pMaskPix) {
- RegionUninit(&region);
- return 0;
- }
- }
-
- if (!exaPixmapHasGpuCopy(pDstPix)) {
- RegionUninit(&region);
- return 0;
- }
-
- if (!(*pExaScr->info->PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix,
- pMaskPix, pDstPix)) {
- RegionUninit(&region);
- return -1;
- }
-
- nbox = RegionNumRects(&region);
- pbox = RegionRects(&region);
-
- xMask = xMask + mask_off_x - xDst - dst_off_x;
- yMask = yMask + mask_off_y - yDst - dst_off_y;
-
- xSrc = xSrc + src_off_x - xDst - dst_off_x;
- ySrc = ySrc + src_off_y - yDst - dst_off_y;
-
- while (nbox--) {
- (*pExaScr->info->Composite) (pDstPix,
- pbox->x1 + xSrc,
- pbox->y1 + ySrc,
- pbox->x1 + xMask,
- pbox->y1 + yMask,
- pbox->x1,
- pbox->y1,
- pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
- pbox++;
- }
- (*pExaScr->info->DoneComposite) (pDstPix);
- exaMarkSync(pDst->pDrawable->pScreen);
-
- RegionUninit(&region);
- return 1;
-}
-
-/**
- * exaTryMagicTwoPassCompositeHelper implements PictOpOver using two passes of
- * simpler operations PictOpOutReverse and PictOpAdd. Mainly used for component
- * alpha and limited 1-tmu cards.
- *
- * From http://anholt.livejournal.com/32058.html:
- *
- * The trouble is that component-alpha rendering requires two different sources
- * for blending: one for the source value to the blender, which is the
- * per-channel multiplication of source and mask, and one for the source alpha
- * for multiplying with the destination channels, which is the multiplication
- * of the source channels by the mask alpha. So the equation for Over is:
- *
- * dst.A = src.A * mask.A + (1 - (src.A * mask.A)) * dst.A
- * dst.R = src.R * mask.R + (1 - (src.A * mask.R)) * dst.R
- * dst.G = src.G * mask.G + (1 - (src.A * mask.G)) * dst.G
- * dst.B = src.B * mask.B + (1 - (src.A * mask.B)) * dst.B
- *
- * But we can do some simpler operations, right? How about PictOpOutReverse,
- * which has a source factor of 0 and dest factor of (1 - source alpha). We
- * can get the source alpha value (srca.X = src.A * mask.X) out of the texture
- * blenders pretty easily. So we can do a component-alpha OutReverse, which
- * gets us:
- *
- * dst.A = 0 + (1 - (src.A * mask.A)) * dst.A
- * dst.R = 0 + (1 - (src.A * mask.R)) * dst.R
- * dst.G = 0 + (1 - (src.A * mask.G)) * dst.G
- * dst.B = 0 + (1 - (src.A * mask.B)) * dst.B
- *
- * OK. And if an op doesn't use the source alpha value for the destination
- * factor, then we can do the channel multiplication in the texture blenders
- * to get the source value, and ignore the source alpha that we wouldn't use.
- * We've supported this in the Radeon driver for a long time. An example would
- * be PictOpAdd, which does:
- *
- * dst.A = src.A * mask.A + dst.A
- * dst.R = src.R * mask.R + dst.R
- * dst.G = src.G * mask.G + dst.G
- * dst.B = src.B * mask.B + dst.B
- *
- * Hey, this looks good! If we do a PictOpOutReverse and then a PictOpAdd right
- * after it, we get:
- *
- * dst.A = src.A * mask.A + ((1 - (src.A * mask.A)) * dst.A)
- * dst.R = src.R * mask.R + ((1 - (src.A * mask.R)) * dst.R)
- * dst.G = src.G * mask.G + ((1 - (src.A * mask.G)) * dst.G)
- * dst.B = src.B * mask.B + ((1 - (src.A * mask.B)) * dst.B)
- */
-
-static int
-exaTryMagicTwoPassCompositeHelper(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst, CARD16 width, CARD16 height)
-{
- ExaScreenPriv(pDst->pDrawable->pScreen);
-
- assert(op == PictOpOver);
-
- if (pExaScr->info->CheckComposite &&
- (!(*pExaScr->info->CheckComposite) (PictOpOutReverse, pSrc, pMask,
- pDst) ||
- !(*pExaScr->info->CheckComposite) (PictOpAdd, pSrc, pMask, pDst))) {
- return -1;
- }
-
- /* Now, we think we should be able to accelerate this operation. First,
- * composite the destination to be the destination times the source alpha
- * factors.
- */
- exaComposite(PictOpOutReverse, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
- xDst, yDst, width, height);
-
- /* Then, add in the source value times the destination alpha factors (1.0).
- */
- exaComposite(PictOpAdd, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
- xDst, yDst, width, height);
-
- return 1;
-}
-
-void
-exaComposite(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
-{
- ExaScreenPriv(pDst->pDrawable->pScreen);
- int ret = -1;
- Bool saveSrcRepeat = pSrc->repeat;
- Bool saveMaskRepeat = pMask ? pMask->repeat : 0;
- RegionRec region;
-
- if (pExaScr->swappedOut)
- goto fallback;
-
- /* Remove repeat in source if useless */
- if (pSrc->pDrawable && pSrc->repeat && !pSrc->transform && xSrc >= 0 &&
- (xSrc + width) <= pSrc->pDrawable->width && ySrc >= 0 &&
- (ySrc + height) <= pSrc->pDrawable->height)
- pSrc->repeat = 0;
-
- if (!pMask && !pSrc->alphaMap && !pDst->alphaMap &&
- (op == PictOpSrc || (op == PictOpOver && !PICT_FORMAT_A(pSrc->format))))
- {
- if (pSrc->pDrawable ?
- (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 &&
- pSrc->repeat) :
- (pSrc->pSourcePict->type == SourcePictTypeSolidFill)) {
- ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
- width, height);
- if (ret == 1)
- goto done;
- }
- else if (pSrc->pDrawable && !pSrc->transform &&
- ((op == PictOpSrc &&
- (pSrc->format == pDst->format ||
- (PICT_FORMAT_COLOR(pDst->format) &&
- PICT_FORMAT_COLOR(pSrc->format) &&
- pDst->format == PICT_FORMAT(PICT_FORMAT_BPP(pSrc->format),
- PICT_FORMAT_TYPE(pSrc->format),
- 0,
- PICT_FORMAT_R(pSrc->format),
- PICT_FORMAT_G(pSrc->format),
- PICT_FORMAT_B(pSrc->format)))))
- || (op == PictOpOver && pSrc->format == pDst->format &&
- !PICT_FORMAT_A(pSrc->format)))) {
- if (!pSrc->repeat && xSrc >= 0 && ySrc >= 0 &&
- (xSrc + width <= pSrc->pDrawable->width) &&
- (ySrc + height <= pSrc->pDrawable->height)) {
- Bool suc;
-
- xDst += pDst->pDrawable->x;
- yDst += pDst->pDrawable->y;
- xSrc += pSrc->pDrawable->x;
- ySrc += pSrc->pDrawable->y;
-
- if (!miComputeCompositeRegion(&region, pSrc, pMask, pDst,
- xSrc, ySrc, xMask, yMask, xDst,
- yDst, width, height))
- goto done;
-
- suc = exaHWCopyNtoN(pSrc->pDrawable, pDst->pDrawable, NULL,
- RegionRects(&region),
- RegionNumRects(&region), xSrc - xDst,
- ySrc - yDst, FALSE, FALSE);
- RegionUninit(&region);
-
- /* Reset values to their original values. */
- xDst -= pDst->pDrawable->x;
- yDst -= pDst->pDrawable->y;
- xSrc -= pSrc->pDrawable->x;
- ySrc -= pSrc->pDrawable->y;
-
- if (!suc)
- goto fallback;
-
- goto done;
- }
-
- if (pSrc->repeat && pSrc->repeatType == RepeatNormal &&
- pSrc->pDrawable->type == DRAWABLE_PIXMAP) {
- DDXPointRec patOrg;
-
- /* Let's see if the driver can do the repeat in one go */
- if (pExaScr->info->PrepareComposite && !pSrc->alphaMap &&
- !pDst->alphaMap) {
- ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc,
- ySrc, xMask, yMask, xDst, yDst,
- width, height);
- if (ret == 1)
- goto done;
- }
-
- /* Now see if we can use exaFillRegionTiled() */
- xDst += pDst->pDrawable->x;
- yDst += pDst->pDrawable->y;
- xSrc += pSrc->pDrawable->x;
- ySrc += pSrc->pDrawable->y;
-
- if (!miComputeCompositeRegion(&region, pSrc, pMask, pDst, xSrc,
- ySrc, xMask, yMask, xDst, yDst,
- width, height))
- goto done;
-
- /* pattern origin is the point in the destination drawable
- * corresponding to (0,0) in the source */
- patOrg.x = xDst - xSrc;
- patOrg.y = yDst - ySrc;
-
- ret = exaFillRegionTiled(pDst->pDrawable, &region,
- (PixmapPtr) pSrc->pDrawable,
- &patOrg, FB_ALLONES, GXcopy, CT_NONE);
-
- RegionUninit(&region);
-
- if (ret)
- goto done;
-
- /* Let's be correct and restore the variables to their original state. */
- xDst -= pDst->pDrawable->x;
- yDst -= pDst->pDrawable->y;
- xSrc -= pSrc->pDrawable->x;
- ySrc -= pSrc->pDrawable->y;
- }
- }
- }
-
- /* Remove repeat in mask if useless */
- if (pMask && pMask->pDrawable && pMask->repeat && !pMask->transform &&
- xMask >= 0 && (xMask + width) <= pMask->pDrawable->width &&
- yMask >= 0 && (yMask + height) <= pMask->pDrawable->height)
- pMask->repeat = 0;
-
- if (pExaScr->info->PrepareComposite &&
- !pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap) {
- Bool isSrcSolid;
-
- ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask,
- yMask, xDst, yDst, width, height);
- if (ret == 1)
- goto done;
-
- /* For generic masks and solid src pictures, mach64 can do Over in two
- * passes, similar to the component-alpha case.
- */
- isSrcSolid = pSrc->pDrawable ?
- (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 &&
- pSrc->repeat) :
- (pSrc->pSourcePict->type == SourcePictTypeSolidFill);
-
- /* If we couldn't do the Composite in a single pass, and it was a
- * component-alpha Over, see if we can do it in two passes with
- * an OutReverse and then an Add.
- */
- if (ret == -1 && op == PictOpOver && pMask &&
- (pMask->componentAlpha || isSrcSolid)) {
- ret = exaTryMagicTwoPassCompositeHelper(op, pSrc, pMask, pDst,
- xSrc, ySrc,
- xMask, yMask, xDst, yDst,
- width, height);
- if (ret == 1)
- goto done;
- }
- }
-
- fallback:
-#if DEBUG_TRACE_FALL
- exaPrintCompositeFallback(op, pSrc, pMask, pDst);
-#endif
-
- ExaCheckComposite(op, pSrc, pMask, pDst, xSrc, ySrc,
- xMask, yMask, xDst, yDst, width, height);
-
- done:
- pSrc->repeat = saveSrcRepeat;
- if (pMask)
- pMask->repeat = saveMaskRepeat;
-}
-
-/**
- * Same as miCreateAlphaPicture, except it uses ExaCheckPolyFillRect instead
- * of PolyFillRect to initialize the pixmap after creating it, to prevent
- * the pixmap from being migrated.
- *
- * See the comments about exaTrapezoids and exaTriangles.
- */
-static PicturePtr
-exaCreateAlphaPicture(ScreenPtr pScreen,
- PicturePtr pDst,
- PictFormatPtr pPictFormat, CARD16 width, CARD16 height)
-{
- PixmapPtr pPixmap;
- PicturePtr pPicture;
- GCPtr pGC;
- int error;
- xRectangle rect;
-
- if (width > 32767 || height > 32767)
- return 0;
-
- if (!pPictFormat) {
- if (pDst->polyEdge == PolyEdgeSharp)
- pPictFormat = PictureMatchFormat(pScreen, 1, PICT_a1);
- else
- pPictFormat = PictureMatchFormat(pScreen, 8, PICT_a8);
- if (!pPictFormat)
- return 0;
- }
-
- pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
- pPictFormat->depth, 0);
- if (!pPixmap)
- return 0;
- pGC = GetScratchGC(pPixmap->drawable.depth, pScreen);
- if (!pGC) {
- (*pScreen->DestroyPixmap) (pPixmap);
- return 0;
- }
- ValidateGC(&pPixmap->drawable, pGC);
- rect.x = 0;
- rect.y = 0;
- rect.width = width;
- rect.height = height;
- ExaCheckPolyFillRect(&pPixmap->drawable, pGC, 1, &rect);
- exaPixmapDirty(pPixmap, 0, 0, width, height);
- FreeScratchGC(pGC);
- pPicture = CreatePicture(0, &pPixmap->drawable, pPictFormat,
- 0, 0, serverClient, &error);
- (*pScreen->DestroyPixmap) (pPixmap);
- return pPicture;
-}
-
-/**
- * exaTrapezoids is essentially a copy of miTrapezoids that uses
- * exaCreateAlphaPicture instead of miCreateAlphaPicture.
- *
- * The problem with miCreateAlphaPicture is that it calls PolyFillRect
- * to initialize the contents after creating the pixmap, which
- * causes the pixmap to be moved in for acceleration. The subsequent
- * call to RasterizeTrapezoid won't be accelerated however, which
- * forces the pixmap to be moved out again.
- *
- * exaCreateAlphaPicture avoids this roundtrip by using ExaCheckPolyFillRect
- * to initialize the contents.
- */
-void
-exaTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
- PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
- int ntrap, xTrapezoid * traps)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- BoxRec bounds;
-
- if (maskFormat) {
- PicturePtr pPicture;
- INT16 xDst, yDst;
- INT16 xRel, yRel;
-
- miTrapezoidBounds(ntrap, traps, &bounds);
-
- if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
- return;
-
- xDst = traps[0].left.p1.x >> 16;
- yDst = traps[0].left.p1.y >> 16;
-
- pPicture = exaCreateAlphaPicture(pScreen, pDst, maskFormat,
- bounds.x2 - bounds.x1,
- bounds.y2 - bounds.y1);
- if (!pPicture)
- return;
-
- exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
- for (; ntrap; ntrap--, traps++)
- if (xTrapezoidValid(traps))
- (*ps->RasterizeTrapezoid) (pPicture, traps, -bounds.x1, -bounds.y1);
- exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
-
- xRel = bounds.x1 + xSrc - xDst;
- yRel = bounds.y1 + ySrc - yDst;
- CompositePicture(op, pSrc, pPicture, pDst,
- xRel, yRel, 0, 0, bounds.x1, bounds.y1,
- bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
- FreePicture(pPicture, 0);
- }
- else {
- if (pDst->polyEdge == PolyEdgeSharp)
- maskFormat = PictureMatchFormat(pScreen, 1, PICT_a1);
- else
- maskFormat = PictureMatchFormat(pScreen, 8, PICT_a8);
- for (; ntrap; ntrap--, traps++)
- exaTrapezoids(op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps);
- }
-}
-
-/**
- * exaTriangles is essentially a copy of miTriangles that uses
- * exaCreateAlphaPicture instead of miCreateAlphaPicture.
- *
- * The problem with miCreateAlphaPicture is that it calls PolyFillRect
- * to initialize the contents after creating the pixmap, which
- * causes the pixmap to be moved in for acceleration. The subsequent
- * call to AddTriangles won't be accelerated however, which forces the pixmap
- * to be moved out again.
- *
- * exaCreateAlphaPicture avoids this roundtrip by using ExaCheckPolyFillRect
- * to initialize the contents.
- */
-void
-exaTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
- PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
- int ntri, xTriangle * tris)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- BoxRec bounds;
-
- if (maskFormat) {
- PicturePtr pPicture;
- INT16 xDst, yDst;
- INT16 xRel, yRel;
-
- miTriangleBounds(ntri, tris, &bounds);
-
- if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
- return;
-
- xDst = tris[0].p1.x >> 16;
- yDst = tris[0].p1.y >> 16;
-
- pPicture = exaCreateAlphaPicture(pScreen, pDst, maskFormat,
- bounds.x2 - bounds.x1,
- bounds.y2 - bounds.y1);
- if (!pPicture)
- return;
-
- exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
- (*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris);
- exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
-
- xRel = bounds.x1 + xSrc - xDst;
- yRel = bounds.y1 + ySrc - yDst;
- CompositePicture(op, pSrc, pPicture, pDst,
- xRel, yRel, 0, 0, bounds.x1, bounds.y1,
- bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
- FreePicture(pPicture, 0);
- }
- else {
- if (pDst->polyEdge == PolyEdgeSharp)
- maskFormat = PictureMatchFormat(pScreen, 1, PICT_a1);
- else
- maskFormat = PictureMatchFormat(pScreen, 8, PICT_a8);
-
- for (; ntri; ntri--, tris++)
- exaTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris);
- }
-}
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
deleted file mode 100644
index ed1401a98..000000000
--- a/exa/exa_unaccel.c
+++ /dev/null
@@ -1,733 +0,0 @@
-/*
- *
- * Copyright © 1999 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "exa_priv.h"
-
-#include "mipict.h"
-
-/*
- * These functions wrap the low-level fb rendering functions and
- * synchronize framebuffer/accelerated drawing by stalling until
- * the accelerator is idle
- */
-
-/**
- * Calls exaPrepareAccess with EXA_PREPARE_SRC for the tile, if that is the
- * current fill style.
- *
- * Solid doesn't use an extra pixmap source, and Stippled/OpaqueStippled are
- * 1bpp and never in fb, so we don't worry about them.
- * We should worry about them for completeness sake and going forward.
- */
-void
-exaPrepareAccessGC(GCPtr pGC)
-{
- if (pGC->stipple)
- exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
- if (pGC->fillStyle == FillTiled)
- exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
-}
-
-/**
- * Finishes access to the tile in the GC, if used.
- */
-void
-exaFinishAccessGC(GCPtr pGC)
-{
- if (pGC->fillStyle == FillTiled)
- exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
- if (pGC->stipple)
- exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
-}
-
-#if DEBUG_TRACE_FALL
-char
-exaDrawableLocation(DrawablePtr pDrawable)
-{
- return exaDrawableIsOffscreen(pDrawable) ? 's' : 'm';
-}
-#endif /* DEBUG_TRACE_FALL */
-
-void
-ExaCheckFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nspans,
- DDXPointPtr ppt, int *pwidth, int fSorted)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC(pGC);
- pGC->ops->FillSpans(pDrawable, pGC, nspans, ppt, pwidth, fSorted);
- exaFinishAccessGC(pGC);
- exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
- DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
- pGC->ops->SetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
- exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
- int x, int y, int w, int h, int leftPad, int format,
- char *bits)
-{
- PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
-
- ExaPixmapPriv(pPixmap);
-
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- if (!pExaScr->prepare_access_reg || !pExaPixmap->pDamage ||
- exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
- pGC->alu, pGC->clientClip != NULL))
- exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
- else
- pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST,
- DamagePendingRegion(pExaPixmap->pDamage));
- pGC->ops->PutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format,
- bits);
- exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckCopyNtoN(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- BoxPtr pbox, int nbox, int dx, int dy, Bool reverse,
- Bool upsidedown, Pixel bitplane, void *closure)
-{
- RegionRec reg;
- int xoff, yoff;
-
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
- exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
-
- if (pExaScr->prepare_access_reg && RegionInitBoxes(&reg, pbox, nbox)) {
- PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc);
-
- exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
- RegionTranslate(&reg, xoff + dx, yoff + dy);
- pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, &reg);
- RegionUninit(&reg);
- }
- else
- exaPrepareAccess(pSrc, EXA_PREPARE_SRC);
-
- if (pExaScr->prepare_access_reg &&
- !exaGCReadsDestination(pDst, pGC->planemask, pGC->fillStyle,
- pGC->alu, pGC->clientClip != NULL) &&
- RegionInitBoxes(&reg, pbox, nbox)) {
- PixmapPtr pPixmap = exaGetDrawablePixmap(pDst);
-
- exaGetDrawableDeltas(pDst, pPixmap, &xoff, &yoff);
- RegionTranslate(&reg, xoff, yoff);
- pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, &reg);
- RegionUninit(&reg);
- }
- else
- exaPrepareAccess(pDst, EXA_PREPARE_DEST);
-
- /* This will eventually call fbCopyNtoN, with some calculation overhead. */
- while (nbox--) {
- pGC->ops->CopyArea(pSrc, pDst, pGC, pbox->x1 - pSrc->x + dx,
- pbox->y1 - pSrc->y + dy, pbox->x2 - pbox->x1,
- pbox->y2 - pbox->y1, pbox->x1 - pDst->x,
- pbox->y1 - pDst->y);
- pbox++;
- }
- exaFinishAccess(pSrc, EXA_PREPARE_SRC);
- exaFinishAccess(pDst, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-static void
-ExaFallbackPrepareReg(DrawablePtr pDrawable,
- GCPtr pGC,
- int x, int y, int width, int height,
- int index, Bool checkReads)
-{
- ScreenPtr pScreen = pDrawable->pScreen;
-
- ExaScreenPriv(pScreen);
-
- if (pExaScr->prepare_access_reg &&
- !(checkReads && exaGCReadsDestination(pDrawable, pGC->planemask,
- pGC->fillStyle, pGC->alu,
- pGC->clientClip != NULL))) {
- BoxRec box;
- RegionRec reg;
- int xoff, yoff;
- PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
-
- exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
- box.x1 = pDrawable->x + x + xoff;
- box.y1 = pDrawable->y + y + yoff;
- box.x2 = box.x1 + width;
- box.y2 = box.y1 + height;
-
- RegionInit(&reg, &box, 1);
- pExaScr->prepare_access_reg(pPixmap, index, &reg);
- RegionUninit(&reg);
- }
- else
- exaPrepareAccess(pDrawable, index);
-}
-
-RegionPtr
-ExaCheckCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int w, int h, int dstx, int dsty)
-{
- RegionPtr ret;
-
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
- exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
- ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h, EXA_PREPARE_SRC, FALSE);
- ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h, EXA_PREPARE_DEST, TRUE);
- ret = pGC->ops->CopyArea(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
- exaFinishAccess(pSrc, EXA_PREPARE_SRC);
- exaFinishAccess(pDst, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-
- return ret;
-}
-
-RegionPtr
-ExaCheckCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int w, int h, int dstx, int dsty,
- unsigned long bitPlane)
-{
- RegionPtr ret;
-
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
- exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
- ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h, EXA_PREPARE_SRC, FALSE);
- ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h, EXA_PREPARE_DEST, TRUE);
- ret = pGC->ops->CopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
- bitPlane);
- exaFinishAccess(pSrc, EXA_PREPARE_SRC);
- exaFinishAccess(pDst, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-
- return ret;
-}
-
-void
-ExaCheckPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
- DDXPointPtr pptInit)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
- pGC->ops->PolyPoint(pDrawable, pGC, mode, npt, pptInit);
- exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckPolylines(DrawablePtr pDrawable, GCPtr pGC,
- int mode, int npt, DDXPointPtr ppt)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n",
- pDrawable, exaDrawableLocation(pDrawable),
- pGC->lineWidth, mode, npt));
-
- exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC(pGC);
- pGC->ops->Polylines(pDrawable, pGC, mode, npt, ppt);
- exaFinishAccessGC(pGC);
- exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckPolySegment(DrawablePtr pDrawable, GCPtr pGC,
- int nsegInit, xSegment * pSegInit)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable,
- exaDrawableLocation(pDrawable), pGC->lineWidth, nsegInit));
-
- exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC(pGC);
- pGC->ops->PolySegment(pDrawable, pGC, nsegInit, pSegInit);
- exaFinishAccessGC(pGC);
- exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * pArcs)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
-
- exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC(pGC);
- pGC->ops->PolyArc(pDrawable, pGC, narcs, pArcs);
- exaFinishAccessGC(pGC);
- exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
- int nrect, xRectangle *prect)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
-
- exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC(pGC);
- pGC->ops->PolyFillRect(pDrawable, pGC, nrect, prect);
- exaFinishAccessGC(pGC);
- exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr * ppci, void *pglyphBase)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC(pGC);
- pGC->ops->ImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
- exaFinishAccessGC(pGC);
- exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr * ppci, void *pglyphBase)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable,
- exaDrawableLocation(pDrawable), pGC->fillStyle, pGC->alu));
- exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC(pGC);
- pGC->ops->PolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
- exaFinishAccessGC(pGC);
- exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckPushPixels(GCPtr pGC, PixmapPtr pBitmap,
- DrawablePtr pDrawable, int w, int h, int x, int y)
-{
- EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable,
- exaDrawableLocation(&pBitmap->drawable),
- exaDrawableLocation(pDrawable)));
- ExaFallbackPrepareReg(pDrawable, pGC, x, y, w, h, EXA_PREPARE_DEST, TRUE);
- ExaFallbackPrepareReg(&pBitmap->drawable, pGC, 0, 0, w, h,
- EXA_PREPARE_SRC, FALSE);
- exaPrepareAccessGC(pGC);
- pGC->ops->PushPixels(pGC, pBitmap, pDrawable, w, h, x, y);
- exaFinishAccessGC(pGC);
- exaFinishAccess(&pBitmap->drawable, EXA_PREPARE_SRC);
- exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK_GC(pGC);
-}
-
-void
-ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
-{
- DrawablePtr pDrawable = &pWin->drawable;
- ScreenPtr pScreen = pDrawable->pScreen;
-
- EXA_PRE_FALLBACK(pScreen);
- EXA_FALLBACK(("from %p\n", pWin));
-
- /* Only need the source bits, the destination region will be overwritten */
- if (pExaScr->prepare_access_reg) {
- PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin);
- int xoff, yoff;
-
- exaGetDrawableDeltas(&pWin->drawable, pPixmap, &xoff, &yoff);
- RegionTranslate(prgnSrc, xoff, yoff);
- pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, prgnSrc);
- RegionTranslate(prgnSrc, -xoff, -yoff);
- }
- else
- exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
-
- swap(pExaScr, pScreen, CopyWindow);
- pScreen->CopyWindow(pWin, ptOldOrg, prgnSrc);
- swap(pExaScr, pScreen, CopyWindow);
- exaFinishAccess(pDrawable, EXA_PREPARE_SRC);
- EXA_POST_FALLBACK(pScreen);
-}
-
-void
-ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
- unsigned int format, unsigned long planeMask, char *d)
-{
- ScreenPtr pScreen = pDrawable->pScreen;
-
- EXA_PRE_FALLBACK(pScreen);
- EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
-
- ExaFallbackPrepareReg(pDrawable, NULL, x, y, w, h, EXA_PREPARE_SRC, FALSE);
- swap(pExaScr, pScreen, GetImage);
- pScreen->GetImage(pDrawable, x, y, w, h, format, planeMask, d);
- swap(pExaScr, pScreen, GetImage);
- exaFinishAccess(pDrawable, EXA_PREPARE_SRC);
- EXA_POST_FALLBACK(pScreen);
-}
-
-void
-ExaCheckGetSpans(DrawablePtr pDrawable,
- int wMax,
- DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart)
-{
- ScreenPtr pScreen = pDrawable->pScreen;
-
- EXA_PRE_FALLBACK(pScreen);
- EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
- swap(pExaScr, pScreen, GetSpans);
- pScreen->GetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
- swap(pExaScr, pScreen, GetSpans);
- exaFinishAccess(pDrawable, EXA_PREPARE_SRC);
- EXA_POST_FALLBACK(pScreen);
-}
-
-static void
-ExaSrcValidate(DrawablePtr pDrawable,
- int x, int y, int width, int height, unsigned int subWindowMode)
-{
- ScreenPtr pScreen = pDrawable->pScreen;
-
- ExaScreenPriv(pScreen);
- PixmapPtr pPix = exaGetDrawablePixmap(pDrawable);
- BoxRec box;
- RegionRec reg;
- RegionPtr dst;
- int xoff, yoff;
-
- if (pExaScr->srcPix == pPix)
- dst = &pExaScr->srcReg;
- else if (pExaScr->maskPix == pPix)
- dst = &pExaScr->maskReg;
- else
- return;
-
- exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
-
- box.x1 = x + xoff;
- box.y1 = y + yoff;
- box.x2 = box.x1 + width;
- box.y2 = box.y1 + height;
-
- RegionInit(&reg, &box, 1);
- RegionUnion(dst, dst, &reg);
- RegionUninit(&reg);
-
- swap(pExaScr, pScreen, SourceValidate);
- pScreen->SourceValidate(pDrawable, x, y, width, height, subWindowMode);
- swap(pExaScr, pScreen, SourceValidate);
-}
-
-static Bool
-ExaPrepareCompositeReg(ScreenPtr pScreen,
- CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
-{
- RegionRec region;
- RegionPtr dstReg = NULL;
- RegionPtr srcReg = NULL;
- RegionPtr maskReg = NULL;
- PixmapPtr pSrcPix = NULL;
- PixmapPtr pMaskPix = NULL;
- PixmapPtr pDstPix;
-
- ExaScreenPriv(pScreen);
- Bool ret;
-
- RegionNull(&region);
-
- if (pSrc->pDrawable) {
- pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
- RegionNull(&pExaScr->srcReg);
- srcReg = &pExaScr->srcReg;
- pExaScr->srcPix = pSrcPix;
- if (pSrc != pDst)
- RegionTranslate(pSrc->pCompositeClip,
- -pSrc->pDrawable->x, -pSrc->pDrawable->y);
- } else
- pExaScr->srcPix = NULL;
-
- if (pMask && pMask->pDrawable) {
- pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
- RegionNull(&pExaScr->maskReg);
- maskReg = &pExaScr->maskReg;
- pExaScr->maskPix = pMaskPix;
- if (pMask != pDst && pMask != pSrc)
- RegionTranslate(pMask->pCompositeClip,
- -pMask->pDrawable->x, -pMask->pDrawable->y);
- } else
- pExaScr->maskPix = NULL;
-
- RegionTranslate(pDst->pCompositeClip,
- -pDst->pDrawable->x, -pDst->pDrawable->y);
-
- pExaScr->SavedSourceValidate = ExaSrcValidate;
- swap(pExaScr, pScreen, SourceValidate);
- ret = miComputeCompositeRegion(&region, pSrc, pMask, pDst,
- xSrc, ySrc, xMask, yMask,
- xDst, yDst, width, height);
- swap(pExaScr, pScreen, SourceValidate);
-
- RegionTranslate(pDst->pCompositeClip,
- pDst->pDrawable->x, pDst->pDrawable->y);
- if (pSrc->pDrawable && pSrc != pDst)
- RegionTranslate(pSrc->pCompositeClip,
- pSrc->pDrawable->x, pSrc->pDrawable->y);
- if (pMask && pMask->pDrawable && pMask != pDst && pMask != pSrc)
- RegionTranslate(pMask->pCompositeClip,
- pMask->pDrawable->x, pMask->pDrawable->y);
-
- if (!ret) {
- if (srcReg)
- RegionUninit(srcReg);
- if (maskReg)
- RegionUninit(maskReg);
-
- return FALSE;
- }
-
- /**
- * Don't limit alphamaps readbacks for now until we've figured out how that
- * should be done.
- */
-
- if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
- pExaScr->
- prepare_access_reg(exaGetDrawablePixmap(pSrc->alphaMap->pDrawable),
- EXA_PREPARE_AUX_SRC, NULL);
- if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
- pExaScr->
- prepare_access_reg(exaGetDrawablePixmap(pMask->alphaMap->pDrawable),
- EXA_PREPARE_AUX_MASK, NULL);
-
- if (pSrcPix)
- pExaScr->prepare_access_reg(pSrcPix, EXA_PREPARE_SRC, srcReg);
-
- if (pMaskPix)
- pExaScr->prepare_access_reg(pMaskPix, EXA_PREPARE_MASK, maskReg);
-
- if (srcReg)
- RegionUninit(srcReg);
- if (maskReg)
- RegionUninit(maskReg);
-
- pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
- if (!exaOpReadsDestination(op)) {
- int xoff;
- int yoff;
-
- exaGetDrawableDeltas(pDst->pDrawable, pDstPix, &xoff, &yoff);
- RegionTranslate(&region, pDst->pDrawable->x + xoff,
- pDst->pDrawable->y + yoff);
- dstReg = &region;
- }
-
- if (pDst->alphaMap && pDst->alphaMap->pDrawable)
- pExaScr->
- prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable),
- EXA_PREPARE_AUX_DEST, dstReg);
- pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, dstReg);
-
- RegionUninit(&region);
- return TRUE;
-}
-
-void
-ExaCheckComposite(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
-
- EXA_PRE_FALLBACK(pScreen);
-
- if (pExaScr->prepare_access_reg) {
- if (!ExaPrepareCompositeReg(pScreen, op, pSrc, pMask, pDst, xSrc,
- ySrc, xMask, yMask, xDst, yDst, width,
- height))
- goto out_no_clip;
- }
- else {
-
- /* We need to prepare access to any separate alpha maps first,
- * in case the driver doesn't support EXA_PREPARE_AUX*,
- * in which case EXA_PREPARE_SRC may be used for moving them out.
- */
-
- if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
- exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
- if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
- exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
- if (pDst->alphaMap && pDst->alphaMap->pDrawable)
- exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
-
- exaPrepareAccess(pDst->pDrawable, EXA_PREPARE_DEST);
-
- EXA_FALLBACK(("from picts %p/%p to pict %p\n", pSrc, pMask, pDst));
-
- if (pSrc->pDrawable != NULL)
- exaPrepareAccess(pSrc->pDrawable, EXA_PREPARE_SRC);
- if (pMask && pMask->pDrawable != NULL)
- exaPrepareAccess(pMask->pDrawable, EXA_PREPARE_MASK);
- }
-
- swap(pExaScr, ps, Composite);
- ps->Composite(op,
- pSrc,
- pMask,
- pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
- swap(pExaScr, ps, Composite);
- if (pMask && pMask->pDrawable != NULL)
- exaFinishAccess(pMask->pDrawable, EXA_PREPARE_MASK);
- if (pSrc->pDrawable != NULL)
- exaFinishAccess(pSrc->pDrawable, EXA_PREPARE_SRC);
- exaFinishAccess(pDst->pDrawable, EXA_PREPARE_DEST);
- if (pDst->alphaMap && pDst->alphaMap->pDrawable)
- exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
- if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
- exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
- if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
- exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
-
- out_no_clip:
- EXA_POST_FALLBACK(pScreen);
-}
-
-/**
- * Avoid migration ping-pong when using a mask.
- */
-void
-ExaCheckGlyphs(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
-
- EXA_PRE_FALLBACK(pScreen);
-
- miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
-
- EXA_POST_FALLBACK(pScreen);
-}
-
-void
-ExaCheckAddTraps(PicturePtr pPicture,
- INT16 x_off, INT16 y_off, int ntrap, xTrap * traps)
-{
- ScreenPtr pScreen = pPicture->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
-
- EXA_PRE_FALLBACK(pScreen);
-
- EXA_FALLBACK(("to pict %p (%c)\n", pPicture,
- exaDrawableLocation(pPicture->pDrawable)));
- exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
- swap(pExaScr, ps, AddTraps);
- ps->AddTraps(pPicture, x_off, y_off, ntrap, traps);
- swap(pExaScr, ps, AddTraps);
- exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
- EXA_POST_FALLBACK(pScreen);
-}
-
-/**
- * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps
- * that happen to be 1x1. Pixmap must be at least 8bpp.
- */
-CARD32
-exaGetPixmapFirstPixel(PixmapPtr pPixmap)
-{
- switch (pPixmap->drawable.bitsPerPixel) {
- case 32:
- {
- CARD32 pixel;
-
- pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
- ZPixmap, ~0, (char *) &pixel);
- return pixel;
- }
- case 16:
- {
- CARD16 pixel;
-
- pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
- ZPixmap, ~0, (char *) &pixel);
- return pixel;
- }
- case 8:
- case 4:
- case 1:
- {
- CARD8 pixel;
-
- pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
- ZPixmap, ~0, (char *) &pixel);
- return pixel;
- }
- default:
- FatalError("%s called for invalid bpp %d\n", __func__,
- pPixmap->drawable.bitsPerPixel);
- }
-}
diff --git a/exa/meson.build b/exa/meson.build
deleted file mode 100644
index a3b7aea8c..000000000
--- a/exa/meson.build
+++ /dev/null
@@ -1,19 +0,0 @@
-srcs_exa = [
- 'exa.c',
- 'exa_classic.c',
- 'exa_migration_classic.c',
- 'exa_driver.c',
- 'exa_mixed.c',
- 'exa_migration_mixed.c',
- 'exa_accel.c',
- 'exa_glyphs.c',
- 'exa_offscreen.c',
- 'exa_render.c',
- 'exa_unaccel.c',
-]
-
-libxserver_exa = static_library('libxserver_exa',
- srcs_exa,
- include_directories: inc,
- dependencies: common_dep,
-)
diff --git a/meson.build b/meson.build
index 16c87a1a8..fab53d947 100644
--- a/meson.build
+++ b/meson.build
@@ -413,7 +413,6 @@ inc = include_directories(
'Xi',
'composite',
'damageext',
- 'exa',
'fb',
'glamor',
'mi',