xf86-video-intel: 3 commits - src/sna/sna_display.c src/sna/sna.h src/sna/sna_video_sprite.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Feb 13 15:56:38 CET 2014


 src/sna/sna.h              |    3 
 src/sna/sna_display.c      |  242 ++++++++++++++++++++++++++-------------------
 src/sna/sna_video_sprite.c |   14 +-
 3 files changed, 155 insertions(+), 104 deletions(-)

New commits:
commit 83d17cded854871fd41cd3fcf25f38c9b67a4705
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Feb 13 12:57:50 2014 +0000

    sna: Clear DPMS tracking on VT switch
    
    Assume the worst and force us to reset the property when we restore
    control.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index e123f48..85003bf 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1191,6 +1191,8 @@ sna_crtc_disable(xf86CrtcPtr crtc)
 		kgem_bo_destroy(&sna->kgem, sna_crtc->bo);
 		sna_crtc->bo = NULL;
 	}
+
+	assert(sna_crtc->dpms_mode == DPMSModeOff);
 }
 
 static void update_flush_interval(struct sna *sna)
@@ -2117,7 +2119,7 @@ sna_crtc_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num)
 		return false;
 
 	sna_crtc->id = mode->kmode->crtcs[num];
-	sna_crtc->dpms_mode = DPMSModeOff;
+	sna_crtc->dpms_mode = -1;
 
 	VG_CLEAR(get_pipe);
 	get_pipe.pipe = 0;
@@ -4355,7 +4357,7 @@ void sna_mode_reset(struct sna *sna)
 		if (sna_crtc == NULL)
 			continue;
 
-		sna_crtc->dpms_mode = DPMSModeOff;
+		sna_crtc->dpms_mode = -1;
 
 		/* Force the rotation property to be reset on next use */
 		rotation_reset(&sna_crtc->primary_rotation);
@@ -4367,7 +4369,7 @@ void sna_mode_reset(struct sna *sna)
 		if (sna_output == NULL)
 			continue;
 
-		sna_output->dpms_mode = DPMSModeOff;
+		sna_output->dpms_mode = -1;
 	}
 }
 
commit 135da294106f7158bb68eeeb9e6c171bcddd94f3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Feb 13 11:58:15 2014 +0000

    sna: Extend native rotation support to sprites
    
    The sprite plane can be independently rotated to the CRTC primary plane.
    To rotate the sprite plane, we just set a property on the plane similar
    to how we rotate the CRTC, so we can refactor them together to use the
    same routines.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 7833095..7dc5067 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -439,8 +439,9 @@ static inline void sna_dri_close(struct sna *sna, ScreenPtr pScreen) { }
 #endif
 void sna_dri_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap);
 
+extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation);
 extern int sna_crtc_to_pipe(xf86CrtcPtr crtc);
-extern uint32_t sna_crtc_to_plane(xf86CrtcPtr crtc);
+extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc);
 extern uint32_t sna_crtc_id(xf86CrtcPtr crtc);
 
 CARD32 sna_format_for_depth(int depth);
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 5c0a5a3..e123f48 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -93,22 +93,29 @@ union compat_mode_get_connector{
 
 extern XF86ConfigPtr xf86configptr;
 
+struct rotation {
+	uint32_t obj_id, obj_type;
+	uint32_t prop_id;
+	uint32_t supported;
+	uint32_t current;
+};
+
 struct sna_crtc {
 	struct drm_mode_modeinfo kmode;
 	int dpms_mode;
 	PixmapPtr scanout_pixmap;
 	struct kgem_bo *bo, *shadow_bo;
 	uint32_t cursor;
+	uint32_t sprite;
 	bool shadow;
 	bool fallback_shadow;
 	bool transform;
 	uint8_t id;
 	uint8_t pipe;
-	uint8_t plane;
 
-	uint32_t rotation_id;
-	uint32_t supported_rotations;
-	uint32_t rotation, last_rotation;
+	uint32_t rotation;
+	struct rotation primary_rotation;
+	struct rotation sprite_rotation;
 };
 
 struct sna_property {
@@ -199,9 +206,9 @@ int sna_crtc_to_pipe(xf86CrtcPtr crtc)
 	return to_sna_crtc(crtc)->pipe;
 }
 
-uint32_t sna_crtc_to_plane(xf86CrtcPtr crtc)
+uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc)
 {
-	return to_sna_crtc(crtc)->plane;
+	return to_sna_crtc(crtc)->sprite;
 }
 
 #ifndef NDEBUG
