[PATCH] present: Fix Async swap logic
Chris Wilson
chris at chris-wilson.co.uk
Wed Nov 4 02:01:20 PST 2015
On Wed, Nov 04, 2015 at 10:48:40AM +0100, Axel Davy wrote:
> On 04/11/2015 10:40, Chris Wilson wrote:
> >On Tue, Nov 03, 2015 at 09:14:51AM +0100, Axel Davy wrote:
> >>+ if (pixmap != NULL &&
> >>+ !(options & PresentOptionCopy) &&
> >>+ screen_priv->info) {
> >>+ if (target_msc > crtc_msc &&
> >>+ present_check_flip (target_crtc, window, pixmap, TRUE, valid, x_off, y_off))
> >>+ {
> >>+ vblank->flip = TRUE;
> >>+ vblank->sync_flip = TRUE;
> >>+ target_msc--;
> >>+ } else if (target_msc == crtc_msc &&
> >>+ (options & PresentOptionAsync) &&
> >>+ (screen_priv->info->capabilities & PresentCapabilityAsync) &&
> >>+ present_check_flip (target_crtc, window, pixmap, FALSE, valid, x_off, y_off))
> >>+ {
> >>+ vblank->flip = TRUE;
> >>+ }
> >> }
> >For reference, this is how I fixed the async flip + swap elision:
> >
> >t a/present/present.c b/present/present.c
> >index e9ccfb8..32522af 100644
> >--- a/present/present.c
> >+++ b/present/present.c
> >@@ -861,19 +861,19 @@ present_pixmap(WindowPtr window,
> > vblank->notifies = notifies;
> > vblank->num_notifies = num_notifies;
> >- if (!(options & PresentOptionAsync))
> >- vblank->sync_flip = TRUE;
> >-
> >- if (!(options & PresentOptionCopy) &&
> >- !((options & PresentOptionAsync) &&
> >- (!screen_priv->info ||
> >- !(screen_priv->info->capabilities & PresentCapabilityAsync))) &&
> >- pixmap != NULL &&
> >- present_check_flip (target_crtc, window, pixmap, vblank->sync_flip, valid, x_off, y_off))
> >- {
> >- vblank->flip = TRUE;
> >- if (vblank->sync_flip)
> >+ if (!(options & PresentOptionCopy) && pixmap != NULL) {
> >+ if (options & PresentOptionAsync &&
> >+ (screen_priv->info &&
> >+ screen_priv->info->capabilities & PresentCapabilityAsync) &&
> >+ present_check_flip (target_crtc, window, pixmap, FALSE, valid, x_off, y_off)) {
> >+ vblank->flip = TRUE;
> >+ }
> >+ else if (present_check_flip (target_crtc, window, pixmap, TRUE, valid, x_off, y_off)) {
> >+ vblank->flip = TRUE;
> >+ vblank->sync_flip = TRUE;
> > target_msc--;
> >+ } else if (options & PresentOptionAsync)
> >+ target_msc++;
> > }
> > if (wait_fence) {
> >
> >
> Hi,
>
> Could you explain:
> . Why you increase target_msc when the Async option is requested ?
It's the fallthrough path where the client requested an async swap but
we cannot perform one and so must use a synchronous wait for the vblank
(in which case we actually wait for the vblank before target_msc, hence
the increment here to compenstae).
> . Why you check for Async flips first (isn't sync flips better when
> possible) ?
The choice is between using native async flips or emulating them through
sync flips. Native wins.
> To me the Async option isn't related particularly to Async flips.
> Async flips is just an optimization to handle it without a copy in
> the case you would need one.
It is described as being "perform the flip as soon as possible (if
target < current msc) without regard to synchronisation to vrefresh".
That says use tearing native async flips to me.
> http://cgit.freedesktop.org/xorg/proto/presentproto/tree/presentproto.txt#n212
> Given the spec, I believe when target_msc > crtc_msc, the behaviour
> should be the same with or without the flag, and thus you shouldn't
> increase target_msc.
Exactly, hence why we need to fudge it in the code to maintain the
requested msc (as the code fudges it again later on).
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
More information about the xorg-devel
mailing list