diff options
author | Dave Airlie <airlied@redhat.com> | 2012-05-11 16:34:56 +0100 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-05-11 16:34:56 +0100 |
commit | b6b402241099daa5c040936e294e3e954c365444 (patch) | |
tree | bc68d02628d88ae9013ee4bcbc48f04dac7e9cc2 | |
parent | ff202f5065a899c4614f427368d98d5bdd2c552c (diff) |
dirty pixmap trackingdrvmodelv3
-rw-r--r-- | src/intel.h | 11 | ||||
-rw-r--r-- | src/intel_display.c | 50 | ||||
-rw-r--r-- | src/intel_driver.c | 122 | ||||
-rw-r--r-- | src/intel_module.c | 3 | ||||
-rw-r--r-- | src/intel_uxa.c | 2 |
5 files changed, 181 insertions, 7 deletions
diff --git a/src/intel.h b/src/intel.h index d0493486..e8be837f 100644 --- a/src/intel.h +++ b/src/intel.h @@ -156,6 +156,14 @@ enum dri_type { DRI_DRI2 }; +typedef struct _DirtyUpdate { + PixmapPtr dst, src, slave_dst;; + int x, y; + DamagePtr damage; + struct xorg_list ent; +} DirtyUpdateRec, *DirtyUpdatePtr; + + typedef struct intel_screen_private { ScrnInfoPtr scrn; int cpp; @@ -166,6 +174,7 @@ typedef struct intel_screen_private { void *modes; drm_intel_bo *front_buffer, *back_buffer; + drm_intel_bo *slave_front_buffer; PixmapPtr back_pixmap; unsigned int back_name; long front_pitch, front_tiling; @@ -353,6 +362,8 @@ typedef struct intel_screen_private { struct udev_monitor *uevent_monitor; InputHandlerProc uevent_handler; #endif + struct xorg_list dirty_list; + int fb_id; } intel_screen_private; enum { diff --git a/src/intel_display.c b/src/intel_display.c index 63c68310..e4d029a2 100644 --- a/src/intel_display.c +++ b/src/intel_display.c @@ -340,6 +340,7 @@ intel_crtc_apply(xf86CrtcPtr crtc) ScrnInfoPtr scrn = crtc->scrn; struct intel_crtc *intel_crtc = crtc->driver_private; struct intel_mode *mode = intel_crtc->mode; + intel_screen_private *intel = intel_get_screen_private(scrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); uint32_t *output_ids; int output_count = 0; @@ -363,13 +364,15 @@ intel_crtc_apply(xf86CrtcPtr crtc) output_count++; } + if (!intel->fb_id) { #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,5,99,0,0) - if (!xf86CrtcRotate(crtc, mode, rotation)) - goto done; + if (!xf86CrtcRotate(crtc, mode, rotation)) + goto done; #else - if (!xf86CrtcRotate(crtc)) - goto done; + if (!xf86CrtcRotate(crtc)) + goto done; #endif + } #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,0,0,0) crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, @@ -383,7 +386,12 @@ intel_crtc_apply(xf86CrtcPtr crtc) fb_id = intel_crtc->rotate_fb_id; x = 0; y = 0; + } else if (intel->fb_id) { + fb_id = intel->fb_id; + x = 0; + y = 0; } + ret = drmModeSetCrtc(mode->fd, crtc_id(intel_crtc), fb_id, x, y, output_ids, output_count, &intel_crtc->kmode); @@ -646,6 +654,35 @@ intel_crtc_destroy(xf86CrtcPtr crtc) crtc->driver_private = NULL; } +static Bool +intel_set_slave_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) +{ + ScrnInfoPtr scrn = crtc->scrn; + intel_screen_private *intel = intel_get_screen_private(scrn); + dri_bo *bo; + int ret; + + if (!ppix) { + intel->front_buffer = intel->slave_front_buffer; + intel->fb_id = 0; + return TRUE; + } + + bo = intel_get_pixmap_bo(ppix); + if (intel->front_buffer) { + ErrorF("have front buffer\n"); + } + + intel->slave_front_buffer = intel->front_buffer; + intel->front_buffer = bo; + + ret = drmModeAddFB(intel->drmSubFD, ppix->drawable.width, + ppix->drawable.height, ppix->drawable.depth, + ppix->drawable.bitsPerPixel, ppix->devKind, + bo->handle, &intel->fb_id); + return TRUE; +} + static const xf86CrtcFuncsRec intel_crtc_funcs = { .dpms = intel_crtc_dpms, .set_mode_major = intel_crtc_set_mode_major, @@ -659,6 +696,7 @@ static const xf86CrtcFuncsRec intel_crtc_funcs = { .shadow_destroy = intel_crtc_shadow_destroy, .gamma_set = intel_crtc_gamma_set, .destroy = intel_crtc_destroy, + .set_slave_pixmap = intel_set_slave_pixmap, }; static void @@ -1651,6 +1689,10 @@ Bool intel_mode_pre_init(ScrnInfoPtr scrn, int fd, int cpp) for (i = 0; i < mode->mode_res->count_connectors; i++) intel_output_init(scrn, mode, i); + { + xf86ProviderPtr provider; + provider = xf86ProviderCreate(scrn); + } xf86InitialConfiguration(scrn, TRUE); has_flipping = 0; diff --git a/src/intel_driver.c b/src/intel_driver.c index 624bf115..12beb4c2 100644 --- a/src/intel_driver.c +++ b/src/intel_driver.c @@ -555,7 +555,7 @@ static Bool I830PreInit(ScrnInfoPtr scrn, int flags) intel->pEnt = pEnt; scrn->displayWidth = 640; /* default it */ - + list_init(&intel->dirty_list); if (intel->pEnt->location.type != BUS_PCI && intel->pEnt->location.type != BUS_UDEV) return FALSE; @@ -736,12 +736,80 @@ void IntelEmitInvarientState(ScrnInfoPtr scrn) I915EmitInvarientState(scrn); } +static Bool +redisplay_dirty(ScreenPtr screen, DirtyUpdatePtr dirty) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + intel_screen_private *intel = intel_get_screen_private(scrn); + GCPtr pGC; + RegionPtr region = DamageRegion(dirty->damage); + RegionRec pixregion; + int n; + BoxPtr b; + miCopyProc copy_proc; + PixmapRegionInit(&pixregion, dirty->dst); + RegionTranslate(&pixregion, dirty->x, dirty->y); + RegionIntersect(&pixregion, &pixregion, region); + + if (RegionNil(&pixregion)) { + RegionUninit(&pixregion); + return FALSE;; + } + + 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); + + intel_batch_submit(scrn); + { + drm_intel_bo *bo = intel_get_pixmap_bo(dirty->dst); + drm_intel_bo_map(bo, FALSE); + drm_intel_bo_unmap(bo); + } + DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion); + RegionUninit(&pixregion); + return 0; +} + +static void +intel_dirty_update(ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + intel_screen_private *intel = intel_get_screen_private(scrn); + RegionPtr region; + DirtyUpdatePtr ent; + + if (xorg_list_is_empty(&intel->dirty_list)) + return; + + xorg_list_for_each_entry(ent, &intel->dirty_list, ent) { + region = DamageRegion(ent->damage); + if (RegionNotEmpty(region)) { + redisplay_dirty(screen, ent); + DamageEmpty(ent->damage); + } + } +} + static void I830BlockHandler(ScreenPtr screen, pointer blockData, pointer pTimeout, pointer pReadmask) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); + intel_dirty_update(screen); + screen->BlockHandler = intel->BlockHandler; (*screen->BlockHandler) (screen, blockData, pTimeout, pReadmask); @@ -754,6 +822,55 @@ I830BlockHandler(ScreenPtr screen, pointer blockData, pointer pTimeout, pointer } static Bool +intel_start_pixmap_tracking(PixmapPtr dst, + PixmapPtr src, + PixmapPtr dst_slave, + int x, int y) +{ + ScreenPtr screen = src->drawable.pScreen; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + intel_screen_private *intel = intel_get_screen_private(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, &intel->dirty_list); + return TRUE; +} + +static Bool +intel_stop_pixmap_tracking(PixmapPtr src, PixmapPtr dst) +{ + ScreenPtr screen = src->drawable.pScreen; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + intel_screen_private *intel = intel_get_screen_private(scrn); + DirtyUpdatePtr ent, safe; + + xorg_list_for_each_entry_safe(ent, safe, &intel->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 intel_init_initial_framebuffer(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); @@ -1013,6 +1130,9 @@ I830ScreenInit(ScreenPtr screen, int argc, char **argv) intel->BlockHandler = screen->BlockHandler; screen->BlockHandler = I830BlockHandler; + screen->StartPixmapTracking = intel_start_pixmap_tracking; + screen->StopPixmapTracking = intel_stop_pixmap_tracking; + if (!AddCallback(&FlushCallback, intel_flush_callback, scrn)) return FALSE; diff --git a/src/intel_module.c b/src/intel_module.c index 97a05872..d49ef85d 100644 --- a/src/intel_module.c +++ b/src/intel_module.c @@ -385,7 +385,8 @@ intel_udev_probe(DriverPtr driver, xf86AddEntityToScreen(scrn, entity_num); intel_init_scrn(scrn); - scrn->roles = ROLE_MASTER | ROLE_SLAVE_OUTPUT; + scrn->roles = RR_Role_Master | RR_Role_Slave_Output; + scrn->abilities = RR_Ability_Offload_Slaves | RR_Ability_Output_Slaves; xf86DrvMsg(scrn->scrnIndex, X_INFO, "using drv %s\n", dev ? dev->path : "Default device"); diff --git a/src/intel_uxa.c b/src/intel_uxa.c index bb032bee..75185da1 100644 --- a/src/intel_uxa.c +++ b/src/intel_uxa.c @@ -932,7 +932,7 @@ static Bool intel_uxa_get_image(PixmapPtr pixmap, FreeScratchGC(gc); - intel_batch_submit(xf86Screens[screen->myNum]); + intel_batch_submit(xf86ScreenToScrn(screen)); x = y = 0; pixmap = scratch; |