2005-07-01 10:56:12 +02:00
|
|
|
/*
|
2005-10-12 09:46:36 +02:00
|
|
|
* Copyright © 2001 Keith Packard
|
2005-07-01 10:56:12 +02:00
|
|
|
*
|
2005-10-12 09:46:36 +02:00
|
|
|
* Partly based on code that is Copyright © The XFree86 Project Inc.
|
2005-07-01 10:56:12 +02:00
|
|
|
*
|
|
|
|
* 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
|
2005-08-07 01:46:38 +02:00
|
|
|
#include <xorg-config.h>
|
2005-07-01 10:56:12 +02:00
|
|
|
#endif
|
|
|
|
#include "exaPriv.h"
|
|
|
|
|
|
|
|
#ifdef RENDER
|
|
|
|
#include "mipict.h"
|
|
|
|
|
2005-07-07 17:05:02 +02:00
|
|
|
#include "xf86str.h"
|
|
|
|
#include "xf86.h"
|
|
|
|
|
2005-07-01 10:56:12 +02:00
|
|
|
|
- Change migration-in rule slightly: previously, if your score was less
than the max, it was bumped, and then if you were above the threshhold
you got moved in. Instead, do the above-threshhold check separate from
score starting out less than max. While this will likely make thrashing
cases worse, I hope it will fix some issues with long term performance
(think of an xcompmgr with a backbuffer it's doing only accelerated
operations to. If some new pixmap comes in and bumps it out, even once,
it will never get a chance to re-migrate because its score will be
maxed). Change migration-out to be the same way for symmetry, though it
shouldn't ever affect anything.
- Fix a lot of debugging output, both in terms of printing quality, and
completeness. The fallback debugging covers a lot more now, pointing
out new areas for improvement. Debugging toggles are now centralized in
exaPriv.h.
2005-09-21 12:27:53 +02:00
|
|
|
#if DEBUG_TRACE_FALL
|
2005-07-01 10:56:12 +02:00
|
|
|
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" : "");
|
|
|
|
|
- Don't try to upload 0 byte-per-pixel (PICT_a1) data using
RADEONHostDataBlit.
- Disable the shortcut for switching from 3d to 3d in radeon_exa.c. It
appears that we do need the cache flush here, thought it's not clear
why. Disable the 2d to 2d shortcut while here, since I'm unsure of what
we're doing. Exposed by the following bit:
- Bug #4485: Add a new routine, exaGlyphs, to handle font drawing. Glyphs
were being accumulated in from non-migratable scratch pixmaps, causing
the destination pixmap to move towards screen but the migration
necessary for source never to happen, leading to abysmal performance.
Instead, copy the scratch glyph data into a real pixmap first, then
composite from that into the destination, allowing for migration. time
ls -lR from programs/Xserver showed 26.9% (+/- 6.3%) decrease in wall
time (n=3).
- Create exaDrawableUse* wrapping exaPixmapUse*, but which are aware of
windows needing backing store. Makes migration code prettier, and
ensures that composited windows will be migrated as normal when we turn
off cw for EXA. (issue brought up by keithp)
2005-09-17 22:02:02 +02:00
|
|
|
snprintf(string, n, "0x%lx:%c fmt %s (%s)", (long)pict->pDrawable, loc, format, size);
|
2005-07-01 10:56:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
- Don't try to upload 0 byte-per-pixel (PICT_a1) data using
RADEONHostDataBlit.
- Disable the shortcut for switching from 3d to 3d in radeon_exa.c. It
appears that we do need the cache flush here, thought it's not clear
why. Disable the 2d to 2d shortcut while here, since I'm unsure of what
we're doing. Exposed by the following bit:
- Bug #4485: Add a new routine, exaGlyphs, to handle font drawing. Glyphs
were being accumulated in from non-migratable scratch pixmaps, causing
the destination pixmap to move towards screen but the migration
necessary for source never to happen, leading to abysmal performance.
Instead, copy the scratch glyph data into a real pixmap first, then
composite from that into the destination, allowing for migration. time
ls -lR from programs/Xserver showed 26.9% (+/- 6.3%) decrease in wall
time (n=3).
- Create exaDrawableUse* wrapping exaPixmapUse*, but which are aware of
windows needing backing store. Makes migration code prettier, and
ensures that composited windows will be migrated as normal when we turn
off cw for EXA. (issue brought up by keithp)
2005-09-17 22:02:02 +02:00
|
|
|
exaDrawableUseMemory(pSrc->pDrawable);
|
|
|
|
exaDrawableUseScreen(pDst->pDrawable);
|
2005-07-01 10:56:12 +02:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
2005-09-11 21:08:10 +02:00
|
|
|
exaPrepareAccess(&pSrcPix->drawable, EXA_PREPARE_SRC);
|
2005-10-12 09:46:36 +02:00
|
|
|
switch (pSrcPix->drawable.bitsPerPixel) {
|
|
|
|
case 32:
|
|
|
|
pixel = *(CARD32 *)(pSrcPix->devPrivate.ptr);
|
|
|
|
break;
|
|
|
|
case 16:
|
|
|
|
pixel = *(CARD16 *)(pSrcPix->devPrivate.ptr);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
pixel = *(CARD8 *)(pSrcPix->devPrivate.ptr);
|
|
|
|
break;
|
|
|
|
}
|
2005-07-01 10:56:12 +02:00
|
|
|
if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
|
|
|
|
pSrc->format))
|
|
|
|
{
|
|
|
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
|
|
|
return -1;
|
|
|
|
}
|
2005-09-11 21:08:10 +02:00
|
|
|
exaFinishAccess(&pSrcPix->drawable, EXA_PREPARE_SRC);
|
|
|
|
|
2005-07-01 10:56:12 +02:00
|
|
|
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;
|
|
|
|
|
2005-08-30 06:41:04 +02:00
|
|
|
/* Bail if we might exceed coord limits by rendering from/to these. We
|
|
|
|
* should really be making some scratch pixmaps with offsets and coords
|
|
|
|
* adjusted to deal with this, but it hasn't been done yet.
|
|
|
|
*/
|
|
|
|
if (pSrc->pDrawable->width > pExaScr->info->card.maxX ||
|
|
|
|
pSrc->pDrawable->height > pExaScr->info->card.maxY ||
|
|
|
|
pDst->pDrawable->width > pExaScr->info->card.maxX ||
|
|
|
|
pDst->pDrawable->height > pExaScr->info->card.maxY ||
|
|
|
|
(pMask && (pMask->pDrawable->width > pExaScr->info->card.maxX ||
|
|
|
|
pMask->pDrawable->height > pExaScr->info->card.maxY)))
|
2005-07-01 10:56:12 +02:00
|
|
|
{
|
2005-08-30 06:41:04 +02:00
|
|
|
return -1;
|
2005-07-01 10:56:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
- Don't try to upload 0 byte-per-pixel (PICT_a1) data using
RADEONHostDataBlit.
- Disable the shortcut for switching from 3d to 3d in radeon_exa.c. It
appears that we do need the cache flush here, thought it's not clear
why. Disable the 2d to 2d shortcut while here, since I'm unsure of what
we're doing. Exposed by the following bit:
- Bug #4485: Add a new routine, exaGlyphs, to handle font drawing. Glyphs
were being accumulated in from non-migratable scratch pixmaps, causing
the destination pixmap to move towards screen but the migration
necessary for source never to happen, leading to abysmal performance.
Instead, copy the scratch glyph data into a real pixmap first, then
composite from that into the destination, allowing for migration. time
ls -lR from programs/Xserver showed 26.9% (+/- 6.3%) decrease in wall
time (n=3).
- Create exaDrawableUse* wrapping exaPixmapUse*, but which are aware of
windows needing backing store. Makes migration code prettier, and
ensures that composited windows will be migrated as normal when we turn
off cw for EXA. (issue brought up by keithp)
2005-09-17 22:02:02 +02:00
|
|
|
exaDrawableUseScreen(pSrc->pDrawable);
|
|
|
|
if (pMask != NULL)
|
|
|
|
exaDrawableUseScreen(pMask->pDrawable);
|
|
|
|
exaDrawableUseScreen(pDst->pDrawable);
|
2005-07-01 10:56:12 +02:00
|
|
|
|
|
|
|
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;
|
2005-07-07 17:05:02 +02:00
|
|
|
ScrnInfoPtr pScrn = XF86SCRNINFO(pDst->pDrawable->pScreen);
|
2005-10-07 01:45:29 +02:00
|
|
|
Bool saveSrcRepeat = pSrc->repeat;
|
|
|
|
Bool saveMaskRepeat = pMask ? pMask->repeat : 0;
|
2005-07-07 17:05:02 +02:00
|
|
|
|
|
|
|
if (!pScrn->vtSema) {
|
|
|
|
exaDrawableDirty(pDst->pDrawable);
|
|
|
|
pExaScr->SavedComposite(op, pSrc, pMask, pDst, xSrc, ySrc,
|
|
|
|
xMask, yMask, xDst, yDst, width, height);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-09-11 20:43:55 +02:00
|
|
|
/* simplify the drivers by reducing here */
|
|
|
|
switch (op) {
|
|
|
|
case PictOpDisjointClear:
|
|
|
|
case PictOpConjointClear:
|
|
|
|
op = PictOpClear;
|
|
|
|
break;
|
|
|
|
case PictOpDisjointSrc:
|
|
|
|
case PictOpConjointSrc:
|
|
|
|
op = PictOpSrc;
|
|
|
|
break;
|
|
|
|
case PictOpDisjointDst:
|
|
|
|
case PictOpConjointDst:
|
|
|
|
case PictOpDst:
|
|
|
|
return;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2005-07-01 10:56:12 +02:00
|
|
|
|
2005-10-07 01:45:29 +02:00
|
|
|
/* Remove repeat in source if useless */
|
|
|
|
if (pSrc->repeat && !pSrc->transform && xSrc >= 0 &&
|
|
|
|
(xSrc + width) <= pSrc->pDrawable->width && ySrc >= 0 &&
|
|
|
|
(ySrc + height) <= pSrc->pDrawable->height)
|
|
|
|
pSrc->repeat = 0;
|
|
|
|
|
2005-07-01 10:56:12 +02:00
|
|
|
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)
|
2005-10-07 01:45:29 +02:00
|
|
|
goto bail;
|
2005-07-01 10:56:12 +02:00
|
|
|
}
|
|
|
|
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))
|
2005-10-07 01:45:29 +02:00
|
|
|
goto bail;
|
2005-07-01 10:56:12 +02:00
|
|
|
|
|
|
|
|
2005-09-30 04:03:45 +02:00
|
|
|
exaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, NULL,
|
2005-07-01 10:56:12 +02:00
|
|
|
REGION_RECTS(®ion), REGION_NUM_RECTS(®ion),
|
|
|
|
xSrc - xDst, ySrc - yDst,
|
2005-09-30 04:03:45 +02:00
|
|
|
FALSE, FALSE, 0, NULL);
|
2005-10-06 23:55:41 +02:00
|
|
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
2005-10-07 01:45:29 +02:00
|
|
|
goto bail;
|
2005-07-01 10:56:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-10-07 01:45:29 +02:00
|
|
|
/* Remove repeat in mask if useless */
|
|
|
|
if (pMask && pMask->repeat && !pMask->transform && xMask >= 0 &&
|
|
|
|
(xMask + width) <= pMask->pDrawable->width && yMask >= 0 &&
|
|
|
|
(yMask + height) <= pMask->pDrawable->height)
|
|
|
|
pMask->repeat = 0;
|
|
|
|
|
|
|
|
|
2005-07-01 10:56:12 +02:00
|
|
|
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)
|
2005-10-07 01:45:29 +02:00
|
|
|
goto bail;
|
2005-07-01 10:56:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ret != 0) {
|
|
|
|
/* failure to accelerate was not due to pixmaps being in the wrong
|
|
|
|
* locations.
|
|
|
|
*/
|
- Don't try to upload 0 byte-per-pixel (PICT_a1) data using
RADEONHostDataBlit.
- Disable the shortcut for switching from 3d to 3d in radeon_exa.c. It
appears that we do need the cache flush here, thought it's not clear
why. Disable the 2d to 2d shortcut while here, since I'm unsure of what
we're doing. Exposed by the following bit:
- Bug #4485: Add a new routine, exaGlyphs, to handle font drawing. Glyphs
were being accumulated in from non-migratable scratch pixmaps, causing
the destination pixmap to move towards screen but the migration
necessary for source never to happen, leading to abysmal performance.
Instead, copy the scratch glyph data into a real pixmap first, then
composite from that into the destination, allowing for migration. time
ls -lR from programs/Xserver showed 26.9% (+/- 6.3%) decrease in wall
time (n=3).
- Create exaDrawableUse* wrapping exaPixmapUse*, but which are aware of
windows needing backing store. Makes migration code prettier, and
ensures that composited windows will be migrated as normal when we turn
off cw for EXA. (issue brought up by keithp)
2005-09-17 22:02:02 +02:00
|
|
|
exaDrawableUseMemory(pSrc->pDrawable);
|
|
|
|
if (pMask != NULL)
|
|
|
|
exaDrawableUseMemory(pMask->pDrawable);
|
|
|
|
exaDrawableUseMemory(pDst->pDrawable);
|
2005-07-01 10:56:12 +02:00
|
|
|
}
|
|
|
|
|
- Change migration-in rule slightly: previously, if your score was less
than the max, it was bumped, and then if you were above the threshhold
you got moved in. Instead, do the above-threshhold check separate from
score starting out less than max. While this will likely make thrashing
cases worse, I hope it will fix some issues with long term performance
(think of an xcompmgr with a backbuffer it's doing only accelerated
operations to. If some new pixmap comes in and bumps it out, even once,
it will never get a chance to re-migrate because its score will be
maxed). Change migration-out to be the same way for symmetry, though it
shouldn't ever affect anything.
- Fix a lot of debugging output, both in terms of printing quality, and
completeness. The fallback debugging covers a lot more now, pointing
out new areas for improvement. Debugging toggles are now centralized in
exaPriv.h.
2005-09-21 12:27:53 +02:00
|
|
|
#if DEBUG_TRACE_FALL
|
2005-07-01 10:56:12 +02:00
|
|
|
exaPrintCompositeFallback (op, pSrc, pMask, pDst);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
|
|
|
|
xMask, yMask, xDst, yDst, width, height);
|
2005-10-07 01:45:29 +02:00
|
|
|
|
|
|
|
bail:
|
|
|
|
pSrc->repeat = saveSrcRepeat;
|
|
|
|
if (pMask)
|
|
|
|
pMask->repeat = saveMaskRepeat;
|
2005-07-01 10:56:12 +02:00
|
|
|
}
|
|
|
|
#endif
|
- Don't try to upload 0 byte-per-pixel (PICT_a1) data using
RADEONHostDataBlit.
- Disable the shortcut for switching from 3d to 3d in radeon_exa.c. It
appears that we do need the cache flush here, thought it's not clear
why. Disable the 2d to 2d shortcut while here, since I'm unsure of what
we're doing. Exposed by the following bit:
- Bug #4485: Add a new routine, exaGlyphs, to handle font drawing. Glyphs
were being accumulated in from non-migratable scratch pixmaps, causing
the destination pixmap to move towards screen but the migration
necessary for source never to happen, leading to abysmal performance.
Instead, copy the scratch glyph data into a real pixmap first, then
composite from that into the destination, allowing for migration. time
ls -lR from programs/Xserver showed 26.9% (+/- 6.3%) decrease in wall
time (n=3).
- Create exaDrawableUse* wrapping exaPixmapUse*, but which are aware of
windows needing backing store. Makes migration code prettier, and
ensures that composited windows will be migrated as normal when we turn
off cw for EXA. (issue brought up by keithp)
2005-09-17 22:02:02 +02:00
|
|
|
|
|
|
|
#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
|
|
|
|
|
|
|
|
/* exaGlyphs is a slight variation on miGlyphs, to support acceleration. The
|
|
|
|
* issue is that miGlyphs' use of ModifyPixmapHeader makes it impossible to
|
|
|
|
* migrate these pixmaps. So, instead we create a pixmap at the beginning of
|
|
|
|
* the loop and upload each glyph into the pixmap before compositing.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
exaGlyphs (CARD8 op,
|
|
|
|
PicturePtr pSrc,
|
|
|
|
PicturePtr pDst,
|
|
|
|
PictFormatPtr maskFormat,
|
|
|
|
INT16 xSrc,
|
|
|
|
INT16 ySrc,
|
|
|
|
int nlist,
|
|
|
|
GlyphListPtr list,
|
|
|
|
GlyphPtr *glyphs)
|
|
|
|
{
|
|
|
|
ExaScreenPriv (pDst->pDrawable->pScreen);
|
|
|
|
PixmapPtr pPixmap = NULL, pScratchPixmap = NULL;
|
|
|
|
PicturePtr pPicture;
|
|
|
|
PixmapPtr pMaskPixmap = NULL;
|
|
|
|
PicturePtr pMask;
|
|
|
|
ScreenPtr pScreen = pDst->pDrawable->pScreen;
|
|
|
|
int width = 0, height = 0;
|
|
|
|
int x, y;
|
|
|
|
int xDst = list->xOff, yDst = list->yOff;
|
|
|
|
int n;
|
|
|
|
GlyphPtr glyph;
|
|
|
|
int error;
|
|
|
|
BoxRec extents;
|
|
|
|
CARD32 component_alpha;
|
|
|
|
|
|
|
|
/* If the driver doesn't support accelerated composite, there's no point in
|
2005-10-09 04:03:22 +02:00
|
|
|
* going to this extra work. Assume that no driver will be able to do
|
|
|
|
* component-alpha, which is likely accurate (at least until we make a CA
|
|
|
|
* helper).
|
- Don't try to upload 0 byte-per-pixel (PICT_a1) data using
RADEONHostDataBlit.
- Disable the shortcut for switching from 3d to 3d in radeon_exa.c. It
appears that we do need the cache flush here, thought it's not clear
why. Disable the 2d to 2d shortcut while here, since I'm unsure of what
we're doing. Exposed by the following bit:
- Bug #4485: Add a new routine, exaGlyphs, to handle font drawing. Glyphs
were being accumulated in from non-migratable scratch pixmaps, causing
the destination pixmap to move towards screen but the migration
necessary for source never to happen, leading to abysmal performance.
Instead, copy the scratch glyph data into a real pixmap first, then
composite from that into the destination, allowing for migration. time
ls -lR from programs/Xserver showed 26.9% (+/- 6.3%) decrease in wall
time (n=3).
- Create exaDrawableUse* wrapping exaPixmapUse*, but which are aware of
windows needing backing store. Makes migration code prettier, and
ensures that composited windows will be migrated as normal when we turn
off cw for EXA. (issue brought up by keithp)
2005-09-17 22:02:02 +02:00
|
|
|
*/
|
2005-10-09 04:03:22 +02:00
|
|
|
if (!pExaScr->info->accel.PrepareComposite ||
|
|
|
|
(maskFormat && NeedsComponent(maskFormat->format))) {
|
- Don't try to upload 0 byte-per-pixel (PICT_a1) data using
RADEONHostDataBlit.
- Disable the shortcut for switching from 3d to 3d in radeon_exa.c. It
appears that we do need the cache flush here, thought it's not clear
why. Disable the 2d to 2d shortcut while here, since I'm unsure of what
we're doing. Exposed by the following bit:
- Bug #4485: Add a new routine, exaGlyphs, to handle font drawing. Glyphs
were being accumulated in from non-migratable scratch pixmaps, causing
the destination pixmap to move towards screen but the migration
necessary for source never to happen, leading to abysmal performance.
Instead, copy the scratch glyph data into a real pixmap first, then
composite from that into the destination, allowing for migration. time
ls -lR from programs/Xserver showed 26.9% (+/- 6.3%) decrease in wall
time (n=3).
- Create exaDrawableUse* wrapping exaPixmapUse*, but which are aware of
windows needing backing store. Makes migration code prettier, and
ensures that composited windows will be migrated as normal when we turn
off cw for EXA. (issue brought up by keithp)
2005-09-17 22:02:02 +02:00
|
|
|
miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (maskFormat)
|
|
|
|
{
|
|
|
|
GCPtr pGC;
|
|
|
|
xRectangle rect;
|
|
|
|
|
|
|
|
miGlyphExtents (nlist, list, glyphs, &extents);
|
|
|
|
|
|
|
|
if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
|
|
|
|
return;
|
|
|
|
width = extents.x2 - extents.x1;
|
|
|
|
height = extents.y2 - extents.y1;
|
|
|
|
pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
|
|
|
|
maskFormat->depth);
|
|
|
|
if (!pMaskPixmap)
|
|
|
|
return;
|
|
|
|
component_alpha = NeedsComponent(maskFormat->format);
|
|
|
|
pMask = CreatePicture (0, &pMaskPixmap->drawable,
|
|
|
|
maskFormat, CPComponentAlpha, &component_alpha,
|
|
|
|
serverClient, &error);
|
|
|
|
if (!pMask)
|
|
|
|
{
|
|
|
|
(*pScreen->DestroyPixmap) (pMaskPixmap);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
|
|
|
|
ValidateGC (&pMaskPixmap->drawable, pGC);
|
|
|
|
rect.x = 0;
|
|
|
|
rect.y = 0;
|
|
|
|
rect.width = width;
|
|
|
|
rect.height = height;
|
|
|
|
(*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
|
|
|
|
FreeScratchGC (pGC);
|
|
|
|
x = -extents.x1;
|
|
|
|
y = -extents.y1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pMask = pDst;
|
|
|
|
x = 0;
|
|
|
|
y = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (nlist--)
|
|
|
|
{
|
|
|
|
GCPtr pGC;
|
|
|
|
int maxwidth = 0, maxheight = 0, i;
|
|
|
|
|
|
|
|
x += list->xOff;
|
|
|
|
y += list->yOff;
|
|
|
|
n = list->len;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
if (glyphs[i]->info.width > maxwidth)
|
|
|
|
maxwidth = glyphs[i]->info.width;
|
|
|
|
if (glyphs[i]->info.height > maxheight)
|
|
|
|
maxheight = glyphs[i]->info.height;
|
|
|
|
}
|
2005-09-22 00:26:07 +02:00
|
|
|
if (maxwidth == 0 || maxheight == 0) {
|
|
|
|
while (n--)
|
|
|
|
{
|
|
|
|
glyph = *glyphs++;
|
|
|
|
x += glyph->info.xOff;
|
|
|
|
y += glyph->info.yOff;
|
|
|
|
}
|
|
|
|
list++;
|
- Don't try to upload 0 byte-per-pixel (PICT_a1) data using
RADEONHostDataBlit.
- Disable the shortcut for switching from 3d to 3d in radeon_exa.c. It
appears that we do need the cache flush here, thought it's not clear
why. Disable the 2d to 2d shortcut while here, since I'm unsure of what
we're doing. Exposed by the following bit:
- Bug #4485: Add a new routine, exaGlyphs, to handle font drawing. Glyphs
were being accumulated in from non-migratable scratch pixmaps, causing
the destination pixmap to move towards screen but the migration
necessary for source never to happen, leading to abysmal performance.
Instead, copy the scratch glyph data into a real pixmap first, then
composite from that into the destination, allowing for migration. time
ls -lR from programs/Xserver showed 26.9% (+/- 6.3%) decrease in wall
time (n=3).
- Create exaDrawableUse* wrapping exaPixmapUse*, but which are aware of
windows needing backing store. Makes migration code prettier, and
ensures that composited windows will be migrated as normal when we turn
off cw for EXA. (issue brought up by keithp)
2005-09-17 22:02:02 +02:00
|
|
|
continue;
|
2005-09-22 00:26:07 +02:00
|
|
|
}
|
- Don't try to upload 0 byte-per-pixel (PICT_a1) data using
RADEONHostDataBlit.
- Disable the shortcut for switching from 3d to 3d in radeon_exa.c. It
appears that we do need the cache flush here, thought it's not clear
why. Disable the 2d to 2d shortcut while here, since I'm unsure of what
we're doing. Exposed by the following bit:
- Bug #4485: Add a new routine, exaGlyphs, to handle font drawing. Glyphs
were being accumulated in from non-migratable scratch pixmaps, causing
the destination pixmap to move towards screen but the migration
necessary for source never to happen, leading to abysmal performance.
Instead, copy the scratch glyph data into a real pixmap first, then
composite from that into the destination, allowing for migration. time
ls -lR from programs/Xserver showed 26.9% (+/- 6.3%) decrease in wall
time (n=3).
- Create exaDrawableUse* wrapping exaPixmapUse*, but which are aware of
windows needing backing store. Makes migration code prettier, and
ensures that composited windows will be migrated as normal when we turn
off cw for EXA. (issue brought up by keithp)
2005-09-17 22:02:02 +02:00
|
|
|
|
|
|
|
/* Get a scratch pixmap to wrap the original glyph data */
|
|
|
|
pScratchPixmap = GetScratchPixmapHeader (pScreen, glyphs[0]->info.width,
|
|
|
|
glyphs[0]->info.height,
|
|
|
|
list->format->depth,
|
|
|
|
list->format->depth,
|
|
|
|
0, (pointer) (glyphs[0] + 1));
|
|
|
|
if (!pScratchPixmap)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Create the (real) temporary pixmap to store the current glyph in */
|
|
|
|
pPixmap = (*pScreen->CreatePixmap) (pScreen, maxwidth, maxheight,
|
|
|
|
list->format->depth);
|
|
|
|
if (!pPixmap) {
|
|
|
|
FreeScratchPixmapHeader (pScratchPixmap);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create a temporary picture to wrap the temporary pixmap, so it can be
|
|
|
|
* used as a source for Composite.
|
|
|
|
*/
|
|
|
|
component_alpha = NeedsComponent(list->format->format);
|
|
|
|
pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
|
|
|
|
CPComponentAlpha, &component_alpha,
|
|
|
|
serverClient, &error);
|
|
|
|
if (!pPicture) {
|
|
|
|
(*pScreen->DestroyPixmap) (pPixmap);
|
|
|
|
FreeScratchPixmapHeader (pScratchPixmap);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get a scratch GC with which to copy the glyph data from scratch to
|
|
|
|
* temporary
|
|
|
|
*/
|
|
|
|
pGC = GetScratchGC (list->format->depth, pScreen);
|
|
|
|
ValidateGC (&pPixmap->drawable, pGC);
|
|
|
|
|
|
|
|
/* Give the temporary pixmap an initial kick towards the screen, so
|
|
|
|
* it'll stick there.
|
|
|
|
*/
|
|
|
|
exaPixmapUseScreen (pPixmap);
|
|
|
|
|
|
|
|
while (n--)
|
|
|
|
{
|
|
|
|
glyph = *glyphs++;
|
|
|
|
|
|
|
|
(*pScreen->ModifyPixmapHeader) (pScratchPixmap,
|
2005-09-18 04:32:23 +02:00
|
|
|
glyph->info.width,
|
|
|
|
glyph->info.height,
|
- Don't try to upload 0 byte-per-pixel (PICT_a1) data using
RADEONHostDataBlit.
- Disable the shortcut for switching from 3d to 3d in radeon_exa.c. It
appears that we do need the cache flush here, thought it's not clear
why. Disable the 2d to 2d shortcut while here, since I'm unsure of what
we're doing. Exposed by the following bit:
- Bug #4485: Add a new routine, exaGlyphs, to handle font drawing. Glyphs
were being accumulated in from non-migratable scratch pixmaps, causing
the destination pixmap to move towards screen but the migration
necessary for source never to happen, leading to abysmal performance.
Instead, copy the scratch glyph data into a real pixmap first, then
composite from that into the destination, allowing for migration. time
ls -lR from programs/Xserver showed 26.9% (+/- 6.3%) decrease in wall
time (n=3).
- Create exaDrawableUse* wrapping exaPixmapUse*, but which are aware of
windows needing backing store. Makes migration code prettier, and
ensures that composited windows will be migrated as normal when we turn
off cw for EXA. (issue brought up by keithp)
2005-09-17 22:02:02 +02:00
|
|
|
0, 0, -1, (pointer) (glyph + 1));
|
|
|
|
pScratchPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
|
|
|
|
|
|
|
/* Copy the glyph data into the proper pixmap instead of a fake.
|
2005-09-18 04:32:23 +02:00
|
|
|
* First we try to use UploadToScreen, if we can, then we fall back
|
|
|
|
* to a plain exaCopyArea in case of failure.
|
- Don't try to upload 0 byte-per-pixel (PICT_a1) data using
RADEONHostDataBlit.
- Disable the shortcut for switching from 3d to 3d in radeon_exa.c. It
appears that we do need the cache flush here, thought it's not clear
why. Disable the 2d to 2d shortcut while here, since I'm unsure of what
we're doing. Exposed by the following bit:
- Bug #4485: Add a new routine, exaGlyphs, to handle font drawing. Glyphs
were being accumulated in from non-migratable scratch pixmaps, causing
the destination pixmap to move towards screen but the migration
necessary for source never to happen, leading to abysmal performance.
Instead, copy the scratch glyph data into a real pixmap first, then
composite from that into the destination, allowing for migration. time
ls -lR from programs/Xserver showed 26.9% (+/- 6.3%) decrease in wall
time (n=3).
- Create exaDrawableUse* wrapping exaPixmapUse*, but which are aware of
windows needing backing store. Makes migration code prettier, and
ensures that composited windows will be migrated as normal when we turn
off cw for EXA. (issue brought up by keithp)
2005-09-17 22:02:02 +02:00
|
|
|
*/
|
2005-09-18 04:32:23 +02:00
|
|
|
if (!pExaScr->info->accel.UploadToScreen ||
|
|
|
|
!exaPixmapIsOffscreen(pPixmap) ||
|
|
|
|
!(*pExaScr->info->accel.UploadToScreen) (pPixmap, 0, 0,
|
|
|
|
glyph->info.width,
|
|
|
|
glyph->info.height,
|
|
|
|
pScratchPixmap->devPrivate.ptr,
|
|
|
|
pScratchPixmap->devKind))
|
|
|
|
{
|
|
|
|
exaCopyArea (&pScratchPixmap->drawable, &pPixmap->drawable, pGC,
|
|
|
|
0, 0, glyph->info.width, glyph->info.height, 0, 0);
|
2005-10-04 13:24:09 +02:00
|
|
|
} else {
|
|
|
|
exaDrawableDirty (&pPixmap->drawable);
|
2005-09-18 04:32:23 +02:00
|
|
|
}
|
- Don't try to upload 0 byte-per-pixel (PICT_a1) data using
RADEONHostDataBlit.
- Disable the shortcut for switching from 3d to 3d in radeon_exa.c. It
appears that we do need the cache flush here, thought it's not clear
why. Disable the 2d to 2d shortcut while here, since I'm unsure of what
we're doing. Exposed by the following bit:
- Bug #4485: Add a new routine, exaGlyphs, to handle font drawing. Glyphs
were being accumulated in from non-migratable scratch pixmaps, causing
the destination pixmap to move towards screen but the migration
necessary for source never to happen, leading to abysmal performance.
Instead, copy the scratch glyph data into a real pixmap first, then
composite from that into the destination, allowing for migration. time
ls -lR from programs/Xserver showed 26.9% (+/- 6.3%) decrease in wall
time (n=3).
- Create exaDrawableUse* wrapping exaPixmapUse*, but which are aware of
windows needing backing store. Makes migration code prettier, and
ensures that composited windows will be migrated as normal when we turn
off cw for EXA. (issue brought up by keithp)
2005-09-17 22:02:02 +02:00
|
|
|
|
|
|
|
if (maskFormat)
|
|
|
|
{
|
|
|
|
CompositePicture (PictOpAdd,
|
|
|
|
pPicture,
|
2005-09-30 04:03:45 +02:00
|
|
|
NULL,
|
- Don't try to upload 0 byte-per-pixel (PICT_a1) data using
RADEONHostDataBlit.
- Disable the shortcut for switching from 3d to 3d in radeon_exa.c. It
appears that we do need the cache flush here, thought it's not clear
why. Disable the 2d to 2d shortcut while here, since I'm unsure of what
we're doing. Exposed by the following bit:
- Bug #4485: Add a new routine, exaGlyphs, to handle font drawing. Glyphs
were being accumulated in from non-migratable scratch pixmaps, causing
the destination pixmap to move towards screen but the migration
necessary for source never to happen, leading to abysmal performance.
Instead, copy the scratch glyph data into a real pixmap first, then
composite from that into the destination, allowing for migration. time
ls -lR from programs/Xserver showed 26.9% (+/- 6.3%) decrease in wall
time (n=3).
- Create exaDrawableUse* wrapping exaPixmapUse*, but which are aware of
windows needing backing store. Makes migration code prettier, and
ensures that composited windows will be migrated as normal when we turn
off cw for EXA. (issue brought up by keithp)
2005-09-17 22:02:02 +02:00
|
|
|
pMask,
|
|
|
|
0, 0,
|
|
|
|
0, 0,
|
|
|
|
x - glyph->info.x,
|
|
|
|
y - glyph->info.y,
|
|
|
|
glyph->info.width,
|
|
|
|
glyph->info.height);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CompositePicture (op,
|
|
|
|
pSrc,
|
|
|
|
pPicture,
|
|
|
|
pDst,
|
|
|
|
xSrc + (x - glyph->info.x) - xDst,
|
|
|
|
ySrc + (y - glyph->info.y) - yDst,
|
|
|
|
0, 0,
|
|
|
|
x - glyph->info.x,
|
|
|
|
y - glyph->info.y,
|
|
|
|
glyph->info.width,
|
|
|
|
glyph->info.height);
|
|
|
|
}
|
|
|
|
x += glyph->info.xOff;
|
|
|
|
y += glyph->info.yOff;
|
|
|
|
}
|
|
|
|
list++;
|
|
|
|
FreeScratchGC (pGC);
|
|
|
|
FreePicture ((pointer) pPicture, 0);
|
|
|
|
(*pScreen->DestroyPixmap) (pPixmap);
|
|
|
|
FreeScratchPixmapHeader (pScratchPixmap);
|
|
|
|
}
|
|
|
|
if (maskFormat)
|
|
|
|
{
|
|
|
|
x = extents.x1;
|
|
|
|
y = extents.y1;
|
|
|
|
CompositePicture (op,
|
|
|
|
pSrc,
|
|
|
|
pMask,
|
|
|
|
pDst,
|
|
|
|
xSrc + x - xDst,
|
|
|
|
ySrc + y - yDst,
|
|
|
|
0, 0,
|
|
|
|
x, y,
|
|
|
|
width, height);
|
|
|
|
FreePicture ((pointer) pMask, (XID) 0);
|
|
|
|
(*pScreen->DestroyPixmap) (pMaskPixmap);
|
|
|
|
}
|
|
|
|
}
|