xserver: Branch 'master' - 7 commits

Keith Packard keithp at kemper.freedesktop.org
Thu Dec 5 09:52:40 PST 2013


 glx/Makefile.am         |    3 +-
 glx/glxcmds.c           |   61 ++++++++++++++++++++++++++++++++++++++++++++++++
 glx/glxdri2.c           |   33 ++++++++-----------------
 glx/glxext.c            |    3 ++
 glx/glxserver.h         |    9 +++++++
 present/present.c       |   61 ++++++++++++++++++++++++++++++++++++++++--------
 present/present.h       |    9 +++++++
 present/present_event.c |   10 +++++++
 present/present_priv.h  |    7 +++--
 9 files changed, 160 insertions(+), 36 deletions(-)

New commits:
commit 653d33941b0808ef910aaa5f3aeab05d9c1a100b
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Nov 26 12:18:12 2013 -0800

    present: Report damage when flipping
    
    Limit damage to the 'update' region.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/present/present.c b/present/present.c
index 251931a..ffbb0b3 100644
--- a/present/present.c
+++ b/present/present.c
@@ -520,6 +520,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
             /* Try to flip
              */
             if (present_flip(vblank->crtc, vblank->event_id, vblank->target_msc, vblank->pixmap, vblank->sync_flip)) {
+                RegionPtr damage;
 
                 /* Fix window pixmaps:
                  *  1) Restore previous flip window pixmap
@@ -530,6 +531,16 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
                                                (*screen->GetScreenPixmap)(screen));
                 (*screen->SetWindowPixmap)(vblank->window, vblank->pixmap);
                 (*screen->SetWindowPixmap)(screen->root, vblank->pixmap);
+
+                /* Report update region as damaged
+                 */
+                if (vblank->update) {
+                    damage = vblank->update;
+                    RegionIntersect(damage, damage, &window->clipList);
+                } else
+                    damage = &window->clipList;
+
+                DamageDamageRegion(&vblank->window->drawable, damage);
                 return;
             }
 
commit 5cf12c9569ac3d83fe1b7a8376c15f8f0b01655e
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Nov 26 12:10:48 2013 -0800

    present: Also set the root window pixmap when flipping
    
    This makes sure that things like software cursors continue to work
    while the screen is flipped.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/present/present.c b/present/present.c
index 3fd5e8b..251931a 100644
--- a/present/present.c
+++ b/present/present.c
@@ -324,6 +324,8 @@ present_unflip(ScreenPtr screen)
         (*screen->SetWindowPixmap)(screen_priv->flip_window,
                                    (*screen->GetScreenPixmap)(screen));
 
+    (*screen->SetWindowPixmap)(screen->root, (*screen->GetScreenPixmap)(screen));
+
     /* Update the screen pixmap with the current flip pixmap contents
      */
     if (screen_priv->flip_pixmap && screen_priv->flip_window) {
@@ -527,6 +529,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
                     (*screen->SetWindowPixmap)(screen_priv->flip_window,
                                                (*screen->GetScreenPixmap)(screen));
                 (*screen->SetWindowPixmap)(vblank->window, vblank->pixmap);
+                (*screen->SetWindowPixmap)(screen->root, vblank->pixmap);
                 return;
             }
 
commit 4aa77378de69efdc10bced6ba650b0ebff50c112
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Nov 26 12:06:57 2013 -0800

    present: Clear target_crtc if driver lacks Present support
    
    If the driver doesn't have the necessary hooks for Present, then the
    target_crtc needs to be set to NULL to make sure the extension uses
    the present_fake code.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Tested-by: Fredrik Höglund <fredrik at kde.org>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/present/present.c b/present/present.c
index 76e12ed..3fd5e8b 100644
--- a/present/present.c
+++ b/present/present.c
@@ -594,7 +594,9 @@ present_pixmap(WindowPtr window,
     if (!window_priv)
         return BadAlloc;
 
-    if (!target_crtc) {
+    if (!screen_priv || !screen_priv->info)
+        target_crtc = NULL;
+    else if (!target_crtc) {
         /* Update the CRTC if we have a pixmap or we don't have a CRTC
          */
         if (!pixmap)
commit 3dd5bfe540b295bb37a2c2fd0ba4a31fb217612b
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Nov 21 22:48:31 2013 -0800

    present: Send GLX_BufferSwapComplete events from present extension
    
    This allows GL to support the GLX_INTEL_swap_event extension.
    
    v2: Return GLX_BLIT_COMPLETE_INTEL for unknown swap types
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glx/Makefile.am b/glx/Makefile.am
index 5f28e87..44d3a7d 100644
--- a/glx/Makefile.am
+++ b/glx/Makefile.am
@@ -20,7 +20,8 @@ AM_CPPFLAGS = \
 	-I$(top_srcdir)/hw/xfree86/os-support/bus \
 	-I$(top_srcdir)/hw/xfree86/common \
 	-I$(top_srcdir)/hw/xfree86/dri \
-	-I$(top_srcdir)/mi
+	-I$(top_srcdir)/mi \
+	-I$(top_srcdir)/present
 
 if DRI2_AIGLX
 AM_CPPFLAGS += -I$(top_srcdir)/hw/xfree86/dri2
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index efa4aec..b8da048 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -2468,3 +2468,64 @@ __glXDisp_ClientInfo(__GLXclientState * cl, GLbyte * pc)
 
     return Success;
 }
+
+#include <GL/glxtokens.h>
+
+void
+__glXsendSwapEvent(__GLXdrawable *drawable, int type, CARD64 ust,
+                   CARD64 msc, CARD32 sbc)
+{
+    ClientPtr client = clients[CLIENT_ID(drawable->drawId)];
+
+    xGLXBufferSwapComplete2 wire =  {
+        .type = __glXEventBase + GLX_BufferSwapComplete
+    };
+
+    if (!client)
+        return;
+
+    if (!(drawable->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK))
+        return;
+
+    wire.event_type = type;
+    wire.drawable = drawable->drawId;
+    wire.ust_hi = ust >> 32;
+    wire.ust_lo = ust & 0xffffffff;
+    wire.msc_hi = msc >> 32;
+    wire.msc_lo = msc & 0xffffffff;
+    wire.sbc = sbc;
+
+    WriteEventsToClient(client, 1, (xEvent *) &wire);
+}
+
+#if PRESENT
+static void
+__glXpresentCompleteNotify(WindowPtr window, CARD8 present_mode, CARD32 serial,
+                           uint64_t ust, uint64_t msc)
+{
+    __GLXdrawable *drawable;
+    int glx_type;
+    int rc;
+
+    rc = dixLookupResourceByType((pointer *) &drawable, window->drawable.id,
+                                 __glXDrawableRes, serverClient, DixGetAttrAccess);
+
+    if (rc != Success)
+        return;
+
+    if (present_mode == PresentCompleteModeFlip)
+        glx_type = GLX_FLIP_COMPLETE_INTEL;
+    else
+        glx_type = GLX_BLIT_COMPLETE_INTEL;
+        
+    __glXsendSwapEvent(drawable, glx_type, ust, msc, serial);
+}
+
+#include <present.h>
+
+void
+__glXregisterPresentCompleteNotify(void)
+{
+    present_register_complete_notify(__glXpresentCompleteNotify);
+}
+#endif
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index fbbd1fd..e245e81 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -177,36 +177,25 @@ __glXdriSwapEvent(ClientPtr client, void *data, int type, CARD64 ust,
                   CARD64 msc, CARD32 sbc)
 {
     __GLXdrawable *drawable = data;
-    xGLXBufferSwapComplete2 wire =  {
-        .type = __glXEventBase + GLX_BufferSwapComplete
-    };
-
-    if (!(drawable->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK))
-        return;
-
+    int glx_type;
     switch (type) {
     case DRI2_EXCHANGE_COMPLETE:
-        wire.event_type = GLX_EXCHANGE_COMPLETE_INTEL;
+        glx_type = GLX_EXCHANGE_COMPLETE_INTEL;
         break;
+    default:
+        /* unknown swap completion type,
+         * BLIT is a reasonable default, so
+         * fall through ...
+         */
     case DRI2_BLIT_COMPLETE:
-        wire.event_type = GLX_BLIT_COMPLETE_INTEL;
+        glx_type = GLX_BLIT_COMPLETE_INTEL;
         break;
     case DRI2_FLIP_COMPLETE:
-        wire.event_type = GLX_FLIP_COMPLETE_INTEL;
-        break;
-    default:
-        /* unknown swap completion type */
-        wire.event_type = 0;
+        glx_type = GLX_FLIP_COMPLETE_INTEL;
         break;
     }
-    wire.drawable = drawable->drawId;
-    wire.ust_hi = ust >> 32;
-    wire.ust_lo = ust & 0xffffffff;
-    wire.msc_hi = msc >> 32;
-    wire.msc_lo = msc & 0xffffffff;
-    wire.sbc = sbc;
-
-    WriteEventsToClient(client, 1, (xEvent *) &wire);
+    
+    __glXsendSwapEvent(drawable, glx_type, ust, msc, sbc);
 }
 
 /*
diff --git a/glx/glxext.c b/glx/glxext.c
index 3a7de28..601d08a 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -399,6 +399,9 @@ GlxExtensionInit(void)
 
     __glXErrorBase = extEntry->errorBase;
     __glXEventBase = extEntry->eventBase;
+#if PRESENT
+    __glXregisterPresentCompleteNotify();
+#endif
 }
 
 /************************************************************************/
diff --git a/glx/glxserver.h b/glx/glxserver.h
index 5e29abb..f862b63 100644
--- a/glx/glxserver.h
+++ b/glx/glxserver.h
@@ -120,6 +120,15 @@ void glxResumeClients(void);
 void __glXsetGetProcAddress(void (*(*get_proc_address) (const char *)) (void));
 void *__glGetProcAddress(const char *);
 
+void
+__glXsendSwapEvent(__GLXdrawable *drawable, int type, CARD64 ust,
+                   CARD64 msc, CARD32 sbc);
+
+#if PRESENT
+void
+__glXregisterPresentCompleteNotify(void);
+#endif
+
 /*
 ** State kept per client.
 */
diff --git a/present/present.h b/present/present.h
index 6a451fb..0e3bdc0 100644
--- a/present/present.h
+++ b/present/present.h
@@ -115,4 +115,13 @@ present_event_abandon(RRCrtcPtr crtc);
 extern _X_EXPORT Bool
 present_screen_init(ScreenPtr screen, present_screen_info_ptr info);
 
+typedef void (*present_complete_notify_proc)(WindowPtr window,
+                                             CARD8 mode,
+                                             CARD32 serial,
+                                             uint64_t ust,
+                                             uint64_t msc);
+
+extern _X_EXPORT void
+present_register_complete_notify(present_complete_notify_proc proc);
+
 #endif /* _PRESENT_H_ */
diff --git a/present/present_event.c b/present/present_event.c
index a8f7176..f0d509e 100644
--- a/present/present_event.c
+++ b/present/present_event.c
@@ -137,6 +137,14 @@ present_send_config_notify(WindowPtr window, int x, int y, int w, int h, int bw,
     }
 }
 
+static present_complete_notify_proc complete_notify;
+
+void
+present_register_complete_notify(present_complete_notify_proc proc)
+{
+    complete_notify = proc;
+}
+
 void
 present_send_complete_notify(WindowPtr window, CARD8 kind, CARD8 mode, CARD32 serial, uint64_t ust, uint64_t msc)
 {
@@ -165,6 +173,8 @@ present_send_complete_notify(WindowPtr window, CARD8 kind, CARD8 mode, CARD32 se
             }
         }
     }