@@ -862,6 +869,43 @@ sna_crtc_force_outputs_off(xf86CrtcPtr crtc)
 }
 
 static bool
+rotation_set(struct sna *sna, struct rotation *r, uint32_t desired)
+{
+	if (desired == r->current)
+		return true;
+
+	if ((desired & r->supported) == 0)
+		return false;
+
+	DBG(("%s: obj=%d, type=%u set-rotation=%x\n",
+	     __FUNCTION__, r->obj_id, r->obj_type, desired));
+
+	assert(r->obj_id);
+	assert(r->obj_type);
+	assert(r->prop_id);
+
+	if (drmModeObjectSetProperty(sna->kgem.fd,
+				     r->obj_id, r->obj_type,
+				     r->prop_id, desired))
+		return false;
+
+	r->current = desired;
+	return true;
+}
+
+bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation)
+{
+	DBG(("%s: CRTC:%d [pipe=%d], sprite=%u set-rotation=%x\n",
+	     __FUNCTION__,
+	     to_sna_crtc(crtc)->id, to_sna_crtc(crtc)->pipe, to_sna_crtc(crtc)->sprite,
+	     rotation));
+
+	return rotation_set(to_sna(crtc->scrn),
+			    &to_sna_crtc(crtc)->sprite_rotation,
+			    rotation);
+}
+
+static bool
 sna_crtc_apply(xf86CrtcPtr crtc)
 {
 	struct sna *sna = to_sna(crtc->scrn);
@@ -876,30 +920,13 @@ sna_crtc_apply(xf86CrtcPtr crtc)
 
 	assert(config->num_output < ARRAY_SIZE(output_ids));
 
-	if (sna_crtc->rotation != sna_crtc->last_rotation) {
-		assert(sna_crtc->rotation_id);
-
-		DBG(("%s: disabling CRTC:%d [pipe=%d] before changing rotation from %x to %x\n",
-		     __FUNCTION__, sna_crtc->id, sna_crtc->pipe,
-		     sna_crtc->last_rotation, sna_crtc->rotation));
-
-		memset(&arg, 0, sizeof(arg));
-		arg.crtc_id = sna_crtc->id;
-		(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg);
-
-		if (drmModeObjectSetProperty(sna->kgem.fd, sna_crtc->id,
-					     DRM_MODE_OBJECT_CRTC,
-					     sna_crtc->rotation_id,
-					     sna_crtc->rotation)) {
-			ERR(("%s: set-rotation failed (rotation-id=%d, rotation=%d) on CRTC:%d [pipe=%d], errno=%d\n",
-			     __FUNCTION__, sna_crtc->rotation_id, sna_crtc->rotation, sna_crtc->id, sna_crtc->pipe, errno));
-			return false;
-		}
-
-		sna_crtc->last_rotation = sna_crtc->rotation;
-		DBG(("%s: CRTC:%d [pipe=%d] rotation set to %x\n",
-		     __FUNCTION__, sna_crtc->id, sna_crtc->pipe, sna_crtc->rotation));
+	if (!rotation_set(sna, &sna_crtc->primary_rotation, sna_crtc->rotation)) {
+		ERR(("%s: set-primary-rotation failed (rotation-id=%d, rotation=%d) on CRTC:%d [pipe=%d], errno=%d\n",
+		     __FUNCTION__, sna_crtc->primary_rotation.prop_id, sna_crtc->rotation, sna_crtc->id, sna_crtc->pipe, errno));
+		return false;
 	}
+	DBG(("%s: CRTC:%d [pipe=%d] primary rotation set to %x\n",
+	     __FUNCTION__, sna_crtc->id, sna_crtc->pipe, sna_crtc->rotation));
 
 	for (i = 0; i < config->num_output; i++) {
 		xf86OutputPtr output = config->output[i];
@@ -1156,14 +1183,7 @@ sna_crtc_disable(xf86CrtcPtr crtc)
 	arg.crtc_id = sna_crtc->id;
 	(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg);
 
-	if (sna_crtc->last_rotation != RR_Rotate_0) {
-		assert(sna_crtc->rotation_id);
-		(void)drmModeObjectSetProperty(sna->kgem.fd, sna_crtc->id,
-					       DRM_MODE_OBJECT_CRTC,
-					       sna_crtc->rotation_id,
-					       RR_Rotate_0);
-		sna_crtc->last_rotation = RR_Rotate_0;
-	}
+	rotation_set(sna, &sna_crtc->primary_rotation, RR_Rotate_0);
 
 	sna_crtc_disable_shadow(sna, sna_crtc);
 
@@ -1399,9 +1419,9 @@ static bool use_shadow(struct sna *sna, xf86CrtcPtr crtc)
 			       &f_fb_to_crtc)) {
 		bool needs_transform = true;
 		DBG(("%s: natively supported rotation? rotation=%x & supported=%x == %d\n",
-		     __FUNCTION__, crtc->rotation, to_sna_crtc(crtc)->supported_rotations,
-		     !!(crtc->rotation & to_sna_crtc(crtc)->supported_rotations)));
-		if (to_sna_crtc(crtc)->supported_rotations & crtc->rotation)
+		     __FUNCTION__, crtc->rotation, to_sna_crtc(crtc)->primary_rotation.supported,
+		     !!(crtc->rotation & to_sna_crtc(crtc)->primary_rotation.supported)));
+		if (to_sna_crtc(crtc)->primary_rotation.supported & crtc->rotation)
 			needs_transform = RRTransformCompute(crtc->x, crtc->y,
 							     crtc->mode.HDisplay, crtc->mode.VDisplay,
 							     RR_Rotate_0, transform,
@@ -1545,6 +1565,7 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
 			return NULL;
 
 		assert(!sna_crtc->shadow);
+		assert(sna_crtc->primary_rotation.supported & crtc->rotation);
 		sna_crtc->rotation = crtc->rotation;
 		return kgem_bo_reference(bo);
 	}
