Attached is the third version of the patch. This adds the following functionality to VirtualGL 2.3.2:

- Advertise support for the GLX Swap Control extensions (GLX_EXT_swap_control, GLX_SGI_swap_control). - Modify glXQueryDrawable() to intercept the attributes 'GLX_SWAP_INTERVAL_EXT' and 'GLX_MAX_SWAP_INTERVAL_EXT' and return our simulated interval values. - Modify glXSwapBuffers() to simulate the "sync to vblank" functionality. - Add glXSwapIntervalEXT() to set the glxSwapInterval (required for the GLX_EXT_swap_control extension). - Modify glXSwapIntervalEXT() to set the glxSwapInterval (required for the GLX_SGI_swap_control extension). - Modify VGLConfig to expose the "Emulated Monitor Refresh Rate" setting. - Modify VGLRUN to override the default value (60) of the "Emulated Monitor Refresh Rate" setting.


---
Thanks,
Dyweni

On 2013-06-04 15:16, Dyweni - VirtualGL-Users wrote:
Hi DRC,

You are correct.  Running vglrun with '-sp -fps 60' limits the 3D
rendering rate as you described. The 3D rendering rate follows the -fps
value.  I didn't realize that -sp would lock the two rates together.

I have another patch coming soon that implements GLX_SGI_swap_control /
glXSwapIntervalSGI and perfects the delay within glXSwapBuffers.


---
Thanks,
Dyweni


On 2013-06-04 14:13, DRC wrote:
Dyweni,

I await your response on this before I proceed any further. I need to
resolve the matter of whether you simply forgot to disable frame
spoiling (which is what I suspect, since your previous messages made
no
mention of using the -sp switch to vglrun or setting VGL_SPOIL to 0)
or
whether, for whatever reason, disabling it did not lock the 3D
rendering
rate to VGL_FPS (and if that's the case, I'm not sure I understand how
that could happen.)


You have to disable frame spoiling in order for the -fps option to
limit
the actual 3D rendering rate:

Did you pass 'sp' to vglrun?

vglrun -sp -fps {f} {application}

I am more keen on the idea of implementing GLX_EXT_swap_control as
opposed to implementing a separate frame rate governor, and I will
look
at your patch in detail.  However, I also want to understand whether
doing the above (using the existing frame rate governor without frame
spoiling) accomplishes a similar effect and, if not, why not.

------------------------------------------------------------------------------
How ServiceNow helps IT people transform IT departments:
1. A cloud service to automate IT design, transition and operations
2. Dashboards that offer high-level views of enterprise services
3. A single system of record for all IT processes
http://p.sf.net/sfu/servicenow-d2d-j
_______________________________________________
VirtualGL-Users mailing list
VirtualGL-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/virtualgl-users

------------------------------------------------------------------------------
How ServiceNow helps IT people transform IT departments:
1. A cloud service to automate IT design, transition and operations
2. Dashboards that offer high-level views of enterprise services
3. A single system of record for all IT processes
http://p.sf.net/sfu/servicenow-d2d-j
_______________________________________________
VirtualGL-Users mailing list
VirtualGL-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/virtualgl-users
From 94981a5365268e73a278e33ef5ac14fbe8d90b63 Mon Sep 17 00:00:00 2001
From: root <r...@phenom.dyweni.com>
Date: Sun, 2 Jun 2013 15:47:23 -0500
Subject: [PATCH 1/2] VirtualGL: Add support for GLX Swap Control Extensions

This add support for the following:
- GLX_EXT_swap_control
- GLX_SGI_swap_control
---
 .../work/VirtualGL-2.3.2/common/glx.h              |  5 ++
 .../work/VirtualGL-2.3.2/common/rr.h               |  1 +
 .../work/VirtualGL-2.3.2/server/faker-glx.cpp      | 98 ++++++++++++++++++++--
 .../work/VirtualGL-2.3.2/server/faker-mapfile.c    |  1 +
 .../work/VirtualGL-2.3.2/server/faker-sym.cpp      |  1 +
 .../work/VirtualGL-2.3.2/server/faker-sym.h        |  2 +
 .../work/VirtualGL-2.3.2/server/fakerconfig.cpp    |  3 +
 .../work/VirtualGL-2.3.2/server/vglconfig.cpp      | 25 +++++-
 .../work/VirtualGL-2.3.2/server/vglrun             |  3 +
 9 files changed, 130 insertions(+), 9 deletions(-)