+    if (complete_notify)
+        (*complete_notify)(window, mode, serial, ust, msc);
 }
 
 void
commit cde86e68fcb716f34c90f5a16eb868870f5c85e4
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Nov 25 23:06:08 2013 -0800

    present: Set window pixmap to flipped pixmap
    
    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>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/present/present.c b/present/present.c
index af5bf64..76e12ed 100644
--- a/present/present.c
+++ b/present/present.c
@@ -115,7 +115,8 @@ present_check_flip(RRCrtcPtr    crtc,
     }
 
     /* Make sure the window hasn't been redirected with Composite */
-    if (screen->GetWindowPixmap(window) != screen->GetScreenPixmap(screen))
+    if (screen->GetWindowPixmap(window) != screen->GetScreenPixmap(screen) &&
+        screen->GetWindowPixmap(window) != screen_priv->flip_pixmap)
         return FALSE;
 
     /* Check for full-screen window */
@@ -319,6 +320,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 +491,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 +517,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 && 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 +548,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);
 
commit 04e138846e128670d409798aa2e797c3c5503a47
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Nov 25 23:10:17 2013 -0800

    present: Leave vblank on window list until flip complete
    
    If the window is destroyed, then we've got cleanup work to do, even if
    the vblank has already been executed -- we need to clear the window
    pointer so that we don't try to deliver events to it.
    
    Leaving it on the window list meant that when walking that list, we
    need to know whether the vblank is waiting to be executed or waiting
    for the flip to complete, so a new 'queued' flag was added to the
    vblank to distinguish between the two states.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/present/present.c b/present/present.c
index f446feb..af5bf64 100644
--- a/present/present.c
+++ b/present/present.c
@@ -348,6 +348,8 @@ present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
 
     present_flip_idle(screen);
 
+    xorg_list_del(&vblank->event_queue);
+
     /* Transfer reference for pixmap and fence from vblank to screen_priv */
     screen_priv->flip_crtc = vblank->crtc;
     screen_priv->flip_window = vblank->window;
