}
if (use_cpu(pixmap, priv, op, width, height) &&
- !picture_is_gpu(sna, src) && !picture_is_gpu(sna, mask)) {
+ !picture_is_gpu(sna, src, PREFER_GPU_RENDER) &&
+ !picture_is_gpu(sna, mask, PREFER_GPU_RENDER)) {
DBG(("%s: fallback, dst pixmap=%ld is too small (or completely damaged)\n",
__FUNCTION__, pixmap->drawable.serialNumber));
goto fallback;
}
if ((too_small(priv) || DAMAGE_IS_ALL(priv->cpu_damage)) &&
- !picture_is_gpu(sna, src)) {
+ !picture_is_gpu(sna, src, 0)) {
DBG(("%s: fallback -- too small (%dx%d)\n",
__FUNCTION__, dst->pDrawable->width, dst->pDrawable->height));
goto fallback;
}
if ((too_small(priv) || DAMAGE_IS_ALL(priv->cpu_damage)) &&
- !picture_is_gpu(sna, src)) {
+ !picture_is_gpu(sna, src, 0)) {
DBG(("%s: fallback -- too small (%dx%d)\n",
__FUNCTION__, dst->pDrawable->width, dst->pDrawable->height));
goto fallback;
}
static inline bool
-picture_is_gpu(struct sna *sna, PicturePtr picture)
+picture_is_gpu(struct sna *sna, PicturePtr picture, unsigned flags)
{
- if (!picture || !picture->pDrawable)
+ if (!picture)
return false;
- return is_gpu(sna, picture->pDrawable, PREFER_GPU_RENDER);
+
+ if (!picture->pDrawable) {
+ switch (flags) {
+ case PREFER_GPU_RENDER:
+ switch (picture->pSourcePict->type) {
+ case SourcePictTypeSolidFill:
+ case SourcePictTypeLinear:
+ return false;
+ default:
+ return true;
+ }
+ case PREFER_GPU_SPANS:
+ return true;
+ default:
+ return false;
+ }
+ } else {
+ if (picture->repeat &&
+ (picture->pDrawable->width | picture->pDrawable->height) == 1)
+ return flags == PREFER_GPU_SPANS;
+ }
+
+ return is_gpu(sna, picture->pDrawable, flags);
}
static inline bool
DBG(("%s: mask (%dx%d) depth=%d, format=%08x\n",
__FUNCTION__, width, height, depth, format));
if (is_gpu(sna, dst->pDrawable, PREFER_GPU_RENDER) ||
- picture_is_gpu(sna, src)) {
+ picture_is_gpu(sna, src, PREFER_GPU_RENDER)) {
int num_threads;
scratch = sna_pixmap_create_upload(screen,
case PICT_x8r8g8b8:
case PICT_a8r8g8b8:
- if (picture_is_gpu(sna, src))
+ if (picture_is_gpu(sna, src, 0))
return false;
switch (op) {
if (FORCE_FALLBACK == 0 &&
(too_small(priv) || DAMAGE_IS_ALL(priv->cpu_damage)) &&
- !picture_is_gpu(sna, src) && untransformed(src)) {
+ !picture_is_gpu(sna, src, 0) && untransformed(src)) {
DBG(("%s: force fallbacks -- (too small, %dx%d? %d || all-cpu? %d) && (src-is-cpu? %d && untransformed? %d)\n",
__FUNCTION__, dst->pDrawable->width, dst->pDrawable->height,
too_small(priv), (int)DAMAGE_IS_ALL(priv->cpu_damage),
- !picture_is_gpu(sna, src), untransformed(src)));
+ !picture_is_gpu(sna, src, 0), untransformed(src)));
force_fallback:
force_fallback = true;
{
if (!force_fallback &&
(is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS) ||
- picture_is_gpu(sna, src))) {
+ picture_is_gpu(sna, src, PREFER_GPU_SPANS))) {
DBG(("%s: fallback -- not forcing\n", __FUNCTION__));
return false;
}