summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-05-11 16:34:56 +0100
committerDave Airlie <airlied@redhat.com>2012-05-11 16:34:56 +0100
commitb6b402241099daa5c040936e294e3e954c365444 (patch)
treebc68d02628d88ae9013ee4bcbc48f04dac7e9cc2
parentff202f5065a899c4614f427368d98d5bdd2c552c (diff)
dirty pixmap trackingdrvmodelv3
-rw-r--r--src/intel.h11
-rw-r--r--src/intel_display.c50
-rw-r--r--src/intel_driver.c122
-rw-r--r--src/intel_module.c3
-rw-r--r--src/intel_uxa.c2
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;