Rearrange and rename EXA code to be a bit more logically organized. Also

removes a little bit of debugging leftovers. Summary:
exa.c -> exa.c (miscellaneous code) exa_accel.c (all acceleration code)
    exa_migration.c (migration logic) exaasync.c -> exa_unaccel.c (software
    fallbacks) exapict.c -> exa_render.c (render extension stuff)
    exaoffscreen.c -> exa_offscreen.c exaPriv.h -> exa_priv.h
This commit is contained in:
Eric Anholt 2006-02-02 20:09:14 +00:00
parent 25d4ff870d
commit 3366b68365
21 changed files with 113 additions and 8284 deletions

View File

@ -1,3 +1,34 @@
2006-02-02 Eric Anholt <anholt@FreeBSD.org>
reviewed by: zrusin
* hw/xfree86/exa/Makefile.am:
* hw/xfree86/exa/exa.c: (exaPixmapIsOffscreen),
(exaGetOffscreenPixmap), (exaDrawableIsOffscreen),
(exaPrepareAccess), (exaFinishAccess), (exaCreateGC),
(exaDriverInit):
* hw/xfree86/exa/exaPriv.h:
* hw/xfree86/exa/exa_accel.c: (exaPaintWindow):
* hw/xfree86/exa/exa_migration.c: (exaMoveOutPixmap),
(exaPixmapUseScreen), (exaPixmapUseMemory):
* hw/xfree86/exa/exa_offscreen.c:
* hw/xfree86/exa/exa_priv.h:
* hw/xfree86/exa/exa_render.c:
* hw/xfree86/exa/exa_unaccel.c:
* hw/xfree86/exa/exaasync.c:
* hw/xfree86/exa/exaoffscreen.c:
* hw/xfree86/exa/exapict.c:
Rearrange and rename EXA code to be a bit more logically organized.
Also removes a little bit of debugging leftovers. Summary:
exa.c -> exa.c (miscellaneous code)
exa_accel.c (all acceleration code)
exa_migration.c (migration logic)
exaasync.c -> exa_unaccel.c (software fallbacks)
exapict.c -> exa_render.c (render extension stuff)
exaoffscreen.c -> exa_offscreen.c
exaPriv.h -> exa_priv.h
2006-02-01 Alan Hourihane <alanh@fairlite.demon.co.uk>
* randr/randr.c: (RRGetRotation):

View File

@ -11,9 +11,12 @@ INCLUDES = \
AM_CFLAGS = $(XORG_CFLAGS) @SERVER_DEFINES@ @MODULE_DEFINES@ @LOADER_DEFINES@
libexa_la_SOURCES = \
exaasync.c \
exa.c \
exa.h \
exaoffscreen.c \
exapict.c \
exaPriv.h
exa_accel.c \
exa_migration.c \
exa_offscreen.c \
exa_render.c \
exa_priv.h \
exa_unaccel.c

