summaryrefslogtreecommitdiff
path: root/src/sna/gen2_render.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sna/gen2_render.c')
-rw-r--r--src/sna/gen2_render.c75
1 files changed, 50 insertions, 25 deletions
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 57bb835a..597d5f3d 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -1512,16 +1512,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)
+ return false;
+
+ if (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_unhandled_gradient(p) ||
- !gen2_check_filter(p) ||
- !gen2_check_repeat(p) ||
- need_upload(p));
+ if (is_unhandled_gradient(p) || !gen2_check_repeat(p))
+ return true;
+
+ if (pixmap && source_is_busy(pixmap))
+ return false;
+
+ return has_alphamap(p) || !gen2_check_filter(p) || need_upload(p);
}
static bool
@@ -1534,6 +1555,7 @@ gen2_composite_fallback(struct sna *sna,
PixmapPtr src_pixmap;
PixmapPtr mask_pixmap;
PixmapPtr dst_pixmap;
+ bool src_fallback, mask_fallback;
if (!gen2_check_dst_format(dst->format)) {
DBG(("%s: unknown destination format: %d\n",
@@ -1542,18 +1564,27 @@ gen2_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 = NULL;
+ }
/* 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;
}
@@ -1566,34 +1597,28 @@ gen2_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;