* GPU-Accelerated OpenGL (Using VirtualGL with TurboVNC)
{anchor: VGL}

Referring to the VirtualGL User's Guide, VirtualGL's X11 Transport draws
OpenGL-rendered frames to an X display using standard X11 drawing commands.
Since this results in the frames being sent uncompressed to the X server, the
X11 Transport is designed to be used with an "X proxy."  An X proxy acts as a
virtual X server, receiving X11 commands from applications (and from
VirtualGL), rendering the X11 commands into images, compressing the resulting
images, and sending the compressed images over the network to a client or
clients.

Since VirtualGL sends rendered frames to the X proxy at a very fast rate, the
X proxy must be able to compress the frames very quickly in order to keep up.
When VirtualGL was first released, most X proxies couldn't.  They simply
weren't designed to compress, with any degree of performance, the large and
complex images generated by 3D applications.  Enter TurboVNC.  Although
TurboVNC can be used with all types of applications, it was initially designed
as a fast X proxy for VirtualGL.  TurboVNC provides an alternate means of
delivering rendered frames from VirtualGL to a client machine without using
VirtualGL's built-in VGL Transport.

*** Advantages of TurboVNC (when compared to the VGL Transport)
#OPT: noList! plain!

	* When using the VGL Transport, non-OpenGL elements of the 3D application's
		GUI are sent over the network using remote X11, which does not perform well
		on high-latency networks such as broadband or long-haul fibre.  On such
		networks, non-OpenGL elements of the 3D application's GUI will load and
		render much faster (perhaps even orders of magnitude faster) with TurboVNC
		than with the VGL Transport.

	* For 3D applications whose rendered frames do not contain very many unique
		colors (for instance, CAD applications in wireframe mode), the hybrid
		encoding methods used by TurboVNC generally require less network bandwidth
		than the pure JPEG encoding method used by the VGL Transport.

	* TurboVNC provides two lossless compression modes, one of which is designed
		to reduce host CPU usage on gigabit networks and the other of which is
		designed to provide reasonable performance on wide-area networks (at the
		expense of higher host CPU usage.)  The VGL Transport's only lossless
		option is uncompressed RGB.

	* TurboVNC includes a Lossless Refresh feature that will, automatically
		(during periods of inactivity) or on demand, send a mathematically lossless
		copy of remote desktop regions that were previously sent using lossy
		compression.  Refer to {ref prefix="Sections ": LR} and
		{ref prefix="Section ": ALR}.

	* TurboVNC provides rudimentary collaboration capabilities.  Multiple users
		can simultaneously view the same TurboVNC session and pass around control
		of the keyboard and mouse.

	* From the point of view of the 3D application, the TurboVNC session is
		stateless.  If the network hiccups or the viewer is otherwise disconnected,
		then the TurboVNC session continues to run on the host and can be rejoined
		from any machine on the network.

	* No X server is required on the client machine.  This reduces the deployment
		complexity for Windows clients.

	* Any machine with a web browser, and any mobile device, can be used as a
		TurboVNC client (with reduced performance and features relative to the
		TurboVNC Viewer.)  Refer to {ref prefix="Section ": noVNC}.

*** Disadvantages of TurboVNC (when compared to the VGL transport)
#OPT: noList! plain!

	* No seamless windows.  All application windows are constrained to a virtual
		desktop, which is displayed in a single window on the client machine.

	* TurboVNC generally requires about 20% more host CPU cycles to maintain the
		same frame rate as the VGL Transport, both because it has to compress more
		pixels in each frame (an entire desktop rather than a single window) and
		because it has to perform 2D (X11) rendering as well as 3D rendering.

	* TurboVNC does not support quad-buffered stereo.

** Using VirtualGL on a TurboVNC Host

The most common (and optimal) way to use VirtualGL with TurboVNC is to
configure the same machine as a TurboVNC host and a VirtualGL server.  This
allows VirtualGL to send rendered frames to TurboVNC through shared memory
rather than over a network.

#IMG: x11transport.png
#OPT fmt=latex: w=4cm

The following procedure describes how to launch a 3D application using this
configuration.

