From: Dave Airlie <airl...@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 <airl...@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 29ac5a4..bc803d7 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 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel