summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-05-11 16:34:46 +0100
committerDave Airlie <airlied@redhat.com>2012-05-11 16:34:46 +0100
commit255152a21f875f02ea5a4d775fc4a8f4b0e7c6e6 (patch)
tree740dc2e48d9e06ec8f309383baa147087ec2e637
parent8d50b443fb466cc7abc8e267594a96231ad3aea8 (diff)
dirty pixmap trackingdrvmodelv3
-rw-r--r--src/drmmode_display.c5
-rw-r--r--src/nouveau_dri2.c31
-rw-r--r--src/nouveau_xv.c2
-rw-r--r--src/nv_driver.c138
-rw-r--r--src/nv_type.h10
5 files changed, 163 insertions, 23 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 3276e80..b1d973b 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1199,6 +1199,11 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp)
for (i = 0; i < drmmode->mode_res->count_connectors; i++)
drmmode_output_init(pScrn, drmmode, i);
+ {
+ xf86ProviderPtr provider;
+
+ provider = xf86ProviderCreate(pScrn);
+ }
xf86InitialConfiguration(pScrn, TRUE);
return TRUE;
diff --git a/src/nouveau_dri2.c b/src/nouveau_dri2.c
index 7b700f6..05a7474 100644
--- a/src/nouveau_dri2.c
+++ b/src/nouveau_dri2.c
@@ -90,6 +90,7 @@ nouveau_dri2_create_buffer(DrawablePtr pDraw, unsigned int attachment,
return &nvbuf->base;
}
+
void
nouveau_dri2_destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buf)
{
@@ -114,9 +115,11 @@ nouveau_dri2_create_buffer_pixmap(ScreenPtr pScreen, PixmapPtr pPixmap,
PixmapPtr ppix = NULL;
if (attachment == DRI2BufferFrontLeft) {
- ppix = pPixmap;
- /* TODO set swap limit */
- ppix->refcnt++;
+ if (pPixmap->drawable.pScreen == pScreen) {
+ ppix = pPixmap;
+ /* TODO set swap limit */
+ ppix->refcnt++;
+ }
} else {
int bpp;
unsigned int usage_hint = NOUVEAU_CREATE_PIXMAP_TILED;
@@ -133,15 +136,17 @@ nouveau_dri2_create_buffer_pixmap(ScreenPtr pScreen, PixmapPtr pPixmap,
ppix = pScreen->CreatePixmap(pScreen, w, h, bpp,
usage_hint);
}
- pNv->exa_force_cp = TRUE;
- exaMoveInPixmap(ppix);
- pNv->exa_force_cp = FALSE;
+ if (ppix) {
+ pNv->exa_force_cp = TRUE;
+ exaMoveInPixmap(ppix);
+ pNv->exa_force_cp = FALSE;
- nvpix = nouveau_pixmap(ppix);
- if (!nvpix || !nvpix->bo ||
- nouveau_bo_name_get(nvpix->bo, name)) {
- pScreen->DestroyPixmap(ppix);
- return NULL;
+ nvpix = nouveau_pixmap(ppix);
+ if (!nvpix || !nvpix->bo ||
+ nouveau_bo_name_get(nvpix->bo, name)) {
+ pScreen->DestroyPixmap(ppix);
+ return NULL;
+ }
}
return ppix;
}
@@ -154,10 +159,10 @@ nouveau_dri2_destroy_buffer_pixmap(PixmapPtr pixmap)
static void
nouveau_dri2_copy_region_pixmap(PixmapPtr src, PixmapPtr dst,
- RegionPtr pRegion, RegionPtr f_c,
+ RegionPtr pRegion, int x, int y,
DRI2CopyPixmapPtrCB cb)
{
- cb(src, dst, pRegion, f_c);
+ cb(src, dst, pRegion, x, y);
}
void
diff --git a/src/nouveau_xv.c b/src/nouveau_xv.c
index 11248e6..e65d61f 100644
--- a/src/nouveau_xv.c
+++ b/src/nouveau_xv.c
@@ -2111,6 +2111,8 @@ NVInitVideo(ScreenPtr pScreen)
}
}
+ num_adaptors = 0; // TODO
+ return;
if (num_adaptors)
xf86XVScreenInit(pScreen, adaptors, num_adaptors);
if (newAdaptors)
diff --git a/src/nv_driver.c b/src/nv_driver.c
index 72cc8da..2270144 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -115,7 +115,8 @@ NVUdevProbe(DriverPtr driver,
scrn->EnterVT = NVEnterVT;
scrn->LeaveVT = NVLeaveVT;
scrn->FreeScreen = NVFreeScreen;
- scrn->roles = ROLE_MASTER | ROLE_SLAVE_OFFLOAD;
+ scrn->roles = RR_Role_Master | RR_Role_Slave_Offload;
+ scrn->abilities = RR_Ability_Output_Slaves;
return scrn != NULL;
}
/*
@@ -418,6 +419,68 @@ NVFlushCallback(CallbackListPtr *list, pointer user_data, pointer call_data)
nouveau_pushbuf_kick(pNv->pushbuf, pNv->pushbuf->channel);
}
+static void
+redisplay_dirty(ScreenPtr screen, DirtyUpdatePtr dirty)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ NVPtr pNv = NVPTR(scrn);
+ RegionPtr region = DamageRegion(dirty->damage);
+ RegionRec pixregion;
+ BoxPtr b;
+ int n;
+ GCPtr pGC;
+ miCopyProc copy_proc;
+
+ PixmapRegionInit(&pixregion, dirty->dst);
+ RegionTranslate(&pixregion, dirty->x, dirty->y);
+ RegionIntersect(&pixregion, &pixregion, region);
+
+ if (RegionNil(&pixregion)) {
+ RegionUninit(&pixregion);
+ return;
+ }
+
+ RegionTranslate(&pixregion, -dirty->x, -dirty->y);
+ n = RegionNumRects(&pixregion);
+ b = RegionRects(&pixregion);
+
+ copy_proc = screen->GetCopyAreaFunction(&dirty->src->drawable,
+ &dirty->dst->drawable);
+
+ pGC = GetScratchGC(dirty->src->drawable.depth, screen);
+ ValidateGC(&dirty->dst->drawable, pGC);
+ miCopyRegion(&dirty->src->drawable,
+ &dirty->dst->drawable,
+ pGC, &pixregion, dirty->x, dirty->y,
+ copy_proc, 0, NULL);
+ FreeScratchGC(pGC);
+
+ DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion);
+ RegionUninit(&pixregion);
+}
+
+static void
+nouveau_dirty_update(ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ NVPtr pNv = NVPTR(scrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ RegionPtr region;
+ DirtyUpdatePtr ent;
+
+ if (xorg_list_is_empty(&pNv->dirty_list))
+ return;
+
+ xorg_list_for_each_entry(ent, &pNv->dirty_list, ent) {
+ region = DamageRegion(ent->damage);
+ if (RegionNotEmpty(region)) {
+ redisplay_dirty(screen, ent);
+ DamageEmpty(ent->damage);
+ }
+ }
+}
+
+
#if 0
static void
NVBlockHandler_old (
@@ -454,6 +517,8 @@ NVBlockHandler (
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
NVPtr pNv = NVPTR(pScrn);
+ nouveau_dirty_update(pScreen);
+
pScreen->BlockHandler = pNv->BlockHandler;
(*pScreen->BlockHandler) (pScreen, blockData, pTimeout, pReadmask);
pScreen->BlockHandler = NVBlockHandler;
@@ -465,6 +530,53 @@ NVBlockHandler (
(*pNv->VideoTimerCallback)(pScrn, currentTime.milliseconds);
}
+static
+void nouveau_start_pixmap_tracking(PixmapPtr dst, PixmapPtr src,
+ PixmapPtr dst_slave, int x, int y)
+{
+ ScreenPtr screen = dst->drawable.pScreen;
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ NVPtr pNv = NVPTR(scrn);
+ DirtyUpdatePtr dirty_update;
+
+ dirty_update = calloc(1, sizeof(DirtyUpdateRec));
+ if (!dirty_update)
+ return FALSE;
+
+ dirty_update->dst = dst;
+ 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, &pNv->dirty_list);
+ return TRUE;
+}
+
+static Bool
+nouveau_stop_pixmap_tracking(PixmapPtr src, PixmapPtr dst)
+{
+ ScreenPtr screen = src->drawable.pScreen;
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ NVPtr pNv = NVPTR(scrn);
+ DirtyUpdatePtr ent, safe;
+
+ xorg_list_for_each_entry_safe(ent, safe, &pNv->dirty_list, ent) {
+ if (ent->src == src && ent->dst == dst) {
+ DamageUnregister(&src->drawable, ent->damage);
+ DamageDestroy(ent->damage);
+ xorg_list_del(&ent->ent);
+ free(ent);
+ }
+ }
+ return TRUE;
+}
+
static Bool
NVCreateScreenResources(ScreenPtr pScreen)
{
@@ -707,6 +819,7 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
pNv = NVPTR(pScrn);
+ xorg_list_init(&pNv->dirty_list);
/* Get the entity, and make sure it is PCI. */
pNv->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
if (pNv->pEnt->location.type != BUS_PCI && pNv->pEnt->location.type != BUS_UDEV)
@@ -1236,15 +1349,17 @@ NVScreenInit(ScreenPtr pScreen, int argc, char **argv)
return FALSE;
/* Fixup RGB ordering */
- visual = pScreen->visuals + pScreen->numVisuals;
- while (--visual >= pScreen->visuals) {
- if ((visual->class | DynamicClass) == DirectColor) {
- visual->offsetRed = pScrn->offset.red;
- visual->offsetGreen = pScrn->offset.green;
- visual->offsetBlue = pScrn->offset.blue;
- visual->redMask = pScrn->mask.red;
- visual->greenMask = pScrn->mask.green;
- visual->blueMask = pScrn->mask.blue;
+ if (!pScreen->isGPU) {
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
}
}
@@ -1311,6 +1426,9 @@ NVScreenInit(ScreenPtr pScreen, int argc, char **argv)
pNv->CreateScreenResources = pScreen->CreateScreenResources;
pScreen->CreateScreenResources = NVCreateScreenResources;
+ pScreen->StartPixmapTracking = nouveau_start_pixmap_tracking;
+ pScreen->StopPixmapTracking = nouveau_stop_pixmap_tracking;
+
if (!xf86CrtcScreenInit(pScreen))
return FALSE;
diff --git a/src/nv_type.h b/src/nv_type.h
index 43f146b..73822d1 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -26,6 +26,13 @@
#define NV_ARCH_C0 0xc0
#define NV_ARCH_E0 0xe0
+typedef struct _DirtyUpdate {
+ PixmapPtr dst, src, slave_dst;
+ int x, y;
+ DamagePtr damage;
+ struct xorg_list ent;
+} DirtyUpdateRec, *DirtyUpdatePtr;
+
/* NV50 */
typedef struct _NVRec *NVPtr;
typedef struct _NVRec {
@@ -108,6 +115,9 @@ typedef struct _NVRec {
PixmapPtr pspix, pmpix, pdpix;
PicturePtr pspict, pmpict;
Pixel fg_colour;
+
+ struct xorg_list dirty_list;
+
} NVRec;
#define NVPTR(p) ((NVPtr)((p)->driverPrivate))