[Mesa-dev] [PATCH 7.11] gallium/dri: Handle xserver that doesn't send needless DRI2 invalidate events

Ville Syrjälä syrjala at sci.fi
Sun Dec 18 08:22:01 PST 2011


Ever since xserver commit 531869448d07e00ae241120b59f3aaaa5709d59c,
the server no longer sends invalidate events to clients, unless they
have performed a GetBuffers request since the drawable was last
invalidated.

If the drawable gets invalidated immediately after the GetBuffers
request was processed by the X server, it's possible that Xlib
will process the invalidate event while waiting for the GetBuffers
reply. So the server, thinking the client knows that the buffers
are invalid, is waiting for another GetBuffers request before
sending any more invalidate events. The client, on the other hand,
believes the buffers to be valid, and thus is expecting to receive
another invalidate event before it has to send another GetBuffers
request. The end result is that the client never again sends
a GetBuffers request.

To avoid this problem, take a snapshot of lastStamp before
doing GetBuffers, and retry if the snapshot and the current
lastStamp no longer match after the GetBuffers reply has been
processed.

Signed-off-by: Ville Syrjälä <syrjala at sci.fi>
---
It looks like master should already handle this, as there's a
retry loop inside st_framebuffer_validate(). I didn't test that
in practice though.

 .../state_trackers/dri/common/dri_drawable.c       |   30 +++++++++++--------
 1 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.c b/src/gallium/state_trackers/dri/common/dri_drawable.c
index 28a33ac..6748fbc 100644
--- a/src/gallium/state_trackers/dri/common/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.c
@@ -51,6 +51,7 @@ dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
    unsigned statt_mask, new_mask;
    boolean new_stamp;
    int i;
+   unsigned int lastStamp;
 
    statt_mask = 0x0;
    for (i = 0; i < count; i++)
@@ -64,23 +65,26 @@ dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
     * least for DRI1.  dPriv->lastStamp is the client stamp.  It has the value
     * of the server stamp when last checked.
     */
-   new_stamp = (drawable->texture_stamp != drawable->dPriv->lastStamp);
+   do {
+      lastStamp = drawable->dPriv->lastStamp;
+      new_stamp = (drawable->texture_stamp != lastStamp);
 
-   if (new_stamp || new_mask || screen->broken_invalidate) {
-      if (new_stamp && drawable->update_drawable_info)
-         drawable->update_drawable_info(drawable);
+      if (new_stamp || new_mask || screen->broken_invalidate) {
+         if (new_stamp && drawable->update_drawable_info)
+            drawable->update_drawable_info(drawable);
 
-      drawable->allocate_textures(drawable, statts, count);
+         drawable->allocate_textures(drawable, statts, count);
 
-      /* add existing textures */
-      for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
-         if (drawable->textures[i])
-            statt_mask |= (1 << i);
-      }
+         /* add existing textures */
+         for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+            if (drawable->textures[i])
+               statt_mask |= (1 << i);
+         }
 
-      drawable->texture_stamp = drawable->dPriv->lastStamp;
-      drawable->texture_mask = statt_mask;
-   }
+         drawable->texture_stamp = lastStamp;
+         drawable->texture_mask = statt_mask;
+      }
+   } while (lastStamp != drawable->dPriv->lastStamp);
 
    if (!out)
       return TRUE;
-- 
1.7.3.4



More information about the mesa-dev mailing list