Edit

IABSD.fr/xenocara/driver/xf86-video-intel/test/test_display.c

Branch :

  • Show log

    Commit

  • Author : matthieu
    Date : 2015-04-12 19:41:54
    Hash : d031df27
    Message : Update to xf86-video-intel 2.99.916 Fixes a display bug seenby ajacoutot@, ok jsg@ and kettenis@. newer X.Org (2.99.917 or master) version cause corruption on older machines (X40, i965), probably caused by a bug in our kernel, under investigation by kettenis@.

  • driver/xf86-video-intel/test/test_display.c
  • #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    
    #include "test.h"
    
    static Window get_root(struct test_display *t)
    {
    	XSetWindowAttributes attr;
    	Window w;
    
    	/* Be nasty and install a fullscreen window on top so that we
    	 * can guarantee we do not get clipped by children.
    	 */
    	attr.override_redirect = 1;
    	w = XCreateWindow(t->dpy, DefaultRootWindow(t->dpy),
    			  0, 0, t->width, t->height, 0,
    			  DefaultDepth(t->dpy, DefaultScreen(t->dpy)),
    			  InputOutput,
    			  DefaultVisual(t->dpy, DefaultScreen(t->dpy)),
    			  CWOverrideRedirect, &attr);
    	XMapWindow(t->dpy, w);
    
    	return w;
    }
    
    static Display *out_display(int argc, char **argv)
    {
    	Display *dpy;
    	const char *name = NULL;
    	int i;
    
    	for (i = 0; i < argc; i++) {
    		if (strncmp(argv[i], "-d", 2) == 0) {
    			if (argv[i][2] == '\0') {
    				if (i+1 < argc) {
    					name = argv[i+1];
    					i++;
    				}
    			} else
    				name = argv[i] + 2;
    		}
    	}
    
    	if (name == NULL)
    		name = getenv("DISPLAY");
    	if (name == NULL)
    		name = ":0"; /* useful default */
    
    	dpy = XOpenDisplay(name);
    	if (dpy == NULL)
    		die("unable to open out display %s\n", name);
    
    	printf("Opened connection to %s for testing.\n", name);
    	return dpy;
    }
    
    static Display *ref_display(int width, int height, int depth)
    {
    	Display *dpy;
    	char buf[160];
    	const char *name;
    	int try;
    
    	name = getenv("REF_DISPLAY");
    	if (name) {
    		dpy = XOpenDisplay(name);
    		if (dpy == NULL)
    			die("unable to open reference display %s\n", name);
    
    		printf("Opened connection to %s for reference.\n", name);
    		return dpy;
    	}
    
    	snprintf(buf, sizeof(buf),
    		 "Xvfb -ac -terminate -screen 0 %dx%dx%d :99 >/dev/null 2>&1 &",
    		 width, height, depth);
    	if (system(buf))
    		die("unable to spawn '%s' for reference display\n", buf);
    
    	try = 0;
    	while (try++ < 1000) {
    		dpy = XOpenDisplay(":99");
    		if (dpy)
    			break;
    		usleep(1000);
    	}
    
    	if (dpy == NULL)
    		die("unable to open reference display\n");
    
    	return dpy;
    }
    
    static void shm_setup(struct test_display *d)
    {
    	int major, minor;
    	int size;
    
    	XShmQueryVersion(d->dpy, &major, &minor, &d->has_shm_pixmaps);
    	if (major == 0 && minor == 0)
    		die("XSHM not supported\n");
    
    	size = d->width * d->height * 4;
    	d->max_shm_size = size;
    
    	d->shm.shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0600);
    	if (d->shm.shmid == -1)
    		die("failed to allocated %d bytes for a shm segment\n", size);
    
    	d->shm.shmaddr = shmat(d->shm.shmid, NULL, 0);
    	d->shm.readOnly = 0;
    	XShmAttach(d->dpy, &d->shm);
    	XSync(d->dpy, 1);
    }
    
    static void default_setup(struct test_display *dpy)
    {
    	dpy->width = WidthOfScreen(DefaultScreenOfDisplay(dpy->dpy));
    	dpy->height = HeightOfScreen(DefaultScreenOfDisplay(dpy->dpy));
    	dpy->format =
    		XRenderFindVisualFormat(dpy->dpy,
    					DefaultVisual(dpy->dpy,
    						      DefaultScreen(dpy->dpy)));
    	dpy->depth = DefaultDepth(dpy->dpy, DefaultScreen(dpy->dpy));
    }
    
    static void test_get_displays(int argc, char **argv,
    			      struct test_display *out,
    			      struct test_display *ref)
    {
    	out->dpy = out_display(argc, argv);
    	default_setup(out);
    	shm_setup(out);
    	out->root = get_root(out);
    	out->target = OUT;
    
    	ref->dpy = ref_display(out->width, out->height, out->depth);
    	default_setup(ref);
    	shm_setup(ref);
    	ref->root = get_root(ref);
    	ref->target = REF;
    }
    
    void test_init(struct test *test, int argc, char **argv)
    {
    	memset(test, 0, sizeof(*test));
    	test_get_displays(argc, argv, &test->out, &test->ref);
    }
    
    void test_timer_start(struct test_display *t, struct timespec *tv)
    {
    	clock_gettime(CLOCK_MONOTONIC, tv);
    }
    
    double test_timer_stop(struct test_display *t, struct timespec *tv)
    {
    	XImage *image;
    	struct timespec now;
    
    	image = XGetImage(t->dpy, t->root, 0, 0, 1, 1, AllPlanes, ZPixmap);
    	clock_gettime(CLOCK_MONOTONIC, &now);
    	XDestroyImage(image);
    
    	return (now.tv_sec - tv->tv_sec) + 1e-9*(now.tv_nsec - tv->tv_nsec);
    }