diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-05-07 15:20:32 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2016-05-07 15:20:32 +0100 |
commit | b89f203b0d65b607bc906b9a1ac184ebef7b41df (patch) | |
tree | 687c78ac055d471e2e57451f8c137fda36acf708 | |
parent | 47cd7fdd0b0fe004c77b1c7862161d8968af2cc2 (diff) |
sna: Do not force ping-pong migration for TearFree + NoAccel
If acceleration is disabled, but we are using TearFree, then ideally we
want to flip the shadow buffer onto the scanout. If the shadow buffer is
already on the GPU, e.g. having been swapped in by a compositor, then we
do not want to move it to the CPU domain only to copy it back to a new
buffer and then flipped for a TearFree update.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna_display.c | 115 |
1 files changed, 18 insertions, 97 deletions
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index 759659da..2c6059d2 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -210,8 +210,6 @@ struct sna_crtc { struct pict_f_transform cursor_to_fb, fb_to_cursor; - RegionRec client_damage; /* XXX overlap with shadow damage? */ - uint16_t shadow_bo_width, shadow_bo_height; uint32_t rotation; @@ -1665,12 +1663,13 @@ static bool wait_for_shadow(struct sna *sna, sna->mode.shadow_region.extents.y1, sna->mode.shadow_region.extents.x2, sna->mode.shadow_region.extents.y2)); - ret = sna->render.copy_boxes(sna, GXcopy, - &pixmap->drawable, priv->gpu_bo, 0, 0, - &pixmap->drawable, bo, 0, 0, - region_rects(&sna->mode.shadow_region), - region_num_rects(&sna->mode.shadow_region), - 0); + if (!sna->render.copy_boxes(sna, GXcopy, + &pixmap->drawable, priv->gpu_bo, 0, 0, + &pixmap->drawable, bo, 0, 0, + region_rects(&sna->mode.shadow_region), + region_num_rects(&sna->mode.shadow_region), + 0)) + ERR(("%s: copy failed\n", __FUNCTION__)); } if (priv->cow) @@ -2552,7 +2551,7 @@ out_shadow: return NULL; } - if (sna->mode.shadow == NULL && !wedged(sna)) { + if (sna->mode.shadow == NULL) { struct kgem_bo *shadow; DBG(("%s: creating TearFree shadow bo\n", __FUNCTION__)); @@ -2743,7 +2742,6 @@ sna_crtc_damage(xf86CrtcPtr crtc) __FUNCTION__, sna_crtc_id(crtc), region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); - to_sna_crtc(crtc)->client_damage = region; assert(sna->mode.shadow_damage && sna->mode.shadow_active); damage = DamageRegion(sna->mode.shadow_damage); @@ -8516,6 +8514,9 @@ static bool move_crtc_to_gpu(struct sna *sna) xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); int i; + if (sna->flags & SNA_TEAR_FREE) + return true; + for (i = 0; i < sna->mode.num_real_crtc; i++) { struct sna_crtc *crtc = to_sna_crtc(config->crtc[i]); @@ -8530,6 +8531,9 @@ static bool move_crtc_to_gpu(struct sna *sna) if (crtc->client_bo) continue; + if (crtc->shadow_bo) + continue; + DBG(("%s: CRTC %d [pipe=%d] requires frontbuffer\n", __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc))); return sna_pixmap_move_to_gpu(sna->front, @@ -8592,7 +8596,7 @@ void sna_mode_redisplay(struct sna *sna) return; } - if (wedged(sna) || !move_crtc_to_gpu(sna)) { + if (!move_crtc_to_gpu(sna)) { DBG(("%s: forcing scanout update using the CPU\n", __FUNCTION__)); if (!sna_pixmap_move_to_cpu(sna->front, MOVE_READ)) return; @@ -8613,97 +8617,14 @@ void sna_mode_redisplay(struct sna *sna) damage.data = NULL; RegionIntersect(&damage, &damage, region); if (!box_empty(&damage.extents)) { - struct kgem_bo *bo = NULL; - DBG(("%s: fallback intersects pipe=%d [(%d, %d), (%d, %d)]\n", __FUNCTION__, __sna_crtc_pipe(sna_crtc), damage.extents.x1, damage.extents.y1, damage.extents.x2, damage.extents.y2)); - if (sna->flags & SNA_TEAR_FREE) { - RegionRec new_damage; - - RegionNull(&new_damage); - RegionCopy(&new_damage, &damage); - - bo = sna_crtc->cache_bo; - if (bo == NULL) { - damage.extents = crtc->bounds; - damage.data = NULL; - bo = kgem_create_2d(&sna->kgem, - crtc->mode.HDisplay, - crtc->mode.VDisplay, - crtc->scrn->bitsPerPixel, - sna_crtc->bo->tiling, - CREATE_SCANOUT); - } else - RegionUnion(&damage, &damage, &sna_crtc->client_damage); - - DBG(("%s: TearFree fallback, shadow handle=%d, crtc handle=%d\n", __FUNCTION__, bo->handle, sna_crtc->bo->handle)); - - sna_crtc->client_damage = new_damage; - } - - if (bo == NULL) - bo = sna_crtc->bo; - sna_crtc_redisplay__fallback(crtc, &damage, bo); - - if (bo != sna_crtc->bo) { - struct drm_mode_crtc_page_flip arg; - - arg.crtc_id = __sna_crtc_id(sna_crtc); - arg.fb_id = get_fb(sna, bo, - crtc->mode.HDisplay, - crtc->mode.VDisplay); - - arg.user_data = (uintptr_t)sna_crtc; - arg.flags = DRM_MODE_PAGE_FLIP_EVENT; - arg.reserved = 0; - - if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) { - if (sna_crtc_flip(sna, sna_crtc, bo, 0, 0)) { - DBG(("%s: removing handle=%d [active_scanout=%d] from scanout, installing handle=%d [active_scanout=%d]\n", - __FUNCTION__, sna_crtc->bo->handle, sna_crtc->bo->active_scanout, - bo->handle, bo->active_scanout)); - assert(sna_crtc->bo->active_scanout); - assert(sna_crtc->bo->refcnt >= sna_crtc->bo->active_scanout); - sna_crtc->bo->active_scanout--; - kgem_bo_destroy(&sna->kgem, sna_crtc->bo); - - sna_crtc->bo = bo; - sna_crtc->bo->active_scanout++; - sna_crtc->cache_bo = NULL; - } else { - DBG(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n", - __FUNCTION__, arg.fb_id, i, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), errno)); - xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, - "Page flipping failed, disabling TearFree\n"); - sna->flags &= ~SNA_TEAR_FREE; - - damage.extents = crtc->bounds; - damage.data = NULL; - sna_crtc_redisplay__fallback(crtc, &damage, sna_crtc->bo); - - kgem_bo_destroy(&sna->kgem, bo); - sna_crtc->cache_bo = NULL; - } - } else { - sna->mode.flip_active++; - - assert(sna_crtc->flip_bo == NULL); - sna_crtc->flip_handler = shadow_flip_handler; - sna_crtc->flip_data = sna; - sna_crtc->flip_bo = bo; - sna_crtc->flip_bo->active_scanout++; - sna_crtc->flip_serial = sna_crtc->mode_serial; - sna_crtc->flip_pending = true; - - sna_crtc->cache_bo = kgem_bo_reference(sna_crtc->bo); - - DBG(("%s: recording flip on CRTC:%d handle=%d, active_scanout=%d, serial=%d\n", - __FUNCTION__, __sna_crtc_id(sna_crtc), sna_crtc->flip_bo->handle, sna_crtc->flip_bo->active_scanout, sna_crtc->flip_serial)); - } - } + sna_crtc_redisplay__fallback(crtc, + &damage, + sna_crtc->bo); } RegionUninit(&damage); |