[PATCH] present: Set window pixmap to flipped pixmap

Keith Packard keithp at keithp.com
Mon Nov 25 23:29:56 PST 2013


This makes other drawing to the window appear on the screen.

Note that no child windows can be affected because only full-screen
windows are eligible for flipping, and so we only need to set pixmap
for the window itself.

Signed-off-by: Keith Packard <keithp at keithp.com>
---

The current mesa DRI3/Present code is using xcb_copy_area to update
the front buffer from the back buffer, which fails in the flip case.

Fixing mesa to use present_pixmap would also fix this problem, and
make cogl's partial updates become vblank synchronized without
the horrible hacks it currently performs. Fixing cogl to be able to
directly get at Present would be even better; perhaps through some new
GL extension, instead of trying to make cogl use Present directly?

 present/present.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/present/present.c b/present/present.c
index bedb9f2..e396255 100644
--- a/present/present.c
+++ b/present/present.c
@@ -319,6 +319,10 @@ present_unflip(ScreenPtr screen)
     assert (!screen_priv->unflip_event_id);
     assert (!screen_priv->flip_pending);
 
+    if (screen_priv->flip_window)
+        (*screen->SetWindowPixmap)(screen_priv->flip_window,
+                                   (*screen->GetScreenPixmap)(screen));
+
     /* Update the screen pixmap with the current flip pixmap contents
      */
     if (screen_priv->flip_pixmap && screen_priv->flip_window) {
@@ -486,7 +490,8 @@ static void
 present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
 {
     WindowPtr                   window = vblank->window;
-    present_screen_priv_ptr     screen_priv = present_screen_priv(window->drawable.pScreen);
+    ScreenPtr                   screen = window->drawable.pScreen;
+    present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
 
     if (vblank->wait_fence) {
         if (!present_fence_check_triggered(vblank->wait_fence)) {
@@ -511,8 +516,18 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
             xorg_list_add(&vblank->event_queue, &present_flip_queue);
             /* Try to flip
              */
-            if (present_flip(vblank->crtc, vblank->event_id, vblank->target_msc, vblank->pixmap, vblank->sync_flip))
+            if (present_flip(vblank->crtc, vblank->event_id, vblank->target_msc, vblank->pixmap, vblank->sync_flip)) {
+
+                /* Fix window pixmaps:
+                 *  1) Restore previous flip window pixmap
+                 *  2) Set current flip window pixmap to the new pixmap
+                 */
+                if (screen_priv->flip_window != window)
+                    (*screen->SetWindowPixmap)(screen_priv->flip_window,
+                                               (*screen->GetScreenPixmap)(screen));
+                (*screen->SetWindowPixmap)(vblank->window, vblank->pixmap);
                 return;
+            }
 
             xorg_list_del(&vblank->event_queue);
             /* Oops, flip failed. Clear the flip_pending field
@@ -532,7 +547,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
             /* Check current flip
              */
             if (window == screen_priv->flip_window)
-                present_unflip(window->drawable.pScreen);
+                present_unflip(screen);
         }
         present_copy_region(&window->drawable, vblank->pixmap, vblank->update, vblank->x_off, vblank->y_off);
 
-- 
1.8.4.4



More information about the xorg-devel mailing list