2006-04-26 20:27:40 +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.
|
|
|
|
*/
|
|
|
|
|
2006-02-16 01:14:11 +01:00
|
|
|
#ifdef HAVE_DIX_CONFIG_H
|
|
|
|
#include <dix-config.h>
|
2005-07-01 10:56:12 +02:00
|
|
|
#endif
|
2006-02-16 01:14:11 +01:00
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
2006-02-02 21:09:14 +01:00
|
|
|
#include "exa_priv.h"
|
2005-07-01 10:56:12 +02:00
|
|
|
|
|
|
|
#ifdef RENDER
|
|
|
|
#include "mipict.h"
|
|
|
|
|
- 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" : "");
|
|
|
|
|
2006-04-27 22:27:27 +02:00
|
|
|
snprintf(string, n, "%p:%c fmt %s (%s)", 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);
|
|
|
|
}
|
2006-03-14 22:30:12 +01:00
|
|
|
#endif /* DEBUG_TRACE_FALL */
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
exaOpReadsDestination (CARD8 op)
|
|
|
|
{
|
|
|
|
/* FALSE (does not read destination) is the list of ops in the protocol
|
|
|
|
* document with "0" in the "Fb" column and no "Ab" in the "Fa" column.
|
|
|
|
* That's just Clear and Src. ReduceCompositeOp() will already have
|
|
|
|
* converted con/disjoint clear/src to Clear or Src.
|
|
|
|
*/
|
|
|
|
switch (op) {
|
|
|
|
case PictOpClear:
|
|
|
|
case PictOpSrc:
|
|
|
|
return FALSE;
|
|
|
|
default:
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-07-01 10:56:12 +02:00
|
|
|
|
|
|
|
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;
|
2006-03-14 22:30:12 +01:00
|
|
|
ExaMigrationRec pixmaps[1];
|
2005-07-01 10:56:12 +02:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2006-03-14 21:38:06 +01:00
|
|
|
pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
|
|
|
|
pixel = exaGetPixmapFirstPixel (pSrcPix);
|
|
|
|
|
2006-03-14 22:30:12 +01:00
|
|
|
pixmaps[0].as_dst = TRUE;
|
|
|
|
pixmaps[0].as_src = FALSE;
|
|
|
|
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
|
|
|
|
exaDoMigration(pixmaps, 1, TRUE);
|
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 (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
|
|
|
|
pSrc->format))
|
|
|
|
{
|
|
|
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
|
|
|
return -1;
|
|
|
|
}
|
2005-09-11 21:08:10 +02:00
|
|
|
|
2006-06-24 15:23:14 +02:00
|
|
|
if (!exaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
|
|
|
|
pDst->format))
|
|
|
|
{
|
|
|
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
|
|
|
return -1;
|
|
|
|
}
|
2005-07-01 10:56:12 +02:00
|
|
|
|
2006-03-09 07:04:07 +01:00
|
|
|
if (!(*pExaScr->info->PrepareSolid) (pDstPix, GXcopy, 0xffffffff, pixel))
|
2005-07-01 10:56:12 +02:00
|
|
|
{
|
|
|
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
nbox = REGION_NUM_RECTS(®ion);
|
|
|
|
pbox = REGION_RECTS(®ion);
|
|
|
|
while (nbox--)
|
|
|
|
{
|
2006-03-09 07:04:07 +01:00
|
|
|
(*pExaScr->info->Solid) (pDstPix,
|
|
|
|
pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
|
|
|
|
pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
|
2005-07-01 10:56:12 +02:00
|
|
|
pbox++;
|
|
|
|
}
|
|
|
|
|
2006-03-09 07:04:07 +01:00
|
|
|
(*pExaScr->info->DoneSolid) (pDstPix);
|
2005-07-01 10:56:12 +02:00
|
|
|
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;
|
2006-03-14 22:30:12 +01:00
|
|
|
ExaMigrationRec pixmaps[3];
|
2005-07-01 10:56:12 +02:00
|
|
|
|
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.
|
|
|
|
*/
|
2006-03-09 07:04:07 +01:00
|
|
|
if (pSrc->pDrawable->width > pExaScr->info->maxX ||
|
|
|
|
pSrc->pDrawable->height > pExaScr->info->maxY ||
|
|
|
|
pDst->pDrawable->width > pExaScr->info->maxX ||
|
|
|
|
pDst->pDrawable->height > pExaScr->info->maxY ||
|
|
|
|
(pMask && (pMask->pDrawable->width > pExaScr->info->maxX ||
|
|
|
|
pMask->pDrawable->height > pExaScr->info->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;
|
|
|
|
|
2006-03-09 07:04:07 +01:00
|
|
|
if (pExaScr->info->CheckComposite &&
|
|
|
|
!(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst))
|
2005-07-01 10:56:12 +02:00
|
|
|
{
|
|
|
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2006-03-14 22:30:12 +01:00
|
|
|
pixmaps[0].as_dst = TRUE;
|
|
|
|
pixmaps[0].as_src = exaOpReadsDestination(op);
|
|
|
|
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
|
|
|
|
pixmaps[1].as_dst = FALSE;
|
|
|
|
pixmaps[1].as_src = TRUE;
|
|
|
|
pixmaps[1].pPix = exaGetDrawablePixmap (pSrc->pDrawable);
|
|
|
|
if (pMask) {
|
|
|
|
pixmaps[2].as_dst = FALSE;
|
|
|
|
pixmaps[2].as_src = TRUE;
|
|
|
|
pixmaps[2].pPix = exaGetDrawablePixmap (pMask->pDrawable);
|
|
|
|
exaDoMigration(pixmaps, 3, TRUE);
|
|
|
|
} else {
|
|
|
|
exaDoMigration(pixmaps, 2, TRUE);
|
|
|
|
}
|
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;
|
|
|
|
}
|
|
|
|
|
2006-03-09 07:04:07 +01:00
|
|
|
if (!pSrcPix && (!pMask || pMaskPix) && pExaScr->info->UploadToScratch) {
|
2006-02-02 22:07:06 +01:00
|
|
|
pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
|
2006-03-09 07:04:07 +01:00
|
|
|
if ((*pExaScr->info->UploadToScratch) (pSrcPix, &scratch))
|
2005-07-01 10:56:12 +02:00
|
|
|
pSrcPix = &scratch;
|
2006-03-09 07:04:07 +01:00
|
|
|
} else if (pSrcPix && pMask && !pMaskPix && pExaScr->info->UploadToScratch) {
|
2006-02-02 22:07:06 +01:00
|
|
|
pMaskPix = exaGetDrawablePixmap (pMask->pDrawable);
|
2006-03-09 07:04:07 +01:00
|
|
|
if ((*pExaScr->info->UploadToScratch) (pMaskPix, &scratch))
|
2005-07-01 10:56:12 +02:00
|
|
|
pMaskPix = &scratch;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!pSrcPix || (pMask && !pMaskPix)) {
|
|
|
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-03-09 07:04:07 +01:00
|
|
|
if (!(*pExaScr->info->PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix,
|
|
|
|
pMaskPix, pDstPix))
|
2005-07-01 10:56:12 +02:00
|
|
|
{
|
|
|
|
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--)
|
|
|
|
{
|
2006-03-09 07:04:07 +01:00
|
|
|
(*pExaScr->info->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);
|
2005-07-01 10:56:12 +02:00
|
|
|
pbox++;
|
|
|
|
}
|
|
|
|
|
2006-03-09 07:04:07 +01:00
|
|
|
(*pExaScr->info->DoneComposite) (pDstPix);
|
2005-07-01 10:56:12 +02:00
|
|
|
exaMarkSync(pDst->pDrawable->pScreen);
|
|
|
|
exaDrawableDirty (pDst->pDrawable);
|
|
|
|
|
|
|
|
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2006-08-12 19:54:33 +02:00
|
|
|
/**
|
|
|
|
* exaTryMagicTwoPassCompositeHelper implements PictOpOver using two passes of
|
|
|
|
* simpler operations PictOpOutReverse and PictOpAdd. Mainly used for component
|
|
|
|
* alpha and limited 1-tmu cards.
|
|
|
|
*
|
|
|
|
* From http://anholt.livejournal.com/32058.html:
|
|
|
|
*
|
|
|
|
* The trouble is that component-alpha rendering requires two different sources
|
|
|
|
* for blending: one for the source value to the blender, which is the
|
|
|
|
* per-channel multiplication of source and mask, and one for the source alpha
|
|
|
|
* for multiplying with the destination channels, which is the multiplication
|
|
|
|
* of the source channels by the mask alpha. So the equation for Over is:
|
|
|
|
*
|
|
|
|
* dst.A = src.A * mask.A + (1 - (src.A * mask.A)) * dst.A
|
|
|
|
* dst.R = src.R * mask.R + (1 - (src.A * mask.R)) * dst.R
|
|
|
|
* dst.G = src.G * mask.G + (1 - (src.A * mask.G)) * dst.G
|
|
|
|
* dst.B = src.B * mask.B + (1 - (src.A * mask.B)) * dst.B
|
|
|
|
*
|
|
|
|
* But we can do some simpler operations, right? How about PictOpOutReverse,
|
|
|
|
* which has a source factor of 0 and dest factor of (1 - source alpha). We
|
|
|
|
* can get the source alpha value (srca.X = src.A * mask.X) out of the texture
|
|
|
|
* blenders pretty easily. So we can do a component-alpha OutReverse, which
|
|
|
|
* gets us:
|
|
|
|
*
|
|
|
|
* dst.A = 0 + (1 - (src.A * mask.A)) * dst.A
|
|
|
|
* dst.R = 0 + (1 - (src.A * mask.R)) * dst.R
|
|
|
|
* dst.G = 0 + (1 - (src.A * mask.G)) * dst.G
|
|
|
|
* dst.B = 0 + (1 - (src.A * mask.B)) * dst.B
|
|
|
|
*
|
|
|
|
* OK. And if an op doesn't use the source alpha value for the destination
|
|
|
|
* factor, then we can do the channel multiplication in the texture blenders
|
|
|
|
* to get the source value, and ignore the source alpha that we wouldn't use.
|
|
|
|
* We've supported this in the Radeon driver for a long time. An example would
|
|
|
|
* be PictOpAdd, which does:
|
|
|
|
*
|
|
|
|
* dst.A = src.A * mask.A + dst.A
|
|
|
|
* dst.R = src.R * mask.R + dst.R
|
|
|
|
* dst.G = src.G * mask.G + dst.G
|
|
|
|
* dst.B = src.B * mask.B + dst.B
|
|
|
|
*
|
|
|
|
* Hey, this looks good! If we do a PictOpOutReverse and then a PictOpAdd right
|
|
|
|
* after it, we get:
|
|
|
|
*
|
|
|
|
* dst.A = src.A * mask.A + ((1 - (src.A * mask.A)) * dst.A)
|
|
|
|
* dst.R = src.R * mask.R + ((1 - (src.A * mask.R)) * dst.R)
|
|
|
|
* dst.G = src.G * mask.G + ((1 - (src.A * mask.G)) * dst.G)
|
|
|
|
* dst.B = src.B * mask.B + ((1 - (src.A * mask.B)) * dst.B)
|
|
|
|
*/
|
|
|
|
|
2006-04-26 20:27:40 +02:00
|
|
|
static int
|
2006-08-12 19:54:33 +02:00
|
|
|
exaTryMagicTwoPassCompositeHelper(CARD8 op,
|
|
|
|
PicturePtr pSrc,
|
|
|
|
PicturePtr pMask,
|
|
|
|
PicturePtr pDst,
|
|
|
|
INT16 xSrc,
|
|
|
|
INT16 ySrc,
|
|
|
|
INT16 xMask,
|
|
|
|
INT16 yMask,
|
|
|
|
INT16 xDst,
|
|
|
|
INT16 yDst,
|
|
|
|
CARD16 width,
|
|
|
|
CARD16 height)
|
2006-04-26 20:27:40 +02:00
|
|
|
{
|
|
|
|
ExaScreenPriv (pDst->pDrawable->pScreen);
|
|
|
|
|
|
|
|
assert(op == PictOpOver);
|
|
|
|
|
|
|
|
if (pExaScr->info->CheckComposite &&
|
|
|
|
(!(*pExaScr->info->CheckComposite)(PictOpOutReverse, pSrc, pMask,
|
|
|
|
pDst) ||
|
|
|
|
!(*pExaScr->info->CheckComposite)(PictOpAdd, pSrc, pMask, pDst)))
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now, we think we should be able to accelerate this operation. First,
|
|
|
|
* composite the destination to be the destination times the source alpha
|
|
|
|
* factors.
|
|
|
|
*/
|
|
|
|
exaComposite(PictOpOutReverse, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
|
|
|
|
xDst, yDst, width, height);
|
|
|
|
|
|
|
|
/* Then, add in the source value times the destination alpha factors (1.0).
|
|
|
|
*/
|
|
|
|
exaComposite(PictOpAdd, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
|
|
|
|
xDst, yDst, width, height);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2005-07-01 10:56:12 +02:00
|
|
|
|
|
|
|
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-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
|
|
|
|
2006-03-10 00:29:44 +01:00
|
|
|
/* We currently don't support acceleration of gradients, or other pictures
|
|
|
|
* with a NULL pDrawable.
|
|
|
|
*/
|
|
|
|
if (pExaScr->swappedOut ||
|
|
|
|
pSrc->pDrawable == NULL || (pMask != NULL && pMask->pDrawable == NULL))
|
|
|
|
{
|
|
|
|
ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
|
|
|
|
xMask, yMask, xDst, yDst, width, height);
|
2005-07-07 17:05:02 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
2006-03-10 00:29:44 +01:00
|
|
|
if (!pMask)
|
2005-07-01 10:56:12 +02:00
|
|
|
{
|
|
|
|
if (op == PictOpSrc)
|
|
|
|
{
|
|
|
|
if (pSrc->pDrawable->width == 1 &&
|
2006-07-02 12:41:35 +02:00
|
|
|
pSrc->pDrawable->height == 1 && pSrc->repeat &&
|
|
|
|
pSrc->repeatType == RepeatNormal)
|
2005-07-01 10:56:12 +02:00
|
|
|
{
|
|
|
|
ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
|
|
|
|
width, height);
|
|
|
|
if (ret == 1)
|
2006-04-26 20:27:40 +02:00
|
|
|
goto done;
|
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))
|
2006-04-26 20:27:40 +02:00
|
|
|
goto done;
|
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);
|
2006-04-26 20:27:40 +02:00
|
|
|
goto done;
|
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;
|
|
|
|
|
2006-03-10 00:29:44 +01:00
|
|
|
if (pExaScr->info->PrepareComposite &&
|
2006-07-02 12:41:35 +02:00
|
|
|
(!pSrc->repeat || pSrc->repeat == RepeatNormal) &&
|
|
|
|
(!pMask || !pMask->repeat || pMask->repeat == RepeatNormal) &&
|
2005-07-01 10:56:12 +02:00
|
|
|
!pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap)
|
|
|
|
{
|
2006-08-12 19:54:33 +02:00
|
|
|
Bool isSrcSolid;
|
|
|
|
|
2005-07-01 10:56:12 +02:00
|
|
|
ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask,
|
|
|
|
yMask, xDst, yDst, width, height);
|
|
|
|
if (ret == 1)
|
2006-04-26 20:27:40 +02:00
|
|
|
goto done;
|
|
|
|
|
2006-08-12 19:54:33 +02:00
|
|
|
/* For generic masks and solid src pictures, mach64 can do Over in two
|
|
|
|
* passes, similar to the component-alpha case.
|
|
|
|
*/
|
|
|
|
isSrcSolid = pSrc->pDrawable->width == 1 &&
|
|
|
|
pSrc->pDrawable->height == 1 &&
|
|
|
|
pSrc->repeat;
|
|
|
|
|
2006-04-26 20:27:40 +02:00
|
|
|
/* If we couldn't do the Composite in a single pass, and it was a
|
|
|
|
* component-alpha Over, see if we can do it in two passes with
|
|
|
|
* an OutReverse and then an Add.
|
|
|
|
*/
|
2006-08-12 19:54:33 +02:00
|
|
|
if (ret == -1 && op == PictOpOver && pMask &&
|
|
|
|
(pMask->componentAlpha || isSrcSolid)) {
|
|
|
|
ret = exaTryMagicTwoPassCompositeHelper(op, pSrc, pMask, pDst,
|
|
|
|
xSrc, ySrc,
|
|
|
|
xMask, yMask, xDst, yDst,
|
|
|
|
width, height);
|
2006-04-26 20:27:40 +02:00
|
|
|
if (ret == 1)
|
|
|
|
goto done;
|
|
|
|
}
|
2005-07-01 10:56:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ret != 0) {
|
2006-03-14 22:30:12 +01:00
|
|
|
ExaMigrationRec pixmaps[3];
|
2005-07-01 10:56:12 +02:00
|
|
|
/* failure to accelerate was not due to pixmaps being in the wrong
|
|
|
|
* locations.
|
|
|
|
*/
|
2006-03-14 22:30:12 +01:00
|
|
|
pixmaps[0].as_dst = TRUE;
|
|
|
|
pixmaps[0].as_src = exaOpReadsDestination(op);
|
|
|
|
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
|
|
|
|
pixmaps[1].as_dst = FALSE;
|
|
|
|
pixmaps[1].as_src = TRUE;
|
|
|
|
pixmaps[1].pPix = exaGetDrawablePixmap (pSrc->pDrawable);
|
|
|
|
if (pMask) {
|
|
|
|
pixmaps[2].as_dst = FALSE;
|
|
|
|
pixmaps[2].as_src = TRUE;
|
|
|
|
pixmaps[2].pPix = exaGetDrawablePixmap (pMask->pDrawable);
|
|
|
|
exaDoMigration(pixmaps, 3, FALSE);
|
|
|
|
} else {
|
|
|
|
exaDoMigration(pixmaps, 2, FALSE);
|
|
|
|
}
|
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
|
|
|
|
2006-04-26 20:27:40 +02:00
|
|
|
done:
|
2005-10-07 01:45:29 +02:00
|
|
|
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)
|
|
|
|
|
2006-03-31 21:41:28 +02:00
|
|
|
/**
|
|
|
|
* exaRasterizeTrapezoid is just a wrapper around the software implementation.
|
|
|
|
*
|
|
|
|
* The trapezoid specification is basically too hard to be done in hardware (at
|
|
|
|
* the very least, without programmability), so we just do the appropriate
|
|
|
|
* Prepare/FinishAccess for it before using fbtrap.c.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
exaRasterizeTrapezoid (PicturePtr pPicture, xTrapezoid *trap,
|
|
|
|
int x_off, int y_off)
|
|
|
|
{
|
|
|
|
ExaMigrationRec pixmaps[1];
|
|
|
|
|
|
|
|
pixmaps[0].as_dst = TRUE;
|
|
|
|
pixmaps[0].as_src = TRUE;
|
|
|
|
pixmaps[0].pPix = exaGetDrawablePixmap (pPicture->pDrawable);
|
|
|
|
exaDoMigration(pixmaps, 1, FALSE);
|
|
|
|
|
|
|
|
exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
|
|
|
|
fbRasterizeTrapezoid(pPicture, trap, x_off, y_off);
|
|
|
|
exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* exaAddTriangles does migration and syncing before dumping down to the
|
|
|
|
* software implementation.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
exaAddTriangles (PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntri,
|
|
|
|
xTriangle *tris)
|
|
|
|
{
|
|
|
|
ExaMigrationRec pixmaps[1];
|
|
|
|
|
|
|
|
pixmaps[0].as_dst = TRUE;
|
|
|
|
pixmaps[0].as_src = TRUE;
|
|
|
|
pixmaps[0].pPix = exaGetDrawablePixmap (pPicture->pDrawable);
|
|
|
|
exaDoMigration(pixmaps, 1, FALSE);
|
|
|
|
|
|
|
|
exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
|
|
|
|
fbAddTriangles(pPicture, x_off, y_off, ntri, tris);
|
|
|
|
exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
|
|
|
|
}
|
|
|
|
|
2006-04-26 01:56:17 +02:00
|
|
|
/**
|
|
|
|
* Returns TRUE if the glyphs in the lists intersect. Only checks based on
|
|
|
|
* bounding box, which appears to be good enough to catch most cases at least.
|
|
|
|
*/
|
|
|
|
static Bool
|
|
|
|
exaGlyphsIntersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs)
|
|
|
|
{
|
|
|
|
int x1, x2, y1, y2;
|
|
|
|
int n;
|
|
|
|
GlyphPtr glyph;
|
|
|
|
int x, y;
|
|
|
|
BoxRec extents;
|
|
|
|
Bool first = TRUE;
|
|
|
|
|
|
|
|
x = 0;
|
|
|
|
y = 0;
|
|
|
|
while (nlist--) {
|
|
|
|
x += list->xOff;
|
|
|
|
y += list->yOff;
|
|
|
|
n = list->len;
|
|
|
|
list++;
|
|
|
|
while (n--) {
|
|
|
|
glyph = *glyphs++;
|
|
|
|
|
2006-04-26 03:32:55 +02:00
|
|
|
if (glyph->info.width == 0 || glyph->info.height == 0) {
|
|
|
|
x += glyph->info.xOff;
|
|
|
|
y += glyph->info.yOff;
|
2006-04-26 01:56:17 +02:00
|
|
|
continue;
|
2006-04-26 03:32:55 +02:00
|
|
|
}
|
2006-04-26 01:56:17 +02:00
|
|
|
|
|
|
|
x1 = x - glyph->info.x;
|
|
|
|
if (x1 < MINSHORT)
|
|
|
|
x1 = MINSHORT;
|
|
|
|
y1 = y - glyph->info.y;
|
|
|
|
if (y1 < MINSHORT)
|
|
|
|
y1 = MINSHORT;
|
|
|
|
x2 = x1 + glyph->info.width;
|
|
|
|
if (x2 > MAXSHORT)
|
|
|
|
x2 = MAXSHORT;
|
|
|
|
y2 = y1 + glyph->info.height;
|
|
|
|
if (y2 > MAXSHORT)
|
|
|
|
y2 = MAXSHORT;
|
|
|
|
|
|
|
|
if (first) {
|
|
|
|
extents.x1 = x1;
|
|
|
|
extents.y1 = y1;
|
|
|
|
extents.x2 = x2;
|
|
|
|
extents.y2 = y2;
|
|
|
|
first = FALSE;
|
|
|
|
} else {
|
|
|
|
if (x1 < extents.x2 && x2 > extents.x1 &&
|
|
|
|
y1 < extents.y2 && y2 > extents.y1)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (x1 < extents.x1)
|
|
|
|
extents.x1 = x1;
|
|
|
|
if (x2 > extents.x2)
|
|
|
|
extents.x2 = x2;
|
|
|
|
if (y1 < extents.y1)
|
|
|
|
extents.y1 = y1;
|
|
|
|
if (y2 > extents.y2)
|
|
|
|
extents.y2 = y2;
|
|
|
|
}
|
|
|
|
x += glyph->info.xOff;
|
|
|
|
y += glyph->info.yOff;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
- 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
|
|
|
/* 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);
|
2006-04-27 04:15:19 +02:00
|
|
|
PixmapPtr pPixmap = 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
|
|
|
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;
|
|
|
|
int error;
|
|
|
|
BoxRec extents;
|
|
|
|
CARD32 component_alpha;
|
|
|
|
|
2006-04-26 01:56:17 +02:00
|
|
|
/* If we have a mask format but it's the same as all the glyphs and
|
|
|
|
* the glyphs don't intersect, we can avoid accumulating the glyphs in the
|
|
|
|
* temporary picture.
|
|
|
|
*/
|
|
|
|
if (maskFormat != NULL) {
|
|
|
|
Bool sameFormat = TRUE;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < nlist; i++) {
|
|
|
|
if (maskFormat->format != list[i].format->format) {
|
|
|
|
sameFormat = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (sameFormat) {
|
|
|
|
if (!exaGlyphsIntersect(nlist, list, glyphs)) {
|
|
|
|
maskFormat = 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
|
|
|
/* If the driver doesn't support accelerated composite, there's no point in
|
2006-04-26 20:27:40 +02:00
|
|
|
* going to this extra work. Assume that any driver that supports Composite
|
|
|
|
* will be able to support component alpha using the two-pass 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
|
|
|
*/
|
2006-04-26 20:27:40 +02:00
|
|
|
if (!pExaScr->info->PrepareComposite)
|
2006-04-26 01:56:17 +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
|
|
|
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;
|
|
|
|
}
|
2006-04-27 04:15:19 +02:00
|
|
|
ValidatePicture(pMask);
|
- 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
|
|
|
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--)
|
|
|
|
{
|
2006-04-27 04:15:19 +02:00
|
|
|
GCPtr pGC = 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
|
|
|
int maxwidth = 0, maxheight = 0, i;
|
2006-03-14 22:30:12 +01:00
|
|
|
ExaMigrationRec pixmaps[1];
|
2006-04-27 04:15:19 +02:00
|
|
|
PixmapPtr pScratchPixmap = 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
|
|
|
|
|
|
|
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--)
|
|
|
|
{
|
2006-04-27 04:15:19 +02:00
|
|
|
GlyphPtr glyph;
|
|
|
|
|
2005-09-22 00:26:07 +02:00
|
|
|
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
|
|
|
|
|
|
|
/* Create the (real) temporary pixmap to store the current glyph in */
|
|
|
|
pPixmap = (*pScreen->CreatePixmap) (pScreen, maxwidth, maxheight,
|
|
|
|
list->format->depth);
|
2006-04-27 04:15:19 +02:00
|
|
|
if (!pPixmap)
|
- 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
|
|
|
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);
|
|
|
|
return;
|
|
|
|
}
|
2006-04-27 04:15:19 +02:00
|
|
|
ValidatePicture(pPicture);
|
- 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
|
|
|
|
|
|
|
/* Give the temporary pixmap an initial kick towards the screen, so
|
|
|
|
* it'll stick there.
|
|
|
|
*/
|
2006-03-14 22:30:12 +01:00
|
|
|
pixmaps[0].as_dst = TRUE;
|
|
|
|
pixmaps[0].as_src = TRUE;
|
|
|
|
pixmaps[0].pPix = pPixmap;
|
|
|
|
exaDoMigration (pixmaps, 1, TRUE);
|
- 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
|
|
|
|
|
|
|
while (n--)
|
|
|
|
{
|
2006-04-27 04:15:19 +02:00
|
|
|
GlyphPtr glyph = *glyphs++;
|
|
|
|
pointer glyphdata = (pointer) (glyph + 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
|
|
|
|
|
|
|
(*pScreen->ModifyPixmapHeader) (pScratchPixmap,
|
2005-09-18 04:32:23 +02:00
|
|
|
glyph->info.width,
|
|
|
|
glyph->info.height,
|
2006-04-27 04:15:19 +02:00
|
|
|
0, 0, -1, glyphdata);
|
- 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
|
|
|
|
|
|
|
/* 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
|
|
|
*/
|
2006-03-09 07:04:07 +01:00
|
|
|
if (!pExaScr->info->UploadToScreen ||
|
2005-09-18 04:32:23 +02:00
|
|
|
!exaPixmapIsOffscreen(pPixmap) ||
|
2006-03-09 07:04:07 +01:00
|
|
|
!(*pExaScr->info->UploadToScreen) (pPixmap, 0, 0,
|
2005-09-18 04:32:23 +02:00
|
|
|
glyph->info.width,
|
|
|
|
glyph->info.height,
|
2006-04-27 04:15:19 +02:00
|
|
|
glyphdata,
|
|
|
|
PixmapBytePad(glyph->info.width,
|
|
|
|
list->format->depth)))
|
2005-09-18 04:32:23 +02:00
|
|
|
{
|
2006-04-27 04:15:19 +02:00
|
|
|
/* Set up the scratch pixmap/GC for doing a CopyArea. */
|
|
|
|
if (pScratchPixmap == NULL) {
|
|
|
|
/* Get a scratch pixmap to wrap the original glyph data */
|
|
|
|
pScratchPixmap = GetScratchPixmapHeader (pScreen,
|
|
|
|
glyph->info.width,
|
|
|
|
glyph->info.height,
|
|
|
|
list->format->depth,
|
|
|
|
list->format->depth,
|
|
|
|
-1, glyphdata);
|
|
|
|
if (!pScratchPixmap) {
|
|
|
|
FreePicture(pPicture, 0);
|
|
|
|
(*pScreen->DestroyPixmap) (pPixmap);
|
|
|
|
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);
|
|
|
|
} else {
|
|
|
|
(*pScreen->ModifyPixmapHeader) (pScratchPixmap,
|
|
|
|
glyph->info.width,
|
|
|
|
glyph->info.height,
|
|
|
|
0, 0, -1, glyphdata);
|
|
|
|
pScratchPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
|
|
|
}
|
|
|
|
|
2005-09-18 04:32:23 +02:00
|
|
|
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)
|
|
|
|
{
|
2006-04-27 04:15:19 +02:00
|
|
|
exaComposite (PictOpAdd, pPicture, NULL, pMask, 0, 0, 0, 0,
|
|
|
|
x - glyph->info.x, y - glyph->info.y,
|
|
|
|
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
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-04-27 04:15:19 +02:00
|
|
|
exaComposite (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);
|
- 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
|
|
|
}
|
|
|
|
x += glyph->info.xOff;
|
|
|
|
y += glyph->info.yOff;
|
|
|
|
}
|
|
|
|
list++;
|
2006-04-27 04:15:19 +02:00
|
|
|
if (pGC != NULL)
|
|
|
|
FreeScratchGC (pGC);
|
- 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
|
|
|
FreePicture ((pointer) pPicture, 0);
|
|
|
|
(*pScreen->DestroyPixmap) (pPixmap);
|
2006-04-27 04:15:19 +02:00
|
|
|
if (pScratchPixmap != NULL)
|
|
|
|
FreeScratchPixmapHeader (pScratchPixmap);
|
- 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)
|
|
|
|
{
|
|
|
|
x = extents.x1;
|
|
|
|
y = extents.y1;
|
2006-04-27 04:15:19 +02:00
|
|
|
exaComposite (op, pSrc, pMask, pDst, xSrc + x - xDst, ySrc + y - yDst,
|
|
|
|
0, 0, x, y, width, 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
|
|
|
FreePicture ((pointer) pMask, (XID) 0);
|
|
|
|
(*pScreen->DestroyPixmap) (pMaskPixmap);
|
|
|
|
}
|
|
|
|
}
|