@@ -1944,7 +1965,7 @@ static const xf86CrtcFuncsRec sna_crtc_funcs = {
 };
 
 static int
-sna_crtc_find_plane(struct sna *sna, int pipe)
+sna_crtc_find_sprite(struct sna *sna, int pipe)
 {
 #ifdef DRM_IOCTL_MODE_GETPLANERESOURCES
 	struct drm_mode_get_plane_res r;
@@ -1992,74 +2013,93 @@ sna_crtc_find_plane(struct sna *sna, int pipe)
 }
 
 static void
-sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *sna_crtc)
+rotation_init(struct sna *sna, struct rotation *r, uint32_t obj_id, uint32_t obj_type)
 {
+#if USE_ROTATION
 	drmModeObjectPropertiesPtr props;
+	int i, j;
 
-	sna_crtc->supported_rotations = RR_Rotate_0;
-	sna_crtc->rotation = sna_crtc->last_rotation = RR_Rotate_0;
-
-#if USE_ROTATION
-	props = drmModeObjectGetProperties(sna->kgem.fd,
-					   sna_crtc->id,
-					   DRM_MODE_OBJECT_CRTC);
-	if (props) {
-		int i, j;
+	props = drmModeObjectGetProperties(sna->kgem.fd, obj_id, obj_type);
+	if (props == NULL)
+		return;
 
-		DBG(("%s: CRTC:%d has %d props\n", __FUNCTION__, sna_crtc->id, props->count_props));
+	DBG(("%s: object %d (type %u) has %d props\n", __FUNCTION__,
+	     obj_id, obj_type, props->count_props));
 
-		for (i = 0; i < props->count_props; i++) {
-			struct drm_mode_get_property prop;
-			struct drm_mode_property_enum *enums;
+	for (i = 0; i < props->count_props; i++) {
+		struct drm_mode_get_property prop;
+		struct drm_mode_property_enum *enums;
 
-			memset(&prop, 0, sizeof(prop));
-			prop.prop_id = props->props[i];
-			if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop))
-				continue;
+		memset(&prop, 0, sizeof(prop));
+		prop.prop_id = props->props[i];
+		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop))
+			continue;
 
