[PATCH v6 11/11] modesetting: Implement PRIME syncing as a source
Alex Goins
agoins at nvidia.com
Sat Jun 11 00:21:05 UTC 2016
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
Signed-off-by: Alex Goins <agoins at nvidia.com>
---
hw/xfree86/drivers/modesetting/driver.c | 137 +++++++++++++++++++++++
hw/xfree86/drivers/modesetting/drmmode_display.h | 8 +-
2 files changed, 144 insertions(+), 1 deletion(-)
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 403cb96..bf3ddbf 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)
{
@@ -1010,6 +1042,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);
@@ -1076,6 +1192,8 @@ CreateScreenResources(ScreenPtr pScreen)
pScrPriv->rrEnableSharedPixmapFlipping = msEnableSharedPixmapFlipping;
pScrPriv->rrDisableSharedPixmapFlipping = msDisableSharedPixmapFlipping;
+ pScrPriv->rrStartFlippingPixmapTracking = msStartFlippingPixmapTracking;
+
return ret;
}
@@ -1139,6 +1257,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;
@@ -1336,6 +1468,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 3161bba..6d2c0a4 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;
--
1.9.1
More information about the xorg-devel
mailing list