diff options
author | Dave Airlie <airlied@redhat.com> | 2012-07-26 10:37:04 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-07-26 10:37:48 +1000 |
commit | 87a58bf2020b0c3155d2ff1c4a8e3f068467b0f6 (patch) | |
tree | e52e3270bf09e8be95b4bef67c0a56a01439eab3 | |
parent | dcd66cdec5dced6113e4e97349a564d59937fa69 (diff) |
intel: add pixmap tracking and scanout support.
This adds support for pixmap tracking and scanout of
alternate pixmaps.
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | src/intel.h | 4 | ||||
-rw-r--r-- | src/intel_display.c | 60 | ||||
-rw-r--r-- | src/intel_driver.c | 53 |
3 files changed, 113 insertions, 4 deletions
diff --git a/src/intel.h b/src/intel.h index 0b57aafa..470830ce 100644 --- a/src/intel.h +++ b/src/intel.h @@ -80,6 +80,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define MONITOR_EDID_COMPLETE_RAWDATA EDID_COMPLETE_RAWDATA #endif +#if XF86_CRTC_VERSION >= 5 +#define INTEL_PIXMAP_SHARING 1 +#endif + struct intel_pixmap { dri_bo *bo; diff --git a/src/intel_display.c b/src/intel_display.c index bfe59184..00f895b8 100644 --- a/src/intel_display.c +++ b/src/intel_display.c @@ -85,6 +85,8 @@ struct intel_crtc { uint32_t rotate_fb_id; xf86CrtcPtr crtc; struct list link; + PixmapPtr scanout_pixmap; + uint32_t scanout_fb_id; }; struct intel_property { @@ -359,6 +361,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; @@ -382,13 +385,15 @@ intel_crtc_apply(xf86CrtcPtr crtc) output_count++; } + if (!intel_crtc->scanout_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, @@ -402,6 +407,10 @@ intel_crtc_apply(xf86CrtcPtr crtc) fb_id = intel_crtc->rotate_fb_id; x = 0; y = 0; + } else if (intel_crtc->scanout_fb_id && intel_crtc->scanout_pixmap->drawable.width >= crtc->mode.HDisplay && intel_crtc->scanout_pixmap->drawable.height >= crtc->mode.VDisplay) { + fb_id = intel_crtc->scanout_fb_id; + x = 0; + y = 0; } ret = drmModeSetCrtc(mode->fd, crtc_id(intel_crtc), fb_id, x, y, output_ids, output_count, @@ -665,6 +674,42 @@ intel_crtc_destroy(xf86CrtcPtr crtc) crtc->driver_private = NULL; } +#ifdef INTEL_PIXMAP_SHARING +static Bool +intel_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) +{ + struct intel_crtc *intel_crtc = crtc->driver_private; + ScrnInfoPtr scrn = crtc->scrn; + intel_screen_private *intel = intel_get_screen_private(scrn); + dri_bo *bo; + int ret; + + if (ppix == intel_crtc->scanout_pixmap) + return TRUE; + + if (!ppix) { + intel_crtc->scanout_pixmap = NULL; + if (intel_crtc->scanout_fb_id) { + drmModeRmFB(intel->drmSubFD, intel_crtc->scanout_fb_id); + intel_crtc->scanout_fb_id = 0; + } + return TRUE; + } + + bo = intel_get_pixmap_bo(ppix); + if (intel->front_buffer) { + ErrorF("have front buffer\n"); + } + + intel_crtc->scanout_pixmap = ppix; + ret = drmModeAddFB(intel->drmSubFD, ppix->drawable.width, + ppix->drawable.height, ppix->drawable.depth, + ppix->drawable.bitsPerPixel, ppix->devKind, + bo->handle, &intel_crtc->scanout_fb_id); + return TRUE; +} +#endif + static const xf86CrtcFuncsRec intel_crtc_funcs = { .dpms = intel_crtc_dpms, .set_mode_major = intel_crtc_set_mode_major, @@ -678,6 +723,9 @@ static const xf86CrtcFuncsRec intel_crtc_funcs = { .shadow_destroy = intel_crtc_shadow_destroy, .gamma_set = intel_crtc_gamma_set, .destroy = intel_crtc_destroy, +#ifdef INTEL_PIXMAP_SHARING + .set_scanout_pixmap = intel_set_scanout_pixmap, +#endif }; static void @@ -1643,6 +1691,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); +#ifdef INTEL_PIXMAP_SHARING + xf86ProviderSetup(scrn, NULL, "Intel"); +#endif + xf86InitialConfiguration(scrn, TRUE); mode->event_context.version = DRM_EVENT_CONTEXT_VERSION; diff --git a/src/intel_driver.c b/src/intel_driver.c index b30e7c2b..f58ef5b4 100644 --- a/src/intel_driver.c +++ b/src/intel_driver.c @@ -653,6 +653,50 @@ void IntelEmitInvarientState(ScrnInfoPtr scrn) I915EmitInvarientState(scrn); } +#ifdef INTEL_PIXMAP_SHARING +static Bool +redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + RegionRec pixregion; + int was_blocked; + + PixmapRegionInit(&pixregion, dirty->slave_dst->master_pixmap); + + PixmapSyncDirtyHelper(dirty, &pixregion); + intel_batch_submit(scrn); + was_blocked = xf86BlockSIGIO(); + { + drm_intel_bo *bo = intel_get_pixmap_bo(dirty->slave_dst->master_pixmap); + drm_intel_bo_map(bo, FALSE); + drm_intel_bo_unmap(bo); + } + xf86UnblockSIGIO(was_blocked); + DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion); + RegionUninit(&pixregion); + return 0; +} + +static void +intel_dirty_update(ScreenPtr screen) +{ + RegionPtr region; + PixmapDirtyUpdatePtr ent; + + if (xorg_list_is_empty(&screen->pixmap_dirty_list)) + return; + + ErrorF("list is not empty\n"); + xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) { + region = DamageRegion(ent->damage); + if (RegionNotEmpty(region)) { + redisplay_dirty(screen, ent); + DamageEmpty(ent->damage); + } + } +} +#endif + static void I830BlockHandler(BLOCKHANDLER_ARGS_DECL) { @@ -660,6 +704,10 @@ I830BlockHandler(BLOCKHANDLER_ARGS_DECL) ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); +#ifdef INTEL_PIXMAP_SHARING + intel_dirty_update(screen); +#endif + screen->BlockHandler = intel->BlockHandler; (*screen->BlockHandler) (BLOCKHANDLER_ARGS); @@ -914,6 +962,11 @@ I830ScreenInit(SCREEN_INIT_ARGS_DECL) intel->BlockHandler = screen->BlockHandler; screen->BlockHandler = I830BlockHandler; +#ifdef INTEL_PIXMAP_SHARING + screen->StartPixmapTracking = PixmapStartDirtyTracking; + screen->StopPixmapTracking = PixmapStopDirtyTracking; +#endif + if (!AddCallback(&FlushCallback, intel_flush_callback, scrn)) return FALSE; |