[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