*** Procedure
#OPT: noList! plain!

	#. Follow the procedure described in {ref prefix="Chapter ": TurboVNC_Usage}
		for starting a TurboVNC session and connecting to it.

	#. Open a new terminal inside the remote desktop.

	#. In the terminal, start a 3D application using VirtualGL:

		#Pverb: <<---
		/opt/VirtualGL/bin/vglrun __[vglrun options]__ __3D-application-executable-or-script__ __[arguments]__
		---

** Using VirtualGL on a Machine Other Than a TurboVNC Host

#IMG: vgltransportservernetwork.png
#OPT fmt=latex: w=4cm

If the TurboVNC host and VirtualGL server are different machines, then it is
desirable to use the VGL Transport to send rendered frames from the VirtualGL
server to the TurboVNC session.  It is also desirable to disable image
compression in the VGL Transport.  Otherwise, the images would have to be
compressed by the VirtualGL server, decompressed by the VirtualGL Client, then
recompressed by the TurboVNC Server, which is a waste of CPU resources.
However, sending images uncompressed over a network requires a fast network
(generally, Gigabit Ethernet or faster), so there needs to be a fast link
between the VirtualGL server and the TurboVNC host for this procedure to
perform well.

*** Procedure
#OPT: noList! plain!

	#. Follow the procedure described in {ref prefix="Chapter ": TurboVNC_Usage}
		for starting a TurboVNC session and connecting to it.

	#. Open a new terminal inside the remote desktop.

	#. In the same terminal window, open a Secure Shell (SSH) session into the
		VirtualGL server:

		#Pverb: <<---
		/opt/VirtualGL/bin/vglconnect __[vglconnect options]__ __user__@__server__
		---

		Replace __''user''__ with your username on the VirtualGL server and
		__''server''__ with the hostname or IP address of that server.  Refer to
		the VirtualGL User's Guide for additional ''vglconnect'' options.

	#. In the SSH session, set the ''VGL_COMPRESS'' environment variable to
		''rgb''.

		!!! Passing an argument of ''-c rgb'' to ''vglrun'' achieves the same
		result.

	#. In the SSH session, start a 3D application using VirtualGL:

		#Pverb: <<---
		/opt/VirtualGL/bin/vglrun __[vglrun options]__ __3D-application-executable-or-script__ __[arguments]__
		---

** NV-CONTROL Emulation

This version of TurboVNC includes partial emulation of the ''NV-CONTROL'' X11
extension provided by nVidia's proprietary Un*x drivers.  Certain 3D
applications rely on this extension to query and set low-level GPU properties,
and unfortunately the library (libXNVCtrl) used by applications to interact
with the extension is static, making it impossible to interpose using
VirtualGL.

Passing an argument of {pcode: -nvcontrol __display__} to ''vncserver'' causes
the TurboVNC Server to create a fake ''NV-CONTROL'' extension in the TurboVNC
session and redirect all ''NV-CONTROL'' requests to __''display''__.
__''display''__ should be the X display/screen of the 3D X server you plan to
use with VirtualGL ('':0.0'', for instance.)  The TurboVNC Server does not
attempt to open a connection to this display until an application uses the
''NV-CONTROL'' extension.  If a connection to the 3D X server cannot be opened,
if the 3D X server does not have the ''NV-CONTROL'' extension, or if other
issues are encountered when attempting to redirect ''NV-CONTROL'' requests,
then an X11 BadRequest error will be returned to the application, and the
TurboVNC session log will display an error message explaining why the request
failed.  It is assumed that you have already followed the procedure in the
VirtualGL User's Guide to allow access to the 3D X server.  If access to the 3D
X server is restricted to members of the ''vglusers'' group, then you may need
to execute

	#Verb: <<---
	xauth merge /etc/opt/VirtualGL/vgl_xauth_key
	---

in order to use the ''NV-CONTROL'' extension prior to invoking ''vglrun'' for
the first time.

You can change the 3D X server for a particular TurboVNC session after the
session has been started.  For instance, if you wanted to redirect both
''NV-CONTROL'' requests and OpenGL to a GPU attached to Screen 1 of Display :0,
then you could execute

	#Pverb: <<---
	xprop -root -f VNC_NVCDISPLAY 8s -set VNC_NVCDISPLAY :0.1
	vglrun -d :0.1 __3D-application-executable-or-script__
	---