1084
exa/exa.c

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,7 @@
#ifdef HAVE_CONFIG_H
#include <xorg-config.h>
#endif
#include "exaPriv.h"
#include "exa_priv.h"
#include <X11/fonts/fontstruct.h>
#include "dixfontstr.h"
#include "xf86str.h"
@ -33,543 +33,7 @@
#include "exa.h"
#include "cw.h"
#if DEBUG_MIGRATE
#define DBG_MIGRATE(a) ErrorF a
#else
#define DBG_MIGRATE(a)
#endif
#if DEBUG_PIXMAP
#define DBG_PIXMAP(a) ErrorF a
#else
#define DBG_PIXMAP(a)
#endif
#define STRACE
#define TRACE
static int exaGeneration;
int exaScreenPrivateIndex;
int exaPixmapPrivateIndex;
#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
/* Returns the offset (in bytes) within the framebuffer of the beginning of the
* given pixmap. May need to be extended in the future if we grow support for
* having multiple card-accessible areas at different offsets.
*/
unsigned long
exaGetPixmapOffset(PixmapPtr pPix)
{
ExaScreenPriv (pPix->drawable.pScreen);
return ((unsigned long)pPix->devPrivate.ptr -
(unsigned long)pExaScr->info->card.memoryBase);
}
/* Returns the pitch in bytes of the given pixmap. */
unsigned long
exaGetPixmapPitch(PixmapPtr pPix)
{
return pPix->devKind;
}
/* Returns the size in bytes of the given pixmap in
* video memory. Only valid when the vram storage has been
* allocated
*/
unsigned long
exaGetPixmapSize(PixmapPtr pPix)
{
ExaPixmapPrivPtr pExaPixmap;
pExaPixmap = ExaGetPixmapPriv(pPix);
if (pExaPixmap != NULL)
return pExaPixmap->size;
return 0;
}
void
exaDrawableDirty (DrawablePtr pDrawable)
{
PixmapPtr pPixmap;
ExaPixmapPrivPtr pExaPixmap;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap)((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr)pDrawable;
pExaPixmap = ExaGetPixmapPriv(pPixmap);
if (pExaPixmap != NULL)
pExaPixmap->dirty = TRUE;
}
static void
exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
{
PixmapPtr pPixmap = area->privData;
ExaScreenPriv (pScreen);
ExaPixmapPriv(pPixmap);
int dst_pitch, src_pitch, bytes;
char *dst, *src;
int i;
DBG_MIGRATE (("Save %p (%p) (%dx%d)\n",
(void*)pPixmap->drawable.id,
(void*)(ExaGetPixmapPriv(pPixmap)->area ?
ExaGetPixmapPriv(pPixmap)->area->offset : 0),
pPixmap->drawable.width,
pPixmap->drawable.height));
src_pitch = pPixmap->devKind;
dst_pitch = pExaPixmap->devKind;
src = pPixmap->devPrivate.ptr;
dst = pExaPixmap->devPrivate.ptr;
if (pExaPixmap->dirty) {
if (pExaScr->info->accel.DownloadFromScreen &&
(*pExaScr->info->accel.DownloadFromScreen) (pPixmap,
pPixmap->drawable.x,
pPixmap->drawable.y,
pPixmap->drawable.width,
pPixmap->drawable.height,
dst,
dst_pitch)) {
} else {
exaWaitSync (pPixmap->drawable.pScreen);
bytes = src_pitch < dst_pitch ? src_pitch : dst_pitch;
i = pPixmap->drawable.height;
while (i--) {
memcpy (dst, src, bytes);
dst += dst_pitch;
src += src_pitch;
}
}
}
pPixmap->devKind = dst_pitch;
pPixmap->devPrivate.ptr = pExaPixmap->devPrivate.ptr;
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
pExaPixmap->area = NULL;
/* Mark it dirty now, to say that there is important data in the
* system-memory copy.
*/
pExaPixmap->dirty = TRUE;
}
static int
exaLog2(int val)
{
int bits;
if (!val)
return 0;
for (bits = 0; val != 0; bits++)
val >>= 1;
return bits - 1;
}
static Bool
exaPixmapAllocArea (PixmapPtr pPixmap)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
ExaScreenPriv (pScreen);
ExaPixmapPriv (pPixmap);
int bpp = pPixmap->drawable.bitsPerPixel;
CARD16 h = pPixmap->drawable.height;
CARD16 w = pPixmap->drawable.width;
int pitch;
if (pExaScr->info->card.flags & EXA_OFFSCREEN_ALIGN_POT && w != 1)
w = 1 << (exaLog2(w - 1) + 1);
pitch = (w * bpp / 8) + (pExaScr->info->card.pixmapPitchAlign - 1);
pitch -= pitch % pExaScr->info->card.pixmapPitchAlign;
pExaPixmap->size = pitch * h;
pExaPixmap->devKind = pPixmap->devKind;
pExaPixmap->devPrivate = pPixmap->devPrivate;
pExaPixmap->area = exaOffscreenAlloc (pScreen, pitch * h,
pExaScr->info->card.pixmapOffsetAlign,
FALSE,
exaPixmapSave, (pointer) pPixmap);
if (!pExaPixmap->area)
return FALSE;
DBG_PIXMAP(("++ 0x%lx (0x%x) (%dx%d)\n", pPixmap->drawable.id,
(ExaGetPixmapPriv(pPixmap)->area ?
ExaGetPixmapPriv(pPixmap)->area->offset : 0),
pPixmap->drawable.width,
pPixmap->drawable.height));
pPixmap->devKind = pitch;
pPixmap->devPrivate.ptr = (pointer) ((CARD8 *) pExaScr->info->card.memoryBase + pExaPixmap->area->offset);
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
return TRUE;
}
void
exaMoveInPixmap (PixmapPtr pPixmap)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
ExaScreenPriv (pScreen);
ExaPixmapPriv (pPixmap);
int dst_pitch, src_pitch, bytes;
char *dst, *src;
int i;
DBG_MIGRATE (("-> 0x%lx (0x%x) (%dx%d)\n", pPixmap->drawable.id,
(ExaGetPixmapPriv(pPixmap)->area ?
ExaGetPixmapPriv(pPixmap)->area->offset : 0),
pPixmap->drawable.width,
pPixmap->drawable.height));
src = pPixmap->devPrivate.ptr;
src_pitch = pPixmap->devKind;
if (!exaPixmapAllocArea (pPixmap)) {
DBG_MIGRATE (("failed to allocate fb for pixmap %p (%dx%dx%d)\n",
(pointer)pPixmap,
pPixmap->drawable.width, pPixmap->drawable.height,
pPixmap->drawable.bitsPerPixel));
return;
}
/* If the "dirty" flag has never been set on the in-memory pixmap, then
* nothing has been written to it, so the contents are undefined and we can
* avoid the upload.
*/
if (!pExaPixmap->dirty) {
DBG_MIGRATE(("saved upload of %dx%d\n", pPixmap->drawable.width,
pPixmap->drawable.height));
return;
}
pExaPixmap->dirty = FALSE;
if (pExaScr->info->accel.UploadToScreen)
{
if (pExaScr->info->accel.UploadToScreen(pPixmap, 0, 0,
pPixmap->drawable.width,
pPixmap->drawable.height,
src, src_pitch))
return;
}
dst = pPixmap->devPrivate.ptr;
dst_pitch = pPixmap->devKind;
bytes = src_pitch < dst_pitch ? src_pitch : dst_pitch;
exaWaitSync (pPixmap->drawable.pScreen);
i = pPixmap->drawable.height;
DBG_PIXMAP(("dst = %p, src = %p,(%d, %d) height = %d, mem_base = %p, offset = %d\n",
dst, src, dst_pitch, src_pitch,
i, pExaScr->info->card.memoryBase, ExaGetPixmapPriv(pPixmap)->area->offset));
while (i--) {
memcpy (dst, src, bytes);
dst += dst_pitch;
src += src_pitch;
}
}
static void
exaMoveOutPixmap (PixmapPtr pPixmap)
{
ExaPixmapPriv (pPixmap);
ExaOffscreenArea *area = pExaPixmap->area;
DBG_MIGRATE (("<- 0x%p (0x%p) (%dx%d)\n",
(void*)pPixmap->drawable.id,
(void*)(ExaGetPixmapPriv(pPixmap)->area ?
ExaGetPixmapPriv(pPixmap)->area->offset : 0),
pPixmap->drawable.width,
pPixmap->drawable.height));
STRACE;
if (area)
{
exaPixmapSave (pPixmap->drawable.pScreen, area);
exaOffscreenFree (pPixmap->drawable.pScreen, area);
}
}
void
exaDrawableUseScreen(DrawablePtr pDrawable)
{
PixmapPtr pPixmap;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
exaPixmapUseScreen (pPixmap);
}
void
exaDrawableUseMemory(DrawablePtr pDrawable)
{
PixmapPtr pPixmap;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
exaPixmapUseMemory (pPixmap);
}
void
exaPixmapUseScreen (PixmapPtr pPixmap)
{
ExaPixmapPriv (pPixmap);
STRACE;
if (pExaPixmap == NULL) {
DBG_MIGRATE(("UseScreen: ignoring exa-uncontrolled pixmap %p (%s)\n",
(pointer)pPixmap,
exaPixmapIsOffscreen(pPixmap) ? "s" : "m"));
return;
}
if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) {
DBG_MIGRATE(("UseScreen: not migrating pinned pixmap %p\n",
(pointer)pPixmap));
return;
}
DBG_MIGRATE(("UseScreen %p score %d\n",
(pointer)pPixmap, pExaPixmap->score));
if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) {
exaMoveInPixmap(pPixmap);
pExaPixmap->score = 0;
}
if (pExaPixmap->score < EXA_PIXMAP_SCORE_MAX)
pExaPixmap->score++;
if (pExaPixmap->score >= EXA_PIXMAP_SCORE_MOVE_IN &&
!exaPixmapIsOffscreen(pPixmap))
{
exaMoveInPixmap (pPixmap);
}
ExaOffscreenMarkUsed (pPixmap);
}
void
exaPixmapUseMemory (PixmapPtr pPixmap)
{
ExaPixmapPriv (pPixmap);
if (pExaPixmap == NULL) {
DBG_MIGRATE(("UseMem: ignoring exa-uncontrolled pixmap %p (%s)\n",
(pointer)pPixmap,
exaPixmapIsOffscreen(pPixmap) ? "s" : "m"));
return;
}
DBG_MIGRATE(("UseMem: %p score %d\n", (pointer)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)
exaMoveOutPixmap (pPixmap);
}
static Bool
exaDestroyPixmap (PixmapPtr pPixmap)
{
if (pPixmap->refcnt == 1)
{
ExaPixmapPriv (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 = pExaPixmap->devPrivate;
pPixmap->devKind = pExaPixmap->devKind;
}
}
return fbDestroyPixmap (pPixmap);
}
static PixmapPtr
exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
{
PixmapPtr pPixmap;
ExaPixmapPrivPtr pExaPixmap;
int bpp;
ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
ExaScreenPriv(pScreen);
if (w > 32767 || h > 32767)
return NullPixmap;
if (!pScrn->vtSema || pExaScr->swappedOut) {
pPixmap = pExaScr->SavedCreatePixmap(pScreen, w, h, depth);
} else {
bpp = BitsPerPixel (depth);
if (bpp == 32 && depth == 24)
{
int format;
for (format = 0; format < MAXFORMATS && pScrn->formats[format].depth; ++format)
if (pScrn->formats[format].depth == 24)
{
bpp = pScrn->formats[format].bitsPerPixel;
break;
}
}
pPixmap = fbCreatePixmapBpp (pScreen, w, h, depth, bpp);
}
if (!pPixmap)
return NULL;
pExaPixmap = ExaGetPixmapPriv(pPixmap);
/* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */
if (!w || !h)
pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
else
pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;
pExaPixmap->area = NULL;
pExaPixmap->dirty = FALSE;
return pPixmap;
}
Bool
exaPixmapIsOffscreen(PixmapPtr p)
{
ScreenPtr pScreen = p->drawable.pScreen;
ExaScreenPriv(pScreen);
STRACE;
return ((unsigned long) ((CARD8 *) p->devPrivate.ptr -
(CARD8 *) pExaScr->info->card.memoryBase) <
pExaScr->info->card.memorySize);
}
PixmapPtr
exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp)
{
PixmapPtr pPixmap;
int x, y;
STRACE;
if (pDrawable->type == DRAWABLE_WINDOW) {
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
#ifdef COMPOSITE
x = -pPixmap->screen_x;
y = -pPixmap->screen_y;
#else
x = 0;
y = 0;
#endif
}
else
{
pPixmap = (PixmapPtr) pDrawable;
x = 0;
y = 0;
}
*xp = x;
*yp = y;
if (exaPixmapIsOffscreen (pPixmap))
return pPixmap;
else
return NULL;
}
Bool
exaDrawableIsOffscreen (DrawablePtr pDrawable)
{
PixmapPtr pPixmap;
STRACE;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
return exaPixmapIsOffscreen (pPixmap);
}
void
exaPrepareAccess(DrawablePtr pDrawable, int index)
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
PixmapPtr pPixmap;
STRACE;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
if (index == EXA_PREPARE_DEST)
exaDrawableDirty (pDrawable);
if (exaPixmapIsOffscreen (pPixmap))
exaWaitSync (pDrawable->pScreen);
else
return;
if (pExaScr->info->accel.PrepareAccess == NULL)
return;
if (!(*pExaScr->info->accel.PrepareAccess) (pPixmap, index)) {
ExaPixmapPriv (pPixmap);
if (pExaPixmap->score != EXA_PIXMAP_SCORE_PINNED)
FatalError("Driver failed PrepareAccess on a pinned pixmap\n");
exaMoveOutPixmap (pPixmap);
}
}
void
exaFinishAccess(DrawablePtr pDrawable, int index)
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
PixmapPtr pPixmap;
STRACE;
if (pExaScr->info->accel.FinishAccess == NULL)
return;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
if (!exaPixmapIsOffscreen (pPixmap))
return;
(*pExaScr->info->accel.FinishAccess) (pPixmap, index);
}
static void
exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
@ -1074,7 +538,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
static const GCOps exaOps = {
const GCOps exaOps = {
exaFillSpans,
ExaCheckSetSpans,
ExaCheckPutImage,
@ -1100,41 +564,7 @@ static const GCOps exaOps = {
#endif
};
static void
exaValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable)
{
fbValidateGC (pGC, changes, pDrawable);
if (exaDrawableIsOffscreen (pDrawable))
pGC->ops = (GCOps *) &exaOps;
else
pGC->ops = (GCOps *) &exaAsyncPixmapGCOps;
}
static GCFuncs exaGCFuncs = {
exaValidateGC,
miChangeGC,
miCopyGC,
miDestroyGC,
miChangeClip,
miDestroyClip,
miCopyClip
};
static int
exaCreateGC (GCPtr pGC)
{
STRACE;
if (!fbCreateGC (pGC))
return FALSE;
pGC->funcs = &exaGCFuncs;
return TRUE;
}
static void
void
exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
RegionRec rgnDst;
@ -1326,7 +756,7 @@ fallback:
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
static void
void
exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
{
ScrnInfoPtr pScrn = XF86SCRNINFO(pWin->drawable.pScreen);
@ -1369,239 +799,3 @@ exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
}
ExaCheckPaintWindow (pWin, pRegion, what);
}
static Bool
exaCloseScreen(int i, ScreenPtr pScreen)
{
ExaScreenPriv(pScreen);
#ifdef RENDER
PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
#endif
ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
pScreen->CreateGC = pExaScr->SavedCreateGC;
pScreen->CloseScreen = pExaScr->SavedCloseScreen;
pScreen->GetImage = pExaScr->SavedGetImage;
pScreen->GetSpans = pExaScr->SavedGetSpans;
pScreen->PaintWindowBackground = pExaScr->SavedPaintWindowBackground;
pScreen->PaintWindowBorder = pExaScr->SavedPaintWindowBorder;
pScreen->CreatePixmap = pExaScr->SavedCreatePixmap;
pScreen->DestroyPixmap = pExaScr->SavedDestroyPixmap;
pScreen->CopyWindow = pExaScr->SavedCopyWindow;
#ifdef RENDER
if (ps) {
ps->Composite = pExaScr->SavedComposite;
ps->Glyphs = pExaScr->SavedGlyphs;
}
#endif
if (pExaScr->wrappedEnableDisableFB)
pScrn->EnableDisableFBAccess = pExaScr->SavedEnableDisableFBAccess;
xfree (pExaScr);
return (*pScreen->CloseScreen) (i, pScreen);
}
Bool
exaDriverInit (ScreenPtr pScreen,
ExaDriverPtr pScreenInfo)
{
/* Do NOT use XF86SCRNINFO macro here!! */
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
ExaScreenPrivPtr pExaScr;
#ifdef RENDER
PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
#endif
STRACE;
if (exaGeneration != serverGeneration)
{
exaScreenPrivateIndex = AllocateScreenPrivateIndex();
exaPixmapPrivateIndex = AllocatePixmapPrivateIndex();
exaGeneration = serverGeneration;
}
pExaScr = xcalloc (sizeof (ExaScreenPrivRec), 1);
if (!pExaScr) {
xf86DrvMsg(pScreen->myNum, X_WARNING,
"EXA: Failed to allocate screen private\n");
return FALSE;
}
pExaScr->info = pScreenInfo;
pScreen->devPrivates[exaScreenPrivateIndex].ptr = (pointer) pExaScr;
/*
* Replace various fb screen functions
*/
pExaScr->SavedCloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = exaCloseScreen;
pExaScr->SavedCreateGC = pScreen->CreateGC;
pScreen->CreateGC = exaCreateGC;
pExaScr->SavedGetImage = pScreen->GetImage;
pScreen->GetImage = ExaCheckGetImage;
pExaScr->SavedGetSpans = pScreen->GetSpans;
pScreen->GetSpans = ExaCheckGetSpans;
pExaScr->SavedCopyWindow = pScreen->CopyWindow;
pScreen->CopyWindow = exaCopyWindow;
pExaScr->SavedPaintWindowBackground = pScreen->PaintWindowBackground;
pScreen->PaintWindowBackground = exaPaintWindow;
pExaScr->SavedPaintWindowBorder = pScreen->PaintWindowBorder;
pScreen->PaintWindowBorder = exaPaintWindow;
pScreen->BackingStoreFuncs.SaveAreas = ExaCheckSaveAreas;
pScreen->BackingStoreFuncs.RestoreAreas = ExaCheckRestoreAreas;
#ifdef RENDER
if (ps) {
pExaScr->SavedComposite = ps->Composite;
ps->Composite = exaComposite;
pExaScr->SavedGlyphs = ps->Glyphs;
ps->Glyphs = exaGlyphs;
}
#endif
miDisableCompositeWrapper(pScreen);
/*
* Hookup offscreen pixmaps
*/
if ((pExaScr->info->card.flags & EXA_OFFSCREEN_PIXMAPS) &&
pExaScr->info->card.offScreenBase < pExaScr->info->card.memorySize)
{
if (!AllocatePixmapPrivate(pScreen, exaPixmapPrivateIndex,
sizeof (ExaPixmapPrivRec))) {
xf86DrvMsg(pScreen->myNum, X_WARNING,
"EXA: Failed to allocate pixmap private\n");
return FALSE;
}
pExaScr->SavedCreatePixmap = pScreen->CreatePixmap;
pScreen->CreatePixmap = exaCreatePixmap;
pExaScr->SavedDestroyPixmap = pScreen->DestroyPixmap;
pScreen->DestroyPixmap = exaDestroyPixmap;
}
else
{
xf86DrvMsg(pScreen->myNum, X_INFO, "EXA: No offscreen pixmaps\n");
if (!AllocatePixmapPrivate(pScreen, exaPixmapPrivateIndex, 0))
return FALSE;
}
DBG_PIXMAP(("============== %ld < %ld\n", pExaScr->info->card.offScreenBase,
pExaScr->info->card.memorySize));
if (pExaScr->info->card.offScreenBase < pExaScr->info->card.memorySize) {
if (!exaOffscreenInit (pScreen)) {
xf86DrvMsg(pScreen->myNum, X_WARNING,
"EXA: Offscreen pixmap setup failed\n");
return FALSE;
}
pExaScr->SavedEnableDisableFBAccess = pScrn->EnableDisableFBAccess;
pScrn->EnableDisableFBAccess = exaEnableDisableFBAccess;
pExaScr->wrappedEnableDisableFB = TRUE;
}
return TRUE;
}
void
exaDriverFini (ScreenPtr pScreen)
{
/*right now does nothing*/
}
void exaMarkSync(ScreenPtr pScreen)
{
ExaScreenPriv(pScreen);
ExaCardInfoPtr card = &(pExaScr->info->card);
card->needsSync = TRUE;
if (pExaScr->info->accel.MarkSync != NULL) {
card->lastMarker = (*pExaScr->info->accel.MarkSync)(pScreen);
}
}
void exaWaitSync(ScreenPtr pScreen)
{
ExaScreenPriv(pScreen);
ExaCardInfoPtr card = &(pExaScr->info->card);
ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
if (card->needsSync && pScrn->vtSema) {
(*pExaScr->info->accel.WaitMarker)(pScreen, card->lastMarker);
card->needsSync = FALSE;
}
}
unsigned int exaGetVersion(void)
{
return EXA_VERSION;
}
#ifdef XFree86LOADER
static MODULESETUPPROTO(exaSetup);
static const OptionInfoRec EXAOptions[] = {
{ -1, NULL,
OPTV_NONE, {0}, FALSE }
};
/*ARGSUSED*/
static const OptionInfoRec *
EXAAvailableOptions(void *unused)
{
return (EXAOptions);
}
static XF86ModuleVersionInfo exaVersRec =
{
"exa",
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
XORG_VERSION_CURRENT,
1, 2, 0,
ABI_CLASS_VIDEODRV, /* requires the video driver ABI */
ABI_VIDEODRV_VERSION,
MOD_CLASS_NONE,
{0,0,0,0}
};
XF86ModuleData exaModuleData = { &exaVersRec, exaSetup, NULL };
ModuleInfoRec EXA = {
1,
"EXA",
NULL,
0,
EXAAvailableOptions,
};
/*ARGSUSED*/
static pointer
exaSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor)
{
static Bool Initialised = FALSE;
if (!Initialised) {
Initialised = TRUE;
#ifndef REMOVE_LOADER_CHECK_MODULE_INFO
if (xf86LoaderCheckSymbol("xf86AddModuleInfo"))
#endif
xf86AddModuleInfo(&EXA, Module);
}
return (pointer)TRUE;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "exaPriv.h"
#include "exa_priv.h"
#if DEBUG_OFFSCREEN
#define DBG_OFFSCREEN(a) ErrorF a

View File

@ -67,6 +67,12 @@ do { \
#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
@ -109,6 +115,13 @@ extern int exaPixmapPrivateIndex;
#define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)(s)->devPrivates[exaScreenPrivateIndex].ptr)
#define ExaScreenPriv(s) ExaScreenPrivPtr pExaScr = ExaGetScreenPriv(s)
#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)(p)->devPrivates[exaPixmapPrivateIndex].ptr)
#define ExaSetPixmapPriv(p,a) ((p)->devPrivates[exaPixmapPrivateIndex].ptr = (pointer) (a))
#define ExaPixmapPriv(p) ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p)
@ -230,7 +243,14 @@ ExaCheckRestoreAreas (PixmapPtr pPixmap,
void
ExaCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what);
extern const GCOps exaAsyncPixmapGCOps;
/* exa_accel.c */
void
exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
void
exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
extern const GCOps exaOps, exaAsyncPixmapGCOps;
#ifdef RENDER
void
@ -298,6 +318,9 @@ exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp);
void
exaMoveInPixmap (PixmapPtr pPixmap);
void
exaMoveOutPixmap (PixmapPtr pPixmap);
RegionPtr
exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
int srcx, int srcy, int width, int height, int dstx, int dsty);

View File

@ -25,7 +25,7 @@
#ifdef HAVE_CONFIG_H
#include <xorg-config.h>
#endif
#include "exaPriv.h"
#include "exa_priv.h"
#ifdef RENDER
#include "mipict.h"

View File

@ -21,7 +21,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "exaPriv.h"
#include "exa_priv.h"
/*
* These functions wrap the low-level fb rendering functions and

View File

@ -11,9 +11,12 @@ INCLUDES = \
AM_CFLAGS = $(XORG_CFLAGS) @SERVER_DEFINES@ @MODULE_DEFINES@ @LOADER_DEFINES@
libexa_la_SOURCES = \
exaasync.c \
exa.c \
exa.h \
exaoffscreen.c \
exapict.c \
exaPriv.h
exa_accel.c \
exa_migration.c \
exa_offscreen.c \
exa_render.c \
exa_priv.h \
exa_unaccel.c

File diff suppressed because it is too large Load Diff

View File

@ -1,343 +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_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#include "exa.h"
#include <X11/X.h>
#define NEED_EVENTS
#include <X11/Xproto.h>
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "windowstr.h"
#include "servermd.h"
#include "mibstore.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"
#ifdef RENDER
#include "fbpict.h"
#endif
#define DEBUG_TRACE_FALL 0
#define DEBUG_MIGRATE 0
#define DEBUG_PIXMAP 0
#define DEBUG_OFFSCREEN 0
#if DEBUG_TRACE_FALL
#define EXA_FALLBACK(x) \
do { \
ErrorF("EXA fallback at %s: ", __FUNCTION__); \
ErrorF x; \
} while (0)
#else
#define EXA_FALLBACK(x)
#endif
#ifndef EXA_MAX_FB
#define EXA_MAX_FB FB_OVERLAY_MAX
#endif
typedef void (*EnableDisableFBAccessProcPtr)(int, Bool);
typedef struct {
ExaDriverPtr info;
CreateGCProcPtr SavedCreateGC;
CloseScreenProcPtr SavedCloseScreen;
GetImageProcPtr SavedGetImage;
GetSpansProcPtr SavedGetSpans;
PaintWindowBackgroundProcPtr SavedPaintWindowBackground;
CreatePixmapProcPtr SavedCreatePixmap;
DestroyPixmapProcPtr SavedDestroyPixmap;
PaintWindowBorderProcPtr SavedPaintWindowBorder;
CopyWindowProcPtr SavedCopyWindow;
#ifdef RENDER
CompositeProcPtr SavedComposite;
GlyphsProcPtr SavedGlyphs;
#endif
EnableDisableFBAccessProcPtr SavedEnableDisableFBAccess;
Bool wrappedEnableDisableFB;
Bool swappedOut;
} ExaScreenPrivRec, *ExaScreenPrivPtr;
/*
* This is the only completely portable way to
* compute this info.
*/
#ifndef BitsPerPixel
#define BitsPerPixel(d) (\
PixmapWidthPaddingInfo[d].notPower2 ? \
(PixmapWidthPaddingInfo[d].bytesPerPixel * 8) : \
((1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \
(PixmapWidthPaddingInfo[d].padRoundUp+1)))
#endif
extern int exaScreenPrivateIndex;
extern int exaPixmapPrivateIndex;
#define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)(s)->devPrivates[exaScreenPrivateIndex].ptr)
#define ExaScreenPriv(s) ExaScreenPrivPtr pExaScr = ExaGetScreenPriv(s)
#define ExaGetPixmapPriv(p) ((ExaPixmapPrivPtr)(p)->devPrivates[exaPixmapPrivateIndex].ptr)
#define ExaSetPixmapPriv(p,a) ((p)->devPrivates[exaPixmapPrivateIndex].ptr = (pointer) (a))
#define ExaPixmapPriv(p) ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p)
typedef struct {
ExaOffscreenArea *area;
int score;
int devKind;
DevUnion devPrivate;
/* If area is NULL, then dirty == TRUE means that the pixmap has been
* modified, so the contents are defined. Used to avoid uploads of
* undefined data.
* If area is non-NULL, then dirty == TRUE means that the in-framebuffer
* copy has been changed from the system-memory copy. Used to avoid
* downloads of unmodified data.
*/
Bool dirty;
unsigned int size;
} ExaPixmapPrivRec, *ExaPixmapPrivPtr;
/* exaasync.c */
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);
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
ExaCheckPolyRectangle (DrawablePtr pDrawable, GCPtr pGC,
int nrects, xRectangle *prect);
void
ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
int narcs, xArc *pArcs);
#define ExaCheckFillPolygon miFillPolygon
void
ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
int nrect, xRectangle *prect);
void
ExaCheckPolyFillArc (DrawablePtr pDrawable, GCPtr pGC,
int narcs, xArc *pArcs);
void
ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase);
void
ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase);
void
ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
DrawablePtr pDrawable,
int w, int h, int x, int y);
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
ExaCheckSaveAreas (PixmapPtr pPixmap,
RegionPtr prgnSave,
int xorg,
int yorg,
WindowPtr pWin);
void
ExaCheckRestoreAreas (PixmapPtr pPixmap,
RegionPtr prgnSave,
int xorg,
int yorg,
WindowPtr pWin);
void
ExaCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what);
extern const GCOps exaAsyncPixmapGCOps;
#ifdef RENDER
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);
#endif
/* exaoffscreen.c */
void
ExaOffscreenMarkUsed (PixmapPtr pPixmap);
void
ExaOffscreenSwapOut (ScreenPtr pScreen);
void
ExaOffscreenSwapIn (ScreenPtr pScreen);
void
ExaOffscreenFini (ScreenPtr pScreen);
void
exaEnableDisableFBAccess (int index, Bool enable);
/* exa.c */
void
exaDrawableUseScreen(DrawablePtr pDrawable);
void
exaDrawableUseMemory(DrawablePtr pDrawable);
void
exaPixmapUseScreen (PixmapPtr pPixmap);
void
exaPixmapUseMemory (PixmapPtr pPixmap);
void
exaPrepareAccess(DrawablePtr pDrawable, int index);
void
exaFinishAccess(DrawablePtr pDrawable, int index);
void
exaDrawableDirty(DrawablePtr pDrawable);
Bool
exaDrawableIsOffscreen (DrawablePtr pDrawable);
Bool
exaPixmapIsOffscreen(PixmapPtr p);
PixmapPtr
exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp);
void
exaMoveInPixmap (PixmapPtr pPixmap);
RegionPtr
exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
int srcx, int srcy, int width, int height, int dstx, int dsty);
void
exaCopyNtoN (DrawablePtr pSrcDrawable,
DrawablePtr pDstDrawable,
GCPtr pGC,
BoxPtr pbox,
int nbox,
int dx,
int dy,
Bool reverse,
Bool upsidedown,
Pixel bitplane,
void *closure);
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
exaGlyphs (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int nlist,
GlyphListPtr list,
GlyphPtr *glyphs);
#endif /* EXAPRIV_H */

