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>
This commit is contained in:
Alex Goins 2016-06-16 20:06:56 -07:00 committed by Adam Jackson
parent 44cb9578c0
commit b83dede9cb
2 changed files with 144 additions and 1 deletions

View File

@ -577,6 +577,8 @@ redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty)
static void static void
ms_dirty_update(ScreenPtr screen) ms_dirty_update(ScreenPtr screen)
{ {
modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(screen));
RegionPtr region; RegionPtr region;
PixmapDirtyUpdatePtr ent; PixmapDirtyUpdatePtr ent;
@ -586,12 +588,42 @@ ms_dirty_update(ScreenPtr screen)
xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) { xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) {
region = DamageRegion(ent->damage); region = DamageRegion(ent->damage);
if (RegionNotEmpty(region)) { 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); redisplay_dirty(screen, ent);
DamageEmpty(ent->damage); 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 static void
msBlockHandler(ScreenPtr pScreen, void *pTimeout, void *pReadmask) msBlockHandler(ScreenPtr pScreen, void *pTimeout, void *pReadmask)
{ {
@ -1016,6 +1048,90 @@ msDisableSharedPixmapFlipping(RRCrtcPtr crtc)
drmmode_DisableSharedPixmapFlipping(xf86Crtc, &ms->drmmode); drmmode_DisableSharedPixmapFlipping(xf86Crtc, &ms->drmmode);
} }
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 static Bool
CreateScreenResources(ScreenPtr pScreen) CreateScreenResources(ScreenPtr pScreen)
{ {
@ -1083,6 +1199,8 @@ CreateScreenResources(ScreenPtr pScreen)
pScrPriv->rrEnableSharedPixmapFlipping = msEnableSharedPixmapFlipping; pScrPriv->rrEnableSharedPixmapFlipping = msEnableSharedPixmapFlipping;
pScrPriv->rrDisableSharedPixmapFlipping = msDisableSharedPixmapFlipping; pScrPriv->rrDisableSharedPixmapFlipping = msDisableSharedPixmapFlipping;
pScrPriv->rrStartFlippingPixmapTracking = msStartFlippingPixmapTracking;
return ret; return ret;
} }
@ -1145,6 +1263,20 @@ msSetSharedPixmapBacking(PixmapPtr ppix, void *fd_handle)
#endif #endif
} }
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 static Bool
msSharedPixmapNotifyDamage(PixmapPtr ppix) msSharedPixmapNotifyDamage(PixmapPtr ppix)
{ {
@ -1343,6 +1475,11 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
pScreen->StopPixmapTracking = PixmapStopDirtyTracking; pScreen->StopPixmapTracking = PixmapStopDirtyTracking;
pScreen->SharedPixmapNotifyDamage = msSharedPixmapNotifyDamage; pScreen->SharedPixmapNotifyDamage = msSharedPixmapNotifyDamage;
pScreen->RequestSharedPixmapNotifyDamage =
msRequestSharedPixmapNotifyDamage;
pScreen->PresentSharedPixmap = msPresentSharedPixmap;
pScreen->StopFlippingPixmapTracking = msStopFlippingPixmapTracking;
if (!xf86CrtcScreenInit(pScreen)) if (!xf86CrtcScreenInit(pScreen))
return FALSE; return FALSE;

View File

@ -152,9 +152,15 @@ typedef struct _msPixmapPriv {
DamagePtr slave_damage; DamagePtr slave_damage;
/** Fields for flipping shared pixmaps */ /** Sink fields for flipping shared pixmaps */
int flip_seq; /* seq of current page flip event handler */ int flip_seq; /* seq of current page flip event handler */
Bool wait_for_damage; /* if we have requested damage notification from source */ 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; } msPixmapPrivRec, *msPixmapPrivPtr;
extern DevPrivateKeyRec msPixmapPrivateKeyRec; extern DevPrivateKeyRec msPixmapPrivateKeyRec;