xf86-video-modesetting: Branch 'restart' - src/driver.c src/driver.h

Dave Airlie airlied at kemper.freedesktop.org
Thu Sep 29 05:33:37 PDT 2011


 src/driver.c |   75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/driver.h |    6 +++-
 2 files changed, 79 insertions(+), 2 deletions(-)

New commits:
commit 59a4776f7b4e0f9bbbafe62972487354a8fabda0
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Sep 29 12:38:26 2011 +0100

    port damage tracking code from st/xorg

diff --git a/src/driver.c b/src/driver.c
index 0aaafd1..bc80e30 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -307,6 +307,58 @@ GetRec(ScrnInfoPtr pScrn)
     return TRUE;
 }
 
+static void dispatch_dirty(ScreenPtr pScreen)
+{
+    ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
+    modesettingPtr ms = modesettingPTR(scrn);
+    RegionPtr dirty = DamageRegion(ms->damage);
+    unsigned num_cliprects = REGION_NUM_RECTS(dirty);
+
+    if (num_cliprects) {
+	drmModeClip *clip = alloca(num_cliprects * sizeof(drmModeClip));
+	BoxPtr rect = REGION_RECTS(dirty);
+	int i, ret;
+	    
+	/* XXX no need for copy? */
+	for (i = 0; i < num_cliprects; i++, rect++) {
+	    clip[i].x1 = rect->x1;
+	    clip[i].y1 = rect->y1;
+	    clip[i].x2 = rect->x2;
+	    clip[i].y2 = rect->y2;
+	}
+
+	/* TODO query connector property to see if this is needed */
+	ret = drmModeDirtyFB(ms->fd, ms->fb_id, clip, num_cliprects);
+	if (ret) {
+	    if (ret == -EINVAL) {
+		ms->dirty_enabled = FALSE;
+		DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, ms->damage);
+		DamageDestroy(ms->damage);
+		ms->damage = NULL;
+		xf86DrvMsg(scrn->scrnIndex, X_INFO, "Disabling kernel dirty updates, not required.\n");
+		return;
+	    } else
+		ErrorF("%s: failed to send dirty (%i, %s)\n",
+		       __func__, ret, strerror(-ret));
+	}
+	
+	DamageEmpty(ms->damage);
+    }
+}
+
+static void msBlockHandler(int i, pointer blockData, pointer pTimeout,
+			   pointer pReadmask)
+{
+    ScreenPtr pScreen = screenInfo.screens[i];
+    modesettingPtr ms = modesettingPTR(xf86Screens[pScreen->myNum]);
+
+    pScreen->BlockHandler = ms->BlockHandler;
+    pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
+    pScreen->BlockHandler = msBlockHandler;
+    if (ms->dirty_enabled)
+	dispatch_dirty(pScreen);
+}
+
 static void
 FreeRec(ScrnInfoPtr pScrn)
 {
@@ -494,6 +546,18 @@ CreateScreenResources(ScreenPtr pScreen)
     if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, pixels))
 	FatalError("Couldn't adjust screen pixmap\n");
 
+    ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
+                              pScreen, rootPixmap);
+
+    if (ms->damage) {
+	DamageRegister(&rootPixmap->drawable, ms->damage);
+	ms->dirty_enabled = TRUE;
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n");
+    } else {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "Failed to create screen damage record\n");
+	return FALSE;
+    }
     return ret;
 }
 
@@ -596,6 +660,9 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     ms->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = CloseScreen;
 
+    ms->BlockHandler = pScreen->BlockHandler;
+    pScreen->BlockHandler = msBlockHandler;
+
     if (!xf86CrtcScreenInit(pScreen))
 	return FALSE;
 
@@ -669,6 +736,12 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     modesettingPtr ms = modesettingPTR(pScrn);
 
+    if (ms->damage) {
+	DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, ms->damage);
+	DamageDestroy(ms->damage);
+	ms->damage = NULL;
+    }
+
     drmmode_uevent_fini(pScrn, &ms->drmmode);
 
     drmmode_free_bos(pScrn, &ms->drmmode);
@@ -678,7 +751,7 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
     }
 
     pScreen->CreateScreenResources = ms->createScreenResources;
-
+    pScreen->BlockHandler = ms->BlockHandler;
     drmClose(ms->fd);
     ms->fd = -1;
 
diff --git a/src/driver.h b/src/driver.h
index 255dede..beb5f8d 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -30,6 +30,7 @@
 #include <errno.h>
 #include <drm.h>
 #include <xf86drm.h>
+#include <damage.h>
 
 #include "drmmode_display.h"
 #define DRV_ERROR(msg)	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg);
@@ -68,10 +69,13 @@ typedef struct _modesettingRec
     unsigned int SaveGeneration;
 
     CreateScreenResourcesProcPtr createScreenResources;
-
+    ScreenBlockHandlerProcPtr BlockHandler;
     void *driver;
 
     drmmode_rec drmmode;
+
+    DamagePtr damage;
+    Bool dirty_enabled;
 } modesettingRec, *modesettingPtr;
 
 #define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))


More information about the xorg-commit mailing list