From 255152a21f875f02ea5a4d775fc4a8f4b0e7c6e6 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 11 May 2012 16:34:46 +0100 Subject: dirty pixmap tracking --- src/drmmode_display.c | 5 ++ src/nouveau_dri2.c | 31 +++++++----- src/nouveau_xv.c | 2 + src/nv_driver.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++---- src/nv_type.h | 10 ++++ 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)) -- cgit v1.2.3