summaryrefslogtreecommitdiff
path: root/src/nv_driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nv_driver.c')
-rw-r--r--src/nv_driver.c69
1 files changed, 66 insertions, 3 deletions
diff --git a/src/nv_driver.c b/src/nv_driver.c
index f14c847..5645f59 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -447,15 +447,78 @@ NVFlushCallback(CallbackListPtr *list, pointer user_data, pointer call_data)
}
#ifdef NOUVEAU_PIXMAP_SHARING
+/*
+ * this function can possibly be improved and optimised, by clipping
+ * instead of iterating
+ */
+Bool nvPixmapSyncDirtyHelper(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 is used by the software cursor code
+ * to pull the cursor off of the screen when reading
+ * bits from the frame buffer. Bypassing this function
+ * leaves the software cursor in place
+ */
+ 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;
+ if (dirty->slave_dst->drawable.pScreen == pScreen)
+ dst = dirty->slave_dst;
+
+ 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;
+}
+
static void
redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty)
{
RegionRec pixregion;
- PixmapRegionInit(&pixregion, dirty->slave_dst->master_pixmap);
+ if (dirty->slave_dst->drawable.pScreen == screen)
+ PixmapRegionInit(&pixregion, dirty->src);
+ else
+ PixmapRegionInit(&pixregion, dirty->slave_dst);
DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion);
- PixmapSyncDirtyHelper(dirty, &pixregion);
+ nvPixmapSyncDirtyHelper(dirty, &pixregion);
DamageRegionProcessPending(&dirty->slave_dst->drawable);
RegionUninit(&pixregion);
@@ -676,7 +739,7 @@ nouveau_setup_capabilities(ScrnInfoPtr pScrn)
if (value & DRM_PRIME_CAP_EXPORT)
pScrn->capabilities |= RR_Capability_SourceOutput;
if (value & DRM_PRIME_CAP_IMPORT)
- pScrn->capabilities |= RR_Capability_SourceOffload;
+ pScrn->capabilities |= RR_Capability_SourceOffload | RR_Capability_SinkOutput;
}
#endif
}