View File

@ -25,7 +25,7 @@
#ifdef HAVE_CONFIG_H
#include <xorg-config.h>
#endif
#include "exaPriv.h"
#include "exa_priv.h"
#include <X11/fonts/fontstruct.h>
#include "dixfontstr.h"
#include "xf86str.h"
@ -33,543 +33,7 @@
#include "exa.h"
#include "cw.h"
#if DEBUG_MIGRATE
#define DBG_MIGRATE(a) ErrorF a
#else
#define DBG_MIGRATE(a)
#endif
#if DEBUG_PIXMAP
#define DBG_PIXMAP(a) ErrorF a
#else
#define DBG_PIXMAP(a)
#endif
#define STRACE
#define TRACE
static int exaGeneration;
int exaScreenPrivateIndex;
int exaPixmapPrivateIndex;
#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
/* Returns the offset (in bytes) within the framebuffer of the beginning of the
* given pixmap. May need to be extended in the future if we grow support for
* having multiple card-accessible areas at different offsets.
*/
unsigned long
exaGetPixmapOffset(PixmapPtr pPix)
{
ExaScreenPriv (pPix->drawable.pScreen);
return ((unsigned long)pPix->devPrivate.ptr -
(unsigned long)pExaScr->info->card.memoryBase);
}
/* Returns the pitch in bytes of the given pixmap. */
unsigned long
exaGetPixmapPitch(PixmapPtr pPix)
{
return pPix->devKind;
}
/* Returns the size in bytes of the given pixmap in
* video memory. Only valid when the vram storage has been
* allocated
*/
unsigned long
exaGetPixmapSize(PixmapPtr pPix)
{
ExaPixmapPrivPtr pExaPixmap;
pExaPixmap = ExaGetPixmapPriv(pPix);
if (pExaPixmap != NULL)
return pExaPixmap->size;
return 0;
}
void
exaDrawableDirty (DrawablePtr pDrawable)
{
PixmapPtr pPixmap;
ExaPixmapPrivPtr pExaPixmap;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap)((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr)pDrawable;
pExaPixmap = ExaGetPixmapPriv(pPixmap);
if (pExaPixmap != NULL)
pExaPixmap->dirty = TRUE;
}
static void
exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
{
PixmapPtr pPixmap = area->privData;
ExaScreenPriv (pScreen);
ExaPixmapPriv(pPixmap);
int dst_pitch, src_pitch, bytes;
char *dst, *src;
int i;
DBG_MIGRATE (("Save %p (%p) (%dx%d)\n",
(void*)pPixmap->drawable.id,
(void*)(ExaGetPixmapPriv(pPixmap)->area ?
ExaGetPixmapPriv(pPixmap)->area->offset : 0),
pPixmap->drawable.width,
pPixmap->drawable.height));
src_pitch = pPixmap->devKind;
dst_pitch = pExaPixmap->devKind;
src = pPixmap->devPrivate.ptr;
dst = pExaPixmap->devPrivate.ptr;
if (pExaPixmap->dirty) {
if (pExaScr->info->accel.DownloadFromScreen &&
(*pExaScr->info->accel.DownloadFromScreen) (pPixmap,
pPixmap->drawable.x,
pPixmap->drawable.y,
pPixmap->drawable.width,
pPixmap->drawable.height,
dst,
dst_pitch)) {
} else {
exaWaitSync (pPixmap->drawable.pScreen);
bytes = src_pitch < dst_pitch ? src_pitch : dst_pitch;
i = pPixmap->drawable.height;
while (i--) {
memcpy (dst, src, bytes);
dst += dst_pitch;
src += src_pitch;
}
}
}
pPixmap->devKind = dst_pitch;
pPixmap->devPrivate.ptr = pExaPixmap->devPrivate.ptr;
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
pExaPixmap->area = NULL;
/* Mark it dirty now, to say that there is important data in the
* system-memory copy.
*/
pExaPixmap->dirty = TRUE;
}
static int
exaLog2(int val)
{
int bits;
if (!val)
return 0;
for (bits = 0; val != 0; bits++)
val >>= 1;
return bits - 1;
}
static Bool
exaPixmapAllocArea (PixmapPtr pPixmap)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
ExaScreenPriv (pScreen);
ExaPixmapPriv (pPixmap);
int bpp = pPixmap->drawable.bitsPerPixel;
CARD16 h = pPixmap->drawable.height;
CARD16 w = pPixmap->drawable.width;
int pitch;
if (pExaScr->info->card.flags & EXA_OFFSCREEN_ALIGN_POT && w != 1)
w = 1 << (exaLog2(w - 1) + 1);
pitch = (w * bpp / 8) + (pExaScr->info->card.pixmapPitchAlign - 1);
pitch -= pitch % pExaScr->info->card.pixmapPitchAlign;
pExaPixmap->size = pitch * h;
pExaPixmap->devKind = pPixmap->devKind;
pExaPixmap->devPrivate = pPixmap->devPrivate;
pExaPixmap->area = exaOffscreenAlloc (pScreen, pitch * h,
pExaScr->info->card.pixmapOffsetAlign,
FALSE,
exaPixmapSave, (pointer) pPixmap);
if (!pExaPixmap->area)
return FALSE;
DBG_PIXMAP(("++ 0x%lx (0x%x) (%dx%d)\n", pPixmap->drawable.id,
(ExaGetPixmapPriv(pPixmap)->area ?
ExaGetPixmapPriv(pPixmap)->area->offset : 0),
pPixmap->drawable.width,
pPixmap->drawable.height));
pPixmap->devKind = pitch;
pPixmap->devPrivate.ptr = (pointer) ((CARD8 *) pExaScr->info->card.memoryBase + pExaPixmap->area->offset);
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
return TRUE;
}
void
exaMoveInPixmap (PixmapPtr pPixmap)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
ExaScreenPriv (pScreen);
ExaPixmapPriv (pPixmap);
int dst_pitch, src_pitch, bytes;
char *dst, *src;
int i;
DBG_MIGRATE (("-> 0x%lx (0x%x) (%dx%d)\n", pPixmap->drawable.id,
(ExaGetPixmapPriv(pPixmap)->area ?
ExaGetPixmapPriv(pPixmap)->area->offset : 0),
pPixmap->drawable.width,
pPixmap->drawable.height));
src = pPixmap->devPrivate.ptr;
src_pitch = pPixmap->devKind;
if (!exaPixmapAllocArea (pPixmap)) {
DBG_MIGRATE (("failed to allocate fb for pixmap %p (%dx%dx%d)\n",
(pointer)pPixmap,
pPixmap->drawable.width, pPixmap->drawable.height,
pPixmap->drawable.bitsPerPixel));
return;
}
/* If the "dirty" flag has never been set on the in-memory pixmap, then
* nothing has been written to it, so the contents are undefined and we can
* avoid the upload.
*/
if (!pExaPixmap->dirty) {
DBG_MIGRATE(("saved upload of %dx%d\n", pPixmap->drawable.width,
pPixmap->drawable.height));
return;
}
pExaPixmap->dirty = FALSE;
if (pExaScr->info->accel.UploadToScreen)
{
if (pExaScr->info->accel.UploadToScreen(pPixmap, 0, 0,
pPixmap->drawable.width,
pPixmap->drawable.height,
src, src_pitch))
return;
}
dst = pPixmap->devPrivate.ptr;
dst_pitch = pPixmap->devKind;
bytes = src_pitch < dst_pitch ? src_pitch : dst_pitch;
exaWaitSync (pPixmap->drawable.pScreen);
i = pPixmap->drawable.height;
DBG_PIXMAP(("dst = %p, src = %p,(%d, %d) height = %d, mem_base = %p, offset = %d\n",
dst, src, dst_pitch, src_pitch,
i, pExaScr->info->card.memoryBase, ExaGetPixmapPriv(pPixmap)->area->offset));
while (i--) {
memcpy (dst, src, bytes);
dst += dst_pitch;
src += src_pitch;
}
}
static void
exaMoveOutPixmap (PixmapPtr pPixmap)
{
ExaPixmapPriv (pPixmap);
ExaOffscreenArea *area = pExaPixmap->area;
DBG_MIGRATE (("<- 0x%p (0x%p) (%dx%d)\n",
(void*)pPixmap->drawable.id,
(void*)(ExaGetPixmapPriv(pPixmap)->area ?
ExaGetPixmapPriv(pPixmap)->area->offset : 0),
pPixmap->drawable.width,
pPixmap->drawable.height));
STRACE;
if (area)
{
exaPixmapSave (pPixmap->drawable.pScreen, area);
exaOffscreenFree (pPixmap->drawable.pScreen, area);
}
}
void
exaDrawableUseScreen(DrawablePtr pDrawable)
{
PixmapPtr pPixmap;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
exaPixmapUseScreen (pPixmap);
}
void
exaDrawableUseMemory(DrawablePtr pDrawable)
{
PixmapPtr pPixmap;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
exaPixmapUseMemory (pPixmap);
}
void
exaPixmapUseScreen (PixmapPtr pPixmap)
{
ExaPixmapPriv (pPixmap);
STRACE;
if (pExaPixmap == NULL) {
DBG_MIGRATE(("UseScreen: ignoring exa-uncontrolled pixmap %p (%s)\n",
(pointer)pPixmap,
exaPixmapIsOffscreen(pPixmap) ? "s" : "m"));
return;
}
if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) {
DBG_MIGRATE(("UseScreen: not migrating pinned pixmap %p\n",
(pointer)pPixmap));
return;
}
DBG_MIGRATE(("UseScreen %p score %d\n",
(pointer)pPixmap, pExaPixmap->score));
if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) {
exaMoveInPixmap(pPixmap);
pExaPixmap->score = 0;
}
if (pExaPixmap->score < EXA_PIXMAP_SCORE_MAX)
pExaPixmap->score++;
if (pExaPixmap->score >= EXA_PIXMAP_SCORE_MOVE_IN &&
!exaPixmapIsOffscreen(pPixmap))
{
exaMoveInPixmap (pPixmap);
}
ExaOffscreenMarkUsed (pPixmap);
}
void
exaPixmapUseMemory (PixmapPtr pPixmap)
{
ExaPixmapPriv (pPixmap);
if (pExaPixmap == NULL) {
DBG_MIGRATE(("UseMem: ignoring exa-uncontrolled pixmap %p (%s)\n",
(pointer)pPixmap,
exaPixmapIsOffscreen(pPixmap) ? "s" : "m"));
return;
}
DBG_MIGRATE(("UseMem: %p score %d\n", (pointer)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)
exaMoveOutPixmap (pPixmap);
}
static Bool
exaDestroyPixmap (PixmapPtr pPixmap)
{
if (pPixmap->refcnt == 1)
{
ExaPixmapPriv (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 = pExaPixmap->devPrivate;
pPixmap->devKind = pExaPixmap->devKind;
}
}
return fbDestroyPixmap (pPixmap);
}
static PixmapPtr
exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
{
PixmapPtr pPixmap;
ExaPixmapPrivPtr pExaPixmap;
int bpp;
ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
ExaScreenPriv(pScreen);
if (w > 32767 || h > 32767)
return NullPixmap;
if (!pScrn->vtSema || pExaScr->swappedOut) {
pPixmap = pExaScr->SavedCreatePixmap(pScreen, w, h, depth);
} else {
bpp = BitsPerPixel (depth);
if (bpp == 32 && depth == 24)
{
int format;
for (format = 0; format < MAXFORMATS && pScrn->formats[format].depth; ++format)
if (pScrn->formats[format].depth == 24)
{
bpp = pScrn->formats[format].bitsPerPixel;
break;
}
}
pPixmap = fbCreatePixmapBpp (pScreen, w, h, depth, bpp);
}
if (!pPixmap)
return NULL;
pExaPixmap = ExaGetPixmapPriv(pPixmap);
/* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */
if (!w || !h)
pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
else
pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;
pExaPixmap->area = NULL;
pExaPixmap->dirty = FALSE;
return pPixmap;
}
Bool
exaPixmapIsOffscreen(PixmapPtr p)
{
ScreenPtr pScreen = p->drawable.pScreen;
ExaScreenPriv(pScreen);
STRACE;
return ((unsigned long) ((CARD8 *) p->devPrivate.ptr -
(CARD8 *) pExaScr->info->card.memoryBase) <
pExaScr->info->card.memorySize);
}
PixmapPtr
exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp)
{
PixmapPtr pPixmap;
int x, y;
STRACE;
if (pDrawable->type == DRAWABLE_WINDOW) {
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
#ifdef COMPOSITE
x = -pPixmap->screen_x;
y = -pPixmap->screen_y;
#else
x = 0;
y = 0;
#endif
}
else
{
pPixmap = (PixmapPtr) pDrawable;
x = 0;
y = 0;
}
*xp = x;
*yp = y;
if (exaPixmapIsOffscreen (pPixmap))
return pPixmap;
else
return NULL;
}
Bool
exaDrawableIsOffscreen (DrawablePtr pDrawable)
{
PixmapPtr pPixmap;
STRACE;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
return exaPixmapIsOffscreen (pPixmap);
}
void
exaPrepareAccess(DrawablePtr pDrawable, int index)
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
PixmapPtr pPixmap;
STRACE;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
if (index == EXA_PREPARE_DEST)
exaDrawableDirty (pDrawable);
if (exaPixmapIsOffscreen (pPixmap))
exaWaitSync (pDrawable->pScreen);
else
return;
if (pExaScr->info->accel.PrepareAccess == NULL)
return;
if (!(*pExaScr->info->accel.PrepareAccess) (pPixmap, index)) {
ExaPixmapPriv (pPixmap);
if (pExaPixmap->score != EXA_PIXMAP_SCORE_PINNED)
FatalError("Driver failed PrepareAccess on a pinned pixmap\n");
exaMoveOutPixmap (pPixmap);
}
}
void
exaFinishAccess(DrawablePtr pDrawable, int index)
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
PixmapPtr pPixmap;
STRACE;
if (pExaScr->info->accel.FinishAccess == NULL)
return;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
if (!exaPixmapIsOffscreen (pPixmap))
return;
(*pExaScr->info->accel.FinishAccess) (pPixmap, index);
}
static void
exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
@ -1074,7 +538,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
static const GCOps exaOps = {
const GCOps exaOps = {
exaFillSpans,
ExaCheckSetSpans,
ExaCheckPutImage,
@ -1100,41 +564,7 @@ static const GCOps exaOps = {
#endif
};
static void
exaValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable)
{
fbValidateGC (pGC, changes, pDrawable);
if (exaDrawableIsOffscreen (pDrawable))
pGC->ops = (GCOps *) &exaOps;
else
pGC->ops = (GCOps *) &exaAsyncPixmapGCOps;
}
static GCFuncs exaGCFuncs = {
exaValidateGC,
miChangeGC,
miCopyGC,
miDestroyGC,
miChangeClip,
miDestroyClip,
miCopyClip
};
static int
exaCreateGC (GCPtr pGC)
{
STRACE;
if (!fbCreateGC (pGC))
return FALSE;
pGC->funcs = &exaGCFuncs;
return TRUE;
}
static void
void
exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
RegionRec rgnDst;
@ -1326,7 +756,7 @@ fallback:
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
static void
void
exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
{
ScrnInfoPtr pScrn = XF86SCRNINFO(pWin->drawable.pScreen);
@ -1369,239 +799,3 @@ exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
}
ExaCheckPaintWindow (pWin, pRegion, what);
}
static Bool
exaCloseScreen(int i, ScreenPtr pScreen)
{
ExaScreenPriv(pScreen);
#ifdef RENDER
PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
#endif
ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
pScreen->CreateGC = pExaScr->SavedCreateGC;
pScreen->CloseScreen = pExaScr->SavedCloseScreen;
pScreen->GetImage = pExaScr->SavedGetImage;
pScreen->GetSpans = pExaScr->SavedGetSpans;
pScreen->PaintWindowBackground = pExaScr->SavedPaintWindowBackground;
pScreen->PaintWindowBorder = pExaScr->SavedPaintWindowBorder;
pScreen->CreatePixmap = pExaScr->SavedCreatePixmap;
pScreen->DestroyPixmap = pExaScr->SavedDestroyPixmap;
pScreen->CopyWindow = pExaScr->SavedCopyWindow;
#ifdef RENDER
if (ps) {
ps->Composite = pExaScr->SavedComposite;
ps->Glyphs = pExaScr->SavedGlyphs;
}
#endif
if (pExaScr->wrappedEnableDisableFB)
pScrn->EnableDisableFBAccess = pExaScr->SavedEnableDisableFBAccess;
xfree (pExaScr);
return (*pScreen->CloseScreen) (i, pScreen);
}
Bool
exaDriverInit (ScreenPtr pScreen,
ExaDriverPtr pScreenInfo)
{
/* Do NOT use XF86SCRNINFO macro here!! */
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
ExaScreenPrivPtr pExaScr;
#ifdef RENDER
PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
#endif
STRACE;
if (exaGeneration != serverGeneration)
{
exaScreenPrivateIndex = AllocateScreenPrivateIndex();
exaPixmapPrivateIndex = AllocatePixmapPrivateIndex();
exaGeneration = serverGeneration;
}
pExaScr = xcalloc (sizeof (ExaScreenPrivRec), 1);
if (!pExaScr) {
xf86DrvMsg(pScreen->myNum, X_WARNING,
"EXA: Failed to allocate screen private\n");
return FALSE;
}
pExaScr->info = pScreenInfo;
pScreen->devPrivates[exaScreenPrivateIndex].ptr = (pointer) pExaScr;
/*
* Replace various fb screen functions
*/
pExaScr->SavedCloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = exaCloseScreen;
pExaScr->SavedCreateGC = pScreen->CreateGC;
pScreen->CreateGC = exaCreateGC;
pExaScr->SavedGetImage = pScreen->GetImage;
pScreen->GetImage = ExaCheckGetImage;
pExaScr->SavedGetSpans = pScreen->GetSpans;
pScreen->GetSpans = ExaCheckGetSpans;
pExaScr->SavedCopyWindow = pScreen->CopyWindow;
pScreen->CopyWindow = exaCopyWindow;
pExaScr->SavedPaintWindowBackground = pScreen->PaintWindowBackground;
pScreen->PaintWindowBackground = exaPaintWindow;
pExaScr->SavedPaintWindowBorder = pScreen->PaintWindowBorder;
pScreen->PaintWindowBorder = exaPaintWindow;
pScreen->BackingStoreFuncs.SaveAreas = ExaCheckSaveAreas;
pScreen->BackingStoreFuncs.RestoreAreas = ExaCheckRestoreAreas;
#ifdef RENDER
if (ps) {
pExaScr->SavedComposite = ps->Composite;
ps->Composite = exaComposite;
pExaScr->SavedGlyphs = ps->Glyphs;
ps->Glyphs = exaGlyphs;
}
#endif
miDisableCompositeWrapper(pScreen);
/*
* Hookup offscreen pixmaps
*/
if ((pExaScr->info->card.flags & EXA_OFFSCREEN_PIXMAPS) &&
pExaScr->info->card.offScreenBase < pExaScr->info->card.memorySize)
{
if (!AllocatePixmapPrivate(pScreen, exaPixmapPrivateIndex,
sizeof (ExaPixmapPrivRec))) {
xf86DrvMsg(pScreen->myNum, X_WARNING,
"EXA: Failed to allocate pixmap private\n");
return FALSE;
}
pExaScr->SavedCreatePixmap = pScreen->CreatePixmap;
pScreen->CreatePixmap = exaCreatePixmap;
pExaScr->SavedDestroyPixmap = pScreen->DestroyPixmap;
pScreen->DestroyPixmap = exaDestroyPixmap;
}
else
{
xf86DrvMsg(pScreen->myNum, X_INFO, "EXA: No offscreen pixmaps\n");
if (!AllocatePixmapPrivate(pScreen, exaPixmapPrivateIndex, 0))
return FALSE;
}
DBG_PIXMAP(("============== %ld < %ld\n", pExaScr->info->card.offScreenBase,
pExaScr->info->card.memorySize));
if (pExaScr->info->card.offScreenBase < pExaScr->info->card.memorySize) {
if (!exaOffscreenInit (pScreen)) {
xf86DrvMsg(pScreen->myNum, X_WARNING,
"EXA: Offscreen pixmap setup failed\n");
return FALSE;
}
pExaScr->SavedEnableDisableFBAccess = pScrn->EnableDisableFBAccess;
pScrn->EnableDisableFBAccess = exaEnableDisableFBAccess;
pExaScr->wrappedEnableDisableFB = TRUE;
}
return TRUE;
}
void
exaDriverFini (ScreenPtr pScreen)
{
/*right now does nothing*/
}
void exaMarkSync(ScreenPtr pScreen)
{
ExaScreenPriv(pScreen);
ExaCardInfoPtr card = &(pExaScr->info->card);
card->needsSync = TRUE;
if (pExaScr->info->accel.MarkSync != NULL) {
card->lastMarker = (*pExaScr->info->accel.MarkSync)(pScreen);
}
}
void exaWaitSync(ScreenPtr pScreen)
{
ExaScreenPriv(pScreen);
ExaCardInfoPtr card = &(pExaScr->info->card);
ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
if (card->needsSync && pScrn->vtSema) {
(*pExaScr->info->accel.WaitMarker)(pScreen, card->lastMarker);
card->needsSync = FALSE;
}
}
unsigned int exaGetVersion(void)
{
return EXA_VERSION;
}
#ifdef XFree86LOADER
static MODULESETUPPROTO(exaSetup);
static const OptionInfoRec EXAOptions[] = {
{ -1, NULL,
OPTV_NONE, {0}, FALSE }
};
/*ARGSUSED*/
static const OptionInfoRec *
EXAAvailableOptions(void *unused)
{
return (EXAOptions);
}
static XF86ModuleVersionInfo exaVersRec =
{
"exa",
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
XORG_VERSION_CURRENT,
1, 2, 0,
ABI_CLASS_VIDEODRV, /* requires the video driver ABI */
ABI_VIDEODRV_VERSION,
MOD_CLASS_NONE,
{0,0,0,0}
};
XF86ModuleData exaModuleData = { &exaVersRec, exaSetup, NULL };
ModuleInfoRec EXA = {
1,
"EXA",
NULL,
0,
EXAAvailableOptions,
};
/*ARGSUSED*/
static pointer
exaSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor)
{
static Bool Initialised = FALSE;
if (!Initialised) {
Initialised = TRUE;
#ifndef REMOVE_LOADER_CHECK_MODULE_INFO
if (xf86LoaderCheckSymbol("xf86AddModuleInfo"))
#endif
xf86AddModuleInfo(&EXA, Module);
}
return (pointer)TRUE;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "exaPriv.h"
#include "exa_priv.h"
#if DEBUG_OFFSCREEN
#define DBG_OFFSCREEN(a) ErrorF a

View File

@ -67,6 +67,12 @@ do { \
#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
@ -109,6 +115,13 @@ extern int exaPixmapPrivateIndex;
#define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)(s)->devPrivates[exaScreenPrivateIndex].ptr)
#define ExaScreenPriv(s) ExaScreenPrivPtr pExaScr = ExaGetScreenPriv(s)
#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)(p)->devPrivates[exaPixmapPrivateIndex].ptr)
#define ExaSetPixmapPriv(p,a) ((p)->devPrivates[exaPixmapPrivateIndex].ptr = (pointer) (a))
#define ExaPixmapPriv(p) ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p)
@ -230,7 +243,14 @@ ExaCheckRestoreAreas (PixmapPtr pPixmap,
void
ExaCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what);
extern const GCOps exaAsyncPixmapGCOps;
/* exa_accel.c */
void
exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
void
exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
extern const GCOps exaOps, exaAsyncPixmapGCOps;
#ifdef RENDER
void
@ -298,6 +318,9 @@ exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp);
void
exaMoveInPixmap (PixmapPtr pPixmap);
void
exaMoveOutPixmap (PixmapPtr pPixmap);
RegionPtr
exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
int srcx, int srcy, int width, int height, int dstx, int dsty);

View File

@ -25,7 +25,7 @@
#ifdef HAVE_CONFIG_H
#include <xorg-config.h>
#endif
#include "exaPriv.h"
#include "exa_priv.h"
#ifdef RENDER
#include "mipict.h"

View File

@ -21,7 +21,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "exaPriv.h"
#include "exa_priv.h"
/*
* These functions wrap the low-level fb rendering functions and

View File

@ -1,357 +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 "exaPriv.h"
/*
* These functions wrap the low-level fb rendering functions and
* synchronize framebuffer/accelerated drawing by stalling until
* the accelerator is idle
*/
void
ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
DDXPointPtr ppt, int *pwidth, int fSorted)
{
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbFillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
{
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbSetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
int x, int y, int w, int h, int leftPad, int format,
char *bits)
{
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
RegionPtr
ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
int srcx, int srcy, int w, int h, int dstx, int dsty)
{
RegionPtr ret;
EXA_FALLBACK(("from 0x%lx to 0x%lx\n", (long)pSrc, (long)pDst));
exaPrepareAccess (pDst, EXA_PREPARE_DEST);
exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
ret = fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
exaFinishAccess (pSrc, EXA_PREPARE_SRC);
exaFinishAccess (pDst, EXA_PREPARE_DEST);
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_FALLBACK(("from 0x%lx to 0x%lx\n", (long)pSrc, (long)pDst));
exaPrepareAccess (pDst, EXA_PREPARE_DEST);
exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
ret = fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
bitPlane);
exaFinishAccess (pSrc, EXA_PREPARE_SRC);
exaFinishAccess (pDst, EXA_PREPARE_DEST);
return ret;
}
void
ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
DDXPointPtr pptInit)
{
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyPoint (pDrawable, pGC, mode, npt, pptInit);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
int mode, int npt, DDXPointPtr ppt)
{
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
if (pGC->lineWidth == 0) {
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyLine (pDrawable, pGC, mode, npt, ppt);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
fbPolyLine (pDrawable, pGC, mode, npt, ppt);
}
void
ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
int nsegInit, xSegment *pSegInit)
{
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
if (pGC->lineWidth == 0) {
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
}
void
ExaCheckPolyRectangle (DrawablePtr pDrawable, GCPtr pGC,
int nrects, xRectangle *prect)
{
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
if (pGC->lineWidth == 0) {
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyRectangle (pDrawable, pGC, nrects, prect);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
fbPolyRectangle (pDrawable, pGC, nrects, prect);
}
void
ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
int narcs, xArc *pArcs)
{
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
if (pGC->lineWidth == 0)
{
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyArc (pDrawable, pGC, narcs, pArcs);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
miPolyArc (pDrawable, pGC, narcs, pArcs);
}
#if 0
void
ExaCheckFillPolygon (DrawablePtr pDrawable, GCPtr pGC,
int shape, int mode, int count, DDXPointPtr pPts)
{
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbFillPolygon (pDrawable, pGC, mode, count, pPts);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
#endif
void
ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
int nrect, xRectangle *prect)
{
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyFillRect (pDrawable, pGC, nrect, prect);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
ExaCheckPolyFillArc (DrawablePtr pDrawable, GCPtr pGC,
int narcs, xArc *pArcs)
{
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyFillArc (pDrawable, pGC, narcs, pArcs);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase)
{
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase)
{
EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable));
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
DrawablePtr pDrawable,
int w, int h, int x, int y)
{
EXA_FALLBACK(("from 0x%lx to 0x%lx\n", (long)pBitmap, (long)pDrawable));
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
ExaCheckGetImage (DrawablePtr pDrawable,
int x, int y, int w, int h,
unsigned int format, unsigned long planeMask,
char *d)
{
EXA_FALLBACK(("from 0x%lx\n", (long)pDrawable));
exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
}
void
ExaCheckGetSpans (DrawablePtr pDrawable,
int wMax,
DDXPointPtr ppt,
int *pwidth,
int nspans,
char *pdstStart)
{
EXA_FALLBACK(("from 0x%lx\n", (long)pDrawable));
exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
fbGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
}
void
ExaCheckSaveAreas (PixmapPtr pPixmap,
RegionPtr prgnSave,
int xorg,
int yorg,
WindowPtr pWin)
{
EXA_FALLBACK(("from 0x%lx\n", (long)&pPixmap->drawable));
exaPrepareAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
fbSaveAreas (pPixmap, prgnSave, xorg, yorg, pWin);
exaFinishAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
}
void
ExaCheckRestoreAreas (PixmapPtr pPixmap,
RegionPtr prgnSave,
int xorg,
int yorg,
WindowPtr pWin)
{
EXA_FALLBACK(("to 0x%lx\n", (long)&pPixmap->drawable));
exaPrepareAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
fbRestoreAreas (pPixmap, prgnSave, xorg, yorg, pWin);
exaFinishAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
}
void
ExaCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what)
{
EXA_FALLBACK(("from 0x%lx\n", (long)pWin));
exaPrepareAccess (&pWin->drawable, EXA_PREPARE_DEST);
fbPaintWindow (pWin, pRegion, what);
exaFinishAccess (&pWin->drawable, EXA_PREPARE_DEST);
}
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)
{
EXA_FALLBACK(("from picts 0x%lx/0x%lx to pict 0x%lx\n",
(long)pSrc, (long)pMask, (long)pDst));
exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
if (pMask)
exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK);
fbComposite (op,
pSrc,
pMask,
pDst,
xSrc,
ySrc,
xMask,
yMask,
xDst,
yDst,
width,
height);
if (pMask)
exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK);
exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
}
/*
* Only need to stall for CopyArea/CopyPlane, but we want to have the chance to
* do migration for CopyArea.
*/
const GCOps exaAsyncPixmapGCOps = {
ExaCheckFillSpans,
ExaCheckSetSpans,
ExaCheckPutImage,
exaCopyArea,
ExaCheckCopyPlane,
ExaCheckPolyPoint,
ExaCheckPolylines,
ExaCheckPolySegment,
ExaCheckPolyRectangle,
ExaCheckPolyArc,
ExaCheckFillPolygon,
ExaCheckPolyFillRect,
ExaCheckPolyFillArc,
miPolyText8,
miPolyText16,
miImageText8,
miImageText16,
ExaCheckImageGlyphBlt,
ExaCheckPolyGlyphBlt,
ExaCheckPushPixels
#ifdef NEED_LINEHELPER
,NULL
#endif
};

