diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-03-07 15:52:41 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-03-08 00:58:38 +0000 |
commit | 49a80ce1ff336fb2fa7d214bd3fddbce5a62b77a (patch) | |
tree | 0222c7266af49f66177a2696dbd30de30873ce08 /src/sna/gen6_render.c | |
parent | 4899740f6f0f5b1a5b2b3490502ccdeb7b092877 (diff) |
sna/gen2+: Prefer not to fallback if the source is busy
As if we try to perform the operation with outstanding operations on the
source pixmaps, we will stall waiting for them to complete.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/gen6_render.c')
-rw-r--r-- | src/sna/gen6_render.c | 78 |
1 files changed, 51 insertions, 27 deletions
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c index 9eb4221e..390cb0a9 100644 --- a/src/sna/gen6_render.c +++ b/src/sna/gen6_render.c @@ -2374,7 +2374,7 @@ try_blt(struct sna *sna, } static bool -is_gradient(PicturePtr picture) +check_gradient(PicturePtr picture) { if (picture->pDrawable) return FALSE; @@ -2407,17 +2407,37 @@ need_upload(PicturePtr p) } static bool -source_fallback(PicturePtr p) +source_is_busy(PixmapPtr pixmap) +{ + struct sna_pixmap *priv = sna_pixmap(pixmap); + if (priv == NULL || priv->clear) + return false; + + if (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo)) + return true; + + if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) + return true; + + return priv->gpu_damage && !priv->cpu_damage; +} + +static bool +source_fallback(PicturePtr p, PixmapPtr pixmap) { if (sna_picture_is_solid(p, NULL)) return false; - return (has_alphamap(p) || - is_gradient(p) || - !gen6_check_filter(p) || - !gen6_check_repeat(p) || - !gen6_check_format(p->format) || - need_upload(p)); + if (p->pSourcePict) + return check_gradient(p); + + if (!gen6_check_repeat(p) || !gen6_check_format(p->format)) + return true; + + if (pixmap && source_is_busy(pixmap)) + return false; + + return has_alphamap(p) || !gen6_check_filter(p) || need_upload(p); } static bool @@ -2430,6 +2450,7 @@ gen6_composite_fallback(struct sna *sna, PixmapPtr src_pixmap; PixmapPtr mask_pixmap; PixmapPtr dst_pixmap; + bool src_fallback, mask_fallback; if (!gen6_check_dst_format(dst->format)) { DBG(("%s: unknown destination format: %d\n", @@ -2438,18 +2459,27 @@ gen6_composite_fallback(struct sna *sna, } dst_pixmap = get_drawable_pixmap(dst->pDrawable); + src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL; - mask_pixmap = (mask && mask->pDrawable) ? get_drawable_pixmap(mask->pDrawable) : NULL; + src_fallback = source_fallback(src, src_pixmap); + + if (mask) { + mask_pixmap = mask->pDrawable ? get_drawable_pixmap(mask->pDrawable) : NULL; + mask_fallback = source_fallback(mask, mask_pixmap); + } else { + mask_pixmap = NULL; + mask_fallback = false; + } /* If we are using the destination as a source and need to * readback in order to upload the source, do it all * on the cpu. */ - if (src_pixmap == dst_pixmap && source_fallback(src)) { + if (src_pixmap == dst_pixmap && src_fallback) { DBG(("%s: src is dst and will fallback\n",__FUNCTION__)); return TRUE; } - if (mask_pixmap == dst_pixmap && source_fallback(mask)) { + if (mask_pixmap == dst_pixmap && mask_fallback) { DBG(("%s: mask is dst and will fallback\n",__FUNCTION__)); return TRUE; } @@ -2464,34 +2494,28 @@ gen6_composite_fallback(struct sna *sna, return FALSE; } - if (src_pixmap && !source_fallback(src)) { - priv = sna_pixmap(src_pixmap); - if (priv && priv->gpu_damage && !priv->cpu_damage) { - DBG(("%s: src is already on the GPU, try to use GPU\n", - __FUNCTION__)); - return FALSE; - } + if (src_pixmap && !src_fallback) { + DBG(("%s: src is already on the GPU, try to use GPU\n", + __FUNCTION__)); + return FALSE; } - if (mask_pixmap && !source_fallback(mask)) { - priv = sna_pixmap(mask_pixmap); - if (priv && priv->gpu_damage && !priv->cpu_damage) { - DBG(("%s: mask is already on the GPU, try to use GPU\n", - __FUNCTION__)); - return FALSE; - } + if (mask_pixmap && !mask_fallback) { + DBG(("%s: mask is already on the GPU, try to use GPU\n", + __FUNCTION__)); + return FALSE; } /* However if the dst is not on the GPU and we need to * render one of the sources using the CPU, we may * as well do the entire operation in place onthe CPU. */ - if (source_fallback(src)) { + if (src_fallback) { DBG(("%s: dst is on the CPU and src will fallback\n", __FUNCTION__)); return TRUE; } - if (mask && source_fallback(mask)) { + if (mask && mask_fallback) { DBG(("%s: dst is on the CPU and mask will fallback\n", __FUNCTION__)); return TRUE; |