diff options
author | Alex Goins <agoins@nvidia.com> | 2016-06-16 20:06:56 -0700 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2016-06-28 12:56:45 -0400 |
commit | b83dede9cb930cf55249ad8e935f3c4d4328e2d9 (patch) | |
tree | 27e7c4a204cd7e3500cf184830806019635f52be /hw/xfree86/drivers | |
parent | 44cb9578c0e5e10568826bc3ecbed97d358bba3c (diff) |
modesetting: Implement PRIME syncing as a source
Implements (Start/Stop)FlippingPixmapTracking, PresentSharedPixmap, and
RequestSharedPixmapNotifyDamage, the source functions for PRIME
synchronization and double buffering. Allows modesetting driver to be used
as a source with PRIME synchronization.
v1: N/A
v2: N/A
v3: N/A
v4: Initial commit
v5: Move disabling of reverse PRIME on sink to sink commit
v6: Rebase onto ToT
v7: Unchanged
Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
Diffstat (limited to 'hw/xfree86/drivers')
-rw-r--r-- | hw/xfree86/drivers/modesetting/driver.c | 137 | ||||
-rw-r--r-- | hw/xfree86/drivers/modesetting/drmmode_display.h | 8 |
2 files changed, 144 insertions, 1 deletions
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index 160cbc944..256ca9580 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -577,6 +577,8 @@ redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty) static void ms_dirty_update(ScreenPtr screen) { + modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(screen)); + RegionPtr region; PixmapDirtyUpdatePtr ent; @@ -586,12 +588,42 @@ ms_dirty_update(ScreenPtr screen) xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) { region = DamageRegion(ent->damage); if (RegionNotEmpty(region)) { + msPixmapPrivPtr ppriv = + msGetPixmapPriv(&ms->drmmode, ent->slave_dst); + + if (ppriv->notify_on_damage) { + ppriv->notify_on_damage = FALSE; + + ent->slave_dst->drawable.pScreen-> + SharedPixmapNotifyDamage(ent->slave_dst); + } + + /* Requested manual updating */ + if (ppriv->defer_dirty_update) + continue; + redisplay_dirty(screen, ent); DamageEmpty(ent->damage); } } } +static PixmapDirtyUpdatePtr +ms_dirty_get_ent(ScreenPtr screen, PixmapPtr slave_dst) +{ + PixmapDirtyUpdatePtr ent; + + if (xorg_list_is_empty(&screen->pixmap_dirty_list)) + return NULL; + + xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) { + if (ent->slave_dst == slave_dst) + return ent; + } + + return NULL; +} + static void msBlockHandler(ScreenPtr pScreen, void *pTimeout, void *pReadmask) { @@ -1017,6 +1049,90 @@ msDisableSharedPixmapFlipping(RRCrtcPtr crtc) } static Bool +msStartFlippingPixmapTracking(RRCrtcPtr crtc, PixmapPtr src, + PixmapPtr slave_dst1, PixmapPtr slave_dst2, + int x, int y, int dst_x, int dst_y, + Rotation rotation) +{ + ScreenPtr pScreen = src->drawable.pScreen; + modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(pScreen)); + + msPixmapPrivPtr ppriv1 = msGetPixmapPriv(&ms->drmmode, slave_dst1), + ppriv2 = msGetPixmapPriv(&ms->drmmode, slave_dst2); + + if (!PixmapStartDirtyTracking(src, slave_dst1, x, y, + dst_x, dst_y, rotation)) { + return FALSE; + } + + if (!PixmapStartDirtyTracking(src, slave_dst2, x, y, + dst_x, dst_y, rotation)) { + PixmapStopDirtyTracking(src, slave_dst1); + return FALSE; + } + + ppriv1->slave_src = src; + ppriv2->slave_src = src; + + ppriv1->dirty = ms_dirty_get_ent(pScreen, slave_dst1); + ppriv2->dirty = ms_dirty_get_ent(pScreen, slave_dst2); + + ppriv1->defer_dirty_update = TRUE; + ppriv2->defer_dirty_update = TRUE; + + return TRUE; +} + +static Bool +msPresentSharedPixmap(PixmapPtr slave_dst) +{ + ScreenPtr pScreen = slave_dst->drawable.pScreen; + modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(pScreen)); + + msPixmapPrivPtr ppriv = msGetPixmapPriv(&ms->drmmode, slave_dst); + + RegionPtr region = DamageRegion(ppriv->dirty->damage); + + if (RegionNotEmpty(region)) { + redisplay_dirty(ppriv->slave_src->drawable.pScreen, ppriv->dirty); + DamageEmpty(ppriv->dirty->damage); + + return TRUE; + } + + return FALSE; +} + +static Bool +msStopFlippingPixmapTracking(PixmapPtr src, + PixmapPtr slave_dst1, PixmapPtr slave_dst2) +{ + ScreenPtr pScreen = src->drawable.pScreen; + modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(pScreen)); + + msPixmapPrivPtr ppriv1 = msGetPixmapPriv(&ms->drmmode, slave_dst1), + ppriv2 = msGetPixmapPriv(&ms->drmmode, slave_dst2); + + Bool ret = TRUE; + + ret &= PixmapStopDirtyTracking(src, slave_dst1); + ret &= PixmapStopDirtyTracking(src, slave_dst2); + + if (ret) { + ppriv1->slave_src = NULL; + ppriv2->slave_src = NULL; + + ppriv1->dirty = NULL; + ppriv2->dirty = NULL; + + ppriv1->defer_dirty_update = FALSE; + ppriv2->defer_dirty_update = FALSE; + } + + return ret; +} + +static Bool CreateScreenResources(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); @@ -1083,6 +1199,8 @@ CreateScreenResources(ScreenPtr pScreen) pScrPriv->rrEnableSharedPixmapFlipping = msEnableSharedPixmapFlipping; pScrPriv->rrDisableSharedPixmapFlipping = msDisableSharedPixmapFlipping; + pScrPriv->rrStartFlippingPixmapTracking = msStartFlippingPixmapTracking; + return ret; } @@ -1146,6 +1264,20 @@ msSetSharedPixmapBacking(PixmapPtr ppix, void *fd_handle) } static Bool +msRequestSharedPixmapNotifyDamage(PixmapPtr ppix) +{ + ScreenPtr screen = ppix->drawable.pScreen; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + modesettingPtr ms = modesettingPTR(scrn); + + msPixmapPrivPtr ppriv = msGetPixmapPriv(&ms->drmmode, ppix); + + ppriv->notify_on_damage = TRUE; + + return TRUE; +} + +static Bool msSharedPixmapNotifyDamage(PixmapPtr ppix) { Bool ret = FALSE; @@ -1343,6 +1475,11 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv) pScreen->StopPixmapTracking = PixmapStopDirtyTracking; pScreen->SharedPixmapNotifyDamage = msSharedPixmapNotifyDamage; + pScreen->RequestSharedPixmapNotifyDamage = + msRequestSharedPixmapNotifyDamage; + + pScreen->PresentSharedPixmap = msPresentSharedPixmap; + pScreen->StopFlippingPixmapTracking = msStopFlippingPixmapTracking; if (!xf86CrtcScreenInit(pScreen)) return FALSE; diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h index 3161bba3f..6d2c0a4bc 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.h +++ b/hw/xfree86/drivers/modesetting/drmmode_display.h @@ -152,9 +152,15 @@ typedef struct _msPixmapPriv { DamagePtr slave_damage; - /** Fields for flipping shared pixmaps */ + /** Sink fields for flipping shared pixmaps */ int flip_seq; /* seq of current page flip event handler */ Bool wait_for_damage; /* if we have requested damage notification from source */ + + /** Source fields for flipping shared pixmaps */ + Bool defer_dirty_update; /* if we want to manually update */ + PixmapDirtyUpdatePtr dirty; /* cached dirty ent to avoid searching list */ + PixmapPtr slave_src; /* if we exported shared pixmap, dirty tracking src */ + Bool notify_on_damage; /* if sink has requested damage notification */ } msPixmapPrivRec, *msPixmapPrivPtr; extern DevPrivateKeyRec msPixmapPrivateKeyRec; |