summaryrefslogtreecommitdiff
path: root/src/sna/gen4_render.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sna/gen4_render.c')
-rw-r--r--src/sna/gen4_render.c82
1 files changed, 52 insertions, 30 deletions
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index c3a82a33..02454b21 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -2122,11 +2122,8 @@ try_blt(struct sna *sna,
}
static bool
-is_gradient(PicturePtr picture)
+check_gradient(PicturePtr picture)
{
- if (picture->pDrawable)
- return FALSE;
-
switch (picture->pSourcePict->type) {
case SourcePictTypeSolidFill:
case SourcePictTypeLinear:
@@ -2155,17 +2152,38 @@ 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;
+
+ 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) ||
- !gen4_check_filter(p) ||
- !gen4_check_repeat(p) ||
- !gen4_check_format(p->format) ||
- need_upload(p));
+ if (p->pSourcePict)
+ return check_gradient(p);
+
+ if (!gen4_check_repeat(p) || !gen4_check_format(p->format))
+ return true;
+
+ /* soft errors: perfer to upload/compute rather than readback */
+ if (pixmap && source_is_busy(pixmap))
+ return false;
+
+ return has_alphamap(p) || !gen4_check_filter(p) || need_upload(p);
}
static bool
@@ -2178,6 +2196,7 @@ gen4_composite_fallback(struct sna *sna,
PixmapPtr src_pixmap;
PixmapPtr mask_pixmap;
PixmapPtr dst_pixmap;
+ bool src_fallback, mask_fallback;
if (!gen4_check_dst_format(dst->format)) {
DBG(("%s: unknown destination format: %d\n",
@@ -2186,18 +2205,27 @@ gen4_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;
}
@@ -2210,34 +2238,28 @@ gen4_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_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 && !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;