All of lore.kernel.org
 help / color / mirror / Atom feed
* New case for intel_swap_event
@ 2010-10-11  9:29 Zhao, Jian J
  2010-10-11 18:04 ` Ian Romanick
  0 siblings, 1 reply; 2+ messages in thread
From: Zhao, Jian J @ 2010-10-11  9:29 UTC (permalink / raw)
  To: dri-devel@lists.sourceforge.net; +Cc: Barnes, Jesse


[-- Attachment #1.1: Type: text/plain, Size: 456 bytes --]

Hi,
 Recently I have made a piglit case that can test the behaviors of buffer swap, they are 1) test whether we can get swap events. 2) verify whether the swap is asynchronous 3) verify the swap frequency of swap interval being 0 is larger than interval being 1. Jesse has helped me have brief look on it and give me some advice. I have modified it. Can you help to add it into piglit tests? Thanks for help and comments!


Best regards,
Zhao Jian


[-- Attachment #1.2: Type: text/html, Size: 3210 bytes --]

[-- Attachment #2: swap_event_test.c --]
[-- Type: text/plain, Size: 12943 bytes --]

/*
 *  * This is a simple test case on the intel_swap_event.
 *   * Port by Jian Zhao  08 Sep 2010
 *    *              jian.j.zhao@intel.com
 *     *
 *      * See usage() below for command line options.
 */

#include "piglit-util.h"
#include "GL/glx.h"
#include <sys/time.h>

/* return current time (in seconds) */
static double
current_time(void)
{
	struct timeval tv;
#ifdef __VMS
	(void) gettimeofday(&tv, NULL );
#else
	struct timezone tz;
	(void) gettimeofday(&tv, &tz);
#endif
	return (double) tv.tv_sec + tv.tv_usec / 1000000.0;
}

PFNGLXSWAPINTERVALMESAPROC pglXSwapIntervalMESA;
PFNGLXGETSWAPINTERVALMESAPROC pglXGetSwapIntervalMESA;

#define STACK_L 10

static GLboolean fullscreen = GL_FALSE;	/* Create a single fullscreen window */
static GLboolean verbose = GL_FALSE;	/* Disable verbose.  */
static GLboolean Automatic = GL_FALSE;	/* Disable verbose.  */
static GLboolean test_events = GL_FALSE;	/* Disable verbose.  */
static GLboolean interval_diff = GL_FALSE;	/* Disable verbose.  */
static GLboolean async = GL_FALSE;	/* Disable verbose.  */
int event_base, Glx_event, count=0;
static int Intel_swap_event=0;
int swap_count=0, event_count=0, event_count_total=0, frames_total=0, message_count=0;
static double time_call=0.0, time_fin=0.0, time_val=0.0;
double swap_start[STACK_L],swap_returned[STACK_L];
int interval=1;
char * swap_event_type=NULL;
/**
 * Determine whether or not a GLX extension is supported.
 */
static int
is_glx_extension_supported(Display *dpy, const char *query)
{
	const int scrnum = DefaultScreen(dpy);
	const char *glx_extensions = NULL;
	const size_t len = strlen(query);
	const char *ptr;
	
	if (glx_extensions == NULL) {
		glx_extensions = glXQueryExtensionsString(dpy, scrnum);
	}
	
	ptr = strstr(glx_extensions, query);
	return ((ptr != NULL) && ((ptr[len] == ' ') || (ptr[len] == '\0')));
}

static void
query_swap_event(Display *dpy)
{

	if ( ! is_glx_extension_supported(dpy, "GLX_INTEL_swap_event")) {
		printf("The GLX_INTEL_swap_event is not supported in current version.\n");
		exit(0);
	}else{
		printf("The GLX_INTEL_swap_event is supported in current version.\n");
	}
	
	if (is_glx_extension_supported(dpy, "GLX_MESA_swap_control")) {
		pglXGetSwapIntervalMESA = (PFNGLXGETSWAPINTERVALMESAPROC) glXGetProcAddressARB((const GLubyte *) "glXGetSwapIntervalMESA");
		pglXSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC) glXGetProcAddressARB((const GLubyte *) "glXSwapIntervalMESA");
	}else{
		printf("GLX_MESA_swap_control was not supported by the driver.\n");
	}
}

/** Draw single frame, do SwapBuffers, compute FPS */
static void
draw_frame(Display *dpy, Window win)
{
	static int frames = 0, async_swap;
	static double tRot0 = -1.0, tRate0 = -1.0;
	static double swap_freq[2];
	double dt, t = current_time();
	int tem;
	
	if (tRot0 < 0.0)
		tRot0 = t;
	dt = t - tRot0;
	tRot0 = t;
	
	if (tRate0 < 0.0)
		tRate0 = t;
	if (t - tRate0 >= 3.0) {
		if (message_count & 0x1){
			(*pglXSwapIntervalMESA)(1);
			interval=(*pglXGetSwapIntervalMESA)();
			if ( !  interval == 1 ){
				printf("Failed to set swap interval to 1 by glXSwapIntervalMESA.\n");
				exit(0);
			}
		}else{
			(*pglXSwapIntervalMESA)(0);
			interval=(*pglXGetSwapIntervalMESA)();
			if ( !  interval == 0 ){
				printf("Failed to set swap interval to 0 by glXSwapIntervalMESA.\n");
				exit(0);
			}
		}
		message_count++;
		GLfloat seconds = t - tRate0;
		if ( (time_val / frames) < 0.0016 ){  // 0.0016 <=> 60Hz * 10 or 100Hz * 6 
			async_swap=1;
		}else{
			async_swap=0;
		}
		interval=1-interval;
		swap_freq[interval] = frames / seconds;
		if(Automatic){
			if (message_count==2){
				if (test_events){
					if( ! Intel_swap_event == 0 ){
						if (verbose){
							printf("glXSwapBuffers is called %d times and there is %d Intel_swap_event received in past %3.1f seconds.\n", swap_count, event_count, seconds);
							printf("There is swap events received, and the swap type is %s.\n", swap_event_type);
						}
						piglit_report_result(PIGLIT_SUCCESS);
						exit(0);
					}else{
						if (verbose){
							printf("glXSwapBuffers is called %d times and there is %d Intel_swap_event received in past %3.1f seconds.\n", swap_count, event_count, seconds);
							printf("There is no swap event received, and the swap type is %s.\n", swap_event_type);
						}
						piglit_report_result(PIGLIT_FAILURE);
						exit(1);
					}
					
				}
				if (interval_diff){
					tem = 1.5 * swap_freq[1];
					if ( swap_freq[0] >= tem ){
						if (verbose){
							printf("The swap frequency of no swap interval is much larger than swap interval being 1.\n");
						}
						piglit_report_result(PIGLIT_SUCCESS);
						exit(0);
					}else{
						if (verbose){
							printf("The swap frequency of no swap interval is not much larger than swap interval being 1. They are %lf and %lf.\n", swap_freq[0], swap_freq[1]);
						}
						piglit_report_result(PIGLIT_FAILURE);
						exit(1);
					}
				}
				if (async){
					if (verbose){
						printf("It takes about %lf seconds returning back from the glXSwapBuffers call on average.\n", (time_val / frames));
					}
					if (async_swap ==1 ){
						piglit_report_result(PIGLIT_SUCCESS);
						exit(0);
					}else{
						piglit_report_result(PIGLIT_FAILURE);
						exit(1);
					}
				}
			}	
		}
		tRate0 = t;
		frames = 0;
		time_val = 0;
		swap_count= 0;
		event_count= 0;
	}
	     
	if (frames_total & 1) {
		glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
		glColor3f(1.0f, 1.0f, 1.0f);
	} else {
		glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
		glColor3f(1.0f, 0.0f, 0.0f);
	}
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	count=frames_total%STACK_L;
	time_call=current_time();
	swap_start[count]=time_call;
	glXSwapBuffers(dpy, win);
	time_fin=current_time();
	swap_returned[count]=time_fin;
	time_val+=(time_fin-time_call);
	
	frames++;
	frames_total++;
	swap_count++;
}

/**
 * Remove window border/decorations.
 */
static void
no_border( Display *dpy, Window w)
{
	static const unsigned MWM_HINTS_DECORATIONS = (1 << 1);
	static const int PROP_MOTIF_WM_HINTS_ELEMENTS = 5;
	
	typedef struct
	{
		unsigned long       flags;
		unsigned long       functions;
		unsigned long       decorations;
		long                inputMode;
		unsigned long       status;
	} PropMotifWmHints;
	
	PropMotifWmHints motif_hints;
	Atom prop, proptype;
	unsigned long flags = 0;
	
	/* setup the property */
	motif_hints.flags = MWM_HINTS_DECORATIONS;
	motif_hints.decorations = flags;
	
	/* get the atom for the property */
	prop = XInternAtom( dpy, "_MOTIF_WM_HINTS", True );
	if (!prop) {
		/* something went wrong! */
		return;
	}
	
	/* not sure this is correct, seems to work, XA_WM_HINTS didn't work */
	proptype = prop;
	
	XChangeProperty( dpy, w,                         /* display, window */
	                 prop, proptype,                 /* property, type */
	                 32,                             /* format: 32-bit datums */
	                 PropModeReplace,                /* mode */
	                 (unsigned char *) &motif_hints, /* data */
	                 PROP_MOTIF_WM_HINTS_ELEMENTS    /* nelements */
	               );
}


/*
 * Create an RGB, double-buffered window.
 * Return the window and context handles.
 */
static void
make_window( Display *dpy, const char *name,
             int x, int y, int width, int height,
             Window *winRet, GLXContext *ctxRet)
{
	int attribs[] = { GLX_RGBA,
	                  GLX_RED_SIZE, 1,
	                  GLX_GREEN_SIZE, 1,
	                  GLX_BLUE_SIZE, 1,
	                  GLX_DOUBLEBUFFER,
	                  GLX_DEPTH_SIZE, 1,
	                  None };
	int scrnum;
	XSetWindowAttributes attr;
	unsigned long mask;
	Window root;
	Window win;
	GLXContext ctx;
	XVisualInfo *visinfo;
	
	scrnum = DefaultScreen( dpy );
	root = RootWindow( dpy, scrnum );
	
	if (fullscreen) {
		x = 0; y = 0;
		width = DisplayWidth( dpy, scrnum );
		height = DisplayHeight( dpy, scrnum );
	}
	
	visinfo = glXChooseVisual( dpy, scrnum, attribs );
	if (!visinfo) {
		printf("Error: couldn't get an RGB, Double-buffered visual\n");
		exit(1);
	}
	
	/* window attributes */
	attr.background_pixel = 0;
	attr.border_pixel = 0;
	attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
	attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
	/* XXX this is a bad way to get a borderless window! */
	mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
	
	win = XCreateWindow( dpy, root, x, y, width, height,
	     	        0, visinfo->depth, InputOutput,
	     	        visinfo->visual, mask, &attr );
	
	if (fullscreen)
		no_border(dpy, win);
	
	/* set hints and properties */
	{
		XSizeHints sizehints;
		sizehints.x = x;
		sizehints.y = y;
		sizehints.width  = width;
		sizehints.height = height;
		sizehints.flags = USSize | USPosition;
		XSetNormalHints(dpy, win, &sizehints);
		XSetStandardProperties(dpy, win, name, name,
		                        None, (char **)NULL, 0, &sizehints);
	}
	
	ctx = glXCreateContext( dpy, visinfo, NULL, True );
	if (!ctx) {
		printf("Error: glXCreateContext failed\n");
		exit(1);
	}
	
	XFree(visinfo);
	
	*winRet = win;
	*ctxRet = ctx;
}



/**
 * Only handle one glx event.
 */
void
handle_event(Display *dpy, Window win, XEvent *event)
{
	(void) dpy;
	(void) win;
	if( Glx_event == event->type){
		XEvent * event_p=event;
		GLXBufferSwapComplete * glx_event=(GLXBufferSwapComplete *) event_p;
		static double t_last=-1.0;
		time_fin=current_time();
		if (t_last < 0){
			t_last=time_fin;
		}
		if ( time_fin - t_last >= 3.0){
			if ( verbose ){
				count=event_count_total%STACK_L;
				printf("It receives the recent event at %lf seconds, and that glXSwapBuffers was called at %lf seconds, its swap returned at %lf seconds, so the total time of glXSwapBuffers takes is %lf seconds.\n", time_fin, swap_start[count], swap_returned[count], (time_fin-swap_start[count]));
			}
			t_last=time_fin;
		}
		switch (glx_event->event_type){
		case GLX_EXCHANGE_COMPLETE_INTEL:
			Intel_swap_event=GLX_EXCHANGE_COMPLETE_INTEL;
			swap_event_type="GLX_EXCHANGE_COMPLETE_INTEL";
			event_count++;
			event_count_total++;
			break;
		case GLX_COPY_COMPLETE_INTEL:
			Intel_swap_event=GLX_COPY_COMPLETE_INTEL;
			swap_event_type="GLX_COPY_COMPLETE_INTEL";
			event_count++;
			event_count_total++;
			break;
		case GLX_FLIP_COMPLETE_INTEL:
			Intel_swap_event=GLX_FLIP_COMPLETE_INTEL;
			swap_event_type="GLX_FLIP_COMPLETE_INTEL";
			event_count++;
			event_count_total++;
			break;
		}
	}
}


static void
event_loop(Display *dpy, Window win)
{
	while (1) {
		while (XPending(dpy) > 0) {
			XEvent event;
			XNextEvent(dpy, &event);
			Glx_event=event_base + GLX_BufferSwapComplete;
			handle_event(dpy, win, &event);
		}
		
		draw_frame(dpy, win);
	}
}


static void
usage(void)
{
	printf("Usage:\n");
	printf("  -fullscreen             run in fullscreen mode\n");
	printf("  -v       verbose mode, have more log\n");
	printf("  -auto       test automatically \n");
	printf("  	--event         test whether we can get swap events\n");
	printf("  	--interval      we expect that swap interval set to 0 should have higher swap frequency than interval to 1\n");
	printf("  	--async         test whether glXSwapBuffers is done in asynchronous\n");
}
 

int
main(int argc, char *argv[])
{
	unsigned int winWidth = 30, winHeight = 30;
	int x = 0, y = 0;
	Display *dpy;
	Window win;
	GLXContext ctx;
	char *dpyName = NULL;
	int i, error_base;
	
	for (i = 1; i < argc; i++) {
		if (strcmp(argv[i], "-auto") == 0) {
			Automatic = GL_TRUE;
		}
		else if (strcmp(argv[i], "-v") == 0) {
			verbose = GL_TRUE;
		}
		else if (strcmp(argv[i], "-fullscreen") == 0) {
			fullscreen = GL_TRUE;
		}
		else if (strcmp(argv[i], "--event") == 0) {
			test_events=GL_TRUE;
		}
		else if (strcmp(argv[i], "--async") == 0) {
			async = GL_TRUE;
		}
		else if (strcmp(argv[i], "--interval") == 0) {
			interval_diff = GL_TRUE;
		}
		else {
			usage();
			return -1;
		}
	}
	
	dpy = XOpenDisplay(dpyName);
	if (!dpy) {
		printf("Error: couldn't open display %s\n",
			dpyName ? dpyName : getenv("DISPLAY"));
		return -1;
	}
	
	make_window(dpy, "Swap event test", x, y, winWidth, winHeight, &win, &ctx);
	XMapWindow(dpy, win);
	glXMakeCurrent(dpy, win, ctx);
	query_swap_event(dpy);
	
	glXQueryExtension(dpy, &error_base, &event_base);
	
	(*pglXSwapIntervalMESA)(1);
	interval=(*pglXGetSwapIntervalMESA)();
	event_loop(dpy, win);
	
	glXDestroyContext(dpy, ctx);
	XDestroyWindow(dpy, win);
	XCloseDisplay(dpy);
	
	return 0;
}

[-- Attachment #3: Type: text/plain, Size: 369 bytes --]

------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1,  ECMAScript5, and DOM L2 & L3.
Spend less time writing and  rewriting code and more time creating great
experiences on the web. Be a part of the beta today.
http://p.sf.net/sfu/beautyoftheweb

[-- Attachment #4: Type: text/plain, Size: 161 bytes --]

--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-10-11 18:04 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-11  9:29 New case for intel_swap_event Zhao, Jian J
2010-10-11 18:04 ` Ian Romanick

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.