xf86-video-intel: 2 commits - configure.ac src/sna/sna_display.c test/cursor-test.c test/.gitignore test/Makefile.am

Chris Wilson ickle at kemper.freedesktop.org
Thu Aug 7 03:59:12 PDT 2014


 configure.ac          |    2 
 src/sna/sna_display.c |   38 +++++++----
 test/.gitignore       |    1 
 test/Makefile.am      |    1 
 test/cursor-test.c    |  159 ++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 187 insertions(+), 14 deletions(-)

New commits:
commit 52c1e64692e3e80826e526dd14aec4bee137a19b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Aug 7 11:34:26 2014 +0100

    sna: Flush cursor width changes
    
    The kernel only sees changes in the cursor width when the cursor handle
    is updated. In the cases where we reuse larger bo for smaller cursors,
    make sure we then reset the cursor handle (even though it has not
    changed) so tht the kernel updates its width.
    
    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 a46440a..116f74b 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -122,6 +122,7 @@ struct sna_crtc {
 	DamagePtr slave_damage;
 	struct kgem_bo *bo, *shadow_bo;
 	struct sna_cursor *cursor;
+	unsigned int last_cursor_size;
 	uint32_t offset;
 	bool shadow;
 	bool fallback_shadow;
@@ -4274,11 +4275,12 @@ static struct sna_cursor *__sna_get_cursor(struct sna *sna, xf86CrtcPtr crtc)
 		return cursor;
 	}
 
-	__DBG(("%s: cursor=%dx%d, serial=%d, argb?=%d\n", __FUNCTION__,
+	__DBG(("%s: cursor=%dx%d, pitch=%d, serial=%d, argb?=%d\n", __FUNCTION__,
 	       sna->cursor.ref->bits->width,
 	       sna->cursor.ref->bits->height,
+	       get_cursor_argb(sna->cursor.ref) ? 4*sna->cursor.ref->bits->width : BitmapBytePad(sna->cursor.ref->bits->width),
 	       sna->cursor.serial,
-	       get_cursor_argb(c) != NULL));
+	       get_cursor_argb(sna->cursor.ref) != NULL));
 
 	rotation = crtc->transform_in_use ? crtc->rotation : RR_Rotate_0;
 
@@ -4315,10 +4317,8 @@ static struct sna_cursor *__sna_get_cursor(struct sna *sna, xf86CrtcPtr crtc)
 	pitch = BitmapBytePad(width);
 
 	image = cursor->image;
-	if (image == NULL) {
+	if (image == NULL)
 		image = sna->cursor.scratch;
-		cursor->last_width = cursor->last_height = size;
-	}
 	if (width < cursor->last_width || height < cursor->last_height || rotation != cursor->rotation)
 		memset(image, 0, 4*size*size);
 	if (rotation == RR_Rotate_0) {
@@ -4327,15 +4327,17 @@ static struct sna_cursor *__sna_get_cursor(struct sna *sna, xf86CrtcPtr crtc)
 				uint32_t *p = image + y*size;
 				for (x = 0; x < width; x++) {
 					int byte = x / 8;
-					int bit = x & 7;
+					uint8_t bit = 1 << (x & 7);
 					uint32_t pixel;
-					if (mask[byte] & (1 << bit)) {
-						if (source[byte] & (1 << bit))
+
+					if (mask[byte] & bit) {
+						if (source[byte] & bit)
 							pixel = sna->cursor.fg;
 						else
 							pixel = sna->cursor.bg;
 					} else
 						pixel = 0;
+
 					*p++ = pixel;
 				}
 				mask += pitch;
@@ -4451,7 +4453,8 @@ sna_show_cursors(ScrnInfoPtr scrn)
 		}
 
 		cursor = __sna_get_cursor(sna, crtc);
-		if (cursor == NULL || sna_crtc->cursor == cursor) {
+		if (cursor == NULL ||
+		    (sna_crtc->cursor == cursor && sna_crtc->last_cursor_size == cursor->size)) {
 			DBG(("%s: skipping cursor already show on CRTC (pipe=%d)\n",
 			     __FUNCTION__, sna_crtc->pipe));
 			continue;
@@ -4467,8 +4470,13 @@ sna_show_cursors(ScrnInfoPtr scrn)
 		arg.handle = cursor->handle;
 
 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg) == 0) {
+			if (sna_crtc->cursor) {
+				assert(sna_crtc->cursor->ref > 0);
+				sna_crtc->cursor->ref--;
+			}
 			cursor->ref++;
 			sna_crtc->cursor = cursor;
+			sna_crtc->last_cursor_size = cursor->size;
 		}
 	}
 	sigio_unblock(sigio);
