[PATCH xserver 2/2] modesetting: Fix reverse prime update lagging on secondary GPU outputs

Dave Airlie airlied at gmail.com
Thu Sep 15 20:32:21 UTC 2016


On 15 September 2016 at 23:47, Hans de Goede <hdegoede at redhat.com> wrote:
> When using secondary GPU outputs the primary GPU's blockhandler
> will copy changes from its framebuffer to a pixmap shared with the
> secondary GPU.
>
> In reverse prime setups the secondary GPU's blockhandler will do another
> copy from the shared pixmap to its own framebuffer.
>
> Before this commit, if the primary GPU's blockhandler would run after
> the secondary GPU's blockhandler and no events were pending, then the
> secondary GPU's blockhandler would not run until some events came in
> (WaitForSomething() would block in the poll call), resulting in the
> secondary GPU output sometimes showing stale contents (e.g. a just closed
> window) for easily up to 10 seconds.
>
> This commit fixes this by setting the timeout passed into the
> blockhandler to 0 if any shared pixmaps were updated by the primary GPU,
> forcing an immediate re-run of all blockhandlers.

Nice idea,

Reviewed-by: Dave Airlie <airlied at redhat.com>

>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> ---
>  hw/xfree86/drivers/modesetting/driver.c | 13 ++++++++-----
>  1 file changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
> index f98d6da..d37a42a 100644
> --- a/hw/xfree86/drivers/modesetting/driver.c
> +++ b/hw/xfree86/drivers/modesetting/driver.c
> @@ -584,7 +584,7 @@ dispatch_slave_dirty(ScreenPtr pScreen)
>  }
>
>  static void
> -redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty)
> +redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty, int *timeout)
>  {
>      modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(screen));
>      RegionRec pixregion;
> @@ -602,6 +602,9 @@ redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty)
>           */
>          if (ms->drmmode.glamor)
>              glamor_finish(screen);
> +        /* Ensure the slave processes the damage immediately */
> +        if (timeout)
> +            *timeout = 0;
>      }
>
>      DamageRegionProcessPending(&dirty->slave_dst->drawable);
> @@ -609,7 +612,7 @@ redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty)
>  }
>
>  static void
> -ms_dirty_update(ScreenPtr screen)
> +ms_dirty_update(ScreenPtr screen, int *timeout)
>  {
>      modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(screen));
>
> @@ -636,7 +639,7 @@ ms_dirty_update(ScreenPtr screen)
>              if (ppriv->defer_dirty_update)
>                  continue;
>
> -            redisplay_dirty(screen, ent);
> +            redisplay_dirty(screen, ent, timeout);
>              DamageEmpty(ent->damage);
>          }
>      }
> @@ -672,7 +675,7 @@ msBlockHandler(ScreenPtr pScreen, void *timeout)
>      else if (ms->dirty_enabled)
>          dispatch_dirty(pScreen);
>
> -    ms_dirty_update(pScreen);
> +    ms_dirty_update(pScreen, timeout);
>  }
>
>  static void
> @@ -1261,7 +1264,7 @@ msPresentSharedPixmap(PixmapPtr slave_dst)
>      RegionPtr region = DamageRegion(ppriv->dirty->damage);
>
>      if (RegionNotEmpty(region)) {
> -        redisplay_dirty(ppriv->slave_src->drawable.pScreen, ppriv->dirty);
> +        redisplay_dirty(ppriv->slave_src->drawable.pScreen, ppriv->dirty, NULL);
>          DamageEmpty(ppriv->dirty->damage);
>
>          return TRUE;
> --
> 2.9.3
>
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: https://lists.x.org/mailman/listinfo/xorg-devel


More information about the xorg-devel mailing list