View File

@ -1,401 +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.
*/
#include "exaPriv.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->card.offScreenAreas->base_offset ==
pExaScr->info->card.offScreenBase);
for (area = pExaScr->info->card.offScreenAreas; area; area = area->next)
{
assert (area->offset >= area->base_offset &&
area->offset < (area->base_offset -> area->size));
if (prev)
assert (prev->base_offset + prev->area.size == area->base_offset);
prev = area;
}
assert (prev->base_offset + prev->size == pExaScr->info->card.memorySize);
}
#else
#define ExaOffscreenValidate(s)
#endif
static ExaOffscreenArea *
ExaOffscreenKickOut (ScreenPtr pScreen, ExaOffscreenArea *area)
{
if (area->save)
(*area->save) (pScreen, area);
return exaOffscreenFree (pScreen, area);
}
ExaOffscreenArea *
exaOffscreenAlloc (ScreenPtr pScreen, int size, int align,
Bool locked,
ExaOffscreenSaveProc save,
pointer privData)
{
ExaOffscreenArea *area, *begin, *best;
ExaScreenPriv (pScreen);
int tmp, real_size = 0, best_score;
#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->card.memorySize - pExaScr->info->card.offScreenBase))
{
DBG_OFFSCREEN (("Alloc 0x%x vs (0x%lx) -> TOBIG\n", size,
pExaScr->info->card.memorySize -
pExaScr->info->card.offScreenBase));
return NULL;
}
/* Try to find a free space that'll fit. */
for (area = pExaScr->info->card.offScreenAreas; area; area = area->next)
{
/* skip allocated areas */
if (area->state != ExaOffscreenAvail)
continue;
/* adjust size to match alignment requirement */
real_size = size;
tmp = area->base_offset % align;
if (tmp)
real_size += (align - tmp);
/* does it fit? */
if (real_size <= area->size)
break;
}
if (!area)
{
/*
* Kick out existing users to make space.
*
* First, locate a region which can hold the desired object.
*/
/* prev points at the first object to boot */
best = NULL;
best_score = MAXINT;
for (begin = pExaScr->info->card.offScreenAreas; begin != NULL;
begin = begin->next)
{
int avail, score;
ExaOffscreenArea *scan;
if (begin->state == ExaOffscreenLocked)
continue;
/* adjust size needed to account for alignment loss for this area */
real_size = size;
tmp = begin->base_offset % align;
if (tmp)
real_size += (align - tmp);
avail = 0;
score = 0;
/* now see if we can make room here, and how "costly" it'll be. */
for (scan = begin; scan != NULL; scan = scan->next)
{
if (scan->state == ExaOffscreenLocked) {
/* Can't make room here, start after this locked area. */
begin = scan;
break;
}
/* Score should only be non-zero for ExaOffscreenRemovable */
score += scan->score;
avail += scan->size;
if (avail >= real_size)
break;
}
/* Is it the best option we've found so far? */
if (avail >= real_size && score < best_score) {
best = begin;
best_score = score;
}
}
area = best;
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;
tmp = area->base_offset % align;
if (tmp)
real_size += (align - tmp);
/*
* 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 && area->next->state == ExaOffscreenRemovable);
(void) ExaOffscreenKickOut (pScreen, area->next);
}
}
/* save extra space in new area */
if (real_size < area->size)
{
ExaOffscreenArea *new_area = xalloc (sizeof (ExaOffscreenArea));
if (!new_area)
return NULL;
new_area->base_offset = area->base_offset + real_size;
new_area->offset = new_area->base_offset;
new_area->size = area->size - real_size;
new_area->state = ExaOffscreenAvail;
new_area->save = NULL;
new_area->score = 0;
new_area->next = area->next;
area->next = new_area;
area->size = real_size;
}
/*
* Mark this area as in use
*/
if (locked)
area->state = ExaOffscreenLocked;
else
area->state = ExaOffscreenRemovable;
area->privData = privData;
area->save = save;
area->score = 0;
area->offset = (area->base_offset + align - 1);
area->offset -= area->offset % align;
ExaOffscreenValidate (pScreen);
DBG_OFFSCREEN (("Alloc 0x%x -> 0x%x (0x%x)\n", size,
area->base_offset, area->offset));
return area;
}
void
ExaOffscreenSwapOut (ScreenPtr pScreen)
{
ExaScreenPriv (pScreen);
ExaOffscreenValidate (pScreen);
/* loop until a single free area spans the space */
for (;;)
{
ExaOffscreenArea *area = pExaScr->info->card.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);
}
void
ExaOffscreenSwapIn (ScreenPtr pScreen)
{
exaOffscreenInit (pScreen);
}
void
exaEnableDisableFBAccess (int index, Bool enable)
{
ScreenPtr pScreen = screenInfo.screens[index];
ExaScreenPriv (pScreen);
if (!enable) {
ExaOffscreenSwapOut (pScreen);
pExaScr->swappedOut = TRUE;
}
if (pExaScr->SavedEnableDisableFBAccess)
(*pExaScr->SavedEnableDisableFBAccess)(index, enable);
if (enable) {
ExaOffscreenSwapIn (pScreen);
pExaScr->swappedOut = FALSE;
}
}
/* merge the next free area into this one */
static void
ExaOffscreenMerge (ExaOffscreenArea *area)
{
ExaOffscreenArea *next = area->next;
/* account for space */
area->size += next->size;
/* frob pointer */
area->next = next->next;
xfree (next);
}
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->score = 0;
/*
* Find previous area
*/
if (area == pExaScr->info->card.offScreenAreas)
prev = NULL;
else
for (prev = pExaScr->info->card.offScreenAreas; prev; prev = prev->next)
if (prev->next == area)
break;
/* link with next area if free */
if (next && next->state == ExaOffscreenAvail)
ExaOffscreenMerge (area);
/* link with prev area if free */
if (prev && prev->state == ExaOffscreenAvail)
{
area = prev;
ExaOffscreenMerge (area);
}
ExaOffscreenValidate (pScreen);
DBG_OFFSCREEN(("\tdone freeing\n"));
return area;
}
void
ExaOffscreenMarkUsed (PixmapPtr pPixmap)
{
ExaPixmapPriv (pPixmap);
ExaScreenPriv (pPixmap->drawable.pScreen);
static int iter = 0;
if (!pExaPixmap->area)
return;
/* The numbers here are arbitrary. We may want to tune these. */
pExaPixmap->area->score += 100;
if (++iter == 10) {
ExaOffscreenArea *area;
for (area = pExaScr->info->card.offScreenAreas; area != NULL;
area = area->next)
{
if (area->state == ExaOffscreenRemovable)
area->score = (area->score * 7) / 8;
}
}
}
Bool
exaOffscreenInit (ScreenPtr pScreen)
{
ExaScreenPriv (pScreen);
ExaOffscreenArea *area;
/* Allocate a big free area */
area = xalloc (sizeof (ExaOffscreenArea));
if (!area)
return FALSE;
area->state = ExaOffscreenAvail;
area->base_offset = pExaScr->info->card.offScreenBase;
area->offset = area->base_offset;
area->size = pExaScr->info->card.memorySize - area->base_offset;
area->save = NULL;
area->next = NULL;
area->score = 0;
#if DEBUG_OFFSCREEN
ErrorF("============ initial memory block of %d\n", area->size);
#endif
/* Add it to the free areas */
pExaScr->info->card.offScreenAreas = area;
ExaOffscreenValidate (pScreen);
return TRUE;
}
void
ExaOffscreenFini (ScreenPtr pScreen)
{
ExaScreenPriv (pScreen);
ExaOffscreenArea *area;
/* just free all of the area records */
while ((area = pExaScr->info->card.offScreenAreas))
{
pExaScr->info->card.offScreenAreas = area->next;
xfree (area);
}
}

