i830: if pixman_blt() fails fallback to fbCopyArea()

On older versions of pixman, pixman_blt() can return false if the images
are <= 8bpp. If we are being called from CopyArea, then we cannot return
FALSE here as that will trigger an infinite recursion. Instead we must
manually perform the fallback using fbCopyArea().

Reported-by: Peter Clifton <pcjc2@cam.ac.uk>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2010-04-26 09:07:07 +01:00
parent 86d349aa7b
commit 9a5cd65b59
1 changed files with 38 additions and 9 deletions

View File

@ -825,6 +825,8 @@ static Bool i830_uxa_put_image(PixmapPtr pixmap,
(*screen->DestroyPixmap)(scratch);
} else {
int dst_pitch;
/* bo is not busy so can be mapped without a stall, upload in-place. */
if (drm_intel_gem_bo_map_gtt(priv->bo)) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@ -832,17 +834,44 @@ static Bool i830_uxa_put_image(PixmapPtr pixmap,
return FALSE;
}
pixman_blt((uint32_t *)src, priv->bo->virtual,
src_pitch / sizeof(uint32_t),
pixmap->devKind / sizeof(uint32_t),
pixmap->drawable.bitsPerPixel,
pixmap->drawable.bitsPerPixel,
0, 0,
x, y,
w, h);
ret = TRUE;
/* Older version of pixman did not allow blt for <= 8bpp
* images, so if the blt fails fallback to using the fb.
*/
dst_pitch = i830_pixmap_pitch (pixmap);
if (! pixman_blt((uint32_t *)src,
priv->bo->virtual,
src_pitch / sizeof(uint32_t),
dst_pitch / sizeof(uint32_t),
pixmap->drawable.bitsPerPixel,
pixmap->drawable.bitsPerPixel,
0, 0,
x, y,
w, h))
{
ret = FALSE;
scratch = GetScratchPixmapHeader(screen,
w, h,
pixmap->drawable.depth,
pixmap->drawable.bitsPerPixel,
src_pitch,
(pointer) src);
if (scratch) {
gc = GetScratchGC(pixmap->drawable.depth, screen);
if (gc) {
ret = !! fbCopyArea(&scratch->drawable, &pixmap->drawable, gc,
0, 0,
w, h,
x, y);
FreeScratchGC(gc);
}
FreeScratchPixmapHeader(scratch);
}
}
drm_intel_gem_bo_unmap_gtt(priv->bo);
ret = TRUE;
}
return ret;