summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjala <[email protected]>2012-02-01 05:10:04 +0200
committerDave Airlie <[email protected]>2012-02-03 12:02:58 +0000
commit0fcc518964223d9baaa2b45e80afeb800beb872f (patch)
treeed38fcb298962f050cd00c811d75f8a153e561f9
parent57e44371a5b6aa8122b6a482ed6bd33e797ea1d2 (diff)
gallium/dri: Handle xserver that doesn't send needless DRI2 invalidate events
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 the 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ä <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
-rw-r--r--src/gallium/state_trackers/dri/common/dri_drawable.c30
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 65b3d04be7b..5a261ddb300 100644
--- a/src/gallium/state_trackers/dri/common/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.c
@@ -53,6 +53,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++)
@@ -66,23 +67,26 @@ dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
* 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;