-			DBG(("%s: prop[%d] .id=%d, .name=%s, .flags=%x, .value=%ld\n", __FUNCTION__, i,
-			     props->props[i], prop.name, prop.flags, props->prop_values[i]));
-			if ((prop.flags & DRM_MODE_PROP_BITMASK) == 0)
-				continue;
+		DBG(("%s: prop[%d] .id=%d, .name=%s, .flags=%x, .value=%ld\n", __FUNCTION__, i,
+		     props->props[i], prop.name, prop.flags, props->prop_values[i]));
+		if ((prop.flags & DRM_MODE_PROP_BITMASK) == 0)
+			continue;
 
-			if (strcmp(prop.name, "rotation"))
-				continue;
+		if (strcmp(prop.name, "rotation"))
+			continue;
 
-			/* Note that this property only controls the primary
-			 * plane, not the cursor or sprite planes.
-			 */
-			sna_crtc->rotation_id = props->props[i];
-			sna_crtc->rotation = sna_crtc->last_rotation = props->prop_values[i];
-
-			DBG(("%s: found rotation property .id=%d, num_enums=%d\n",
-			     __FUNCTION__, prop.prop_id, prop.count_enum_blobs));
-			enums = malloc(prop.count_enum_blobs * sizeof(struct drm_mode_property_enum));
-			if (enums != NULL) {
-				prop.count_values = 0;
-				prop.enum_blob_ptr = (uintptr_t)enums;
-
-				if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop) == 0) {
-					/* XXX we assume that the mapping between kernel enum and
-					 * RandR remains fixed for our lifetimes.
-					 */
-					for (j = 0; j < prop.count_enum_blobs; j++) {
-						DBG(("%s: CRTC:%d rotation[%d] = %s [%x]\n", __FUNCTION__, sna_crtc->id, j,
-						     enums[j].name, enums[j].value));
-						sna_crtc->supported_rotations |= 1 << enums[j].value;
-					}
+		r->obj_id = obj_id;
+		r->obj_type = obj_type;
+		r->prop_id = props->props[i];
+		r->current = props->prop_values[i];
+
+		DBG(("%s: found rotation property .id=%d, value=%ld, num_enums=%d\n",
+		     __FUNCTION__, prop.prop_id, (long)props->prop_values[i], prop.count_enum_blobs));
+		enums = malloc(prop.count_enum_blobs * sizeof(struct drm_mode_property_enum));
+		if (enums != NULL) {
+			prop.count_values = 0;
+			prop.enum_blob_ptr = (uintptr_t)enums;
+
+			if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop) == 0) {
+				/* XXX we assume that the mapping between kernel enum and
+				 * RandR remains fixed for our lifetimes.
+				 */
+				for (j = 0; j < prop.count_enum_blobs; j++) {
+					DBG(("%s: rotation[%d] = %s [%x]\n", __FUNCTION__,
+					     j, enums[j].name, enums[j].value));
+					r->supported |= 1 << enums[j].value;
 				}
-
-				free(enums);
 			}
 
-			break;
+			free(enums);
 		}
 
-		drmModeFreeObjectProperties(props);
+		break;
 	}
+
+	drmModeFreeObjectProperties(props);
 #endif
-	DBG(("%s: CRTC:%d [pipe=%d], supported-rotations=%x, current-rotation=%x\n",
-	     __FUNCTION__, sna_crtc->id, sna_crtc->pipe, sna_crtc->supported_rotations, sna_crtc->last_rotation));
+}
+
+static void
+rotation_reset(struct rotation *r)
+{
+	if (r->prop_id == 0)
+		return;
+
+	r->current = 0;
+}
+
+static void
+sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *sna_crtc)
+{
+	sna_crtc->rotation = RR_Rotate_0;
+	sna_crtc->primary_rotation.supported = RR_Rotate_0;
+	sna_crtc->primary_rotation.current = RR_Rotate_0;
+	sna_crtc->sprite_rotation = sna_crtc->primary_rotation;
+
+	rotation_init(sna, &sna_crtc->primary_rotation, sna_crtc->id, DRM_MODE_OBJECT_CRTC);
+	rotation_init(sna, &sna_crtc->sprite_rotation, sna_crtc->sprite, DRM_MODE_OBJECT_PLANE);
+
+	DBG(("%s: CRTC:%d [pipe=%d], primary: supported-rotations=%x, current-rotation=%x, sprite: supported-rotations=%x, current-rotation=%x\n",
+	     __FUNCTION__, sna_crtc->id, sna_crtc->pipe,
+	     sna_crtc->primary_rotation.supported, sna_crtc->primary_rotation.current,
+	     sna_crtc->sprite_rotation.supported, sna_crtc->sprite_rotation.current));
 }
 
 static bool
@@ -2089,7 +2129,7 @@ sna_crtc_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num)
 		return false;
 	}
 	sna_crtc->pipe = get_pipe.pipe;
-	sna_crtc->plane = sna_crtc_find_plane(sna, sna_crtc->pipe);
+	sna_crtc->sprite = sna_crtc_find_sprite(sna, sna_crtc->pipe);
 
 	if (xf86IsEntityShared(scrn->entityList[0]) &&
 	    scrn->confScreen->device->screen != sna_crtc->pipe) {
@@ -4316,6 +4356,10 @@ void sna_mode_reset(struct sna *sna)
 			continue;
 
 		sna_crtc->dpms_mode = DPMSModeOff;
+
+		/* Force the rotation property to be reset on next use */
+		rotation_reset(&sna_crtc->primary_rotation);
+		rotation_reset(&sna_crtc->sprite_rotation);
 	}
 
 	for (i = 0; i < config->num_output; i++) {
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index b6a7950..f4dcb82 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -205,10 +205,10 @@ sna_video_sprite_show(struct sna *sna,
 	/* XXX handle video spanning multiple CRTC */
 
 	VG_CLEAR(s);
-	s.plane_id = sna_crtc_to_plane(crtc);
+	s.plane_id = sna_crtc_to_sprite(crtc);
 
 	update_dst_box_to_crtc_coords(sna, crtc, dstBox);
-	if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+	if (video->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
 		int tmp = frame->width;
 		frame->width = frame->height;
 		frame->height = tmp;
@@ -383,11 +383,15 @@ static int sna_video_sprite_put_image(ClientPtr client,
 				   &clip))
 		goto invisible;
 
-	if (!crtc || sna_crtc_to_plane(crtc) == 0)
+	if (!crtc || sna_crtc_to_sprite(crtc) == 0)
 		goto invisible;
 
-	/* sprites can't handle rotation natively, store it for the copy func */
-	video->rotation = crtc->rotation;
+	/* if sprite can't handle rotation natively, store it for the copy func */
+	video->rotation = RR_Rotate_0;
+	if (!sna_crtc_set_sprite_rotation(crtc, crtc->rotation)) {
+		sna_crtc_set_sprite_rotation(crtc, RR_Rotate_0);
+		video->rotation = crtc->rotation;
+	}
 
 	if (xvmc_passthrough(format->id)) {
 		DBG(("%s: using passthough, name=%d\n",
commit e35017e36e45c57ea9847eb5c8466cac3c4d2cc4
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Feb 13 14:46:39 2014 +0000

    sna: Enable coordinate transforms for native CRTC rotation
    
    Otherwise X tells Clients that the cursor is still in the unrotated
    location when it appears rotated on the display.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 32e74d0..5c0a5a3 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1591,7 +1591,7 @@ static void sna_crtc_randr(xf86CrtcPtr crtc)
 #endif
 		crtc->transform_in_use = TRUE;
 	} else
-		crtc->transform_in_use = FALSE;
+		crtc->transform_in_use = sna_crtc->rotation != RR_Rotate_0;
 
 	crtc->crtc_to_framebuffer = crtc_to_fb;
 	crtc->f_crtc_to_framebuffer = f_crtc_to_fb;


More information about the xorg-commit mailing list