@@ -4480,7 +4488,7 @@ sna_set_cursor_colors(ScrnInfoPtr scrn, int _bg, int _fg)
 	struct sna *sna = to_sna(scrn);
 	uint32_t fg = _fg, bg = _bg;
 
-	__DBG(("%s(%08x, %08x)\n", __FUNCTION__, bg, fg));
+	__DBG(("%s(bg=%08x, fg=%08x)\n", __FUNCTION__, bg, fg));
 
 	/* Save ARGB versions of these colors */
 	fg |= 0xff000000;
@@ -4524,6 +4532,7 @@ sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc)
 	assert(crtc->cursor->ref > 0);
 	crtc->cursor->ref--;
 	crtc->cursor = NULL;
+	crtc->last_cursor_size = 0;
 }
 
 static void
@@ -4623,13 +4632,13 @@ sna_set_cursor_position(ScrnInfoPtr scrn, int x, int y)
 			cursor = __sna_get_cursor(sna, crtc);
 			if (cursor == NULL)
 				cursor = sna_crtc->cursor;
-			if (cursor == NULL || cursor->size > sna->cursor.size) {
+			if (cursor == NULL) {
 				__DBG(("%s: failed to grab cursor, disabling\n",
 				       __FUNCTION__));
 				goto disable;
 			}
 
-			if (sna_crtc->cursor != cursor) {
+			if (sna_crtc->cursor != cursor || sna_crtc->last_cursor_size != cursor->size) {
 				arg.flags |= DRM_MODE_CURSOR_BO;
 				arg.handle = cursor->handle;
 			}
@@ -4659,8 +4668,11 @@ disable:
 					sna_crtc->cursor->ref--;
 				}
 				sna_crtc->cursor = cursor;
-				if (cursor)
+				if (cursor) {
+					sna_crtc->last_cursor_size = cursor->size;
 					cursor->ref++;
+				} else
+					sna_crtc->last_cursor_size = 0;
 			}
 		}
 	}
commit 7763a3da89fac7cbe571535eebd999d178c39e83
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Aug 7 07:50:54 2014 +0100

    test: Exercise different cursor sizes
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/configure.ac b/configure.ac
index 6dff393..e40a965 100644
--- a/configure.ac
+++ b/configure.ac
@@ -202,7 +202,7 @@ if test "x$UDEV" != "xno"; then
 	fi
 fi
 
-PKG_CHECK_MODULES(X11, [x11 xrender xrandr xext xfixes pixman-1 libpng], [x11="yes"], [x11="no"])
+PKG_CHECK_MODULES(X11, [x11 xrender xrandr xext xfixes cairo cairo-xlib-xrender pixman-1 libpng], [x11="yes"], [x11="no"])
 AM_CONDITIONAL(HAVE_X11, test "x$x11" = "xyes")
 
 shm=yes
diff --git a/test/.gitignore b/test/.gitignore
index b1ede80..d036ead 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -6,6 +6,7 @@ basic-lines
 basic-stress
 basic-stippledrect
 basic-tiledrect
+cursor-test
 render-fill
 render-trapezoid
 render-trapezoid-image
diff --git a/test/Makefile.am b/test/Makefile.am
index 7947b83..f9906d4 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -9,6 +9,7 @@ stress_TESTS = \
 	basic-putimage \
 	basic-lines \
 	basic-stress \
+	cursor-test \
 	render-fill \
 	render-trapezoid \
 	render-trapezoid-image \
