Hi Keith and Peter,
this patch has been reviewed by Jesse Barnes and now successfully
tested by the guy who submitted the bug report and by me. Fixes
Bugzilla bug #28383, a quite ugly hang of application windows
bufferswapping, including crashes when moving them between different
crtc's of different refresh rate.
It would be good to apply it to 1.9 and 1.8.2 if possible, for a more
enjoyable multi-display OpenGL experience.
thanks,
-mario
On Jun 14, 2010, at 6:13 PM, Jesse Barnes wrote:
On Sun, 13 Jun 2010 18:05:26 +0200
Mario Kleiner <[email protected]> wrote:
Detect if a drawable has been moved from an original crtc to a new
crtc
with a lower current vblank count than the original crtc inbetween
glXSwapBuffers() calls. Reinitialize drawable's last_swap_target
before scheduling next swap if such a move has taken place.
last_swap_target defines the baseline for scheduling the next swap.
If a movement between crtc's is not taken into account, the swap may
schedule for a vblank count on the new crtc far in the future,
resulting
in a apparent "hang" of the drawable for a long time.
Fixes Bugzilla bug #28383.
Signed-off-by: Mario Kleiner <[email protected]>
---
hw/xfree86/dri2/dri2.c | 15 +++++++++++++++
1 files changed, 15 insertions(+), 0 deletions(-)
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index d33b0d1..1f80022 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -756,6 +756,7 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr
pDraw, CARD64 target_msc,
DRI2DrawablePtr pPriv;
DRI2BufferPtr pDestBuffer = NULL, pSrcBuffer = NULL;
int ret, i;
+ CARD64 ust, current_msc;
pPriv = DRI2GetDrawable(pDraw);
if (pPriv == NULL) {
@@ -800,12 +801,26 @@ DRI2SwapBuffers(ClientPtr client,
DrawablePtr pDraw, CARD64 target_msc,
* need to schedule a swap for the last swap target + the
swap interval.
*/
if (target_msc == 0 && divisor == 0 && remainder == 0) {
+ /* If the current vblank count of the drawable's crtc is lower
+ * than the count stored in last_swap_target from a previous swap
+ * then reinitialize last_swap_target to the current crtc's msc,
+ * otherwise the swap will hang. This will happen if the drawable
+ * is moved to a crtc with a lower refresh rate, or a crtc that
just
+ * got enabled.
+ */
+ if (!(*ds->GetMSC)(pDraw, &ust, ¤t_msc))
+ pPriv->last_swap_target = 0;
+
+ if (current_msc < pPriv->last_swap_target)
+ pPriv->last_swap_target = current_msc;
+
/*
* Swap target for this swap is last swap target + swap interval
since
* we have to account for the current swap count, interval, and the
* number of pending swaps.
*/
*swap_target = pPriv->last_swap_target + pPriv->swap_interval;
+
} else {
/* glXSwapBuffersMscOML could have a 0 target_msc, honor it */
*swap_target = target_msc;
Yeah, this looks ok. Really we should write up GLX extension that
clarifies behavior in multi-head and display on/off situations
too. Is
that something you could do?
Reviewed-by: Jesse Barnes <[email protected]>
--
Jesse Barnes, Intel Open Source Technology Center
_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel