[PATCH 25/36] dix/pixmap: track dirty pixmaps in server. (v3)
Dave Airlie
airlied at gmail.com
Thu Jul 5 08:21:26 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.
v3: address ajax review: use slave_dst, drop unused dst member.
Signed-off-by: Dave Airlie <airlied at redhat.com>
---
dix/dispatch.c | 1 +
dix/pixmap.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++----
include/pixmap.h | 16 ++++++++
include/pixmapstr.h | 8 ++++
include/scrnintstr.h | 2 +
5 files changed, 125 insertions(+), 7 deletions(-)
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 2eb13db..78afe91 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3742,6 +3742,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 7272098..01e1635 100644
--- a/dix/pixmap.c
+++ b/dix/pixmap.c
@@ -140,21 +140,112 @@ PixmapPtr PixmapShareToSlave(PixmapPtr pixmap, ScreenPtr slave)
ret = master->SharePixmapBacking(pixmap, slave, &handle);
if (ret == FALSE)
- return NULL;
-
+ return NULL;
+
spix = slave->CreatePixmap(slave, 0, 0, depth,
- CREATE_PIXMAP_USAGE_SHARED);
+ CREATE_PIXMAP_USAGE_SHARED);
slave->ModifyPixmapHeader(spix, pixmap->drawable.width,
- pixmap->drawable.height, depth, 0,
- pixmap->devKind, NULL);
+ pixmap->drawable.height, depth, 0,
+ pixmap->devKind, NULL);
spix->master_pixmap = pixmap;
ret = slave->SetSharedPixmapBacking(spix, handle);
if (ret == FALSE) {
- slave->DestroyPixmap(spix);
- return NULL;
+ slave->DestroyPixmap(spix);
+ return NULL;
}
return spix;
}
+
+Bool
+PixmapStartDirtyTracking(PixmapPtr src,
+ PixmapPtr slave_dst,
+ 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 = slave_dst;
+ 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..921a94d 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 slave_dst,
+ 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..2a1ef9b 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 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 3a738d3..5ef37ed 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -505,6 +505,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