xf86-video-intel: 3 commits - src/drmmode_display.c src/intel_memory.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Jul 1 15:02:11 PDT 2010


 src/drmmode_display.c |  110 ++++++++++++++++++++++++++++----------------------
 src/intel_memory.c    |   19 ++++++++
 2 files changed, 81 insertions(+), 48 deletions(-)

New commits:
commit afcd41820d7481912b49093670e9d7a4a6a2338f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 1 22:14:03 2010 +0100

    Reduce front buffer stride prior to rejection
    
    If we reject the front buffer because it has too large a stride, repeat
    the allocation using untiled for the cases where we can utilize laxer
    hardware restrictions.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/intel_memory.c b/src/intel_memory.c
index a3d67b4..8443c91 100644
--- a/src/intel_memory.c
+++ b/src/intel_memory.c
@@ -191,7 +191,19 @@ drm_intel_bo *intel_allocate_framebuffer(ScrnInfoPtr scrn,
 		tiling_mode = I915_TILING_NONE;
 
 	width = intel_pad_drawable_width(width);
+	if (!intel_check_display_stride(scrn, width * intel->cpp,
+					tiling_mode != I915_TILING_NONE))
+	    tiling_mode = I915_TILING_NONE;
+	if (!intel_check_display_stride(scrn, width * intel->cpp,
+					tiling_mode != I915_TILING_NONE)) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Expected front buffer stride %d kB "
+			   "will exceed display limit\n",
+			   width * intel->cpp / 1024);
+		return NULL;
+	}
 
+retry:
 	front_buffer = drm_intel_bo_alloc_tiled(intel->bufmgr, "front buffer",
 						width, height, intel->cpp,
 						&tiling_mode, &pitch, 0);
@@ -203,10 +215,15 @@ drm_intel_bo *intel_allocate_framebuffer(ScrnInfoPtr scrn,
 
 	if (!intel_check_display_stride(scrn, pitch,
 				       tiling_mode != I915_TILING_NONE)) {
+		drm_intel_bo_unreference(front_buffer);
+		if (tiling_mode != I915_TILING_NONE) {
+			tiling_mode = I915_TILING_NONE;
+			goto retry;
+		}
+
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "Front buffer stride %ld kB "
 			   "exceeds display limit\n", pitch / 1024);
-		drm_intel_bo_unreference(front_buffer);
 		return NULL;
 	}
 
commit f8778b66a98d68e622cdf5b2d1fd959c4f7a2b2b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 1 21:58:43 2010 +0100

    drmmode: Add missing newlines at the end of log messages.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 67007b5..8391b72 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -358,7 +358,7 @@ drmmode_apply(xf86CrtcPtr crtc)
 			     &drmmode_crtc->kmode);
 	if (ret) {
 		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
-			   "failed to set mode: %s", strerror(-ret));
+			   "failed to set mode: %s\n", strerror(-ret));
 		ret = FALSE;
 	} else
 		ret = TRUE;
@@ -457,7 +457,7 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
 	ret = dri_bo_subdata(drmmode_crtc->cursor, 0, 64*64*4, image);
 	if (ret)
 		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
-			   "failed to set cursor: %s", strerror(-ret));
+			   "failed to set cursor: %s\n", strerror(-ret));
 
 	return;
 }
commit 690fbd1a64c1e1fd07f7f8a5e39e05a33e4d0721
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 1 21:55:04 2010 +0100

    drmmode: Use a copy of the converted mode on resize
    
    Avoid a potential use-after-free of the copied mode string by reusing
    the converted kernel mode on resize.
    
    ==19897== Invalid read of size 8
    ==19897==    at 0x661C330: ??? (strcpy.S:1308)
    ==19897==    by 0x8618AE7: drmmode_set_mode_major (drmmode_display.c:293)
    ==19897==    by 0x8618E6F: drmmode_xf86crtc_resize (drmmode_display.c:1299)
    ==19897==    by 0x529A77: xf86RandR12ScreenSetSize (xf86RandR12.c:708)
    ==19897==    by 0x4BD528: ProcRRSetScreenSize (rrscreen.c:301)
    ==19897==    by 0x42B820: Dispatch (dispatch.c:432)
    ==19897==    by 0x4254C9: main (main.c:289)
    ==19897==  Address 0x72e91e0 is 0 bytes inside a block of size 9 free'd
    ==19897==    at 0x4C23DBC: free (vg_replace_malloc.c:325)
    ==19897==    by 0x48424F: xf86DeleteMode (xf86Mode.c:1921)
    ==19897==    by 0x4942B7: xf86ProbeOutputModes (xf86Crtc.c:1572)
    ==19897==    by 0x5290BB: xf86RandR12GetInfo12 (xf86RandR12.c:1551)
    ==19897==    by 0x5313AE: RRGetInfo (rrinfo.c:202)
    ==19897==    by 0x4BCCAA: rrGetScreenResources (rrscreen.c:337)
    ==19897==    by 0x42B820: Dispatch (dispatch.c:432)
    ==19897==    by 0x4254C9: main (main.c:289)
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 17f6541..67007b5 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -57,6 +57,7 @@ typedef struct {
 
 typedef struct {
     drmmode_ptr drmmode;
+    drmModeModeInfo kmode;
     drmModeCrtcPtr mode_crtc;
     dri_bo *cursor;
     dri_bo *rotate_bo;
@@ -302,52 +303,20 @@ drmmode_crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode)
 }
 
 static Bool
-drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
-		       Rotation rotation, int x, int y)
+drmmode_apply(xf86CrtcPtr crtc)
 {
 	ScrnInfoPtr scrn = crtc->scrn;
-	intel_screen_private *intel = intel_get_screen_private(scrn);
-	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 	drmmode_ptr drmmode = drmmode_crtc->drmmode;
-	int saved_x, saved_y;
-	Rotation saved_rotation;
-	DisplayModeRec saved_mode;
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
 	uint32_t *output_ids;
 	int output_count = 0;
-	int ret = TRUE;
-	int i;
-	int fb_id;
-	drmModeModeInfo kmode;
-	unsigned int pitch = scrn->displayWidth * intel->cpp;
-
-	if (drmmode->fb_id == 0) {
-		ret = drmModeAddFB(drmmode->fd,
-				   scrn->virtualX, scrn->virtualY,
-				   scrn->depth, scrn->bitsPerPixel,
-				   pitch, intel->front_buffer->handle,
-				   &drmmode->fb_id);
-		if (ret < 0) {
-			ErrorF("failed to add fb\n");
-			return FALSE;
-		}
-	}
-
-	saved_mode = crtc->mode;
-	saved_x = crtc->x;
-	saved_y = crtc->y;
-	saved_rotation = crtc->rotation;
-
-	crtc->mode = *mode;
-	crtc->x = x;
-	crtc->y = y;
-	crtc->rotation = rotation;
+	int fb_id, x, y;
+	int i, ret;
 
 	output_ids = calloc(sizeof(uint32_t), xf86_config->num_output);
-	if (!output_ids) {
-		ret = FALSE;
-		goto done;
-	}
+	if (!output_ids)
+		return FALSE;
 
 	for (i = 0; i < xf86_config->num_output; i++) {
 		xf86OutputPtr output = xf86_config->output[i];
@@ -375,9 +344,9 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 			       crtc->gamma_blue, crtc->gamma_size);
 #endif
 
-	drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
-
 
+	x = crtc->x;
+	y = crtc->y;
 	fb_id = drmmode->fb_id;
 	if (drmmode_crtc->rotate_fb_id) {
 		fb_id = drmmode_crtc->rotate_fb_id;
@@ -385,11 +354,13 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 		y = 0;
 	}
 	ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
-			     fb_id, x, y, output_ids, output_count, &kmode);
-	if (ret)
+			     fb_id, x, y, output_ids, output_count,
+			     &drmmode_crtc->kmode);
+	if (ret) {
 		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
 			   "failed to set mode: %s", strerror(-ret));
-	else
+		ret = FALSE;
+	} else
 		ret = TRUE;
 
 	/* Turn on any outputs on this crtc that may have been disabled */
@@ -406,7 +377,52 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 
 	if (scrn->pScreen)
 		xf86_reload_cursors(scrn->pScreen);
+
+	return ret;
+
 done:
+	free(output_ids);
+	return FALSE;
+}
+
+static Bool
+drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
+		       Rotation rotation, int x, int y)
+{
+	ScrnInfoPtr scrn = crtc->scrn;
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	int saved_x, saved_y;
+	Rotation saved_rotation;
+	DisplayModeRec saved_mode;
+	int ret = TRUE;
+	unsigned int pitch = scrn->displayWidth * intel->cpp;
+
+	if (drmmode->fb_id == 0) {
+		ret = drmModeAddFB(drmmode->fd,
+				   scrn->virtualX, scrn->virtualY,
+				   scrn->depth, scrn->bitsPerPixel,
+				   pitch, intel->front_buffer->handle,
+				   &drmmode->fb_id);
+		if (ret < 0) {
+			ErrorF("failed to add fb\n");
+			return FALSE;
+		}
+	}
+
+	saved_mode = crtc->mode;
+	saved_x = crtc->x;
+	saved_y = crtc->y;
+	saved_rotation = crtc->rotation;
+
+	crtc->mode = *mode;
+	crtc->x = x;
+	crtc->y = y;
+	crtc->rotation = rotation;
+
+	drmmode_ConvertToKMode(crtc->scrn, &drmmode_crtc->kmode, mode);
+	ret = drmmode_apply(crtc);
 	if (!ret) {
 		crtc->x = saved_x;
 		crtc->y = saved_y;
@@ -1296,8 +1312,8 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 		if (!crtc->enabled)
 			continue;
 
-		drmmode_set_mode_major(crtc, &crtc->mode,
-				       crtc->rotation, crtc->x, crtc->y);
+		if (!drmmode_apply(crtc))
+			goto fail;
 	}
 
 	if (old_fb_id)


More information about the xorg-commit mailing list