summaryrefslogtreecommitdiff
path: root/present
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2015-02-08 09:47:41 +0000
committerAdam Jackson <ajax@redhat.com>2015-12-07 14:25:43 -0500
commit180b09912c0d2c4a43b5a08678bcad4b818924c7 (patch)
tree36761c28f3cb2c1987445064db89c4a35087a64f /present
parentb2d55338f6b8f43ebcb49994abad123a797248cf (diff)
present: When cancelling a pending synchronous flip, requeue it
The vblank event request for a synchronous flip is scheduled for the vblank before the target flip msc (so that the flip itself appears at the right frame). If we cancel that flip and so wish to schedule a copy instead, that copy needs to be postponed by a frame in order for it be performed at the requested time. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Diffstat (limited to 'present')
-rw-r--r--present/present.c16
-rw-r--r--present/present_priv.h1
2 files changed, 16 insertions, 1 deletions
diff --git a/present/present.c b/present/present.c
index 7af6bb7b8..c55a56e7c 100644
--- a/present/present.c
+++ b/present/present.c
@@ -549,8 +549,13 @@ present_check_flip_window (WindowPtr window)
/* Now check any queued vblanks */
xorg_list_for_each_entry(vblank, &window_priv->vblank, window_list) {
- if (vblank->queued && vblank->flip && !present_check_flip(vblank->crtc, window, vblank->pixmap, vblank->sync_flip, NULL, 0, 0))
+ if (vblank->queued && vblank->flip && !present_check_flip(vblank->crtc, window, vblank->pixmap, vblank->sync_flip, NULL, 0, 0)) {
vblank->flip = FALSE;
+ if (vblank->sync_flip) {
+ vblank->requeue = TRUE;
+ vblank->target_msc++;
+ }
+ }
}
}
@@ -584,6 +589,15 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
uint8_t mode;
+ if (vblank->requeue) {
+ vblank->requeue = FALSE;
+ if (Success == present_queue_vblank(screen,
+ vblank->crtc,
+ vblank->event_id,
+ vblank->target_msc))
+ return;
+ }
+
if (vblank->wait_fence) {
if (!present_fence_check_triggered(vblank->wait_fence)) {
present_fence_set_callback(vblank->wait_fence, present_wait_fence_triggered, vblank);
diff --git a/present/present_priv.h b/present/present_priv.h
index d007fdb24..0d16cfaba 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -70,6 +70,7 @@ struct present_vblank {
present_notify_ptr notifies;
int num_notifies;
Bool queued; /* on present_exec_queue */
+ Bool requeue; /* on queue, but target_msc has changed */
Bool flip; /* planning on using flip */
Bool flip_ready; /* wants to flip, but waiting for previous flip or unflip */
Bool sync_flip; /* do flip synchronous to vblank */