View File

@ -1,811 +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_CONFIG_H
#include <xorg-config.h>
#endif
#include "exaPriv.h"
#ifdef RENDER
#include "mipict.h"
#include "xf86str.h"
#include "xf86.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_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;
}
loc = exaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm';
snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
pict->pDrawable->height, pict->repeat ?
" R" : "");
snprintf(string, n, "0x%lx:%c fmt %s (%s)", (long)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:
sprintf(sop, "Src");
break;
case PictOpOver:
sprintf(sop, "Over");
break;
default:
sprintf(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
static Bool
exaGetPixelFromRGBA(CARD32 *pixel,
CARD16 red,
CARD16 green,
CARD16 blue,
CARD16 alpha,
CARD32 format)
{
int rbits, bbits, gbits, abits;
int rshift, bshift, gshift, ashift;
*pixel = 0;
if (!PICT_FORMAT_COLOR(format))
return FALSE;
rbits = PICT_FORMAT_R(format);
gbits = PICT_FORMAT_G(format);
bbits = PICT_FORMAT_B(format);
abits = PICT_FORMAT_A(format);
if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
bshift = 0;
gshift = bbits;
rshift = gshift + gbits;
ashift = rshift + rbits;
} else { /* PICT_TYPE_ABGR */
rshift = 0;
gshift = rbits;
bshift = gshift + gbits;
ashift = bshift + bbits;
}
*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,
CARD32 format)
{
int rbits, bbits, gbits, abits;
int rshift, bshift, gshift, ashift;
if (!PICT_FORMAT_COLOR(format))
return FALSE;
rbits = PICT_FORMAT_R(format);
gbits = PICT_FORMAT_G(format);
bbits = PICT_FORMAT_B(format);
abits = PICT_FORMAT_A(format);
if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
bshift = 0;
gshift = bbits;
rshift = gshift + gbits;
ashift = rshift + rbits;
} else { /* PICT_TYPE_ABGR */
rshift = 0;
gshift = rbits;
bshift = gshift + gbits;
ashift = bshift + bbits;
}
*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;
}
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;
CARD32 pixel;
CARD16 red, green, blue, alpha;
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
xSrc += pSrc->pDrawable->x;
ySrc += pSrc->pDrawable->y;
if (!miComputeCompositeRegion (&region, pSrc, NULL, pDst,
xSrc, ySrc, 0, 0, xDst, yDst,
width, height))
return 1;
exaDrawableUseMemory(pSrc->pDrawable);
exaDrawableUseScreen(pDst->pDrawable);
pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
if (!pDstPix) {
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
return 0;
}
if (pSrc->pDrawable->type == DRAWABLE_WINDOW)
pSrcPix = (*pSrc->pDrawable->pScreen->GetWindowPixmap)(
(WindowPtr) (pSrc->pDrawable));
else
pSrcPix = (PixmapPtr) (pSrc->pDrawable);
exaPrepareAccess(&pSrcPix->drawable, EXA_PREPARE_SRC);
switch (pSrcPix->drawable.bitsPerPixel) {
case 32:
pixel = *(CARD32 *)(pSrcPix->devPrivate.ptr);
break;
case 16:
pixel = *(CARD16 *)(pSrcPix->devPrivate.ptr);
break;
default:
pixel = *(CARD8 *)(pSrcPix->devPrivate.ptr);
break;
}
if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
pSrc->format))
{
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
return -1;
}
exaFinishAccess(&pSrcPix->drawable, EXA_PREPARE_SRC);
exaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
pDst->format);
if (!(*pExaScr->info->accel.PrepareSolid) (pDstPix, GXcopy, 0xffffffff, pixel))
{
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
return -1;
}
nbox = REGION_NUM_RECTS(&region);
pbox = REGION_RECTS(&region);
while (nbox--)
{
(*pExaScr->info->accel.Solid) (pDstPix,
pbox->x1 + dst_off_x,
pbox->y1 + dst_off_y,
pbox->x2 + dst_off_x,
pbox->y2 + dst_off_y);
pbox++;
}
(*pExaScr->info->accel.DoneSolid) (pDstPix);
exaMarkSync(pDst->pDrawable->pScreen);
exaDrawableDirty (pDst->pDrawable);
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
return 1;
}
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, mask_off_y, dst_off_x, dst_off_y;
PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
struct _Pixmap scratch;
/* Bail if we might exceed coord limits by rendering from/to these. We
* should really be making some scratch pixmaps with offsets and coords
* adjusted to deal with this, but it hasn't been done yet.
*/
if (pSrc->pDrawable->width > pExaScr->info->card.maxX ||
pSrc->pDrawable->height > pExaScr->info->card.maxY ||
pDst->pDrawable->width > pExaScr->info->card.maxX ||
pDst->pDrawable->height > pExaScr->info->card.maxY ||
(pMask && (pMask->pDrawable->width > pExaScr->info->card.maxX ||
pMask->pDrawable->height > pExaScr->info->card.maxY)))
{
return -1;
}
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
if (pMask) {
xMask += pMask->pDrawable->x;
yMask += pMask->pDrawable->y;
}
xSrc += pSrc->pDrawable->x;
ySrc += pSrc->pDrawable->y;
if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height))
return 1;
if (pExaScr->info->accel.CheckComposite &&
!(*pExaScr->info->accel.CheckComposite) (op, pSrc, pMask, pDst))
{
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
return -1;
}
exaDrawableUseScreen(pSrc->pDrawable);
if (pMask != NULL)
exaDrawableUseScreen(pMask->pDrawable);
exaDrawableUseScreen(pDst->pDrawable);
pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
if (pMask)
pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x,
&mask_off_y);
pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
if (!pDstPix) {
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
return 0;
}
if (!pSrcPix && (!pMask || pMaskPix) && pExaScr->info->accel.UploadToScratch) {
if (pSrc->pDrawable->type == DRAWABLE_WINDOW)
pSrcPix = (*pSrc->pDrawable->pScreen->GetWindowPixmap) (
(WindowPtr) pSrc->pDrawable);
else
pSrcPix = (PixmapPtr) pSrc->pDrawable;
if ((*pExaScr->info->accel.UploadToScratch) (pSrcPix, &scratch))
pSrcPix = &scratch;
} else if (pSrcPix && pMask && !pMaskPix && pExaScr->info->accel.UploadToScratch) {
if (pMask->pDrawable->type == DRAWABLE_WINDOW)
pMaskPix = (*pMask->pDrawable->pScreen->GetWindowPixmap) (
(WindowPtr) pMask->pDrawable);
else
pMaskPix = (PixmapPtr) pMask->pDrawable;
if ((*pExaScr->info->accel.UploadToScratch) (pMaskPix, &scratch))
pMaskPix = &scratch;
}
if (!pSrcPix || (pMask && !pMaskPix)) {
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
return 0;
}
if (!(*pExaScr->info->accel.PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix,
pMaskPix, pDstPix))
{
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
return -1;
}
nbox = REGION_NUM_RECTS(&region);
pbox = REGION_RECTS(&region);
xMask -= xDst;
yMask -= yDst;
xSrc -= xDst;
ySrc -= yDst;
while (nbox--)
{
(*pExaScr->info->accel.Composite) (pDstPix,
pbox->x1 + xSrc + src_off_x,
pbox->y1 + ySrc + src_off_y,
pbox->x1 + xMask + mask_off_x,
pbox->y1 + yMask + mask_off_y,
pbox->x1 + dst_off_x,
pbox->y1 + dst_off_y,
pbox->x2 - pbox->x1,
pbox->y2 - pbox->y1);
pbox++;
}
(*pExaScr->info->accel.DoneComposite) (pDstPix);
exaMarkSync(pDst->pDrawable->pScreen);
exaDrawableDirty (pDst->pDrawable);
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
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;
ScrnInfoPtr pScrn = XF86SCRNINFO(pDst->pDrawable->pScreen);
Bool saveSrcRepeat = pSrc->repeat;
Bool saveMaskRepeat = pMask ? pMask->repeat : 0;
if (!pScrn->vtSema) {
exaDrawableDirty(pDst->pDrawable);
pExaScr->SavedComposite(op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height);
return;
}
/* simplify the drivers by reducing here */
switch (op) {
case PictOpDisjointClear:
case PictOpConjointClear:
op = PictOpClear;
break;
case PictOpDisjointSrc:
case PictOpConjointSrc:
op = PictOpSrc;
break;
case PictOpDisjointDst:
case PictOpConjointDst:
case PictOpDst:
return;
default:
break;
}
/* Remove repeat in source if useless */
if (pSrc->repeat && !pSrc->transform && xSrc >= 0 &&
(xSrc + width) <= pSrc->pDrawable->width && ySrc >= 0 &&
(ySrc + height) <= pSrc->pDrawable->height)
pSrc->repeat = 0;
if (!pMask && pSrc->pDrawable)
{
if (op == PictOpSrc)
{
if (pSrc->pDrawable->width == 1 &&
pSrc->pDrawable->height == 1 && pSrc->repeat)
{
ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
width, height);
if (ret == 1)
goto bail;
}
else if (!pSrc->repeat && !pSrc->transform &&
pSrc->format == pDst->format)
{
RegionRec region;
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 bail;
exaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, NULL,
REGION_RECTS(&region), REGION_NUM_RECTS(&region),
xSrc - xDst, ySrc - yDst,
FALSE, FALSE, 0, NULL);
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
goto bail;
}
}
}
/* Remove repeat in mask if useless */
if (pMask && pMask->repeat && !pMask->transform && xMask >= 0 &&
(xMask + width) <= pMask->pDrawable->width && yMask >= 0 &&
(yMask + height) <= pMask->pDrawable->height)
pMask->repeat = 0;
if (pSrc->pDrawable && (!pMask || pMask->pDrawable) &&
pExaScr->info->accel.PrepareComposite &&
!pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap)
{
ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask,
yMask, xDst, yDst, width, height);
if (ret == 1)
goto bail;
}
if (ret != 0) {
/* failure to accelerate was not due to pixmaps being in the wrong
* locations.
*/
exaDrawableUseMemory(pSrc->pDrawable);
if (pMask != NULL)
exaDrawableUseMemory(pMask->pDrawable);
exaDrawableUseMemory(pDst->pDrawable);
}
#if DEBUG_TRACE_FALL
exaPrintCompositeFallback (op, pSrc, pMask, pDst);
#endif
ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height);
bail:
pSrc->repeat = saveSrcRepeat;
if (pMask)
pMask->repeat = saveMaskRepeat;
}
#endif
#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
/* exaGlyphs is a slight variation on miGlyphs, to support acceleration. The
* issue is that miGlyphs' use of ModifyPixmapHeader makes it impossible to
* migrate these pixmaps. So, instead we create a pixmap at the beginning of
* the loop and upload each glyph into the pixmap before compositing.
*/
void
exaGlyphs (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int nlist,
GlyphListPtr list,
GlyphPtr *glyphs)
{
ExaScreenPriv (pDst->pDrawable->pScreen);
PixmapPtr pPixmap = NULL, pScratchPixmap = NULL;
PicturePtr pPicture;
PixmapPtr pMaskPixmap = NULL;
PicturePtr pMask;
ScreenPtr pScreen = pDst->pDrawable->pScreen;
int width = 0, height = 0;
int x, y;
int xDst = list->xOff, yDst = list->yOff;
int n;
GlyphPtr glyph;
int error;
BoxRec extents;
CARD32 component_alpha;
/* If the driver doesn't support accelerated composite, there's no point in
* going to this extra work. Assume that no driver will be able to do
* component-alpha, which is likely accurate (at least until we make a CA
* helper).
*/
if (!pExaScr->info->accel.PrepareComposite ||
(maskFormat && NeedsComponent(maskFormat->format))) {
miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
return;
}
if (maskFormat)
{
GCPtr pGC;
xRectangle rect;
miGlyphExtents (nlist, list, glyphs, &extents);
if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
return;
width = extents.x2 - extents.x1;
height = extents.y2 - extents.y1;
pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
maskFormat->depth);
if (!pMaskPixmap)
return;
component_alpha = NeedsComponent(maskFormat->format);
pMask = CreatePicture (0, &pMaskPixmap->drawable,
maskFormat, CPComponentAlpha, &component_alpha,
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
{
pMask = pDst;
x = 0;
y = 0;
}
while (nlist--)
{
GCPtr pGC;
int maxwidth = 0, maxheight = 0, i;
x += list->xOff;
y += list->yOff;
n = list->len;
for (i = 0; i < n; i++) {
if (glyphs[i]->info.width > maxwidth)
maxwidth = glyphs[i]->info.width;
if (glyphs[i]->info.height > maxheight)
maxheight = glyphs[i]->info.height;
}
if (maxwidth == 0 || maxheight == 0) {
while (n--)
{
glyph = *glyphs++;
x += glyph->info.xOff;
y += glyph->info.yOff;
}
list++;
continue;
}
/* Get a scratch pixmap to wrap the original glyph data */
pScratchPixmap = GetScratchPixmapHeader (pScreen, glyphs[0]->info.width,
glyphs[0]->info.height,
list->format->depth,
list->format->depth,
0, (pointer) (glyphs[0] + 1));
if (!pScratchPixmap)
return;
/* Create the (real) temporary pixmap to store the current glyph in */
pPixmap = (*pScreen->CreatePixmap) (pScreen, maxwidth, maxheight,
list->format->depth);
if (!pPixmap) {
FreeScratchPixmapHeader (pScratchPixmap);
return;
}
/* Create a temporary picture to wrap the temporary pixmap, so it can be
* used as a source for Composite.
*/
component_alpha = NeedsComponent(list->format->format);
pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
CPComponentAlpha, &component_alpha,
serverClient, &error);
if (!pPicture) {
(*pScreen->DestroyPixmap) (pPixmap);
FreeScratchPixmapHeader (pScratchPixmap);
return;
}
/* Get a scratch GC with which to copy the glyph data from scratch to
* temporary
*/
pGC = GetScratchGC (list->format->depth, pScreen);
ValidateGC (&pPixmap->drawable, pGC);
/* Give the temporary pixmap an initial kick towards the screen, so
* it'll stick there.
*/
exaPixmapUseScreen (pPixmap);
while (n--)
{
glyph = *glyphs++;
(*pScreen->ModifyPixmapHeader) (pScratchPixmap,
glyph->info.width,
glyph->info.height,
0, 0, -1, (pointer) (glyph + 1));
pScratchPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
/* Copy the glyph data into the proper pixmap instead of a fake.
* First we try to use UploadToScreen, if we can, then we fall back
* to a plain exaCopyArea in case of failure.
*/
if (!pExaScr->info->accel.UploadToScreen ||
!exaPixmapIsOffscreen(pPixmap) ||
!(*pExaScr->info->accel.UploadToScreen) (pPixmap, 0, 0,
glyph->info.width,
glyph->info.height,
pScratchPixmap->devPrivate.ptr,
pScratchPixmap->devKind))
{
exaCopyArea (&pScratchPixmap->drawable, &pPixmap->drawable, pGC,
0, 0, glyph->info.width, glyph->info.height, 0, 0);
} else {
exaDrawableDirty (&pPixmap->drawable);
}
if (maskFormat)
{
CompositePicture (PictOpAdd,
pPicture,
NULL,
pMask,
0, 0,
0, 0,
x - glyph->info.x,
y - glyph->info.y,
glyph->info.width,
glyph->info.height);
}
else
{
CompositePicture (op,
pSrc,
pPicture,
pDst,
xSrc + (x - glyph->info.x) - xDst,
ySrc + (y - glyph->info.y) - yDst,
0, 0,
x - glyph->info.x,
y - glyph->info.y,
glyph->info.width,
glyph->info.height);
}
x += glyph->info.xOff;
y += glyph->info.yOff;
}
list++;
FreeScratchGC (pGC);
FreePicture ((pointer) pPicture, 0);
(*pScreen->DestroyPixmap) (pPixmap);
FreeScratchPixmapHeader (pScratchPixmap);
}
if (maskFormat)
{
x = extents.x1;
y = extents.y1;
CompositePicture (op,
pSrc,
pMask,
pDst,
xSrc + x - xDst,
ySrc + y - yDst,
0, 0,
x, y,
width, height);
FreePicture ((pointer) pMask, (XID) 0);
(*pScreen->DestroyPixmap) (pMaskPixmap);
}
}