diff options
Diffstat (limited to 'src/sna/sna_present.c')
-rw-r--r-- | src/sna/sna_present.c | 53 |
1 files changed, 45 insertions, 8 deletions
diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c index c96bcd2e..6efe429f 100644 --- a/src/sna/sna_present.c +++ b/src/sna/sna_present.c @@ -539,6 +539,42 @@ get_flip_bo(PixmapPtr pixmap) return NULL; } + if (priv->gpu_bo->scanout) + return priv->gpu_bo; + + if (sna->kgem.has_llc && !wedged(sna)) { + struct kgem_bo *bo; + uint32_t tiling; + + tiling = I915_TILING_NONE; + if ((sna->flags & SNA_LINEAR_FB) == 0) + tiling = I915_TILING_X; + + bo = kgem_create_2d(&sna->kgem, + pixmap->drawable.width, + pixmap->drawable.height, + pixmap->drawable.bitsPerPixel, + tiling, CREATE_SCANOUT | CREATE_CACHED); + if (bo) { + BoxRec box; + + box.x1 = box.y1 = 0; + box.x2 = pixmap->drawable.width; + box.y2 = pixmap->drawable.height; + + if (sna->render.copy_boxes(sna, GXcopy, + &pixmap->drawable, priv->gpu_bo, 0, 0, + &pixmap->drawable, bo, 0, 0, + &box, 1, 0)) { + sna_pixmap_unmap(pixmap, priv); + kgem_bo_destroy(&sna->kgem, priv->gpu_bo); + + priv->gpu_bo = bo; + } else + kgem_bo_destroy(&sna->kgem, bo); + } + } + if (sna->flags & SNA_LINEAR_FB && priv->gpu_bo->tiling && !sna_pixmap_change_tiling(pixmap, I915_TILING_NONE)) { @@ -552,7 +588,6 @@ get_flip_bo(PixmapPtr pixmap) return NULL; } - priv->pinned |= PIN_SCANOUT; return priv->gpu_bo; } @@ -580,19 +615,19 @@ sna_present_flip(RRCrtcPtr crtc, assert(sna->present.unflip == 0); - bo = get_flip_bo(pixmap); - if (bo == NULL) { - DBG(("%s: flip invalid bo\n", __FUNCTION__)); - return FALSE; - } - if (sna->flags & SNA_TEAR_FREE) sna->mode.shadow_enabled = false; assert(!sna->mode.shadow_enabled); if (sna->mode.flip_active) { DBG(("%s: flips still pending\n", __FUNCTION__)); - return false; + return FALSE; + } + + bo = get_flip_bo(pixmap); + if (bo == NULL) { + DBG(("%s: flip invalid bo\n", __FUNCTION__)); + return FALSE; } if (sync_flip) @@ -641,6 +676,8 @@ reset_mode: goto notify; } + assert(sna_pixmap(screen->GetScreenPixmap(screen))->pinned & PIN_SCANOUT); + if (sna->flags & SNA_HAS_ASYNC_FLIP) { DBG(("%s: trying async flip restore\n", __FUNCTION__)); if (flip__async(sna, NULL, event_id, 0, bo)) |