diff options
author | Dave Airlie <airlied@redhat.com> | 2012-07-26 10:37:04 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-09-03 12:28:29 +1000 |
commit | 6705d8237aca90964449e4dbee97b4f62b87c28b (patch) | |
tree | ed10f61099cc352b170c69a2e7f95299e8f905cf /src/intel_display.c | |
parent | 69827126abdfa289417b55fe7db8ae0535037185 (diff) |
intel: add pixmap tracking and scanout support. (v2)
This adds support for pixmap tracking and scanout of
alternate pixmaps.
v2: do dirty updates after uxa block handler, check if kernel
can flush vmap for us so we don't have to.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'src/intel_display.c')
-rw-r--r-- | src/intel_display.c | 60 |
1 files changed, 56 insertions, 4 deletions
diff --git a/src/intel_display.c b/src/intel_display.c index 6dfc8e63..4bc8a7b4 100644 --- a/src/intel_display.c +++ b/src/intel_display.c @@ -86,6 +86,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 { @@ -378,6 +380,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; @@ -401,13 +404,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, @@ -421,6 +426,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, @@ -684,6 +693,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, @@ -697,6 +742,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 @@ -1662,6 +1710,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; |