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:
parent
44cb9578c0
commit
b83dede9cb
|
@ -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)
|
||||
{
|
||||
|
@ -1016,6 +1048,90 @@ msDisableSharedPixmapFlipping(RRCrtcPtr crtc)
|
|||
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
|
||||
CreateScreenResources(ScreenPtr pScreen)
|
||||
{
|
||||
|
@ -1083,6 +1199,8 @@ CreateScreenResources(ScreenPtr pScreen)
|
|||
pScrPriv->rrEnableSharedPixmapFlipping = msEnableSharedPixmapFlipping;
|
||||
pScrPriv->rrDisableSharedPixmapFlipping = msDisableSharedPixmapFlipping;
|
||||
|
||||
pScrPriv->rrStartFlippingPixmapTracking = msStartFlippingPixmapTracking;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1145,6 +1263,20 @@ msSetSharedPixmapBacking(PixmapPtr ppix, void *fd_handle)
|
|||
#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
|
||||
msSharedPixmapNotifyDamage(PixmapPtr ppix)
|
||||
{
|
||||
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue