Example #1
0
void video_sync_all(void)
{
	struct udevice *dev;

	for (uclass_find_first_device(UCLASS_VIDEO, &dev);
	     dev;
	     uclass_find_next_device(&dev)) {
		if (device_active(dev))
			video_sync(dev);
	}
}
Example #2
0
int main(int argc, char *argv[])
{
	Display *disp;
	XVisualInfo *pvi;
	XSetWindowAttributes swa;
	int attrib[14];
	GLint last_val = -1, count = 0;
	Window winGL;
	GLXContext context;
	int dummy;
	Atom wmDelete;
	enum sync_type waitforsync = none;
	int width = 500, height = 500, verbose = 0,
		countonly = 0;
	int c, i = 1;

	opterr = 0;
	while ((c = getopt(argc, argv, optstr)) != -1) {
		switch (c) {
		case 'w':
			width = atoi(optarg);
			break;
		case 'h':
			height = atoi(optarg);
			break;
		case 's':
			switch (optarg[0]) {
			case 'n':
				waitforsync = none;
				break;
			case 's':
				waitforsync = sgi_video_sync;
				break;
			case 'b':
				waitforsync = buffer_swap;
				break;
			default:
				usage(argv[0]);
				break;
			}
			break;
		case 'v':
			verbose = 1;
			break;
		default:
			usage(argv[0]);
			break;
		}
	}

	disp = XOpenDisplay(NULL);
	if (!disp) {
		fprintf(stderr, "failed to open display\n");
		return -1;
	}

	if (!glXQueryExtension(disp, &dummy, &dummy)) {
		fprintf(stderr, "glXQueryExtension failed\n");
		return -1;
	}

	if (!GLXExtensionSupported(disp, "GLX_SGI_video_sync")) {
		fprintf(stderr, "GLX_SGI_video_sync not supported, exiting\n");
		return -1;
	}

	attrib[0] = GLX_RGBA;
	attrib[1] = 1;
	attrib[2] = GLX_RED_SIZE;
	attrib[3] = 1;
	attrib[4] = GLX_GREEN_SIZE;
	attrib[5] = 1;
	attrib[6] = GLX_BLUE_SIZE;
	attrib[7] = 1;
	if (waitforsync != buffer_swap)
		attrib[8] = None;
	else {
		attrib[8] = GLX_DOUBLEBUFFER;
		attrib[9] = 1;
		attrib[10] = None;
	}

	pvi = glXChooseVisual(disp, DefaultScreen(disp), attrib);
	if (!pvi) {
		fprintf(stderr, "failed to choose visual, exiting\n");
		return -1;
	}

	context = glXCreateContext(disp, pvi, None, GL_TRUE);
	if (!context) {
		fprintf(stderr, "failed to create glx context\n");
		return -1;
	}

	pvi->screen = DefaultScreen(disp);

	swa.colormap = XCreateColormap(disp, RootWindow(disp, pvi->screen),
				       pvi->visual, AllocNone);
	swa.border_pixel = 0;
	swa.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
		StructureNotifyMask;
	winGL = XCreateWindow(disp, RootWindow(disp, pvi->screen),
			      0, 0,
			      width, height,
			      0, pvi->depth, InputOutput, pvi->visual,
			      CWBorderPixel | CWColormap | CWEventMask, &swa);
	if (!winGL) {
		fprintf(stderr, "window creation failed\n");
		return -1;
	}
        wmDelete = XInternAtom(disp, "WM_DELETE_WINDOW", True);
        XSetWMProtocols(disp, winGL, &wmDelete, 1);

	XSetStandardProperties(disp, winGL, "glsync test", "glsync text",
			       None, NULL, 0, NULL);

	XMapRaised(disp, winGL);

	glXMakeCurrent(disp, winGL, context);

	video_sync_get = glXGetProcAddress((unsigned char *)"glXGetVideoSyncSGI");
	video_sync = glXGetProcAddress((unsigned char *)"glXWaitVideoSyncSGI");

	if (!video_sync_get || !video_sync) {
		fprintf(stderr, "failed to get sync functions\n");
		return -1;
	}

	video_sync_get(&count);
	count++;
	while (i++) {
		/* Wait for vsync */
		if (waitforsync == sgi_video_sync) {
			if (verbose)
				fprintf(stderr, "waiting on count %d\n", count);
			video_sync(2, (count + 1) % 2, &count);
			if (count < last_val)
				fprintf(stderr, "error:  vblank count went backwards: %d -> %d\n", last_val, count);
			if (count == last_val)
				fprintf(stderr, "error:  count didn't change: %d\n", count);
			last_val = count;
		} else if (waitforsync == buffer_swap) {
			glXSwapBuffers(disp, winGL);
		}

		if (countonly) {
			video_sync(2, 1, &count);
			fprintf(stderr, "current count: %d\n", count);
			sleep(1);
			continue;
		}

		/* Alternate colors to make tearing obvious */
		if (i & 1)
			glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
		else
			glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		glFlush();
	}

	XDestroyWindow(disp, winGL);
	glXDestroyContext(disp, context);
	XCloseDisplay(disp);

	return 0;
}