summaryrefslogtreecommitdiff
path: root/present
diff options
context:
space:
mode:
authorFrank Binns <frank.binns@imgtec.com>2014-06-10 13:43:31 +0100
committerKeith Packard <keithp@keithp.com>2014-06-23 13:48:20 -0700
commit334faabe682a422075ba214501c7554dd5ee5563 (patch)
tree8293206df89caf612f1c9bd2277246caaca36489 /present
parent382ff4a306b97b0ddcdac03ce8611b026ca5323b (diff)
present: restore screen pixmap when aborting a flip
If a 2D application is started on top of a fullscreen 3D application, which is flipping, then we need to stop flipping and restore the root window, and possibly the flip window, to using the screen pixmap. Normally this would be done as part of an unflip. However, in the case that there is a pending flip there is no mechanism to abort so the unflip is deferred until the pending flip completes. This provides a window of opportunity for the 2D application to draw to the wrong pixmap. Restore the screen pixmap at the point a pending flip is marked as aborted, thus avoiding this issue. Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Frank Binns <frank.binns@imgtec.com> Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'present')
-rw-r--r--present/present.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/present/present.c b/present/present.c
index 165860af8..271c251a9 100644
--- a/present/present.c
+++ b/present/present.c
@@ -383,6 +383,24 @@ present_set_tree_pixmap(WindowPtr window, PixmapPtr pixmap)
}
static void
+present_set_abort_flip(ScreenPtr screen)
+{
+ present_screen_priv_ptr screen_priv = present_screen_priv(screen);
+
+ /* Switch back to using the screen pixmap now to avoid
+ * 2D applications drawing to the wrong pixmap.
+ */
+
+ if (screen_priv->flip_window)
+ present_set_tree_pixmap(screen_priv->flip_window,
+ (*screen->GetScreenPixmap)(screen));
+
+ present_set_tree_pixmap(screen->root, (*screen->GetScreenPixmap)(screen));
+
+ screen_priv->flip_pending->abort_flip = TRUE;
+}
+
+static void
present_unflip(ScreenPtr screen)
{
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
@@ -511,7 +529,7 @@ present_check_flip_window (WindowPtr window)
if (flip_pending->window == window) {
if (!present_check_flip(flip_pending->crtc, window, flip_pending->pixmap,
flip_pending->sync_flip, NULL, 0, 0))
- flip_pending->abort_flip = TRUE;
+ present_set_abort_flip(screen);
}
} else {
/*
@@ -634,7 +652,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
/* Check pending flip
*/
if (window == screen_priv->flip_pending->window)
- screen_priv->flip_pending->abort_flip = TRUE;
+ present_set_abort_flip(screen);
} else if (!screen_priv->unflip_event_id) {
/* Check current flip
@@ -916,7 +934,7 @@ present_flip_destroy(ScreenPtr screen)
/* Do the actual cleanup once the flip has been performed by the hardware */
if (screen_priv->flip_pending)
- screen_priv->flip_pending->abort_flip = TRUE;
+ present_set_abort_flip(screen);
}
void