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
|
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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue