summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-07-26 10:37:04 +1000
committerDave Airlie <airlied@redhat.com>2012-07-26 10:37:48 +1000
commit87a58bf2020b0c3155d2ff1c4a8e3f068467b0f6 (patch)
treee52e3270bf09e8be95b4bef67c0a56a01439eab3
parentdcd66cdec5dced6113e4e97349a564d59937fa69 (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.h4
-rw-r--r--src/intel_display.c60
-rw-r--r--src/intel_driver.c53
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;