Adding the new acceleration architecture: Exa. It's meant to replace XAA in
the coming months.
This commit is contained in:
parent
276821605e
commit
30c019e847
|
@ -0,0 +1,240 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#ifndef EXA_H
|
||||||
|
#define EXA_H
|
||||||
|
|
||||||
|
#include "scrnintstr.h"
|
||||||
|
#include "pixmapstr.h"
|
||||||
|
#include "windowstr.h"
|
||||||
|
#include "gcstruct.h"
|
||||||
|
#include "picturestr.h"
|
||||||
|
|
||||||
|
#define EXA_VERSION_MAJOR 0
|
||||||
|
#define EXA_VERSION_MINOR 1
|
||||||
|
#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 offset;
|
||||||
|
int save_offset;
|
||||||
|
int size;
|
||||||
|
int score;
|
||||||
|
pointer privData;
|
||||||
|
|
||||||
|
ExaOffscreenSaveProc save;
|
||||||
|
|
||||||
|
ExaOffscreenState state;
|
||||||
|
|
||||||
|
ExaOffscreenArea *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _ExaCardInfo {
|
||||||
|
/* These are here because I don't want to be adding more to
|
||||||
|
* ScrnInfoRec */
|
||||||
|
CARD8 *memoryBase;
|
||||||
|
unsigned long offScreenBase;
|
||||||
|
|
||||||
|
/* It's fix.smem_len.
|
||||||
|
This one could be potentially substituted by ScrnInfoRec
|
||||||
|
videoRam member, but I do not want to be doing the silly
|
||||||
|
<< 10, >>10 all over the place */
|
||||||
|
unsigned long memorySize;
|
||||||
|
|
||||||
|
int offscreenByteAlign;
|
||||||
|
int offscreenPitch;
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
/* The coordinate limitations for rendering for this hardware.
|
||||||
|
* Exa breaks larger pixmaps into smaller pieces and calls Prepare multiple times
|
||||||
|
* to handle larger pixmaps
|
||||||
|
*/
|
||||||
|
int maxX;
|
||||||
|
int maxY;
|
||||||
|
|
||||||
|
/* private */
|
||||||
|
ExaOffscreenArea *offScreenAreas;
|
||||||
|
Bool needsSync;
|
||||||
|
int lastMarker;
|
||||||
|
} ExaCardInfoRec, *ExaCardInfoPtr;
|
||||||
|
|
||||||
|
typedef struct _ExaAccelInfo {
|
||||||
|
/* PrepareSolid may fail if the pixmaps can't be accelerated to/from.
|
||||||
|
* This is an important feature for handling strange corner cases
|
||||||
|
* in hardware that are poorly expressed through flags.
|
||||||
|
*/
|
||||||
|
Bool (*PrepareSolid) (PixmapPtr pPixmap,
|
||||||
|
int alu,
|
||||||
|
Pixel planemask,
|
||||||
|
Pixel fg);
|
||||||
|
void (*Solid) (PixmapPtr pPixmap, int x1, int y1, int x2, int y2);
|
||||||
|
void (*DoneSolid) (PixmapPtr pPixmap);
|
||||||
|
|
||||||
|
/* PrepareSolid may fail if the pixmaps can't be accelerated to/from.
|
||||||
|
* This is an important feature for handling strange corner cases
|
||||||
|
* in hardware that are poorly expressed through flags.
|
||||||
|
*/
|
||||||
|
Bool (*PrepareCopy) (PixmapPtr pSrcPixmap,
|
||||||
|
PixmapPtr pDstPixmap,
|
||||||
|
Bool upsidedown,
|
||||||
|
Bool reverse,
|
||||||
|
int alu,
|
||||||
|
Pixel planemask);
|
||||||
|
void (*Copy) (PixmapPtr pDstPixmap,
|
||||||
|
int srcX,
|
||||||
|
int srcY,
|
||||||
|
int dstX,
|
||||||
|
int dstY,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
void (*DoneCopy) (PixmapPtr pDstPixmap);
|
||||||
|
|
||||||
|
/* The Composite hooks are a wrapper around the Composite operation.
|
||||||
|
* The CheckComposite occurs before pixmap migration occurs,
|
||||||
|
* and may fail for many hardware-dependent reasons.
|
||||||
|
* PrepareComposite should not fail, and the Bool return may
|
||||||
|
* not be necessary if we can
|
||||||
|
* adequately represent pixmap location/pitch limitations..
|
||||||
|
*/
|
||||||
|
Bool (*CheckComposite) (int op,
|
||||||
|
PicturePtr pSrcPicture,
|
||||||
|
PicturePtr pMaskPicture,
|
||||||
|
PicturePtr pDstPicture);
|
||||||
|
Bool (*PrepareComposite) (int op,
|
||||||
|
PicturePtr pSrcPicture,
|
||||||
|
PicturePtr pMaskPicture,
|
||||||
|
PicturePtr pDstPicture,
|
||||||
|
PixmapPtr pSrc,
|
||||||
|
PixmapPtr pMask,
|
||||||
|
PixmapPtr pDst);
|
||||||
|
void (*Composite) (PixmapPtr pDst,
|
||||||
|
int srcX,
|
||||||
|
int srcY,
|
||||||
|
int maskX,
|
||||||
|
int maskY,
|
||||||
|
int dstX,
|
||||||
|
int dstY,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
void (*DoneComposite) (PixmapPtr pDst);
|
||||||
|
|
||||||
|
/* Attempt to upload the data from src into the rectangle of the
|
||||||
|
* in-framebuffer pDst beginning at x,y and of width w,h. May fail.
|
||||||
|
*/
|
||||||
|
Bool (*UploadToScreen) (PixmapPtr pDst,
|
||||||
|
char *src,
|
||||||
|
int src_pitch);
|
||||||
|
Bool (*UploadToScratch) (PixmapPtr pSrc,
|
||||||
|
PixmapPtr pDst);
|
||||||
|
|
||||||
|
/* Attempt to download the rectangle from the in-framebuffer pSrc into
|
||||||
|
* dst, given the pitch. May fail. Since it is likely
|
||||||
|
* accelerated, a markSync will follow it as with other acceleration
|
||||||
|
* hooks.
|
||||||
|
*/
|
||||||
|
Bool (*DownloadFromScreen)(PixmapPtr pSrc,
|
||||||
|
int x, int y,
|
||||||
|
int w, int h,
|
||||||
|
char *dst, int dst_pitch);
|
||||||
|
|
||||||
|
/* Should return a hrdware-dependent marker number which can
|
||||||
|
* be waited for with WaitMarker. It can be not implemented in which
|
||||||
|
* case WaitMarker must wait for idle on any given marker
|
||||||
|
* number.
|
||||||
|
*/
|
||||||
|
int (*MarkSync) (ScreenPtr pScreen);
|
||||||
|
void (*WaitMarker) (ScreenPtr pScreen, int marker);
|
||||||
|
} ExaAccelInfoRec, *ExaAccelInfoPtr;
|
||||||
|
|
||||||
|
typedef struct _ExaDriver {
|
||||||
|
ExaCardInfoRec card;
|
||||||
|
ExaAccelInfoRec accel;
|
||||||
|
} ExaDriverRec, *ExaDriverPtr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ExaDriverPtr info;
|
||||||
|
} ExaScreenPrivRec, *ExaScreenPrivPtr;
|
||||||
|
|
||||||
|
#define EXA_OFFSCREEN_PIXMAPS (1 << 0)
|
||||||
|
#define EXA_OFFSCREEN_ALIGN_POT (1 << 1)
|
||||||
|
|
||||||
|
|
||||||
|
#define EXA_MAKE_VERSION(a, b, c) (((a) << 16) | ((b) << 8) | (c))
|
||||||
|
#define EXA_VERSION \
|
||||||
|
EXA_MAKE_VERSION(EXA_VERSION_MAJOR, EXA_VERSION_MINOR, EXA_VERSION_RELEASE)
|
||||||
|
#define EXA_IS_VERSION(a,b,c) (EXA_VERSION >= EXA_MAKE_VERSION(a,b,c))
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
exaGetVersion(void);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
exaDriverInit(ScreenPtr pScreen,
|
||||||
|
ExaDriverPtr pScreenInfo);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaDriverFini(ScreenPtr pScreen);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaMarkSync(ScreenPtr pScreen);
|
||||||
|
void
|
||||||
|
exaWaitSync(ScreenPtr pScreen);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
exaOffscreenInit(ScreenPtr pScreen);
|
||||||
|
|
||||||
|
ExaOffscreenArea *
|
||||||
|
exaOffscreenAlloc(ScreenPtr pScreen, int size, int align,
|
||||||
|
Bool locked,
|
||||||
|
ExaOffscreenSaveProc save,
|
||||||
|
pointer privData);
|
||||||
|
|
||||||
|
ExaOffscreenArea *
|
||||||
|
exaOffscreenFree(ScreenPtr pScreen, ExaOffscreenArea *area);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define exaInitCard(exa, sync, memory_base, off_screen_base, memory_size, \
|
||||||
|
offscreen_byte_align, offscreen_pitch, flags, \
|
||||||
|
max_x, max_y) \
|
||||||
|
(exa)->card.Sync = sync; \
|
||||||
|
(exa)->card.memoryBase = memory_base; \
|
||||||
|
(exa)->card.offScreenBase = off_screen_base; \
|
||||||
|
(exa)->card.memorySize = memory_size; \
|
||||||
|
(exa)->card.offscreenByteAlign = offscreen_byte_align; \
|
||||||
|
(exa)->card.offscreenPitch = offscreen_pitch; \
|
||||||
|
(exa)->card.flags = flags; \
|
||||||
|
(exa)->card.maxX = max_x; \
|
||||||
|
(exa)->card.maxY = max_y
|
||||||
|
|
||||||
|
#endif /* EXA_H */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,374 @@
|
||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
#define DEBUG_OFFSCREEN 1
|
||||||
|
#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->area.offset == 0);
|
||||||
|
for (area = pExaScr->info->card.offScreenAreas; area; area = area->next)
|
||||||
|
{
|
||||||
|
if (prev)
|
||||||
|
assert (prev->area.offset + prev->area.size == area->area.offset);
|
||||||
|
|
||||||
|
prev = area;
|
||||||
|
}
|
||||||
|
assert (prev->area.offset + prev->area.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 -> TOBIG\n", size));
|
||||||
|
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->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 to match alignment requirement */
|
||||||
|
real_size = size;
|
||||||
|
tmp = begin->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->next;
|
||||||
|
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 to match alignment requirement */
|
||||||
|
real_size = size;
|
||||||
|
tmp = begin->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->offset = area->offset + real_size;
|
||||||
|
new_area->size = area->size - real_size;
|
||||||
|
new_area->state = ExaOffscreenAvail;
|
||||||
|
new_area->save = 0;
|
||||||
|
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->save_offset = area->offset;
|
||||||
|
area->offset = (area->offset + align - 1) & ~(align - 1);
|
||||||
|
|
||||||
|
ExaOffscreenValidate (pScreen);
|
||||||
|
|
||||||
|
DBG_OFFSCREEN (("Alloc 0x%x -> 0x%x\n", size, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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\n", area->size, area->offset));
|
||||||
|
ExaOffscreenValidate (pScreen);
|
||||||
|
|
||||||
|
area->state = ExaOffscreenAvail;
|
||||||
|
area->save = 0;
|
||||||
|
area->offset = area->save_offset;
|
||||||
|
area->score = 0;
|
||||||
|
/*
|
||||||
|
* Find previous area
|
||||||
|
*/
|
||||||
|
if (area == pExaScr->info->card.offScreenAreas)
|
||||||
|
prev = 0;
|
||||||
|
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->offset = pExaScr->info->card.offScreenBase;
|
||||||
|
area->size = pExaScr->info->card.memorySize - area->offset;
|
||||||
|
area->save = 0;
|
||||||
|
area->next = NULL;
|
||||||
|
area->score = 0;
|
||||||
|
|
||||||
|
ErrorF("============ initial memory block of %d\n", area->size);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,281 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
#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"
|
||||||
|
|
||||||
|
#ifndef EXA_MAX_FB
|
||||||
|
#define EXA_MAX_FB FB_OVERLAY_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
Bool dirty;
|
||||||
|
} 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);
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPaintKey(DrawablePtr pDrawable,
|
||||||
|
RegionPtr pRegion,
|
||||||
|
CARD32 pixel,
|
||||||
|
int layer);
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckOverlayCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaScreenInitAsync (ScreenPtr pScreen);
|
||||||
|
|
||||||
|
extern const GCOps exaAsyncPixmapGCOps;
|
||||||
|
|
||||||
|
/* exapict.c */
|
||||||
|
void
|
||||||
|
ExaPictureInitAsync (ScreenPtr pScreen);
|
||||||
|
|
||||||
|
#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);
|
||||||
|
|
||||||
|
/* exa.c */
|
||||||
|
void
|
||||||
|
exaPixmapUseScreen (PixmapPtr pPixmap);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaPixmapUseMemory (PixmapPtr pPixmap);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaDrawableDirty(DrawablePtr pDrawable);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
exaDrawableIsOffscreen (DrawablePtr pDrawable);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
exaPixmapIsOffscreen(PixmapPtr p);
|
||||||
|
|
||||||
|
PixmapPtr
|
||||||
|
exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaMoveInPixmap (PixmapPtr pPixmap);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
#endif /* EXAPRIV_H */
|
|
@ -0,0 +1,572 @@
|
||||||
|
/*
|
||||||
|
* 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 <config.h>
|
||||||
|
#endif
|
||||||
|
#include "exaPriv.h"
|
||||||
|
|
||||||
|
#ifdef RENDER
|
||||||
|
#include "mipict.h"
|
||||||
|
|
||||||
|
#define EXA_DEBUG_FALLBACKS 0
|
||||||
|
|
||||||
|
#if EXA_DEBUG_FALLBACKS
|
||||||
|
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, 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 (®ion, pSrc, NULL, pDst,
|
||||||
|
xSrc, ySrc, 0, 0, xDst, yDst,
|
||||||
|
width, height))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable);
|
||||||
|
if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseScreen ((PixmapPtr) pDst->pDrawable);
|
||||||
|
|
||||||
|
pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
|
||||||
|
if (!pDstPix) {
|
||||||
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSrc->pDrawable->type == DRAWABLE_WINDOW)
|
||||||
|
pSrcPix = (*pSrc->pDrawable->pScreen->GetWindowPixmap)(
|
||||||
|
(WindowPtr) (pSrc->pDrawable));
|
||||||
|
else
|
||||||
|
pSrcPix = (PixmapPtr) (pSrc->pDrawable);
|
||||||
|
|
||||||
|
/* If source is offscreen, we need to sync the accelerator
|
||||||
|
* before accessing it. We'd prefer for it to be in memory.
|
||||||
|
*/
|
||||||
|
if (exaPixmapIsOffscreen(pSrcPix)) {
|
||||||
|
exaWaitSync(pDst->pDrawable->pScreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel = *(CARD32 *)(pSrcPix->devPrivate.ptr);
|
||||||
|
if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
|
||||||
|
pSrc->format))
|
||||||
|
{
|
||||||
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
exaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
|
||||||
|
pDst->format);
|
||||||
|
|
||||||
|
if (!(*pExaScr->info->accel.PrepareSolid) (pDstPix, GXcopy, 0xffffffff, pixel))
|
||||||
|
{
|
||||||
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nbox = REGION_NUM_RECTS(®ion);
|
||||||
|
pbox = REGION_RECTS(®ion);
|
||||||
|
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, ®ion);
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (pExaScr->info->card.maxX < width ||
|
||||||
|
pExaScr->info->card.maxY < height)
|
||||||
|
{
|
||||||
|
int total_width = width;
|
||||||
|
int total_height = height;
|
||||||
|
int xOff = 0;
|
||||||
|
int yOff = 0;
|
||||||
|
while (total_width > pExaScr->info->card.maxX) {
|
||||||
|
while (total_height > pExaScr->info->card.maxY) {
|
||||||
|
exaTryDriverComposite(op,
|
||||||
|
pSrc,
|
||||||
|
pMask,
|
||||||
|
pDst,
|
||||||
|
xSrc + xOff,
|
||||||
|
ySrc + yOff,
|
||||||
|
xMask + xOff,
|
||||||
|
yMask + yOff,
|
||||||
|
xDst + xOff,
|
||||||
|
yDst + yOff,
|
||||||
|
pExaScr->info->card.maxX,
|
||||||
|
pExaScr->info->card.maxY);
|
||||||
|
total_width -= pExaScr->info->card.maxX;
|
||||||
|
xOff += pExaScr->info->card.maxX;
|
||||||
|
yOff = 0;
|
||||||
|
}
|
||||||
|
if (total_height)
|
||||||
|
exaTryDriverComposite(op,
|
||||||
|
pSrc,
|
||||||
|
pMask,
|
||||||
|
pDst,
|
||||||
|
xSrc + xOff,
|
||||||
|
ySrc + yOff,
|
||||||
|
xMask + xOff,
|
||||||
|
yMask + yOff,
|
||||||
|
xDst + xOff,
|
||||||
|
yDst + yOff,
|
||||||
|
pExaScr->info->card.maxX,
|
||||||
|
total_height);
|
||||||
|
total_height -= pExaScr->info->card.maxY;
|
||||||
|
yOff += pExaScr->info->card.maxY;
|
||||||
|
}
|
||||||
|
if (total_width && total_height)
|
||||||
|
exaTryDriverComposite(op,
|
||||||
|
pSrc,
|
||||||
|
pMask,
|
||||||
|
pDst,
|
||||||
|
xSrc + xOff,
|
||||||
|
ySrc + yOff,
|
||||||
|
xMask + xOff,
|
||||||
|
yMask + yOff,
|
||||||
|
xDst + xOff,
|
||||||
|
yDst + yOff,
|
||||||
|
total_width,
|
||||||
|
total_height);
|
||||||
|
|
||||||
|
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 (®ion, 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, ®ion);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseScreen ((PixmapPtr) pSrc->pDrawable);
|
||||||
|
if (pMask && pMask->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseScreen ((PixmapPtr) pMask->pDrawable);
|
||||||
|
if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseScreen ((PixmapPtr) 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, ®ion);
|
||||||
|
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, ®ion);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(*pExaScr->info->accel.PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix,
|
||||||
|
pMaskPix, pDstPix))
|
||||||
|
{
|
||||||
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nbox = REGION_NUM_RECTS(®ion);
|
||||||
|
pbox = REGION_RECTS(®ion);
|
||||||
|
|
||||||
|
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, ®ion);
|
||||||
|
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;
|
||||||
|
|
||||||
|
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)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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 (®ion, pSrc, pMask, pDst,
|
||||||
|
xSrc, ySrc, xMask, yMask, xDst,
|
||||||
|
yDst, width, height))
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
exaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, 0,
|
||||||
|
REGION_RECTS(®ion), REGION_NUM_RECTS(®ion),
|
||||||
|
xSrc - xDst, ySrc - yDst,
|
||||||
|
FALSE, FALSE, 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
/* failure to accelerate was not due to pixmaps being in the wrong
|
||||||
|
* locations.
|
||||||
|
*/
|
||||||
|
if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable);
|
||||||
|
if (pMask && pMask->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseMemory ((PixmapPtr) pMask->pDrawable);
|
||||||
|
if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseMemory ((PixmapPtr) pDst->pDrawable);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if EXA_DEBUG_FALLBACKS
|
||||||
|
exaPrintCompositeFallback (op, pSrc, pMask, pDst);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
|
||||||
|
xMask, yMask, xDst, yDst, width, height);
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,365 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
exaWaitSync (pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbFillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
|
||||||
|
DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
|
||||||
|
{
|
||||||
|
exaWaitSync (pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbSetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
|
||||||
|
int x, int y, int w, int h, int leftPad, int format,
|
||||||
|
char *bits)
|
||||||
|
{
|
||||||
|
exaWaitSync (pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionPtr
|
||||||
|
ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
||||||
|
int srcx, int srcy, int w, int h, int dstx, int dsty)
|
||||||
|
{
|
||||||
|
exaWaitSync (pSrc->pScreen);
|
||||||
|
exaDrawableDirty (pDst);
|
||||||
|
return fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionPtr
|
||||||
|
ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
||||||
|
int srcx, int srcy, int w, int h, int dstx, int dsty,
|
||||||
|
unsigned long bitPlane)
|
||||||
|
{
|
||||||
|
exaWaitSync (pSrc->pScreen);
|
||||||
|
exaDrawableDirty (pDst);
|
||||||
|
return fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
|
||||||
|
bitPlane);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
|
||||||
|
DDXPointPtr pptInit)
|
||||||
|
{
|
||||||
|
exaWaitSync (pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolyPoint (pDrawable, pGC, mode, npt, pptInit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int mode, int npt, DDXPointPtr ppt)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (pGC->lineWidth == 0) {
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
}
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolyLine (pDrawable, pGC, mode, npt, ppt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int nsegInit, xSegment *pSegInit)
|
||||||
|
{
|
||||||
|
if (pGC->lineWidth == 0) {
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
}
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolyRectangle (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int nrects, xRectangle *prect)
|
||||||
|
{
|
||||||
|
if (pGC->lineWidth == 0) {
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
}
|
||||||
|
fbPolyRectangle (pDrawable, pGC, nrects, prect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int narcs, xArc *pArcs)
|
||||||
|
{
|
||||||
|
if (pGC->lineWidth == 0)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolyArc (pDrawable, pGC, narcs, pArcs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
miPolyArc (pDrawable, pGC, narcs, pArcs);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void
|
||||||
|
ExaCheckFillPolygon (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int shape, int mode, int count, DDXPointPtr pPts)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbFillPolygon (pDrawable, pGC, mode, count, pPts);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int nrect, xRectangle *prect)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolyFillRect (pDrawable, pGC, nrect, prect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolyFillArc (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int narcs, xArc *pArcs)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolyFillArc (pDrawable, pGC, narcs, pArcs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int x, int y, unsigned int nglyph,
|
||||||
|
CharInfoPtr *ppci, pointer pglyphBase)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int x, int y, unsigned int nglyph,
|
||||||
|
CharInfoPtr *ppci, pointer pglyphBase)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
|
||||||
|
DrawablePtr pDrawable,
|
||||||
|
int w, int h, int x, int y)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckGetImage (DrawablePtr pDrawable,
|
||||||
|
int x, int y, int w, int h,
|
||||||
|
unsigned int format, unsigned long planeMask,
|
||||||
|
char *d)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckGetSpans (DrawablePtr pDrawable,
|
||||||
|
int wMax,
|
||||||
|
DDXPointPtr ppt,
|
||||||
|
int *pwidth,
|
||||||
|
int nspans,
|
||||||
|
char *pdstStart)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
fbGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckSaveAreas (PixmapPtr pPixmap,
|
||||||
|
RegionPtr prgnSave,
|
||||||
|
int xorg,
|
||||||
|
int yorg,
|
||||||
|
WindowPtr pWin)
|
||||||
|
{
|
||||||
|
exaWaitSync(pWin->drawable.pScreen);
|
||||||
|
exaDrawableDirty (&pPixmap->drawable);
|
||||||
|
fbSaveAreas (pPixmap, prgnSave, xorg, yorg, pWin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckRestoreAreas (PixmapPtr pPixmap,
|
||||||
|
RegionPtr prgnSave,
|
||||||
|
int xorg,
|
||||||
|
int yorg,
|
||||||
|
WindowPtr pWin)
|
||||||
|
{
|
||||||
|
exaWaitSync(pWin->drawable.pScreen);
|
||||||
|
exaDrawableDirty ((DrawablePtr)pWin);
|
||||||
|
fbRestoreAreas (pPixmap, prgnSave, xorg, yorg, pWin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what)
|
||||||
|
{
|
||||||
|
exaWaitSync (pWin->drawable.pScreen);
|
||||||
|
exaDrawableDirty ((DrawablePtr)pWin);
|
||||||
|
fbPaintWindow (pWin, pRegion, what);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
|
||||||
|
{
|
||||||
|
exaWaitSync (pWin->drawable.pScreen);
|
||||||
|
exaDrawableDirty ((DrawablePtr)pWin);
|
||||||
|
fbCopyWindow (pWin, ptOldOrg, prgnSrc);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if EXA_MAX_FB > 1
|
||||||
|
void
|
||||||
|
ExaCheckPaintKey(DrawablePtr pDrawable,
|
||||||
|
RegionPtr pRegion,
|
||||||
|
CARD32 pixel,
|
||||||
|
int layer)
|
||||||
|
{
|
||||||
|
exaWaitSync (pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbOverlayPaintKey (pDrawable, pRegion, pixel, layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckOverlayCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
|
||||||
|
{
|
||||||
|
exaWaitSync (pWin->drawable.pScreen);
|
||||||
|
exaDrawableDirty ((DrawablePtr)pWin);
|
||||||
|
fbOverlayCopyWindow (pWin, ptOldOrg, prgnSrc);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaScreenInitAsync (ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
pScreen->GetImage = ExaCheckGetImage;
|
||||||
|
pScreen->GetSpans = ExaCheckGetSpans;
|
||||||
|
pScreen->PaintWindowBackground = ExaCheckPaintWindow;
|
||||||
|
pScreen->PaintWindowBorder = ExaCheckPaintWindow;
|
||||||
|
pScreen->CopyWindow = ExaCheckCopyWindow;
|
||||||
|
pScreen->BackingStoreFuncs.SaveAreas = ExaCheckSaveAreas;
|
||||||
|
pScreen->BackingStoreFuncs.RestoreAreas = ExaCheckRestoreAreas;
|
||||||
|
|
||||||
|
#ifdef RENDER
|
||||||
|
ExaPictureInitAsync (pScreen);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
exaWaitSync (pDst->pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDst->pDrawable);
|
||||||
|
fbComposite (op,
|
||||||
|
pSrc,
|
||||||
|
pMask,
|
||||||
|
pDst,
|
||||||
|
xSrc,
|
||||||
|
ySrc,
|
||||||
|
xMask,
|
||||||
|
yMask,
|
||||||
|
xDst,
|
||||||
|
yDst,
|
||||||
|
width,
|
||||||
|
height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaPictureInitAsync (ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
PictureScreenPtr ps;
|
||||||
|
|
||||||
|
ps = GetPictureScreen(pScreen);
|
||||||
|
ps->Composite = ExaCheckComposite;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only need to stall for copyarea/copyplane
|
||||||
|
*/
|
||||||
|
const GCOps exaAsyncPixmapGCOps = {
|
||||||
|
fbFillSpans,
|
||||||
|
fbSetSpans,
|
||||||
|
fbPutImage,
|
||||||
|
ExaCheckCopyArea,
|
||||||
|
ExaCheckCopyPlane,
|
||||||
|
fbPolyPoint,
|
||||||
|
fbPolyLine,
|
||||||
|
fbPolySegment,
|
||||||
|
fbPolyRectangle,
|
||||||
|
fbPolyArc,
|
||||||
|
fbFillPolygon,
|
||||||
|
fbPolyFillRect,
|
||||||
|
fbPolyFillArc,
|
||||||
|
miPolyText8,
|
||||||
|
miPolyText16,
|
||||||
|
miImageText8,
|
||||||
|
miImageText16,
|
||||||
|
fbImageGlyphBlt,
|
||||||
|
fbPolyGlyphBlt,
|
||||||
|
fbPushPixels
|
||||||
|
#ifdef NEED_LINEHELPER
|
||||||
|
,NULL
|
||||||
|
#endif
|
||||||
|
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,240 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#ifndef EXA_H
|
||||||
|
#define EXA_H
|
||||||
|
|
||||||
|
#include "scrnintstr.h"
|
||||||
|
#include "pixmapstr.h"
|
||||||
|
#include "windowstr.h"
|
||||||
|
#include "gcstruct.h"
|
||||||
|
#include "picturestr.h"
|
||||||
|
|
||||||
|
#define EXA_VERSION_MAJOR 0
|
||||||
|
#define EXA_VERSION_MINOR 1
|
||||||
|
#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 offset;
|
||||||
|
int save_offset;
|
||||||
|
int size;
|
||||||
|
int score;
|
||||||
|
pointer privData;
|
||||||
|
|
||||||
|
ExaOffscreenSaveProc save;
|
||||||
|
|
||||||
|
ExaOffscreenState state;
|
||||||
|
|
||||||
|
ExaOffscreenArea *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _ExaCardInfo {
|
||||||
|
/* These are here because I don't want to be adding more to
|
||||||
|
* ScrnInfoRec */
|
||||||
|
CARD8 *memoryBase;
|
||||||
|
unsigned long offScreenBase;
|
||||||
|
|
||||||
|
/* It's fix.smem_len.
|
||||||
|
This one could be potentially substituted by ScrnInfoRec
|
||||||
|
videoRam member, but I do not want to be doing the silly
|
||||||
|
<< 10, >>10 all over the place */
|
||||||
|
unsigned long memorySize;
|
||||||
|
|
||||||
|
int offscreenByteAlign;
|
||||||
|
int offscreenPitch;
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
/* The coordinate limitations for rendering for this hardware.
|
||||||
|
* Exa breaks larger pixmaps into smaller pieces and calls Prepare multiple times
|
||||||
|
* to handle larger pixmaps
|
||||||
|
*/
|
||||||
|
int maxX;
|
||||||
|
int maxY;
|
||||||
|
|
||||||
|
/* private */
|
||||||
|
ExaOffscreenArea *offScreenAreas;
|
||||||
|
Bool needsSync;
|
||||||
|
int lastMarker;
|
||||||
|
} ExaCardInfoRec, *ExaCardInfoPtr;
|
||||||
|
|
||||||
|
typedef struct _ExaAccelInfo {
|
||||||
|
/* PrepareSolid may fail if the pixmaps can't be accelerated to/from.
|
||||||
|
* This is an important feature for handling strange corner cases
|
||||||
|
* in hardware that are poorly expressed through flags.
|
||||||
|
*/
|
||||||
|
Bool (*PrepareSolid) (PixmapPtr pPixmap,
|
||||||
|
int alu,
|
||||||
|
Pixel planemask,
|
||||||
|
Pixel fg);
|
||||||
|
void (*Solid) (PixmapPtr pPixmap, int x1, int y1, int x2, int y2);
|
||||||
|
void (*DoneSolid) (PixmapPtr pPixmap);
|
||||||
|
|
||||||
|
/* PrepareSolid may fail if the pixmaps can't be accelerated to/from.
|
||||||
|
* This is an important feature for handling strange corner cases
|
||||||
|
* in hardware that are poorly expressed through flags.
|
||||||
|
*/
|
||||||
|
Bool (*PrepareCopy) (PixmapPtr pSrcPixmap,
|
||||||
|
PixmapPtr pDstPixmap,
|
||||||
|
Bool upsidedown,
|
||||||
|
Bool reverse,
|
||||||
|
int alu,
|
||||||
|
Pixel planemask);
|
||||||
|
void (*Copy) (PixmapPtr pDstPixmap,
|
||||||
|
int srcX,
|
||||||
|
int srcY,
|
||||||
|
int dstX,
|
||||||
|
int dstY,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
void (*DoneCopy) (PixmapPtr pDstPixmap);
|
||||||
|
|
||||||
|
/* The Composite hooks are a wrapper around the Composite operation.
|
||||||
|
* The CheckComposite occurs before pixmap migration occurs,
|
||||||
|
* and may fail for many hardware-dependent reasons.
|
||||||
|
* PrepareComposite should not fail, and the Bool return may
|
||||||
|
* not be necessary if we can
|
||||||
|
* adequately represent pixmap location/pitch limitations..
|
||||||
|
*/
|
||||||
|
Bool (*CheckComposite) (int op,
|
||||||
|
PicturePtr pSrcPicture,
|
||||||
|
PicturePtr pMaskPicture,
|
||||||
|
PicturePtr pDstPicture);
|
||||||
|
Bool (*PrepareComposite) (int op,
|
||||||
|
PicturePtr pSrcPicture,
|
||||||
|
PicturePtr pMaskPicture,
|
||||||
|
PicturePtr pDstPicture,
|
||||||
|
PixmapPtr pSrc,
|
||||||
|
PixmapPtr pMask,
|
||||||
|
PixmapPtr pDst);
|
||||||
|
void (*Composite) (PixmapPtr pDst,
|
||||||
|
int srcX,
|
||||||
|
int srcY,
|
||||||
|
int maskX,
|
||||||
|
int maskY,
|
||||||
|
int dstX,
|
||||||
|
int dstY,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
void (*DoneComposite) (PixmapPtr pDst);
|
||||||
|
|
||||||
|
/* Attempt to upload the data from src into the rectangle of the
|
||||||
|
* in-framebuffer pDst beginning at x,y and of width w,h. May fail.
|
||||||
|
*/
|
||||||
|
Bool (*UploadToScreen) (PixmapPtr pDst,
|
||||||
|
char *src,
|
||||||
|
int src_pitch);
|
||||||
|
Bool (*UploadToScratch) (PixmapPtr pSrc,
|
||||||
|
PixmapPtr pDst);
|
||||||
|
|
||||||
|
/* Attempt to download the rectangle from the in-framebuffer pSrc into
|
||||||
|
* dst, given the pitch. May fail. Since it is likely
|
||||||
|
* accelerated, a markSync will follow it as with other acceleration
|
||||||
|
* hooks.
|
||||||
|
*/
|
||||||
|
Bool (*DownloadFromScreen)(PixmapPtr pSrc,
|
||||||
|
int x, int y,
|
||||||
|
int w, int h,
|
||||||
|
char *dst, int dst_pitch);
|
||||||
|
|
||||||
|
/* Should return a hrdware-dependent marker number which can
|
||||||
|
* be waited for with WaitMarker. It can be not implemented in which
|
||||||
|
* case WaitMarker must wait for idle on any given marker
|
||||||
|
* number.
|
||||||
|
*/
|
||||||
|
int (*MarkSync) (ScreenPtr pScreen);
|
||||||
|
void (*WaitMarker) (ScreenPtr pScreen, int marker);
|
||||||
|
} ExaAccelInfoRec, *ExaAccelInfoPtr;
|
||||||
|
|
||||||
|
typedef struct _ExaDriver {
|
||||||
|
ExaCardInfoRec card;
|
||||||
|
ExaAccelInfoRec accel;
|
||||||
|
} ExaDriverRec, *ExaDriverPtr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ExaDriverPtr info;
|
||||||
|
} ExaScreenPrivRec, *ExaScreenPrivPtr;
|
||||||
|
|
||||||
|
#define EXA_OFFSCREEN_PIXMAPS (1 << 0)
|
||||||
|
#define EXA_OFFSCREEN_ALIGN_POT (1 << 1)
|
||||||
|
|
||||||
|
|
||||||
|
#define EXA_MAKE_VERSION(a, b, c) (((a) << 16) | ((b) << 8) | (c))
|
||||||
|
#define EXA_VERSION \
|
||||||
|
EXA_MAKE_VERSION(EXA_VERSION_MAJOR, EXA_VERSION_MINOR, EXA_VERSION_RELEASE)
|
||||||
|
#define EXA_IS_VERSION(a,b,c) (EXA_VERSION >= EXA_MAKE_VERSION(a,b,c))
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
exaGetVersion(void);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
exaDriverInit(ScreenPtr pScreen,
|
||||||
|
ExaDriverPtr pScreenInfo);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaDriverFini(ScreenPtr pScreen);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaMarkSync(ScreenPtr pScreen);
|
||||||
|
void
|
||||||
|
exaWaitSync(ScreenPtr pScreen);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
exaOffscreenInit(ScreenPtr pScreen);
|
||||||
|
|
||||||
|
ExaOffscreenArea *
|
||||||
|
exaOffscreenAlloc(ScreenPtr pScreen, int size, int align,
|
||||||
|
Bool locked,
|
||||||
|
ExaOffscreenSaveProc save,
|
||||||
|
pointer privData);
|
||||||
|
|
||||||
|
ExaOffscreenArea *
|
||||||
|
exaOffscreenFree(ScreenPtr pScreen, ExaOffscreenArea *area);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define exaInitCard(exa, sync, memory_base, off_screen_base, memory_size, \
|
||||||
|
offscreen_byte_align, offscreen_pitch, flags, \
|
||||||
|
max_x, max_y) \
|
||||||
|
(exa)->card.Sync = sync; \
|
||||||
|
(exa)->card.memoryBase = memory_base; \
|
||||||
|
(exa)->card.offScreenBase = off_screen_base; \
|
||||||
|
(exa)->card.memorySize = memory_size; \
|
||||||
|
(exa)->card.offscreenByteAlign = offscreen_byte_align; \
|
||||||
|
(exa)->card.offscreenPitch = offscreen_pitch; \
|
||||||
|
(exa)->card.flags = flags; \
|
||||||
|
(exa)->card.maxX = max_x; \
|
||||||
|
(exa)->card.maxY = max_y
|
||||||
|
|
||||||
|
#endif /* EXA_H */
|
|
@ -0,0 +1,281 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
#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"
|
||||||
|
|
||||||
|
#ifndef EXA_MAX_FB
|
||||||
|
#define EXA_MAX_FB FB_OVERLAY_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
Bool dirty;
|
||||||
|
} 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);
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPaintKey(DrawablePtr pDrawable,
|
||||||
|
RegionPtr pRegion,
|
||||||
|
CARD32 pixel,
|
||||||
|
int layer);
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckOverlayCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaScreenInitAsync (ScreenPtr pScreen);
|
||||||
|
|
||||||
|
extern const GCOps exaAsyncPixmapGCOps;
|
||||||
|
|
||||||
|
/* exapict.c */
|
||||||
|
void
|
||||||
|
ExaPictureInitAsync (ScreenPtr pScreen);
|
||||||
|
|
||||||
|
#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);
|
||||||
|
|
||||||
|
/* exa.c */
|
||||||
|
void
|
||||||
|
exaPixmapUseScreen (PixmapPtr pPixmap);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaPixmapUseMemory (PixmapPtr pPixmap);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaDrawableDirty(DrawablePtr pDrawable);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
exaDrawableIsOffscreen (DrawablePtr pDrawable);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
exaPixmapIsOffscreen(PixmapPtr p);
|
||||||
|
|
||||||
|
PixmapPtr
|
||||||
|
exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaMoveInPixmap (PixmapPtr pPixmap);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
#endif /* EXAPRIV_H */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,374 @@
|
||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
#define DEBUG_OFFSCREEN 1
|
||||||
|
#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->area.offset == 0);
|
||||||
|
for (area = pExaScr->info->card.offScreenAreas; area; area = area->next)
|
||||||
|
{
|
||||||
|
if (prev)
|
||||||
|
assert (prev->area.offset + prev->area.size == area->area.offset);
|
||||||
|
|
||||||
|
prev = area;
|
||||||
|
}
|
||||||
|
assert (prev->area.offset + prev->area.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 -> TOBIG\n", size));
|
||||||
|
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->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 to match alignment requirement */
|
||||||
|
real_size = size;
|
||||||
|
tmp = begin->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->next;
|
||||||
|
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 to match alignment requirement */
|
||||||
|
real_size = size;
|
||||||
|
tmp = begin->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->offset = area->offset + real_size;
|
||||||
|
new_area->size = area->size - real_size;
|
||||||
|
new_area->state = ExaOffscreenAvail;
|
||||||
|
new_area->save = 0;
|
||||||
|
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->save_offset = area->offset;
|
||||||
|
area->offset = (area->offset + align - 1) & ~(align - 1);
|
||||||
|
|
||||||
|
ExaOffscreenValidate (pScreen);
|
||||||
|
|
||||||
|
DBG_OFFSCREEN (("Alloc 0x%x -> 0x%x\n", size, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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\n", area->size, area->offset));
|
||||||
|
ExaOffscreenValidate (pScreen);
|
||||||
|
|
||||||
|
area->state = ExaOffscreenAvail;
|
||||||
|
area->save = 0;
|
||||||
|
area->offset = area->save_offset;
|
||||||
|
area->score = 0;
|
||||||
|
/*
|
||||||
|
* Find previous area
|
||||||
|
*/
|
||||||
|
if (area == pExaScr->info->card.offScreenAreas)
|
||||||
|
prev = 0;
|
||||||
|
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->offset = pExaScr->info->card.offScreenBase;
|
||||||
|
area->size = pExaScr->info->card.memorySize - area->offset;
|
||||||
|
area->save = 0;
|
||||||
|
area->next = NULL;
|
||||||
|
area->score = 0;
|
||||||
|
|
||||||
|
ErrorF("============ initial memory block of %d\n", area->size);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,281 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
#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"
|
||||||
|
|
||||||
|
#ifndef EXA_MAX_FB
|
||||||
|
#define EXA_MAX_FB FB_OVERLAY_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
Bool dirty;
|
||||||
|
} 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);
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPaintKey(DrawablePtr pDrawable,
|
||||||
|
RegionPtr pRegion,
|
||||||
|
CARD32 pixel,
|
||||||
|
int layer);
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckOverlayCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaScreenInitAsync (ScreenPtr pScreen);
|
||||||
|
|
||||||
|
extern const GCOps exaAsyncPixmapGCOps;
|
||||||
|
|
||||||
|
/* exapict.c */
|
||||||
|
void
|
||||||
|
ExaPictureInitAsync (ScreenPtr pScreen);
|
||||||
|
|
||||||
|
#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);
|
||||||
|
|
||||||
|
/* exa.c */
|
||||||
|
void
|
||||||
|
exaPixmapUseScreen (PixmapPtr pPixmap);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaPixmapUseMemory (PixmapPtr pPixmap);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaDrawableDirty(DrawablePtr pDrawable);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
exaDrawableIsOffscreen (DrawablePtr pDrawable);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
exaPixmapIsOffscreen(PixmapPtr p);
|
||||||
|
|
||||||
|
PixmapPtr
|
||||||
|
exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaMoveInPixmap (PixmapPtr pPixmap);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
#endif /* EXAPRIV_H */
|
|
@ -0,0 +1,572 @@
|
||||||
|
/*
|
||||||
|
* 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 <config.h>
|
||||||
|
#endif
|
||||||
|
#include "exaPriv.h"
|
||||||
|
|
||||||
|
#ifdef RENDER
|
||||||
|
#include "mipict.h"
|
||||||
|
|
||||||
|
#define EXA_DEBUG_FALLBACKS 0
|
||||||
|
|
||||||
|
#if EXA_DEBUG_FALLBACKS
|
||||||
|
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, 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 (®ion, pSrc, NULL, pDst,
|
||||||
|
xSrc, ySrc, 0, 0, xDst, yDst,
|
||||||
|
width, height))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable);
|
||||||
|
if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseScreen ((PixmapPtr) pDst->pDrawable);
|
||||||
|
|
||||||
|
pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
|
||||||
|
if (!pDstPix) {
|
||||||
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSrc->pDrawable->type == DRAWABLE_WINDOW)
|
||||||
|
pSrcPix = (*pSrc->pDrawable->pScreen->GetWindowPixmap)(
|
||||||
|
(WindowPtr) (pSrc->pDrawable));
|
||||||
|
else
|
||||||
|
pSrcPix = (PixmapPtr) (pSrc->pDrawable);
|
||||||
|
|
||||||
|
/* If source is offscreen, we need to sync the accelerator
|
||||||
|
* before accessing it. We'd prefer for it to be in memory.
|
||||||
|
*/
|
||||||
|
if (exaPixmapIsOffscreen(pSrcPix)) {
|
||||||
|
exaWaitSync(pDst->pDrawable->pScreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel = *(CARD32 *)(pSrcPix->devPrivate.ptr);
|
||||||
|
if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
|
||||||
|
pSrc->format))
|
||||||
|
{
|
||||||
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
exaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
|
||||||
|
pDst->format);
|
||||||
|
|
||||||
|
if (!(*pExaScr->info->accel.PrepareSolid) (pDstPix, GXcopy, 0xffffffff, pixel))
|
||||||
|
{
|
||||||
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nbox = REGION_NUM_RECTS(®ion);
|
||||||
|
pbox = REGION_RECTS(®ion);
|
||||||
|
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, ®ion);
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (pExaScr->info->card.maxX < width ||
|
||||||
|
pExaScr->info->card.maxY < height)
|
||||||
|
{
|
||||||
|
int total_width = width;
|
||||||
|
int total_height = height;
|
||||||
|
int xOff = 0;
|
||||||
|
int yOff = 0;
|
||||||
|
while (total_width > pExaScr->info->card.maxX) {
|
||||||
|
while (total_height > pExaScr->info->card.maxY) {
|
||||||
|
exaTryDriverComposite(op,
|
||||||
|
pSrc,
|
||||||
|
pMask,
|
||||||
|
pDst,
|
||||||
|
xSrc + xOff,
|
||||||
|
ySrc + yOff,
|
||||||
|
xMask + xOff,
|
||||||
|
yMask + yOff,
|
||||||
|
xDst + xOff,
|
||||||
|
yDst + yOff,
|
||||||
|
pExaScr->info->card.maxX,
|
||||||
|
pExaScr->info->card.maxY);
|
||||||
|
total_width -= pExaScr->info->card.maxX;
|
||||||
|
xOff += pExaScr->info->card.maxX;
|
||||||
|
yOff = 0;
|
||||||
|
}
|
||||||
|
if (total_height)
|
||||||
|
exaTryDriverComposite(op,
|
||||||
|
pSrc,
|
||||||
|
pMask,
|
||||||
|
pDst,
|
||||||
|
xSrc + xOff,
|
||||||
|
ySrc + yOff,
|
||||||
|
xMask + xOff,
|
||||||
|
yMask + yOff,
|
||||||
|
xDst + xOff,
|
||||||
|
yDst + yOff,
|
||||||
|
pExaScr->info->card.maxX,
|
||||||
|
total_height);
|
||||||
|
total_height -= pExaScr->info->card.maxY;
|
||||||
|
yOff += pExaScr->info->card.maxY;
|
||||||
|
}
|
||||||
|
if (total_width && total_height)
|
||||||
|
exaTryDriverComposite(op,
|
||||||
|
pSrc,
|
||||||
|
pMask,
|
||||||
|
pDst,
|
||||||
|
xSrc + xOff,
|
||||||
|
ySrc + yOff,
|
||||||
|
xMask + xOff,
|
||||||
|
yMask + yOff,
|
||||||
|
xDst + xOff,
|
||||||
|
yDst + yOff,
|
||||||
|
total_width,
|
||||||
|
total_height);
|
||||||
|
|
||||||
|
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 (®ion, 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, ®ion);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseScreen ((PixmapPtr) pSrc->pDrawable);
|
||||||
|
if (pMask && pMask->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseScreen ((PixmapPtr) pMask->pDrawable);
|
||||||
|
if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseScreen ((PixmapPtr) 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, ®ion);
|
||||||
|
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, ®ion);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(*pExaScr->info->accel.PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix,
|
||||||
|
pMaskPix, pDstPix))
|
||||||
|
{
|
||||||
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nbox = REGION_NUM_RECTS(®ion);
|
||||||
|
pbox = REGION_RECTS(®ion);
|
||||||
|
|
||||||
|
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, ®ion);
|
||||||
|
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;
|
||||||
|
|
||||||
|
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)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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 (®ion, pSrc, pMask, pDst,
|
||||||
|
xSrc, ySrc, xMask, yMask, xDst,
|
||||||
|
yDst, width, height))
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
exaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, 0,
|
||||||
|
REGION_RECTS(®ion), REGION_NUM_RECTS(®ion),
|
||||||
|
xSrc - xDst, ySrc - yDst,
|
||||||
|
FALSE, FALSE, 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
/* failure to accelerate was not due to pixmaps being in the wrong
|
||||||
|
* locations.
|
||||||
|
*/
|
||||||
|
if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable);
|
||||||
|
if (pMask && pMask->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseMemory ((PixmapPtr) pMask->pDrawable);
|
||||||
|
if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseMemory ((PixmapPtr) pDst->pDrawable);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if EXA_DEBUG_FALLBACKS
|
||||||
|
exaPrintCompositeFallback (op, pSrc, pMask, pDst);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
|
||||||
|
xMask, yMask, xDst, yDst, width, height);
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,365 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
exaWaitSync (pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbFillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
|
||||||
|
DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
|
||||||
|
{
|
||||||
|
exaWaitSync (pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbSetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
|
||||||
|
int x, int y, int w, int h, int leftPad, int format,
|
||||||
|
char *bits)
|
||||||
|
{
|
||||||
|
exaWaitSync (pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionPtr
|
||||||
|
ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
||||||
|
int srcx, int srcy, int w, int h, int dstx, int dsty)
|
||||||
|
{
|
||||||
|
exaWaitSync (pSrc->pScreen);
|
||||||
|
exaDrawableDirty (pDst);
|
||||||
|
return fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionPtr
|
||||||
|
ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
||||||
|
int srcx, int srcy, int w, int h, int dstx, int dsty,
|
||||||
|
unsigned long bitPlane)
|
||||||
|
{
|
||||||
|
exaWaitSync (pSrc->pScreen);
|
||||||
|
exaDrawableDirty (pDst);
|
||||||
|
return fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
|
||||||
|
bitPlane);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
|
||||||
|
DDXPointPtr pptInit)
|
||||||
|
{
|
||||||
|
exaWaitSync (pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolyPoint (pDrawable, pGC, mode, npt, pptInit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int mode, int npt, DDXPointPtr ppt)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (pGC->lineWidth == 0) {
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
}
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolyLine (pDrawable, pGC, mode, npt, ppt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int nsegInit, xSegment *pSegInit)
|
||||||
|
{
|
||||||
|
if (pGC->lineWidth == 0) {
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
}
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolyRectangle (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int nrects, xRectangle *prect)
|
||||||
|
{
|
||||||
|
if (pGC->lineWidth == 0) {
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
}
|
||||||
|
fbPolyRectangle (pDrawable, pGC, nrects, prect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int narcs, xArc *pArcs)
|
||||||
|
{
|
||||||
|
if (pGC->lineWidth == 0)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolyArc (pDrawable, pGC, narcs, pArcs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
miPolyArc (pDrawable, pGC, narcs, pArcs);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void
|
||||||
|
ExaCheckFillPolygon (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int shape, int mode, int count, DDXPointPtr pPts)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbFillPolygon (pDrawable, pGC, mode, count, pPts);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int nrect, xRectangle *prect)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolyFillRect (pDrawable, pGC, nrect, prect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolyFillArc (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int narcs, xArc *pArcs)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolyFillArc (pDrawable, pGC, narcs, pArcs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int x, int y, unsigned int nglyph,
|
||||||
|
CharInfoPtr *ppci, pointer pglyphBase)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int x, int y, unsigned int nglyph,
|
||||||
|
CharInfoPtr *ppci, pointer pglyphBase)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
|
||||||
|
DrawablePtr pDrawable,
|
||||||
|
int w, int h, int x, int y)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckGetImage (DrawablePtr pDrawable,
|
||||||
|
int x, int y, int w, int h,
|
||||||
|
unsigned int format, unsigned long planeMask,
|
||||||
|
char *d)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckGetSpans (DrawablePtr pDrawable,
|
||||||
|
int wMax,
|
||||||
|
DDXPointPtr ppt,
|
||||||
|
int *pwidth,
|
||||||
|
int nspans,
|
||||||
|
char *pdstStart)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
fbGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckSaveAreas (PixmapPtr pPixmap,
|
||||||
|
RegionPtr prgnSave,
|
||||||
|
int xorg,
|
||||||
|
int yorg,
|
||||||
|
WindowPtr pWin)
|
||||||
|
{
|
||||||
|
exaWaitSync(pWin->drawable.pScreen);
|
||||||
|
exaDrawableDirty (&pPixmap->drawable);
|
||||||
|
fbSaveAreas (pPixmap, prgnSave, xorg, yorg, pWin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckRestoreAreas (PixmapPtr pPixmap,
|
||||||
|
RegionPtr prgnSave,
|
||||||
|
int xorg,
|
||||||
|
int yorg,
|
||||||
|
WindowPtr pWin)
|
||||||
|
{
|
||||||
|
exaWaitSync(pWin->drawable.pScreen);
|
||||||
|
exaDrawableDirty ((DrawablePtr)pWin);
|
||||||
|
fbRestoreAreas (pPixmap, prgnSave, xorg, yorg, pWin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what)
|
||||||
|
{
|
||||||
|
exaWaitSync (pWin->drawable.pScreen);
|
||||||
|
exaDrawableDirty ((DrawablePtr)pWin);
|
||||||
|
fbPaintWindow (pWin, pRegion, what);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
|
||||||
|
{
|
||||||
|
exaWaitSync (pWin->drawable.pScreen);
|
||||||
|
exaDrawableDirty ((DrawablePtr)pWin);
|
||||||
|
fbCopyWindow (pWin, ptOldOrg, prgnSrc);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if EXA_MAX_FB > 1
|
||||||
|
void
|
||||||
|
ExaCheckPaintKey(DrawablePtr pDrawable,
|
||||||
|
RegionPtr pRegion,
|
||||||
|
CARD32 pixel,
|
||||||
|
int layer)
|
||||||
|
{
|
||||||
|
exaWaitSync (pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbOverlayPaintKey (pDrawable, pRegion, pixel, layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckOverlayCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
|
||||||
|
{
|
||||||
|
exaWaitSync (pWin->drawable.pScreen);
|
||||||
|
exaDrawableDirty ((DrawablePtr)pWin);
|
||||||
|
fbOverlayCopyWindow (pWin, ptOldOrg, prgnSrc);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaScreenInitAsync (ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
pScreen->GetImage = ExaCheckGetImage;
|
||||||
|
pScreen->GetSpans = ExaCheckGetSpans;
|
||||||
|
pScreen->PaintWindowBackground = ExaCheckPaintWindow;
|
||||||
|
pScreen->PaintWindowBorder = ExaCheckPaintWindow;
|
||||||
|
pScreen->CopyWindow = ExaCheckCopyWindow;
|
||||||
|
pScreen->BackingStoreFuncs.SaveAreas = ExaCheckSaveAreas;
|
||||||
|
pScreen->BackingStoreFuncs.RestoreAreas = ExaCheckRestoreAreas;
|
||||||
|
|
||||||
|
#ifdef RENDER
|
||||||
|
ExaPictureInitAsync (pScreen);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
exaWaitSync (pDst->pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDst->pDrawable);
|
||||||
|
fbComposite (op,
|
||||||
|
pSrc,
|
||||||
|
pMask,
|
||||||
|
pDst,
|
||||||
|
xSrc,
|
||||||
|
ySrc,
|
||||||
|
xMask,
|
||||||
|
yMask,
|
||||||
|
xDst,
|
||||||
|
yDst,
|
||||||
|
width,
|
||||||
|
height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaPictureInitAsync (ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
PictureScreenPtr ps;
|
||||||
|
|
||||||
|
ps = GetPictureScreen(pScreen);
|
||||||
|
ps->Composite = ExaCheckComposite;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only need to stall for copyarea/copyplane
|
||||||
|
*/
|
||||||
|
const GCOps exaAsyncPixmapGCOps = {
|
||||||
|
fbFillSpans,
|
||||||
|
fbSetSpans,
|
||||||
|
fbPutImage,
|
||||||
|
ExaCheckCopyArea,
|
||||||
|
ExaCheckCopyPlane,
|
||||||
|
fbPolyPoint,
|
||||||
|
fbPolyLine,
|
||||||
|
fbPolySegment,
|
||||||
|
fbPolyRectangle,
|
||||||
|
fbPolyArc,
|
||||||
|
fbFillPolygon,
|
||||||
|
fbPolyFillRect,
|
||||||
|
fbPolyFillArc,
|
||||||
|
miPolyText8,
|
||||||
|
miPolyText16,
|
||||||
|
miImageText8,
|
||||||
|
miImageText16,
|
||||||
|
fbImageGlyphBlt,
|
||||||
|
fbPolyGlyphBlt,
|
||||||
|
fbPushPixels
|
||||||
|
#ifdef NEED_LINEHELPER
|
||||||
|
,NULL
|
||||||
|
#endif
|
||||||
|
};
|
|
@ -0,0 +1,365 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
exaWaitSync (pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbFillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
|
||||||
|
DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
|
||||||
|
{
|
||||||
|
exaWaitSync (pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbSetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
|
||||||
|
int x, int y, int w, int h, int leftPad, int format,
|
||||||
|
char *bits)
|
||||||
|
{
|
||||||
|
exaWaitSync (pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionPtr
|
||||||
|
ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
||||||
|
int srcx, int srcy, int w, int h, int dstx, int dsty)
|
||||||
|
{
|
||||||
|
exaWaitSync (pSrc->pScreen);
|
||||||
|
exaDrawableDirty (pDst);
|
||||||
|
return fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionPtr
|
||||||
|
ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
||||||
|
int srcx, int srcy, int w, int h, int dstx, int dsty,
|
||||||
|
unsigned long bitPlane)
|
||||||
|
{
|
||||||
|
exaWaitSync (pSrc->pScreen);
|
||||||
|
exaDrawableDirty (pDst);
|
||||||
|
return fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
|
||||||
|
bitPlane);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
|
||||||
|
DDXPointPtr pptInit)
|
||||||
|
{
|
||||||
|
exaWaitSync (pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolyPoint (pDrawable, pGC, mode, npt, pptInit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int mode, int npt, DDXPointPtr ppt)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (pGC->lineWidth == 0) {
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
}
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolyLine (pDrawable, pGC, mode, npt, ppt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int nsegInit, xSegment *pSegInit)
|
||||||
|
{
|
||||||
|
if (pGC->lineWidth == 0) {
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
}
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolyRectangle (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int nrects, xRectangle *prect)
|
||||||
|
{
|
||||||
|
if (pGC->lineWidth == 0) {
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
}
|
||||||
|
fbPolyRectangle (pDrawable, pGC, nrects, prect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int narcs, xArc *pArcs)
|
||||||
|
{
|
||||||
|
if (pGC->lineWidth == 0)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolyArc (pDrawable, pGC, narcs, pArcs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
miPolyArc (pDrawable, pGC, narcs, pArcs);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void
|
||||||
|
ExaCheckFillPolygon (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int shape, int mode, int count, DDXPointPtr pPts)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbFillPolygon (pDrawable, pGC, mode, count, pPts);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int nrect, xRectangle *prect)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolyFillRect (pDrawable, pGC, nrect, prect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolyFillArc (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int narcs, xArc *pArcs)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolyFillArc (pDrawable, pGC, narcs, pArcs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int x, int y, unsigned int nglyph,
|
||||||
|
CharInfoPtr *ppci, pointer pglyphBase)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
|
||||||
|
int x, int y, unsigned int nglyph,
|
||||||
|
CharInfoPtr *ppci, pointer pglyphBase)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
|
||||||
|
DrawablePtr pDrawable,
|
||||||
|
int w, int h, int x, int y)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckGetImage (DrawablePtr pDrawable,
|
||||||
|
int x, int y, int w, int h,
|
||||||
|
unsigned int format, unsigned long planeMask,
|
||||||
|
char *d)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckGetSpans (DrawablePtr pDrawable,
|
||||||
|
int wMax,
|
||||||
|
DDXPointPtr ppt,
|
||||||
|
int *pwidth,
|
||||||
|
int nspans,
|
||||||
|
char *pdstStart)
|
||||||
|
{
|
||||||
|
exaWaitSync(pDrawable->pScreen);
|
||||||
|
fbGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckSaveAreas (PixmapPtr pPixmap,
|
||||||
|
RegionPtr prgnSave,
|
||||||
|
int xorg,
|
||||||
|
int yorg,
|
||||||
|
WindowPtr pWin)
|
||||||
|
{
|
||||||
|
exaWaitSync(pWin->drawable.pScreen);
|
||||||
|
exaDrawableDirty (&pPixmap->drawable);
|
||||||
|
fbSaveAreas (pPixmap, prgnSave, xorg, yorg, pWin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckRestoreAreas (PixmapPtr pPixmap,
|
||||||
|
RegionPtr prgnSave,
|
||||||
|
int xorg,
|
||||||
|
int yorg,
|
||||||
|
WindowPtr pWin)
|
||||||
|
{
|
||||||
|
exaWaitSync(pWin->drawable.pScreen);
|
||||||
|
exaDrawableDirty ((DrawablePtr)pWin);
|
||||||
|
fbRestoreAreas (pPixmap, prgnSave, xorg, yorg, pWin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what)
|
||||||
|
{
|
||||||
|
exaWaitSync (pWin->drawable.pScreen);
|
||||||
|
exaDrawableDirty ((DrawablePtr)pWin);
|
||||||
|
fbPaintWindow (pWin, pRegion, what);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
|
||||||
|
{
|
||||||
|
exaWaitSync (pWin->drawable.pScreen);
|
||||||
|
exaDrawableDirty ((DrawablePtr)pWin);
|
||||||
|
fbCopyWindow (pWin, ptOldOrg, prgnSrc);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if EXA_MAX_FB > 1
|
||||||
|
void
|
||||||
|
ExaCheckPaintKey(DrawablePtr pDrawable,
|
||||||
|
RegionPtr pRegion,
|
||||||
|
CARD32 pixel,
|
||||||
|
int layer)
|
||||||
|
{
|
||||||
|
exaWaitSync (pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDrawable);
|
||||||
|
fbOverlayPaintKey (pDrawable, pRegion, pixel, layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaCheckOverlayCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
|
||||||
|
{
|
||||||
|
exaWaitSync (pWin->drawable.pScreen);
|
||||||
|
exaDrawableDirty ((DrawablePtr)pWin);
|
||||||
|
fbOverlayCopyWindow (pWin, ptOldOrg, prgnSrc);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaScreenInitAsync (ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
pScreen->GetImage = ExaCheckGetImage;
|
||||||
|
pScreen->GetSpans = ExaCheckGetSpans;
|
||||||
|
pScreen->PaintWindowBackground = ExaCheckPaintWindow;
|
||||||
|
pScreen->PaintWindowBorder = ExaCheckPaintWindow;
|
||||||
|
pScreen->CopyWindow = ExaCheckCopyWindow;
|
||||||
|
pScreen->BackingStoreFuncs.SaveAreas = ExaCheckSaveAreas;
|
||||||
|
pScreen->BackingStoreFuncs.RestoreAreas = ExaCheckRestoreAreas;
|
||||||
|
|
||||||
|
#ifdef RENDER
|
||||||
|
ExaPictureInitAsync (pScreen);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
exaWaitSync (pDst->pDrawable->pScreen);
|
||||||
|
exaDrawableDirty (pDst->pDrawable);
|
||||||
|
fbComposite (op,
|
||||||
|
pSrc,
|
||||||
|
pMask,
|
||||||
|
pDst,
|
||||||
|
xSrc,
|
||||||
|
ySrc,
|
||||||
|
xMask,
|
||||||
|
yMask,
|
||||||
|
xDst,
|
||||||
|
yDst,
|
||||||
|
width,
|
||||||
|
height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExaPictureInitAsync (ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
PictureScreenPtr ps;
|
||||||
|
|
||||||
|
ps = GetPictureScreen(pScreen);
|
||||||
|
ps->Composite = ExaCheckComposite;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only need to stall for copyarea/copyplane
|
||||||
|
*/
|
||||||
|
const GCOps exaAsyncPixmapGCOps = {
|
||||||
|
fbFillSpans,
|
||||||
|
fbSetSpans,
|
||||||
|
fbPutImage,
|
||||||
|
ExaCheckCopyArea,
|
||||||
|
ExaCheckCopyPlane,
|
||||||
|
fbPolyPoint,
|
||||||
|
fbPolyLine,
|
||||||
|
fbPolySegment,
|
||||||
|
fbPolyRectangle,
|
||||||
|
fbPolyArc,
|
||||||
|
fbFillPolygon,
|
||||||
|
fbPolyFillRect,
|
||||||
|
fbPolyFillArc,
|
||||||
|
miPolyText8,
|
||||||
|
miPolyText16,
|
||||||
|
miImageText8,
|
||||||
|
miImageText16,
|
||||||
|
fbImageGlyphBlt,
|
||||||
|
fbPolyGlyphBlt,
|
||||||
|
fbPushPixels
|
||||||
|
#ifdef NEED_LINEHELPER
|
||||||
|
,NULL
|
||||||
|
#endif
|
||||||
|
};
|
|
@ -0,0 +1,374 @@
|
||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
#define DEBUG_OFFSCREEN 1
|
||||||
|
#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->area.offset == 0);
|
||||||
|
for (area = pExaScr->info->card.offScreenAreas; area; area = area->next)
|
||||||
|
{
|
||||||
|
if (prev)
|
||||||
|
assert (prev->area.offset + prev->area.size == area->area.offset);
|
||||||
|
|
||||||
|
prev = area;
|
||||||
|
}
|
||||||
|
assert (prev->area.offset + prev->area.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 -> TOBIG\n", size));
|
||||||
|
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->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 to match alignment requirement */
|
||||||
|
real_size = size;
|
||||||
|
tmp = begin->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->next;
|
||||||
|
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 to match alignment requirement */
|
||||||
|
real_size = size;
|
||||||
|
tmp = begin->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->offset = area->offset + real_size;
|
||||||
|
new_area->size = area->size - real_size;
|
||||||
|
new_area->state = ExaOffscreenAvail;
|
||||||
|
new_area->save = 0;
|
||||||
|
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->save_offset = area->offset;
|
||||||
|
area->offset = (area->offset + align - 1) & ~(align - 1);
|
||||||
|
|
||||||
|
ExaOffscreenValidate (pScreen);
|
||||||
|
|
||||||
|
DBG_OFFSCREEN (("Alloc 0x%x -> 0x%x\n", size, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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\n", area->size, area->offset));
|
||||||
|
ExaOffscreenValidate (pScreen);
|
||||||
|
|
||||||
|
area->state = ExaOffscreenAvail;
|
||||||
|
area->save = 0;
|
||||||
|
area->offset = area->save_offset;
|
||||||
|
area->score = 0;
|
||||||
|
/*
|
||||||
|
* Find previous area
|
||||||
|
*/
|
||||||
|
if (area == pExaScr->info->card.offScreenAreas)
|
||||||
|
prev = 0;
|
||||||
|
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->offset = pExaScr->info->card.offScreenBase;
|
||||||
|
area->size = pExaScr->info->card.memorySize - area->offset;
|
||||||
|
area->save = 0;
|
||||||
|
area->next = NULL;
|
||||||
|
area->score = 0;
|
||||||
|
|
||||||
|
ErrorF("============ initial memory block of %d\n", area->size);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,572 @@
|
||||||
|
/*
|
||||||
|
* 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 <config.h>
|
||||||
|
#endif
|
||||||
|
#include "exaPriv.h"
|
||||||
|
|
||||||
|
#ifdef RENDER
|
||||||
|
#include "mipict.h"
|
||||||
|
|
||||||
|
#define EXA_DEBUG_FALLBACKS 0
|
||||||
|
|
||||||
|
#if EXA_DEBUG_FALLBACKS
|
||||||
|
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, 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 (®ion, pSrc, NULL, pDst,
|
||||||
|
xSrc, ySrc, 0, 0, xDst, yDst,
|
||||||
|
width, height))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable);
|
||||||
|
if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseScreen ((PixmapPtr) pDst->pDrawable);
|
||||||
|
|
||||||
|
pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
|
||||||
|
if (!pDstPix) {
|
||||||
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSrc->pDrawable->type == DRAWABLE_WINDOW)
|
||||||
|
pSrcPix = (*pSrc->pDrawable->pScreen->GetWindowPixmap)(
|
||||||
|
(WindowPtr) (pSrc->pDrawable));
|
||||||
|
else
|
||||||
|
pSrcPix = (PixmapPtr) (pSrc->pDrawable);
|
||||||
|
|
||||||
|
/* If source is offscreen, we need to sync the accelerator
|
||||||
|
* before accessing it. We'd prefer for it to be in memory.
|
||||||
|
*/
|
||||||
|
if (exaPixmapIsOffscreen(pSrcPix)) {
|
||||||
|
exaWaitSync(pDst->pDrawable->pScreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel = *(CARD32 *)(pSrcPix->devPrivate.ptr);
|
||||||
|
if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
|
||||||
|
pSrc->format))
|
||||||
|
{
|
||||||
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
exaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
|
||||||
|
pDst->format);
|
||||||
|
|
||||||
|
if (!(*pExaScr->info->accel.PrepareSolid) (pDstPix, GXcopy, 0xffffffff, pixel))
|
||||||
|
{
|
||||||
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nbox = REGION_NUM_RECTS(®ion);
|
||||||
|
pbox = REGION_RECTS(®ion);
|
||||||
|
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, ®ion);
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (pExaScr->info->card.maxX < width ||
|
||||||
|
pExaScr->info->card.maxY < height)
|
||||||
|
{
|
||||||
|
int total_width = width;
|
||||||
|
int total_height = height;
|
||||||
|
int xOff = 0;
|
||||||
|
int yOff = 0;
|
||||||
|
while (total_width > pExaScr->info->card.maxX) {
|
||||||
|
while (total_height > pExaScr->info->card.maxY) {
|
||||||
|
exaTryDriverComposite(op,
|
||||||
|
pSrc,
|
||||||
|
pMask,
|
||||||
|
pDst,
|
||||||
|
xSrc + xOff,
|
||||||
|
ySrc + yOff,
|
||||||
|
xMask + xOff,
|
||||||
|
yMask + yOff,
|
||||||
|
xDst + xOff,
|
||||||
|
yDst + yOff,
|
||||||
|
pExaScr->info->card.maxX,
|
||||||
|
pExaScr->info->card.maxY);
|
||||||
|
total_width -= pExaScr->info->card.maxX;
|
||||||
|
xOff += pExaScr->info->card.maxX;
|
||||||
|
yOff = 0;
|
||||||
|
}
|
||||||
|
if (total_height)
|
||||||
|
exaTryDriverComposite(op,
|
||||||
|
pSrc,
|
||||||
|
pMask,
|
||||||
|
pDst,
|
||||||
|
xSrc + xOff,
|
||||||
|
ySrc + yOff,
|
||||||
|
xMask + xOff,
|
||||||
|
yMask + yOff,
|
||||||
|
xDst + xOff,
|
||||||
|
yDst + yOff,
|
||||||
|
pExaScr->info->card.maxX,
|
||||||
|
total_height);
|
||||||
|
total_height -= pExaScr->info->card.maxY;
|
||||||
|
yOff += pExaScr->info->card.maxY;
|
||||||
|
}
|
||||||
|
if (total_width && total_height)
|
||||||
|
exaTryDriverComposite(op,
|
||||||
|
pSrc,
|
||||||
|
pMask,
|
||||||
|
pDst,
|
||||||
|
xSrc + xOff,
|
||||||
|
ySrc + yOff,
|
||||||
|
xMask + xOff,
|
||||||
|
yMask + yOff,
|
||||||
|
xDst + xOff,
|
||||||
|
yDst + yOff,
|
||||||
|
total_width,
|
||||||
|
total_height);
|
||||||
|
|
||||||
|
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 (®ion, 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, ®ion);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseScreen ((PixmapPtr) pSrc->pDrawable);
|
||||||
|
if (pMask && pMask->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseScreen ((PixmapPtr) pMask->pDrawable);
|
||||||
|
if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseScreen ((PixmapPtr) 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, ®ion);
|
||||||
|
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, ®ion);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(*pExaScr->info->accel.PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix,
|
||||||
|
pMaskPix, pDstPix))
|
||||||
|
{
|
||||||
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nbox = REGION_NUM_RECTS(®ion);
|
||||||
|
pbox = REGION_RECTS(®ion);
|
||||||
|
|
||||||
|
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, ®ion);
|
||||||
|
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;
|
||||||
|
|
||||||
|
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)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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 (®ion, pSrc, pMask, pDst,
|
||||||
|
xSrc, ySrc, xMask, yMask, xDst,
|
||||||
|
yDst, width, height))
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
exaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, 0,
|
||||||
|
REGION_RECTS(®ion), REGION_NUM_RECTS(®ion),
|
||||||
|
xSrc - xDst, ySrc - yDst,
|
||||||
|
FALSE, FALSE, 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
/* failure to accelerate was not due to pixmaps being in the wrong
|
||||||
|
* locations.
|
||||||
|
*/
|
||||||
|
if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable);
|
||||||
|
if (pMask && pMask->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseMemory ((PixmapPtr) pMask->pDrawable);
|
||||||
|
if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
exaPixmapUseMemory ((PixmapPtr) pDst->pDrawable);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if EXA_DEBUG_FALLBACKS
|
||||||
|
exaPrintCompositeFallback (op, pSrc, pMask, pDst);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
|
||||||
|
xMask, yMask, xDst, yDst, width, height);
|
||||||
|
}
|
||||||
|
#endif
|
Loading…
Reference in New Issue