summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-09-07 17:22:31 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-09-07 17:22:31 +0100
commit57bf3d5f0fb4429b0991ad6f22000348820f5bd1 (patch)
treef34036d6539a300e1416ffc8a0313862fd731fc1
parentc17d3b5d5cdbda510a2b6955c3a171457ecde7e5 (diff)
sna: Disable the fb on switching away from X
Currently we turn off the CRTCs when switching away from X in order to not leak our framebuffer. With the new drm_plane support, we can simply unset the framebuffer, which should be a lighterweight operation than disabling the CRTC. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna_display.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 2ba249aa..46fd81fc 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -6245,6 +6245,39 @@ void sna_mode_check(struct sna *sna)
update_flush_interval(sna);
}
+static bool
+sna_crtc_hide_planes(struct sna *sna, struct sna_crtc *crtc)
+{
+#define LOCAL_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct local_mode_set_plane)
+ struct local_mode_set_plane {
+ uint32_t plane_id;
+ uint32_t crtc_id;
+ uint32_t fb_id; /* fb object contains surface format type */
+ uint32_t flags;
+
+ /* Signed dest location allows it to be partially off screen */
+ int32_t crtc_x, crtc_y;
+ uint32_t crtc_w, crtc_h;
+
+ /* Source values are 16.16 fixed point */
+ uint32_t src_x, src_y;
+ uint32_t src_h, src_w;
+ } s;
+
+ if (crtc->primary.id == 0)
+ return false;
+
+ memset(&s, 0, sizeof(s));
+ s.plane_id = crtc->primary.id;
+ if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s))
+ return false;
+
+ s.plane_id = crtc->sprite.id;
+ (void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s);
+
+ return true;
+}
+
void sna_mode_reset(struct sna *sna)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
@@ -6257,7 +6290,8 @@ void sna_mode_reset(struct sna *sna)
sna_hide_cursors(sna->scrn);
for (i = 0; i < sna->mode.num_real_crtc; i++)
- sna_crtc_disable(config->crtc[i]);
+ if (!sna_crtc_hide_planes(sna, to_sna_crtc(config->crtc[i])))
+ sna_crtc_disable(config->crtc[i]);
assert(sna->mode.front_active == 0);
for (i = 0; i < sna->mode.num_real_crtc; i++) {