uxa: Rearrange checking and preparing of composite textures.

x11perf regression caused by 2D driver
  https://bugs.freedesktop.org/show_bug.cgi?id=28047

caused by

  commit a7b800513f
  uxa: Extract sub-region from in-memory buffers.

The issue is that as we extract the region prior to checking whether the
composite can in fact be accelerated, we perform expensive surplus
operations. This is particularly noticeable for ComponentAlpha text,
such as rgb10text. The solution here is to rearrange the
check_composite() prior to acquiring the sources, and only extracting
the subregion if the render path can not actually handle the texture.

Performance (on PineView):
a7b800513^: aa=68600 glyphs/s, rgb=29900 glyphs/s
a7b800513: aa=65700 glyphs/s, rgb=13200 glyphs/s
now: aa=66800 glyph/s, rgb=28800 glyphs/s

The residual lossage seems to be from the extra function call and
dixPrivate lookups. Hmm. More warning is the extremely low performance,
however the results are consistent so the improvement looks real...

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2010-05-10 09:39:44 +01:00
parent 848ab66384
commit f52b6e8322
7 changed files with 283 additions and 274 deletions

View File

@ -447,8 +447,9 @@ void i830_set_gem_max_sizes(ScrnInfoPtr scrn);
drm_intel_bo *i830_allocate_framebuffer(ScrnInfoPtr scrn);
/* i830_render.c */
Bool i830_check_composite(int op, PicturePtr sourcec, PicturePtr mask,
Bool i830_check_composite(int op, PicturePtr source, PicturePtr mask,
PicturePtr dest);
Bool i830_check_composite_texture(ScreenPtr screen, PicturePtr picture);
Bool i830_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask,
PicturePtr dest, PixmapPtr sourcecPixmap,
PixmapPtr maskPixmap, PixmapPtr destPixmap);
@ -460,6 +461,7 @@ void i830_done_composite(PixmapPtr dest);
/* i915_render.c */
Bool i915_check_composite(int op, PicturePtr sourcec, PicturePtr mask,
PicturePtr dest);
Bool i915_check_composite_texture(ScreenPtr screen, PicturePtr picture);
Bool i915_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask,
PicturePtr dest, PixmapPtr sourcecPixmap,
PixmapPtr maskPixmap, PixmapPtr destPixmap);
@ -473,6 +475,7 @@ void gen4_render_state_init(ScrnInfoPtr scrn);
void gen4_render_state_cleanup(ScrnInfoPtr scrn);
Bool i965_check_composite(int op, PicturePtr sourcec, PicturePtr mask,
PicturePtr dest);
Bool i965_check_composite_texture(ScreenPtr screen, PicturePtr picture);
Bool i965_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask,
PicturePtr dest, PixmapPtr sourcecPixmap,
PixmapPtr maskPixmap, PixmapPtr destPixmap);

View File

@ -221,52 +221,6 @@ static Bool i830_get_blend_cntl(ScrnInfoPtr scrn, int op, PicturePtr mask,
return TRUE;
}
static Bool i830_check_composite_texture(ScrnInfoPtr scrn, PicturePtr picture,
int unit)
{
if (picture->repeatType > RepeatReflect) {
intel_debug_fallback(scrn, "Unsupported picture repeat %d\n",
picture->repeatType);
return FALSE;
}
if (picture->filter != PictFilterNearest &&
picture->filter != PictFilterBilinear) {
intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
picture->filter);
return FALSE;
}
if (picture->pDrawable) {
int w, h, i;
w = picture->pDrawable->width;
h = picture->pDrawable->height;
if ((w > 2048) || (h > 2048)) {
intel_debug_fallback(scrn,
"Picture w/h too large (%dx%d)\n",
w, h);
return FALSE;
}
for (i = 0;
i < sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]);
i++) {
if (i830_tex_formats[i].fmt == picture->format)
break;
}
if (i == sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]))
{
intel_debug_fallback(scrn, "Unsupported picture format "
"0x%x\n",
(int)picture->format);
return FALSE;
}
}
return TRUE;
}
static uint32_t i8xx_get_card_format(PicturePtr picture)
{
int i;
@ -413,16 +367,6 @@ i830_check_composite(int op, PicturePtr source_picture, PicturePtr mask_picture,
}
}
if (!i830_check_composite_texture(scrn, source_picture, 0)) {
intel_debug_fallback(scrn, "Check Src picture texture\n");
return FALSE;
}
if (mask_picture != NULL
&& !i830_check_composite_texture(scrn, mask_picture, 1)) {
intel_debug_fallback(scrn, "Check Mask picture texture\n");
return FALSE;
}
if (!i830_get_dest_format(dest_picture, &tmp1)) {
intel_debug_fallback(scrn, "Get Color buffer format\n");
return FALSE;
@ -431,6 +375,58 @@ i830_check_composite(int op, PicturePtr source_picture, PicturePtr mask_picture,
return TRUE;
}
Bool
i830_check_composite_texture(ScreenPtr screen, PicturePtr picture)
{
if (picture->repeatType > RepeatReflect) {
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
intel_debug_fallback(scrn, "Unsupported picture repeat %d\n",
picture->repeatType);
return FALSE;
}
if (picture->filter != PictFilterNearest &&
picture->filter != PictFilterBilinear) {
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
picture->filter);
return FALSE;
}
if (picture->pDrawable) {
int w, h, i;
w = picture->pDrawable->width;
h = picture->pDrawable->height;
if ((w > 2048) || (h > 2048)) {
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
intel_debug_fallback(scrn,
"Picture w/h too large (%dx%d)\n",
w, h);
return FALSE;
}
for (i = 0;
i < sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]);
i++) {
if (i830_tex_formats[i].fmt == picture->format)
break;
}
if (i == sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]))
{
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
intel_debug_fallback(scrn, "Unsupported picture format "
"0x%x\n",
(int)picture->format);
return FALSE;
}
return TRUE;
}
return FALSE;
}
Bool
i830_prepare_composite(int op, PicturePtr source_picture,
PicturePtr mask_picture, PicturePtr dest_picture,

View File

@ -1078,17 +1078,20 @@ Bool i830_uxa_init(ScreenPtr screen)
/* Composite */
if (!IS_I9XX(intel)) {
intel->uxa_driver->check_composite = i830_check_composite;
intel->uxa_driver->check_composite_texture = i830_check_composite_texture;
intel->uxa_driver->prepare_composite = i830_prepare_composite;
intel->uxa_driver->composite = i830_composite;
intel->uxa_driver->done_composite = i830_done_composite;
} else if (IS_I915G(intel) || IS_I915GM(intel) ||
IS_I945G(intel) || IS_I945GM(intel) || IS_G33CLASS(intel)) {
intel->uxa_driver->check_composite = i915_check_composite;
intel->uxa_driver->check_composite_texture = i915_check_composite_texture;
intel->uxa_driver->prepare_composite = i915_prepare_composite;
intel->uxa_driver->composite = i915_composite;
intel->uxa_driver->done_composite = i830_done_composite;
} else {
intel->uxa_driver->check_composite = i965_check_composite;
intel->uxa_driver->check_composite_texture = i965_check_composite_texture;
intel->uxa_driver->prepare_composite = i965_prepare_composite;
intel->uxa_driver->composite = i965_composite;
intel->uxa_driver->done_composite = i830_done_composite;

View File

@ -176,54 +176,10 @@ static Bool i915_get_dest_format(PicturePtr dest_picture, uint32_t * dst_format)
return TRUE;
}
static Bool i915_check_composite_texture(ScrnInfoPtr scrn, PicturePtr picture,
int unit)
{
if (picture->repeatType > RepeatReflect) {
intel_debug_fallback(scrn, "Unsupported picture repeat %d\n",
picture->repeatType);
return FALSE;
}
if (picture->filter != PictFilterNearest &&
picture->filter != PictFilterBilinear) {
intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
picture->filter);
return FALSE;
}
if (picture->pDrawable) {
int w, h, i;
w = picture->pDrawable->width;
h = picture->pDrawable->height;
if ((w > 2048) || (h > 2048)) {
intel_debug_fallback(scrn,
"Picture w/h too large (%dx%d)\n",
w, h);
return FALSE;
}
for (i = 0;
i < sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]);
i++) {
if (i915_tex_formats[i].fmt == picture->format)
break;
}
if (i == sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]))
{
intel_debug_fallback(scrn, "Unsupported picture format "
"0x%x\n",
(int)picture->format);
return FALSE;
}
}
return TRUE;
}
Bool
i915_check_composite(int op, PicturePtr source_picture, PicturePtr mask_picture,
i915_check_composite(int op,
PicturePtr source_picture,
PicturePtr mask_picture,
PicturePtr dest_picture)
{
ScrnInfoPtr scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum];
@ -251,16 +207,6 @@ i915_check_composite(int op, PicturePtr source_picture, PicturePtr mask_picture,
}
}
if (!i915_check_composite_texture(scrn, source_picture, 0)) {
intel_debug_fallback(scrn, "Check Src picture texture\n");
return FALSE;
}
if (mask_picture != NULL
&& !i915_check_composite_texture(scrn, mask_picture, 1)) {
intel_debug_fallback(scrn, "Check Mask picture texture\n");
return FALSE;
}
if (!i915_get_dest_format(dest_picture, &tmp1)) {
intel_debug_fallback(scrn, "Get Color buffer format\n");
return FALSE;
@ -269,6 +215,64 @@ i915_check_composite(int op, PicturePtr source_picture, PicturePtr mask_picture,
return TRUE;
}
Bool
i915_check_composite_texture(ScreenPtr screen, PicturePtr picture)
{
if (picture->repeatType > RepeatReflect) {
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
intel_debug_fallback(scrn, "Unsupported picture repeat %d\n",
picture->repeatType);
return FALSE;
}
if (picture->filter != PictFilterNearest &&
picture->filter != PictFilterBilinear) {
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
picture->filter);
return FALSE;
}
if (picture->pSourcePict) {
SourcePict *source = picture->pSourcePict;
if (source->type == SourcePictTypeSolidFill)
return TRUE;
}
if (picture->pDrawable) {
int w, h, i;
w = picture->pDrawable->width;
h = picture->pDrawable->height;
if ((w > 2048) || (h > 2048)) {
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
intel_debug_fallback(scrn,
"Picture w/h too large (%dx%d)\n",
w, h);
return FALSE;
}
for (i = 0;
i < sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]);
i++) {
if (i915_tex_formats[i].fmt == picture->format)
break;
}
if (i == sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]))
{
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
intel_debug_fallback(scrn, "Unsupported picture format "
"0x%x\n",
(int)picture->format);
return FALSE;
}
return TRUE;
}
return FALSE;
}
static Bool i915_texture_setup(PicturePtr picture, PixmapPtr pixmap, int unit)
{
ScrnInfoPtr scrn = xf86Screens[picture->pDrawable->pScreen->myNum];
@ -382,39 +386,53 @@ i915_prepare_composite(int op, PicturePtr source_picture,
intel->render_dest_picture = dest_picture;
intel->render_dest = dest;
intel->render_source_is_solid =
source_picture->pDrawable &&
source_picture->pDrawable->width == 1 &&
source_picture->pDrawable->height == 1 &&
source_picture->repeat;
intel->render_source_is_solid = FALSE;
if (source_picture->pSourcePict) {
SourcePict *source = source_picture->pSourcePict;
if (source->type == SourcePictTypeSolidFill) {
intel->render_source_is_solid = TRUE;
intel->render_source_solid = source->solidFill.color;
}
} else if (source_picture->pDrawable) {
intel->render_source_is_solid =
source_picture->pDrawable->width == 1 &&
source_picture->pDrawable->height == 1 &&
source_picture->repeat;
if (intel->render_source_is_solid) {
if (! uxa_get_color_for_pixmap (source,
source_picture->format,
PICT_a8r8g8b8,
&intel->render_source_solid))
intel->render_source_is_solid = FALSE;
if (intel->render_source_is_solid) {
if (! uxa_get_color_for_pixmap (source,
source_picture->format,
PICT_a8r8g8b8,
&intel->render_source_solid))
intel->render_source_is_solid = FALSE;
}
}
if (!intel->render_source_is_solid && !intel_check_pitch_3d(source))
return FALSE;
intel->render_mask_is_solid = TRUE; /* mask == NULL => opaque */
if (mask) {
intel->render_mask_is_solid =
mask_picture->pDrawable &&
mask_picture->pDrawable->width == 1 &&
mask_picture->pDrawable->height == 1 &&
mask_picture->repeat;
if (intel->render_mask_is_solid) {
if (! uxa_get_color_for_pixmap (mask,
mask_picture->format,
PICT_a8r8g8b8,
&intel->render_mask_solid))
intel->render_mask_is_solid = FALSE;
}
if (!intel->render_mask_is_solid && !intel_check_pitch_3d(mask))
return FALSE;
if (mask_picture->pSourcePict) {
SourcePict *source = mask_picture->pSourcePict;
if (source->type == SourcePictTypeSolidFill) {
intel->render_mask_is_solid = TRUE;
intel->render_mask_solid = source->solidFill.color;
}
} else if (mask_picture->pDrawable) {
intel->render_mask_is_solid =
mask_picture->pDrawable->width == 1 &&
mask_picture->pDrawable->height == 1 &&
mask_picture->repeat;
if (intel->render_mask_is_solid) {
if (! uxa_get_color_for_pixmap (mask,
mask_picture->format,
PICT_a8r8g8b8,
&intel->render_mask_solid))
intel->render_mask_is_solid = FALSE;
}
}
if (!intel->render_mask_is_solid && !intel_check_pitch_3d(mask))
return FALSE;
}
if (!intel_check_pitch_3d(dest))

View File

@ -183,54 +183,6 @@ static Bool i965_get_dest_format(PicturePtr dest_picture, uint32_t * dst_format)
return TRUE;
}
static Bool i965_check_composite_texture(ScrnInfoPtr scrn, PicturePtr picture,
int unit)
{
if (picture->repeatType > RepeatReflect) {
intel_debug_fallback(scrn,
"extended repeat (%d) not supported\n",
picture->repeatType);
return FALSE;
}
if (picture->filter != PictFilterNearest &&
picture->filter != PictFilterBilinear) {
intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
picture->filter);
return FALSE;
}
if (picture->pDrawable) {
int w, h, i;
w = picture->pDrawable->width;
h = picture->pDrawable->height;
if ((w > 8192) || (h > 8192)) {
intel_debug_fallback(scrn,
"Picture w/h too large (%dx%d)\n",
w, h);
return FALSE;
}
for (i = 0;
i < sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]);
i++) {
if (i965_tex_formats[i].fmt == picture->format)
break;
}
if (i == sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]))
{
intel_debug_fallback(scrn,
"Unsupported picture format "
"0x%x\n",
(int)picture->format);
return FALSE;
}
}
return TRUE;
}
Bool
i965_check_composite(int op, PicturePtr source_picture, PicturePtr mask_picture,
PicturePtr dest_picture)
@ -267,25 +219,69 @@ i965_check_composite(int op, PicturePtr source_picture, PicturePtr mask_picture,
}
}
if (!i965_check_composite_texture(scrn, source_picture, 0)) {
intel_debug_fallback(scrn, "Check Src picture texture\n");
return FALSE;
}
if (mask_picture != NULL
&& !i965_check_composite_texture(scrn, mask_picture, 1)) {
intel_debug_fallback(scrn, "Check Mask picture texture\n");
return FALSE;
}
if (!i965_get_dest_format(dest_picture, &tmp1)) {
intel_debug_fallback(scrn, "Get Color buffer format\n");
return FALSE;
}
return TRUE;
}
Bool
i965_check_composite_texture(ScreenPtr screen, PicturePtr picture)
{
if (picture->repeatType > RepeatReflect) {
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
intel_debug_fallback(scrn,
"extended repeat (%d) not supported\n",
picture->repeatType);
return FALSE;
}
if (picture->filter != PictFilterNearest &&
picture->filter != PictFilterBilinear) {
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
picture->filter);
return FALSE;
}
if (picture->pDrawable) {
int w, h, i;
w = picture->pDrawable->width;
h = picture->pDrawable->height;
if ((w > 8192) || (h > 8192)) {
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
intel_debug_fallback(scrn,
"Picture w/h too large (%dx%d)\n",
w, h);
return FALSE;
}
for (i = 0;
i < sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]);
i++) {
if (i965_tex_formats[i].fmt == picture->format)
break;
}
if (i == sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]))
{
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
intel_debug_fallback(scrn,
"Unsupported picture format "
"0x%x\n",
(int)picture->format);
return FALSE;
}
return TRUE;
}
return FALSE;
}
#define BRW_GRF_BLOCKS(nreg) ((nreg + 15) / 16 - 1)
/* Set up a default static partitioning of the URB, which is supposed to

View File

@ -642,8 +642,7 @@ uxa_acquire_drawable(ScreenPtr pScreen,
PicturePtr pSrc,
INT16 x, INT16 y,
CARD16 width, CARD16 height,
INT16 * out_x, INT16 * out_y,
Bool force)
INT16 * out_x, INT16 * out_y)
{
PixmapPtr pPixmap;
PicturePtr pDst;
@ -651,17 +650,17 @@ uxa_acquire_drawable(ScreenPtr pScreen,
int depth, error;
int tx, ty;
if (!force && uxa_drawable_is_offscreen(pSrc->pDrawable)) {
*out_x = x + pSrc->pDrawable->x;
*out_y = y + pSrc->pDrawable->y;
return pSrc;
}
depth = pSrc->pDrawable->depth;
if (depth == 1 || !transform_is_integer_translation(pSrc->transform, &tx, &ty)) {
/* XXX extract the sample extents and do the transformation on the GPU */
pDst = uxa_render_picture(pScreen, pSrc, x, y, width, height);
goto done;
} else {
if (width == pSrc->pDrawable->width && height == pSrc->pDrawable->depth) {
*out_x = x + pSrc->pDrawable->x;
*out_y = y + pSrc->pDrawable->y;
return pSrc;
}
}
pPixmap = pScreen->CreatePixmap(pScreen, width, height, depth, 0);
@ -671,9 +670,7 @@ uxa_acquire_drawable(ScreenPtr pScreen,
/* Skip the copy if the result remains in memory and not a bo */
if (!uxa_drawable_is_offscreen(&pPixmap->drawable)) {
pScreen->DestroyPixmap(pPixmap);
*out_x = x + pSrc->pDrawable->x;
*out_y = y + pSrc->pDrawable->y;
return pSrc;
return 0;
}
pGC = GetScratchGC(depth, pScreen);
@ -705,14 +702,21 @@ uxa_acquire_source(ScreenPtr pScreen,
PicturePtr pPict,
INT16 x, INT16 y,
CARD16 width, CARD16 height,
INT16 * out_x, INT16 * out_y,
Bool force)
INT16 * out_x, INT16 * out_y)
{
uxa_screen_t *uxa_screen = uxa_get_screen(pScreen);
if (uxa_screen->info->check_composite_texture &&
uxa_screen->info->check_composite_texture(pScreen, pPict)) {
*out_x = x + pPict->pDrawable->x;
*out_y = y + pPict->pDrawable->y;
return pPict;
}
if (pPict->pDrawable)
return uxa_acquire_drawable(pScreen, pPict,
x, y, width, height,
out_x, out_y,
force);
out_x, out_y);
*out_x = 0;
*out_y = 0;
@ -725,14 +729,21 @@ uxa_acquire_mask(ScreenPtr pScreen,
PicturePtr pPict,
INT16 x, INT16 y,
INT16 width, INT16 height,
INT16 * out_x, INT16 * out_y,
Bool force)
INT16 * out_x, INT16 * out_y)
{
uxa_screen_t *uxa_screen = uxa_get_screen(pScreen);
if (uxa_screen->info->check_composite_texture &&
uxa_screen->info->check_composite_texture(pScreen, pPict)) {
*out_x = x + pPict->pDrawable->x;
*out_y = y + pPict->pDrawable->y;
return pPict;
}
if (pPict->pDrawable)
return uxa_acquire_drawable(pScreen, pPict,
x, y, width, height,
out_x, out_y,
force);
out_x, out_y);
*out_x = 0;
*out_y = 0;
@ -872,12 +883,14 @@ uxa_try_driver_composite(CARD8 op,
RegionRec region;
BoxPtr pbox;
int nbox;
INT16 _xSrc = xSrc, _ySrc = ySrc;
INT16 _xMask = xMask, _yMask = yMask;
int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
PicturePtr localSrc, localMask = NULL;
if (uxa_screen->info->check_composite &&
!(*uxa_screen->info->check_composite) (op, pSrc, pMask, pDst))
return -1;
pDstPix =
uxa_get_offscreen_pixmap(pDst->pDrawable, &dst_off_x, &dst_off_y);
if (!pDstPix)
@ -886,18 +899,18 @@ uxa_try_driver_composite(CARD8 op,
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
localSrc = uxa_acquire_source(pDst->pDrawable->pScreen,
pSrc, xSrc, ySrc, width, height,
&xSrc, &ySrc,
FALSE);
localSrc = uxa_acquire_source(pDst->pDrawable->pScreen, pSrc,
xSrc, ySrc,
width, height,
&xSrc, &ySrc);
if (!localSrc)
return 0;
if (pMask) {
localMask = uxa_acquire_mask(pDst->pDrawable->pScreen,
pMask, xMask, yMask, width, height,
&xMask, &yMask,
FALSE);
localMask = uxa_acquire_mask(pDst->pDrawable->pScreen, pMask,
xMask, yMask,
width, height,
&xMask, &yMask);
if (!localMask) {
if (localSrc != pSrc)
FreePicture(localSrc, 0);
@ -906,45 +919,6 @@ uxa_try_driver_composite(CARD8 op,
}
}
recheck:
if (uxa_screen->info->check_composite &&
!(*uxa_screen->info->check_composite) (op, localSrc, localMask,
pDst)) {
if (localSrc == pSrc || (localMask && localMask == pMask)) {
if (localSrc == pSrc) {
localSrc = uxa_acquire_source(pDst->pDrawable->pScreen,
pSrc, _xSrc, _ySrc, width, height,
&xSrc, &ySrc, TRUE);
if (!localSrc || localSrc == pSrc) {
if (localMask && localMask != pMask)
FreePicture(localMask, 0);
return -(localSrc == pSrc);
}
}
if (localMask && localMask == pMask) {
localMask = uxa_acquire_mask(pDst->pDrawable->pScreen,
pMask, _xMask, _yMask, width, height,
&xMask, &yMask, TRUE);
if (!localMask || localMask == pMask) {
if (localSrc != pSrc)
FreePicture(localSrc, 0);
return -(localMask == pMask);
}
}
goto recheck;
}
if (localSrc != pSrc)
FreePicture(localSrc, 0);
if (localMask && localMask != pMask)
FreePicture(localMask, 0);
return -1;
}
if (!miComputeCompositeRegion(&region, localSrc, localMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height)) {
@ -1306,9 +1280,15 @@ uxa_composite(CARD8 op,
/* For generic masks and solid src pictures, mach64 can do
* Over in two passes, similar to the component-alpha case.
*/
isSrcSolid = pSrc->pDrawable &&
pSrc->pDrawable->width == 1 &&
pSrc->pDrawable->height == 1 && pSrc->repeat;
isSrcSolid =
pSrc->pDrawable ?
pSrc->pDrawable->width == 1 &&
pSrc->pDrawable->height == 1 &&
pSrc->repeat :
pSrc->pSourcePict ?
pSrc->pSourcePict->type == SourcePictTypeSolidFill :
0;
/* 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
@ -1320,13 +1300,13 @@ uxa_composite(CARD8 op,
uxa_try_magic_two_pass_composite_helper(op, pSrc,
pMask, pDst,
xSrc, ySrc,
xMask,
yMask, xDst,
yDst, width,
height);
xMask, yMask,
xDst, yDst,
width, height);
if (ret == 1)
goto done;
}
}
fallback:

View File

@ -251,6 +251,19 @@ typedef struct _UxaDriver {
PicturePtr pMaskPicture,
PicturePtr pDstPicture);
/**
* check_composite_texture() checks to see if a source to the composite
* operation can be used without midification.
*
* @param pScreen Screen
* @param pPicture Picture
*
* The check_composite_texture() call is recommended if prepare_composite() is
* implemented, but is not required.
*/
Bool(*check_composite_texture) (ScreenPtr pScreen,
PicturePtr pPicture);
/**
* prepare_composite() sets up the driver for doing a composite
* operation described in the Render extension protocol spec.