diff --git a/test/cursor-test.c b/test/cursor-test.c
new file mode 100644
index 0000000..9259049
--- /dev/null
+++ b/test/cursor-test.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <cairo.h>
+#include <cairo-xlib.h>
+#include <cairo-xlib-xrender.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/Xrender.h>
+
+#include <string.h>
+
+static void core_cursor(Display *dpy, int width, int height)
+{
+	char text[256];
+	cairo_surface_t *surface;
+	cairo_text_extents_t extents;
+	cairo_t *cr;
+	Pixmap bitmap;
+	int scr = DefaultScreen(dpy);
+	Window root = RootWindow(dpy, scr);
+	XColor bg, fg;
+	int pitch;
+	char *data;
+	GC gc;
+
+	sprintf(text, "%dx%d", width, height);
+
+	pitch = (width + 31) >> 5 << 2;
+	data = calloc(pitch, height);
+
+	surface = cairo_image_surface_create_for_data((unsigned char *)data, CAIRO_FORMAT_A1, width, height, pitch);
+	cr = cairo_create(surface);
+	cairo_text_extents(cr, text, &extents);
+	cairo_move_to(cr, 0, extents.height);
+	cairo_show_text(cr, text);
+	cairo_destroy(cr);
+	cairo_surface_destroy(surface);
+
+	bitmap = XCreatePixmap(dpy, root, width, height, 1);
+	gc = XCreateGC(dpy, bitmap, 0, NULL);
+	if (gc != NULL) {
+		XImage ximage = {
+			.height = height,
+			.width = width,
+			.depth = 1,
+			.bits_per_pixel = 1,
+			.xoffset = 0,
+			.format = XYPixmap,
+			.data = data,
+			.byte_order = LSBFirst,
+			.bitmap_unit = 32,
+			.bitmap_bit_order = LSBFirst,
+			.bitmap_pad = 32,
+			.bytes_per_line = pitch,
+		};
+		XPutImage(dpy, bitmap, gc, &ximage, 0, 0, 0, 0, width, height);
+		XFreeGC(dpy, gc);
+	}
+	free(data);
+
+	XParseColor(dpy, DefaultColormap(dpy, scr), "green", &fg);
+	XParseColor(dpy, DefaultColormap(dpy, scr), "black", &bg);
+
+	XDefineCursor(dpy, root, XCreatePixmapCursor(dpy, bitmap, bitmap, &fg, &bg, 0, 0));
+	XFreePixmap(dpy, bitmap);
+}
+
+static void render_cursor(Display *dpy, int width, int height)
+{
+	char text[256];
+	cairo_surface_t *surface;
+	cairo_text_extents_t extents;
+	cairo_t *cr;
+	Pixmap pixmap;
+	Picture picture;
+
+	sprintf(text, "%dx%d", width, height);
+
+	pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy), width, height, 32);
+	surface = cairo_xlib_surface_create_with_xrender_format(dpy, pixmap,
+								DefaultScreenOfDisplay(dpy),
+								XRenderFindStandardFormat(dpy, PictStandardARGB32),
+								width, height);
+	cr = cairo_create(surface);
+	cairo_surface_destroy(surface);
+
+	cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
+	cairo_paint(cr);
+	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+
+	cairo_text_extents(cr, text, &extents);
+	cairo_move_to(cr, 0, extents.height);
+	cairo_set_source_rgb(cr, 1, 0, 1);
+	cairo_show_text(cr, text);
+	cairo_destroy(cr);
+
+	picture = XRenderCreatePicture(dpy, pixmap, XRenderFindStandardFormat(dpy, PictStandardARGB32), 0, NULL);
+	XFreePixmap(dpy, pixmap);
+
+	XDefineCursor(dpy, DefaultRootWindow(dpy), XRenderCreateCursor(dpy, picture, 0, 0));
+	XRenderFreePicture(dpy, picture);
+}
+
+int main(void)
+{
+	Display *dpy;
+	int sizes[] = { 24, 32, 48, 64, 72, 128, 160, 256 };
+	int x, y;
+
+	dpy = XOpenDisplay(NULL);
+	if (dpy == NULL)
+		dpy = XOpenDisplay(":0"); /* lazy */
+	if (dpy == NULL)
+		return 77;
+
+	for (x = 0; x < sizeof(sizes)/sizeof(sizes[0]); x++) {
+		for (y = 0; y < sizeof(sizes)/sizeof(sizes[0]); y++) {
+			printf("Testing %dx%d (core)\n", sizes[x], sizes[y]);
+			core_cursor(dpy, sizes[x], sizes[y]);
+			XSync(dpy, True);
+			sleep(2);
+
+			printf("Testing %dx%d (render)\n", sizes[x], sizes[y]);
+			render_cursor(dpy, sizes[x], sizes[y]);
+			XSync(dpy, True);
+			sleep(2);
+		}
+	}
+
+	return 0;
+}


More information about the xorg-commit mailing list