@@ -378,14 +380,12 @@ present_event_notify(uint64_t event_id, uint64_t ust, uint64_t msc)
     DebugPresent(("\te %lld ust %lld msc %lld\n", event_id, ust, msc));
     xorg_list_for_each_entry_safe(vblank, tmp, &present_exec_queue, event_queue) {
         if (vblank->event_id == event_id) {
-            xorg_list_del(&vblank->event_queue);
             present_execute(vblank, ust, msc);
             return;
         }
     }
     xorg_list_for_each_entry_safe(vblank, tmp, &present_flip_queue, event_queue) {
         if (vblank->event_id == event_id) {
-            xorg_list_del(&vblank->event_queue);
             present_flip_notify(vblank, ust, msc);
             return;
         }
@@ -447,7 +447,7 @@ present_check_flip_window (WindowPtr window)
 
     /* Now check any queued vblanks */
     xorg_list_for_each_entry(vblank, &window_priv->vblank, window_list) {
-        if (vblank->flip && !present_check_flip(vblank->crtc, window, vblank->pixmap, FALSE, NULL, 0, 0))
+        if (vblank->queued && vblank->flip && !present_check_flip(vblank->crtc, window, vblank->pixmap, FALSE, NULL, 0, 0))
             vblank->flip = FALSE;
     }
 }
@@ -496,16 +496,17 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
     }
 
     xorg_list_del(&vblank->event_queue);
+    vblank->queued = FALSE;
+
     if (vblank->pixmap && vblank->window) {
 
         if (vblank->flip && screen_priv->flip_pending == NULL && !screen_priv->unflip_event_id) {
 
             DebugPresent(("\tf %p %8lld: %08lx -> %08lx\n", vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
-            /* Prepare to flip by removing from the window/screen lists
+            /* Prepare to flip by placing it in the flip queue and
              * and sticking it into the flip_pending field
              */
             screen_priv->flip_pending = vblank;
-            xorg_list_del(&vblank->window_list);
 
             xorg_list_add(&vblank->event_queue, &present_flip_queue);
             /* Try to flip
@@ -701,10 +702,12 @@ present_pixmap(WindowPtr window,
                       target_crtc));
 
     xorg_list_add(&vblank->event_queue, &present_exec_queue);
+    vblank->queued = TRUE;
     if (target_msc >= crtc_msc) {
         ret = present_queue_vblank(screen, target_crtc, vblank->event_id, target_msc);
         if (ret != Success) {
             xorg_list_del(&vblank->event_queue);
+            vblank->queued = FALSE;
             goto failure;
         }
     } else
@@ -737,6 +740,7 @@ present_abort_vblank(ScreenPtr screen, RRCrtcPtr crtc, uint64_t event_id, uint64
     xorg_list_for_each_entry_safe(vblank, tmp, &present_exec_queue, event_queue) {
         if (vblank->event_id == event_id) {
             xorg_list_del(&vblank->event_queue);
+            vblank->queued = FALSE;
             return;
         }
     }
diff --git a/present/present_priv.h b/present/present_priv.h
index 500c7c2..8d3e007 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -69,9 +69,10 @@ struct present_vblank {
     present_fence_ptr   wait_fence;
     present_notify_ptr  notifies;
     int                 num_notifies;
-    Bool                flip;
-    Bool                sync_flip;
-    Bool                abort_flip;
+    Bool                queued;         /* on present_exec_queue */
+    Bool                flip;           /* planning on using flip */
+    Bool                sync_flip;      /* do flip synchronous to vblank */
+    Bool                abort_flip;     /* aborting this flip */
 };
 
 typedef struct present_screen_priv {
commit b121d62accb8c346b4e1b1bce99586e13712f04a
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Nov 26 03:07:55 2013 -0800

    present: Add a debug output line when skipping a pending present
    
    When an application provides two pixmaps for the same MSC, the
    previous one is skipped. This just dumps out some information at that point
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/present/present.c b/present/present.c
index f9eef6b..f446feb 100644
--- a/present/present.c
+++ b/present/present.c
@@ -621,6 +621,11 @@ present_pixmap(WindowPtr window,
             if (vblank->crtc != target_crtc || vblank->target_msc != target_msc)
                 continue;
 
+            DebugPresent(("\tx %lld %p %8lld: %08lx -> %08lx (crtc %p)\n",
+                          vblank->event_id, vblank, target_msc,
+                          vblank->pixmap->drawable.id, vblank->window->drawable.id,
+                          vblank->crtc));
+
             present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
             present_fence_destroy(vblank->idle_fence);
             dixDestroyPixmap(vblank->pixmap, vblank->pixmap->drawable.id);


More information about the xorg-commit mailing list