diff --git a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/common/glx.h b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/common/glx.h
index 962c79c..d11c87f 100644
--- a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/common/glx.h
+++ b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/common/glx.h
@@ -131,6 +131,9 @@ extern "C" {
 #define GLX_PBUFFER_WIDTH                  0x8041
 #endif
 
+#define GLX_SWAP_INTERVAL_EXT              0x20F1
+#define GLX_MAX_SWAP_INTERVAL_EXT          0x20F2
+
 #ifndef GLX_ARB_get_proc_address
 typedef void (*__GLXextFuncPtr)(void);
 #endif
@@ -195,6 +198,8 @@ extern Bool glXQueryVersion(Display *dpy, int *major, int *minor);
 
 extern void glXSwapBuffers(Display *dpy, GLXDrawable drawable);
 
+extern void glXSwapIntervalEXT(Display *dpy, GLXDrawable drawable, int interval);
+
 extern void glXUseXFont(Font font, int first, int count, int list_base);
 
 extern void glXWaitGL(void);
diff --git a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/common/rr.h b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/common/rr.h
index 817b7e1..3cd9912 100644
--- a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/common/rr.h
+++ b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/common/rr.h
@@ -154,6 +154,7 @@ typedef struct _FakerConfig
   double flushdelay;
   int forcealpha;
   double fps;
+  double fps3d;
   double gamma;
   unsigned char gamma_lut[256];
   unsigned short gamma_lut16[65536];
diff --git a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-glx.cpp b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-glx.cpp
index 11fc0eb..a756901 100644
--- a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-glx.cpp
+++ b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-glx.cpp
@@ -158,6 +158,9 @@ GLXDrawable ServerDrawable(Display *dpy, GLXDrawable draw)
 
 extern "C" {
 
+static int glxSwapInterval = 1;
+static int glxMaxSwapInterval = 8;
+
 // Return a set of Pbuffer-compatible FB configs from the 3D X server that
 // contain the desired GLX attributes.
 
@@ -860,7 +863,7 @@ void glXFreeContextEXT(Display *dpy, GLXContext ctx)
 // properly report the extensions and GLX version it supports.
 
 static const char *glxextensions=
-	"GLX_ARB_get_proc_address GLX_ARB_multisample GLX_EXT_visual_info GLX_EXT_visual_rating GLX_SGI_make_current_read GLX_SGIX_fbconfig GLX_SGIX_pbuffer GLX_SUN_get_transparent_index GLX_ARB_create_context GLX_ARB_create_context_profile";
+	"GLX_ARB_get_proc_address GLX_ARB_multisample GLX_EXT_visual_info GLX_EXT_visual_rating GLX_SGI_make_current_read GLX_SGIX_fbconfig GLX_SGIX_pbuffer GLX_SUN_get_transparent_index GLX_ARB_create_context GLX_ARB_create_context_profile GLX_EXT_swap_control GLX_SGI_swap_control";
 
 const char *glXGetClientString(Display *dpy, int name)
 {
@@ -1198,6 +1201,7 @@ void (*glXGetProcAddressARB(const GLubyte *procName))(void)
 		checkfaked(glXQueryExtension)
 		checkfaked(glXQueryVersion)
 		checkfaked(glXSwapBuffers)
+		checkfaked(glXSwapIntervalEXT);
 		checkfaked(glXUseXFont)
 		checkfaked(glXWaitGL)
 
@@ -1645,6 +1649,15 @@ void glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute,
 
 	TRY();
 
+	// Intercept SWAP CONTROL attributes
+	if (attribute == GLX_SWAP_INTERVAL_EXT) {
+		*value = glxSwapInterval;
+		goto done;
+	} else if (attribute == GLX_MAX_SWAP_INTERVAL_EXT) {
+		*value = glxMaxSwapInterval;
+		goto done;
+	}
+
 	if(winh.isoverlay(dpy, draw))
 	{
 		_glXQueryDrawable(dpy, draw, attribute, value);
@@ -1726,17 +1739,44 @@ void glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
 }
 
 
+
+#include <sys/time.h>
+#include <unistd.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 * 1000000 + tv.tv_usec;
+}
+
+
 // If the application is rendering to the back buffer, VirtualGL will read
 // back and send the buffer whenever glXSwapBuffers() is called.
 
 void glXSwapBuffers(Display* dpy, GLXDrawable drawable)
 {
 	pbwin *pbw=NULL;
+	static int frames = 0;
+	static double last = -1.0, last2 = -1.0;
+	double delay;
+	GLfloat seconds;
+	GLfloat fps;
 
 		opentrace(glXSwapBuffers);  prargd(dpy);  prargx(drawable);  starttrace();
 
 	TRY();
 
+	if (last < 0.0)
+		last2 = last = current_time();
+
 	if(winh.isoverlay(dpy, drawable))
 	{
 		_glXSwapBuffers(dpy, drawable);
@@ -1751,6 +1791,24 @@ void glXSwapBuffers(Display* dpy, GLXDrawable drawable)
 	}
 	else _glXSwapBuffers(_localdpy, drawable);
 
+	if (glxSwapInterval > 0)
+	{
+		delay = (1000000 / (fconfig.fps3d / glxSwapInterval)) - (current_time() - last);
+		if (delay > 0)
+			usleep(delay);
+		last = current_time();
+	}
+	
+	frames++;
+	if (current_time() - last2 >= 5000000)
+	{
+		seconds = (current_time() - last2) / 1000000;
+		fps = frames / seconds;
+		printf("FAKER_GLX:  %d frames in %3.1f seconds = %6.3f FPS (interval %i, max %i)\n", frames, seconds, fps, glxSwapInterval, glxMaxSwapInterval);
+		last2 = current_time();
+		frames = 0;
+	}
+
 	CATCH();
 
 	done:
@@ -1760,6 +1818,31 @@ void glXSwapBuffers(Display* dpy, GLXDrawable drawable)
 }
 
 
+// Sets the GLX SWAP CONTROL INTERVAL
+void glXSwapIntervalEXT(Display *dpy, GLXDrawable drawable, int interval)
+{
+
+		opentrace(glXMakeCurrent);  prargd(dpy);  prargx(drawable);  prargi(interval);
+		starttrace();
+
+	TRY();
+
+	// don't set internval if beyond max interval
+	if (interval > glxMaxSwapInterval)
+		goto done;
+	
+	// set the interval
+	glxSwapInterval = interval;
+	
+	CATCH();
+
+	done:
+
+		stoptrace();  prargi(glxSwapInterval);
+		closetrace();
+}
+
+
 // Returns the transparent index from the overlay visual on the 2D X server
 
 int glXGetTransparentIndexSUN(Display *dpy, Window overlay,
@@ -1846,15 +1929,16 @@ Bool glXResetFrameCountNV(Display *dpy, int screen)
 }
 
 
-// Recent releases of the nVidia drivers always try to send this function to
-// the 2D X server for some reason, and some apps don't bother to ask VirtualGL
-// whether it supports GLX_SGI_swap_control, so we have to interpose this
-// function out of existence (it isn't relevant with Pbuffers, anyhow.)
+// Set the emulated GLX Swap Interval.
 
 int glXSwapIntervalSGI(int interval)
 {
-	if(fconfig.trace)
-		rrout.print("[VGL] glXSwapIntervalSGI() [NOT SUPPORTED]\n");
+	// don't set internval if beyond max interval
+	if (interval > glxMaxSwapInterval)
+		return 1;
+	
+	// now set the interval
+	glxSwapInterval = interval;
 	return 0;
 }
 
diff --git a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-mapfile.c b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-mapfile.c
index 21337ee..eba7c5c 100644
--- a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-mapfile.c
+++ b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-mapfile.c
@@ -13,6 +13,7 @@
 		glXQueryExtension;
 		glXQueryVersion;
 		glXSwapBuffers;
+		glXSwapIntervalEXT;
 		glXUseXFont;
 		glXWaitGL;
 
diff --git a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-sym.cpp b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-sym.cpp
index 6532867..2d84b07 100644
--- a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-sym.cpp
+++ b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-sym.cpp
@@ -168,6 +168,7 @@ static int __vgl_loadglsymbols(void *dllhnd)
 	lsym(glXQueryExtension)
 	lsym(glXQueryVersion)
 	lsym(glXSwapBuffers)
+	lsym(glXSwapIntervalEXT);
 	lsym(glXUseXFont)
 	lsym(glXWaitGL)
 
diff --git a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-sym.h b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-sym.h
index 30fbb7c..97617fb 100644
--- a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-sym.h
+++ b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/faker-sym.h
@@ -179,6 +179,8 @@ funcdef3(Bool, glXQueryVersion, Display *, dpy, int *, major, int *, minor,
 
 funcdef2(void, glXSwapBuffers, Display *, dpy, GLXDrawable, drawable,);
 
+funcdef3(void, glXSwapIntervalEXT, Display *, dpy, GLXDrawable, drawable, int, interval,);
+
 funcdef4(void, glXUseXFont, Font, font, int, first, int, count, int,
 	list_base,);
 
diff --git a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/fakerconfig.cpp b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/fakerconfig.cpp
index 90e31f4..bbabcb6 100644
--- a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/fakerconfig.cpp
+++ b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/fakerconfig.cpp
@@ -160,6 +160,7 @@ static void fconfig_init(void)
 	fconfig.compress=-1;
 	strncpy(fconfig.config, VGLCONFIG_PATH, MAXSTR);
 	fconfig.forcealpha=-1;
+	fconfig.fps3d=60;
 	fconfig_setgamma(fconfig, 1.0);
 	fconfig.glflushtrigger=1;
 	fconfig.gui=1;
@@ -307,6 +308,7 @@ void fconfig_reloadenv(void)
 	}
 	fetchenv_bool("VGL_FORCEALPHA", forcealpha);
 	fetchenv_dbl("VGL_FPS", fps, 0.0, 1000000.0);
+	fetchenv_dbl("VGL_FPS3D", fps3d, 0.0, 1000000.0);
 	if((env=getenv("VGL_GAMMA"))!=NULL && strlen(env)>0)
 	{
 		if(!strcmp(env, "1"))
@@ -548,6 +550,7 @@ void fconfig_print(FakerConfig &fc)
 	prconfint(compress);
 	prconfstr(config);
 	prconfdbl(fps);
+	prconfdbl(fps3d);
 	prconfdbl(flushdelay);
 	prconfint(forcealpha);
 	prconfdbl(gamma);
diff --git a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/vglconfig.cpp b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/vglconfig.cpp
index 6389c60..47583b8 100644
--- a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/vglconfig.cpp
+++ b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/vglconfig.cpp
@@ -39,7 +39,7 @@ Fl_Choice *compchoice=NULL, *sampchoice=NULL,
 	*stereochoice=NULL, *profchoice=NULL;
 Fl_Light_Button *spoilbutton=NULL, *ifbutton=NULL;
 Fl_Value_Slider *qualslider=NULL;
-Fl_Float_Input *gammainput=NULL, *fpsinput;
+Fl_Float_Input *gammainput=NULL, *fpsinput, *fps3dinput;
 Fl_Check_Button *fpsbutton=NULL;
 int ppid=-1;
 
@@ -162,6 +162,13 @@ void SetFPS(void)
 	fpsinput->value(temps);
 }
 
+void SetFPS3D(void)
+{
+	char temps[20];
+	snprintf(temps, 19, "%.2f", fconfig.fps3d);
+	fps3dinput->value(temps);
+}
+
 
 // Callbacks
 
@@ -254,6 +261,15 @@ void FPSCB(Fl_Widget *w, void *data)
 	input->value(temps);
 }
 
+void FPS3DCB(Fl_Widget *w, void *data)
+{
+	Fl_Float_Input *input=(Fl_Float_Input *)w;
+	fconfig.fps3d=atof(input->value());
+	char temps[20];
+	snprintf(temps, 19, "%.2f", fconfig.fps3d);
+	input->value(temps);
+}
+
 
 // Menus
 
@@ -340,7 +356,7 @@ void init(int argc, char **argv)
 {
 	char temps[20];
 
-	errifnot(win=new Fl_Double_Window(485, 340, "VirtualGL Configuration"));
+	errifnot(win=new Fl_Double_Window(485, 375, "VirtualGL Configuration"));
 
 	if(strlen(fconfig.transport)>0)
 	{
@@ -411,6 +427,11 @@ void init(int argc, char **argv)
 	fpsinput->callback(FPSCB, 0);
 	SetFPS();
 
+	errifnot(fps3dinput=new Fl_Float_Input(240, 340, 85, 25,
+		"Emulate Monitor Refresh Rate: "));
+	fps3dinput->callback(FPS3DCB, 0);
+	SetFPS3D();
+
 	win->end();
   win->show(argc, argv);
 }
diff --git a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/vglrun b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/vglrun
index 1b620e4..1dd4f31 100644
--- a/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/vglrun
+++ b/virtualgl-2.3.2-r2/work/VirtualGL-2.3.2/server/vglrun
@@ -59,6 +59,8 @@ usage()
 	echo
 	echo "-fps <f>  : Limit client/server frame rate to <f> frames/sec"
 	echo
+	echo "-fps3d <f>: Emulate Monitor Refresh Rate [default = 60]"
+	echo
 	echo "-gamma <g>: Set gamma correction factor to <g> (see docs)"
 	echo
 	echo "-ge       : Fool application into thinking that LD_PRELOAD is unset"
@@ -165,6 +167,7 @@ do
 	-v*)        VGL_VERBOSE=0     ; export VGL_VERBOSE  ;;
 	+v*)        VGL_VERBOSE=1     ; export VGL_VERBOSE  ;;
 	-fps)       VGL_FPS=$2        ; export VGL_FPS      ; shift     ;;
+	-fps3d)     VGL_FPS3D=$2      ; export VGL_FPS3D    ; shift     ;;
 	-ms)        VGL_SAMPLES=$2    ; export VGL_SAMPLES  ; shift     ;;
 	-ld)        LD_LIBRARY_PATH=$2:$LD_LIBRARY_PATH ;
 	            export LD_LIBRARY_PATH              ; shift     ;;
-- 
1.8.1.5

------------------------------------------------------------------------------
How ServiceNow helps IT people transform IT departments:
1. A cloud service to automate IT design, transition and operations
2. Dashboards that offer high-level views of enterprise services
3. A single system of record for all IT processes
http://p.sf.net/sfu/servicenow-d2d-j
_______________________________________________
VirtualGL-Users mailing list
VirtualGL-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/virtualgl-users

Reply via email to