diff options
-rw-r--r-- | src/sna/sna.h | 1 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 30 | ||||
-rw-r--r-- | src/sna/sna_composite.c | 7 |
3 files changed, 24 insertions, 14 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h index aed3e08b..ee3f821d 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -507,6 +507,7 @@ struct kgem_bo *sna_pixmap_change_tiling(PixmapPtr pixmap, uint32_t tiling); #define FORCE_GPU 0x2 #define RENDER_GPU 0x4 #define IGNORE_CPU 0x8 +#define REPLACES 0x10 struct kgem_bo * sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box, struct sna_damage ***damage); diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 2c785704..6ed9e770 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -2946,6 +2946,8 @@ sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box, box->x1, box->y1, box->x2, box->y2, flags)); + assert((hint & REPLACES) == 0 || (hint & IGNORE_CPU)); + assert(box->x2 > box->x1 && box->y2 > box->y1); assert(pixmap->refcnt); assert_pixmap_damage(pixmap); @@ -3001,7 +3003,7 @@ sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box, __FUNCTION__, priv->flush, priv->shm, priv->cpu, flags)); if ((flags & PREFER_GPU) == 0 && - (!priv->gpu_damage || !kgem_bo_is_busy(priv->gpu_bo))) { + (flags & REPLACES || !priv->gpu_damage || !kgem_bo_is_busy(priv->gpu_bo))) { DBG(("%s: try cpu as GPU bo is idle\n", __FUNCTION__)); goto use_cpu_bo; } @@ -12179,18 +12181,20 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect) } hint |= IGNORE_CPU; } - if (priv->cpu_damage == NULL && - (region_subsumes_drawable(®ion, &pixmap->drawable) || - box_inplace(pixmap, ®ion.extents))) { - DBG(("%s: promoting to full GPU\n", __FUNCTION__)); - if (priv->gpu_bo) { - assert(priv->gpu_bo->proxy == NULL); - sna_damage_all(&priv->gpu_damage, - pixmap->drawable.width, - pixmap->drawable.height); - } - } + if (region_subsumes_drawable(®ion, &pixmap->drawable)) + hint |= REPLACES; if (priv->cpu_damage == NULL) { + if (hint & REPLACES && + box_inplace(pixmap, ®ion.extents)) { + DBG(("%s: promoting to full GPU\n", + __FUNCTION__)); + if (priv->gpu_bo) { + assert(priv->gpu_bo->proxy == NULL); + sna_damage_all(&priv->gpu_damage, + pixmap->drawable.width, + pixmap->drawable.height); + } + } DBG(("%s: dropping last-cpu hint\n", __FUNCTION__)); priv->cpu = false; } @@ -12209,6 +12213,8 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect) DBG(("%s: not using GPU, hint=%x\n", __FUNCTION__, hint)); goto fallback; } + if (hint & REPLACES) + kgem_bo_undo(&sna->kgem, bo); if (gc_is_solid(gc, &color)) { DBG(("%s: solid fill [%08x], testing for blt\n", diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c index ae63e683..17cc68c1 100644 --- a/src/sna/sna_composite.c +++ b/src/sna/sna_composite.c @@ -933,8 +933,9 @@ sna_composite_rectangles(CARD8 op, sna_damage_destroy(&priv->cpu_damage); list_del(&priv->flush_list); } - if (region_subsumes_drawable(®ion, &pixmap->drawable) || - box_inplace(pixmap, ®ion.extents)) { + if (region_subsumes_drawable(®ion, &pixmap->drawable)) + hint |= REPLACES; + if (hint & REPLACES || box_inplace(pixmap, ®ion.extents)) { DBG(("%s: promoting to full GPU\n", __FUNCTION__)); if (priv->gpu_bo && priv->cpu_damage == NULL) { assert(priv->gpu_bo->proxy == NULL); @@ -958,6 +959,8 @@ sna_composite_rectangles(CARD8 op, DBG(("%s: fallback due to no GPU bo\n", __FUNCTION__)); goto fallback; } + if (hint & REPLACES) + kgem_bo_undo(&sna->kgem, bo); if (!sna->render.fill_boxes(sna, op, dst->format, color, pixmap, bo, boxes, num_boxes)) { |