Mesa (master): st/xorg: Add support for dirty framebuffer region reporting.

Michel Dänzer daenzer at kemper.freedesktop.org
Wed Aug 26 11:19:41 UTC 2009


Module: Mesa
Branch: master
Commit: b2e1b258812167ce8d33f5978f877439e280a1e4
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=b2e1b258812167ce8d33f5978f877439e280a1e4

Author: Michel Dänzer <daenzer at vmware.com>
Date:   Wed Aug 26 13:18:37 2009 +0200

st/xorg: Add support for dirty framebuffer region reporting.

Add a BlockHandler which flushes the context and reports the dirty region
gathered using the X server damage layer.

In the interim, with dirty region reporting only allocate textures for the
framebuffer and shared pixmaps (e.g. DRI2 buffers) and fall back to software
for other pixmaps. This will be improved in the future.

---

 src/gallium/state_trackers/xorg/xorg_driver.c  |   65 ++++++++++++++++++++++++
 src/gallium/state_trackers/xorg/xorg_exa.c     |   14 +++++-
 src/gallium/state_trackers/xorg/xorg_tracker.h |    8 +++
 3 files changed, 86 insertions(+), 1 deletions(-)

diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index 53d1a33..923662b 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -54,6 +54,7 @@
 
 #include <pciaccess.h>
 
+#include "pipe/p_context.h"
 #include "xorg_tracker.h"
 #include "xorg_winsys.h"
 
@@ -424,6 +425,44 @@ RestoreHWState(ScrnInfoPtr pScrn)
     return TRUE;
 }
 
+static void xorgBlockHandler(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 = xorgBlockHandler;
+
+    ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+    {
+	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;
+
+	    for (i = 0; i < num_cliprects; i++, rect++) {
+		clip[i].x = rect->x1;
+		clip[i].y = rect->y1;
+		clip[i].width = rect->x2 - rect->x1;
+		clip[i].height = rect->y2 - rect->y1;
+	    }
+
+	    /* TODO query connector property to see if this is needed */
+	    drmModeDirtyFB(ms->fd, ms->fb_id, clip, num_cliprects);
+
+	    DamageEmpty(ms->damage);
+	}
+    }
+#endif
+}
+
 static Bool
 CreateScreenResources(ScreenPtr pScreen)
 {
@@ -460,6 +499,21 @@ CreateScreenResources(ScreenPtr pScreen)
 
     AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
 
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+    ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
+                              pScreen, rootPixmap);
+
+    if (ms->damage) {
+       DamageRegister(&rootPixmap->drawable, ms->damage);
+
+       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n");
+    } else {
+       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                  "Failed to create screen damage record\n");
+       return FALSE;
+    }
+#endif
+
     return ret;
 }
 
@@ -536,6 +590,8 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 
     fbPictureInit(pScreen, NULL, 0);
 
+    ms->blockHandler = pScreen->BlockHandler;
+    pScreen->BlockHandler = xorgBlockHandler;
     ms->createScreenResources = pScreen->CreateScreenResources;
     pScreen->CreateScreenResources = CreateScreenResources;
 
@@ -699,8 +755,17 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
     driCloseScreen(pScreen);
 #endif
 
+    pScreen->BlockHandler = ms->blockHandler;
     pScreen->CreateScreenResources = ms->createScreenResources;
 
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+    if (ms->damage) {
+	DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, ms->damage);
+	DamageDestroy(ms->damage);
+	ms->damage = NULL;
+    }
+#endif
+
     if (ms->exa)
 	xorg_exa_close(pScrn);
 
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index 9f3f82c..3c90c2c 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -472,7 +472,11 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
 	pipe_texture_reference(&priv->tex, NULL);
     }
 
-    if (!priv->tex) {
+    if (!priv->tex
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+	&& priv->flags
+#endif
+	) {
 	struct pipe_texture template;
 
 	memset(&template, 0, sizeof(template));
@@ -488,6 +492,14 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
 	priv->tex = exa->scrn->texture_create(exa->scrn, &template);
     }
 
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+    if (!priv->tex) {
+	if (pPixData)
+	    pPixmap->devPrivate.ptr = pPixData;
+	else
+	    pPixmap->devPrivate.ptr = xalloc(pPixmap->drawable.height * pPixmap->devKind);
+    } else
+#endif
     if (pPixData) {
 	struct pipe_transfer *transfer =
 	    exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h
index 910782d..da850bb 100644
--- a/src/gallium/state_trackers/xorg/xorg_tracker.h
+++ b/src/gallium/state_trackers/xorg/xorg_tracker.h
@@ -41,6 +41,10 @@
 #include <xf86.h>
 #include <exa.h>
 
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+#include <damage.h>
+#endif
+
 #include "pipe/p_screen.h"
 #include "state_tracker/drm_api.h"
 
@@ -76,6 +80,7 @@ typedef struct _modesettingRec
 
     unsigned int SaveGeneration;
 
+    void (*blockHandler)(int, pointer, pointer, pointer);
     CreateScreenResourcesProcPtr createScreenResources;
 
     /* gallium */
@@ -87,6 +92,9 @@ typedef struct _modesettingRec
     void *exa;
     Bool noEvict;
 
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+    DamagePtr damage;
+#endif
 } modesettingRec, *modesettingPtr;
 
 #define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))




More information about the mesa-commit mailing list