sna: Reorder frontbuffer resize vs flip event queue draining
If we are not careful, we may process an unflip in the middle of resizing the frontbuffer - when the ScreenPixmap state is ill-defined. First flush all the pending flip events, cancel any residual unflips, then update the screen pixmap. This should be enough to close the race. References: https://bugs.freedesktop.org/show_bug.cgi?id=98855#c11 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
fcf943f45b
commit
ff25ad3402
|
|
@ -5679,6 +5679,14 @@ sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
|
|||
assert(sna->mode.shadow_damage == NULL);
|
||||
assert(sna->mode.shadow == NULL);
|
||||
|
||||
/* Flush pending shadow updates */
|
||||
if (sna->mode.flip_active) {
|
||||
DBG(("%s: waiting for %d outstanding TearFree flips\n",
|
||||
__FUNCTION__, sna->mode.flip_active));
|
||||
while (sna->mode.flip_active && sna_mode_wait_for_event(sna))
|
||||
sna_mode_wakeup(sna);
|
||||
}
|
||||
|
||||
/* Cancel a pending [un]flip (as the pixmaps no longer match) */
|
||||
sna_present_cancel_flip(sna);
|
||||
copy_front(sna, sna->front, new_front);
|
||||
|
|
@ -5692,14 +5700,6 @@ sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
|
|||
scrn->virtualY = height;
|
||||
scrn->displayWidth = width;
|
||||
|
||||
/* Flush pending shadow updates */
|
||||
if (sna->mode.flip_active) {
|
||||
DBG(("%s: waiting for %d outstanding TearFree flips\n",
|
||||
__FUNCTION__, sna->mode.flip_active));
|
||||
while (sna->mode.flip_active && sna_mode_wait_for_event(sna))
|
||||
sna_mode_wakeup(sna);
|
||||
}
|
||||
|
||||
/* Only update the CRTCs if we are in control */
|
||||
if (!scrn->vtSema)
|
||||
return TRUE;
|
||||
|
|
|
|||
|
|
@ -926,12 +926,12 @@ reset_mode:
|
|||
goto notify;
|
||||
}
|
||||
|
||||
assert(sna_pixmap(screen->GetScreenPixmap(screen))->pinned & PIN_SCANOUT);
|
||||
|
||||
/* Are we unflipping after a failure that left our ScreenP in place? */
|
||||
if (!sna_needs_page_flip(sna, bo))
|
||||
goto notify;
|
||||
|
||||
assert(sna_pixmap(screen->GetScreenPixmap(screen))->pinned & PIN_SCANOUT);
|
||||
|
||||
if (sna->flags & SNA_HAS_ASYNC_FLIP) {
|
||||
DBG(("%s: trying async flip restore\n", __FUNCTION__));
|
||||
if (flip__async(sna, NULL, event_id, 0, bo))
|
||||
|
|
|
|||
Loading…
Reference in New Issue