summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2016-09-15 14:35:52 +0200
committerAdam Jackson <ajax@redhat.com>2016-09-28 14:53:39 -0400
commit299cbb92670fdb83c24c3ef6327eb9d66b8be92a (patch)
treeecd7ae3d26ece747caf6c7a78fb1f8955630f56a
parente8695100b17b758359fc4897dbe995231ed224fc (diff)
modesetting: Fix reverse prime update lagging on secondary GPU outputs
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. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--hw/xfree86/drivers/modesetting/driver.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index f98d6da2b..d37a42a39 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;