[PATCH 28/36] dix/pixmap: track dirty pixmaps in server. (v2)
Dave Airlie
airlied at gmail.com
Mon Jul 2 03:13:21 PDT 2012
From: Dave Airlie <airlied at redhat.com>
This adds two functions for drivers to use directly to keep a
linked list of slave pixmaps to do damage tracking on and keep
updated. It also adds a helper function that drivers may optionally
call to do a simple copy area damage update.
v2: use damage.h not damagestr.h, fixes ephyr build.
Signed-off-by: Dave Airlie <airlied at redhat.com>
---
dix/dispatch.c | 1 +
dix/pixmap.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/pixmap.h | 16 +++++++++
include/pixmapstr.h | 8 +++++
include/scrnintstr.h | 2 ++
5 files changed, 118 insertions(+)
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 59dce2f..417fcf4 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3740,6 +3740,7 @@ static int init_screen(ScreenPtr pScreen, int i, Bool gpu)
pScreen->ClipNotify = 0; /* for R4 ddx compatibility */
pScreen->CreateScreenResources = 0;
+ xorg_list_init(&pScreen->pixmap_dirty_list);
xorg_list_init(&pScreen->unattached_list);
xorg_list_init(&pScreen->output_slave_list);
diff --git a/dix/pixmap.c b/dix/pixmap.c
index 993e16e..7a11d1d 100644
--- a/dix/pixmap.c
+++ b/dix/pixmap.c
@@ -158,3 +158,94 @@ PixmapPtr PixmapShareToSlave(PixmapPtr pixmap, ScreenPtr slave)
return spix;
}
+
+Bool
+PixmapStartDirtyTracking(PixmapPtr src,
+ PixmapPtr dst_slave,
+ int x, int y)
+{
+ ScreenPtr screen = src->drawable.pScreen;
+ PixmapDirtyUpdatePtr dirty_update;
+
+ dirty_update = calloc(1, sizeof(PixmapDirtyUpdateRec));
+ if (!dirty_update)
+ return FALSE;
+
+ dirty_update->src = src;
+ dirty_update->slave_dst = dst_slave;
+ dirty_update->x = x;
+ dirty_update->y = y;
+
+ dirty_update->damage = DamageCreate(NULL, NULL,
+ DamageReportNone,
+ TRUE, src->drawable.pScreen,
+ src->drawable.pScreen);
+ DamageRegister(&src->drawable, dirty_update->damage);
+ xorg_list_add(&dirty_update->ent, &screen->pixmap_dirty_list);
+ return TRUE;
+}
+
+Bool
+PixmapStopDirtyTracking(PixmapPtr src, PixmapPtr slave_dst)
+{
+ ScreenPtr screen = src->drawable.pScreen;
+ PixmapDirtyUpdatePtr ent, safe;
+
+ xorg_list_for_each_entry_safe(ent, safe, &screen->pixmap_dirty_list, ent) {
+ if (ent->src == src && ent->slave_dst == slave_dst) {
+ DamageUnregister(&src->drawable, ent->damage);
+ DamageDestroy(ent->damage);
+ xorg_list_del(&ent->ent);
+ free(ent);
+ }
+ }
+ return TRUE;
+}
+
+Bool PixmapSyncDirtyHelper(PixmapDirtyUpdatePtr dirty, RegionPtr dirty_region)
+{
+ ScreenPtr pScreen = dirty->src->drawable.pScreen;
+ int n;
+ BoxPtr b;
+ RegionPtr region = DamageRegion(dirty->damage);
+ GCPtr pGC;
+ PixmapPtr dst;
+ SourceValidateProcPtr SourceValidate;
+
+ SourceValidate = pScreen->SourceValidate;
+ pScreen->SourceValidate = NULL;
+
+ RegionTranslate(dirty_region, dirty->x, dirty->y);
+ RegionIntersect(dirty_region, dirty_region, region);
+
+ if (RegionNil(dirty_region)) {
+ RegionUninit(dirty_region);
+ return FALSE;
+ }
+
+ dst = dirty->slave_dst->master_pixmap;
+
+ RegionTranslate(dirty_region, -dirty->x, -dirty->y);
+ n = RegionNumRects(dirty_region);
+ b = RegionRects(dirty_region);
+
+ pGC = GetScratchGC(dirty->src->drawable.depth, pScreen);
+ ValidateGC(&dst->drawable, pGC);
+
+ while (n--) {
+ BoxRec dst_box;
+ int w, h;
+
+ dst_box = *b;
+ w = dst_box.x2 - dst_box.x1;
+ h = dst_box.y2 - dst_box.y1;
+
+ pGC->ops->CopyArea(&dirty->src->drawable, &dst->drawable, pGC,
+ dirty->x + dst_box.x1, dirty->y + dst_box.y1, w, h, dst_box.x1, dst_box.y1);
+ b++;
+ }
+ FreeScratchGC(pGC);
+
+ pScreen->SourceValidate = SourceValidate;
+ return TRUE;
+}
diff --git a/include/pixmap.h b/include/pixmap.h
index 8c523bd..3e0daef 100644
--- a/include/pixmap.h
+++ b/include/pixmap.h
@@ -49,6 +49,7 @@ SOFTWARE.
#include "misc.h"
#include "screenint.h"
+#include "regionstr.h"
/* types for Drawable */
#define DRAWABLE_WINDOW 0
@@ -73,6 +74,8 @@ SOFTWARE.
typedef struct _Drawable *DrawablePtr;
typedef struct _Pixmap *PixmapPtr;
+typedef struct _PixmapDirtyUpdate *PixmapDirtyUpdatePtr;
+
typedef union _PixUnion {
PixmapPtr pixmap;
unsigned long pixel;
@@ -112,4 +115,17 @@ extern _X_EXPORT void FreePixmap(PixmapPtr /*pPixmap */ );
extern _X_EXPORT PixmapPtr
PixmapShareToSlave(PixmapPtr pixmap, ScreenPtr slave);
+extern _X_EXPORT Bool
+PixmapStartDirtyTracking(PixmapPtr src,
+ PixmapPtr dst_slave,
+ int x, int y);
+
+extern _X_EXPORT Bool
+PixmapStopDirtyTracking(PixmapPtr src, PixmapPtr slave_dst);
+
+/* helper function, drivers can do this themselves if they can do it more
+ efficently */
+extern _X_EXPORT Bool
+PixmapSyncDirtyHelper(PixmapDirtyUpdatePtr dirty, RegionPtr dirty_region);
+
#endif /* PIXMAP_H */
diff --git a/include/pixmapstr.h b/include/pixmapstr.h
index 40af5c4..a0b3269 100644
--- a/include/pixmapstr.h
+++ b/include/pixmapstr.h
@@ -50,6 +50,7 @@ SOFTWARE.
#include "screenint.h"
#include "regionstr.h"
#include "privates.h"
+#include "damage.h"
typedef struct _Drawable {
unsigned char type; /* DRAWABLE_<type> */
@@ -84,6 +85,13 @@ typedef struct _Pixmap {
PixmapPtr master_pixmap; /* pointer to master copy of pixmap for pixmap sharing */
} PixmapRec;
+typedef struct _PixmapDirtyUpdate {
+ PixmapPtr dst, src, slave_dst;
+ int x, y;
+ DamagePtr damage;
+ struct xorg_list ent;
+} PixmapDirtyUpdateRec;
+
static inline void
PixmapBox(BoxPtr box, PixmapPtr pixmap)
{
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index 5b9f245..caa6509 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -503,6 +503,8 @@ typedef struct _Screen {
StartPixmapTrackingProcPtr StartPixmapTracking;
StopPixmapTrackingProcPtr StopPixmapTracking;
+
+ struct xorg_list pixmap_dirty_list;
} ScreenRec;
static inline RegionPtr
--
1.7.10.2
More information about the xorg-devel
mailing list