[HowTo]Install VirtualGL and TurboVNC to Jetson TK1

I installed VirtualGL and TurboVNC in my Jetson TK1.
I can execute CUDA samples in my Jetson TK1 without HDMI cable and watch rendered image from windows8 using TurboVNC Viewer or Android tablet using bVNC.
VirtualGL take rendering image from OpenGL application and TurboVNC send compressed image of whole desktop to client.
TurboVNC also recive user inputs from VNC clients and send them to applications in server.

TurboVNC:
http://www.turbovnc.org/
The VirtualGL Project:
http://www.virtualgl.org/

VirtualGL and TurboVNC Tips:
https://devtalk.nvidia.com/default/topic/828974/jetson-tk1/-howto-install-virtualgl-and-turbovnc-to-jetson-tk1/post/4685962/#4685962
VirtualGL and TurboVNC for 64-bit Linux For Tegra R24.1/R24.2:
https://devtalk.nvidia.com/default/topic/828974/jetson-tk1/-howto-install-virtualgl-and-turbovnc-to-jetson-tk1/post/4939863/#4939863

Compiled binary of VirtualGL and TurboVNC for ARM CPU are not provided, so I build them from source code.
How to install

wget http://demotomohiro.github.io/hardware/jetson_tk1/pkg/libjpeg-turbo_1.4.0_armhf.deb
wget http://demotomohiro.github.io/hardware/jetson_tk1/pkg/virtualgl_2.4_armhf.deb
wget http://demotomohiro.github.io/hardware/jetson_tk1/pkg/turbovnc_1.2.3_armhf.deb
sudo dpkg -i libjpeg-turbo_1.4.0_armhf.deb
sudo dpkg -i virtualgl_2.4_armhf.deb
sudo dpkg -i turbovnc_1.2.3_armhf.deb
sudo vi /etc/X11/xorg.conf

Add the following line to the “Screen” section in xorg.conf to run Xorg without the external display.

Section "Screen"
Identifier  "Screen0"
…
Option "AllowEmptyInitialConfiguration"
Option "UseEdid" "False"
...
EndSection
sudo vi /etc/ld.so.conf.d/libjpeg-turbo.conf

Add the following line

/opt/libjpeg-turbo/lib32
sudo ldconfig
#Configure VirtualGL
#http://svn.code.sf.net/p/virtualgl/code/tags/2.4/doc/index.html#hd006
sudo /opt/VirtualGL/bin/vglserver_config
sudo usermod -a -G vglusers ubuntu
sudo usermod -a -G vglusers root
#Star TurboVNC
/opt/TurboVNC/bin/vncserver
#Stop TurboVNC
/opt/TurboVNC/bin/vncserver -kill :1
#I installed xfce4
vi .vnc/xstartup.turbovnc

Set following text

#!/bin/sh

unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
startxfce4 &

Let’s run CUDA sample from vnc client

#login from vnc client
cd NVIDIA_CUDA-6.5_Samples/bin/armv7l/linux/release/gnueabihf/
/opt/VirtualGL/bin/vglrun ./oceanFFT

How to build libjpeg-turbo, VirtualGL and TurboVNC from source code:

#install tools to build libjpeg-turbo, VirtualGL and TurboVNC.
sudo apt-get install cmake-curses-gui
sudo apt-get install autoconf
sudo apt-get install libtool
sudo apt-get install g++
sudo apt-get install subversion
#install required libraries.
sudo apt-get install libjpeg-turbo8
sudo apt-get install libjpeg-turbo8-dev
sudo apt-get install libgl1-mesa-dev
sudo apt-get install libglu1-mesa-dev
sudo apt-get install libxv-dev
sudo apt-get install libpam0g-dev
sudo apt-get install libxt-dev
sudo apt-get install libxcursor-dev
sudo apt-get install libxaw7-dev

#download source code of libjpeg-turbo
svn co svn://svn.code.sf.net/p/libjpeg-turbo/code/tags/1.4.0 libjpeg-turbo
mkdir libjpeg-turbo-build
cd libjpeg-turbo
autoreconf -fiv
cd ../libjpeg-turbo-build
sh ../libjpeg-turbo/configure DEBARCH=armhf
make
make deb
sudo dpkg -i libjpeg-turbo_1.4.0_armhf.deb

#download source code of VirtualGL
svn co svn://svn.code.sf.net/p/virtualgl/code/tags/2.4 vgl
mkdir vgl-build
cd vgl-build
cmake -G "Unix Makefiles" -DTJPEG_LIBRARY="-L/opt/libjpeg-turbo/lib32/ -lturbojpeg" ../vgl
#List and configure CMake options
ccmake ../vgl
#build VirtualGL
make
vi pkgscripts/makedpkg
#Change "DEBARCH=armv7l" to "DEBARCH=armhf"
vi pkgscripts/deb-control
#Change "Architecture: armv7l" to "Architecture: armhf"
make deb 
sudo dpkg -i virtualgl_2.4_armhf.deb

cd ..
#download source code of TurboVNC
svn co svn://svn.code.sf.net/p/turbovnc/code/tags/1.2.3 vnc
mkdir vnc-build
cd vnc-build
cmake -G "Unix Makefiles" -DTJPEG_LIBRARY="-L/opt/libjpeg-turbo/lib32/ -lturbojpeg" ../vnc
#List and configure CMake options
ccmake	../vnc
make
vi pkgscripts/makedpkg
#Change "DEBARCH=armv7l" to "DEBARCH=armhf"
vi pkgscripts/deb-control
#Change "Architecture: armv7l" to "Architecture: armhf"
make deb
sudo dpkg -i turbovnc_1.2.3_armhf.deb
sudo vi /etc/X11/xorg.conf

Add the following line to the “Screen” section in xorg.conf to run Xorg without the external display.

Section "Screen"
Identifier  "Screen0"
…
Option "AllowEmptyInitialConfiguration"
Option "UseEdid" "False"
...
EndSection
sudo vi /etc/ld.so.conf.d/libjpeg-turbo.conf

Add the following line

/opt/libjpeg-turbo/lib32
sudo ldconfig
#Configure VirtualGL
#http://svn.code.sf.net/p/virtualgl/code/tags/2.4/doc/index.html#hd006
sudo /opt/VirtualGL/bin/vglserver_config
sudo usermod -a -G vglusers ubuntu
sudo usermod -a -G vglusers root
#Star TurboVNC
/opt/TurboVNC/bin/vncserver
#Stop TurboVNC
/opt/TurboVNC/bin/vncserver -kill :1
#I installed xfce4
vi .vnc/xstartup.turbovnc

Set following text

#!/bin/sh

unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
startxfce4 &

Let’s run CUDA sample from vnc client

#login from vnc client
cd NVIDIA_CUDA-6.5_Samples/bin/armv7l/linux/release/gnueabihf/
/opt/VirtualGL/bin/vglrun ./oceanFFT

Awesome! Thanks for it!

Thanks, I’ll post it onto the eLinux Wiki :-)

What sort of performance are you getting through it? eg: is there about 1 second of delay between the Jetson and what you see remotely, and just showing 1 FPS of changes remotely, or is it better or worse than that?

I’m using VNC client in same local network to Jetson TK1.
I’m not still testing it through WAN.

When I use TurboVNC Viewer in windows8 to connect TurboVNC server in Jetson TK1 and run oceanFFT(512x512), I can see smooth animation.
I can rotate camera with almost no delay.
When I maximaize window of oceanFFT(1240x900), it runs less smooth(looks like about 10FPS) and I see few delay(100~200ms).

I have followed all the steps and I get to control the Jetson TK1 from my Laptop (Ubuntu 14.04 or Windows 8.1), I can only see images from games samples brownser and “no graphics” CUDA samples like “maxMul” but with CUDA samples like “particles” or “ocean FFT” I can’t get see anything in my remote desktop. I am sure I am to connect to my Jetson TK1 (I cheked).

My Jetson TK! is LAN connected to the router and my Laptop via WIFI access.

Any suggestion ?

Thanks.

Did you executed program with vglrun like this?

/opt/VirtualGL/bin/vglrun ./oceanFFT

When you run OpenGL programs from remote desktop, you need to run program with vglrun.

Does VirtualGL still use the GPU for graphics and compositing but redirect the final framebuffer to memory instead of HDMI? Does TurboVNC simply compress that framebuffer? Or is this all ARM based graphics? Would the GPU be completely free for compute then?

This page explains how VirtualGL works.
http://www.virtualgl.org/About/Background

TurboVNC compress screen image using libjpeg-turbo.
http://www.libjpeg-turbo.org/
libjpeg-turbo uses NEON SIMD instructions in ARM system.

I tried some OpenGL programs from TurboVNC client.
oceanFFT in CUDA samples runs smoothly from TurboVNC client.
smokeParticles runs in about 5fps.
It runs in almost same fps when jetson tk1 is connected to HDMI display.

glxgears runs in about 1000fps when Jetson tk1 is connected HDMI display.
But it runs in about 130fps from TurboVNC client.
When I maximized glxgears window, fps drop down to 15fps.

I can run samples in NVIDIAGameWorks/OpenGLSampels in Jetson tk1.
But When I try to run them from TurboVNC client, they output “Failed to initialize GLFW” and quit.

glxinfo from TurboVNC client says:
OpenGL version string: 4.4.0 NVIDIA 21.3
OpenGL shading language version string: 4.40 NVIDIA via Cg compiler

I think OpenGL programs are executed using GPU.
But when fps is more then 120 or screen size is large, copying frame buffer and compressing it become bottleneck and cannot run as fast as when Jetson is connected to HDMI display.
If TurboVNC or VirtualGL could use the hardware encoder in GPU to compress frame buffer, they might runs faster in large screen.

Has anyone (besides demotomohiro) been able to follow the instructions above and verify that it works? I haven’t had time to test it properly myself, but if someone verifies it works then I’ll post it on the Wiki.

Ok, so this looks like it uses the TK1s GPU for compositing and the final framebuffer is compressed via TurboJPEG with NEON SIMD optimizations and transmitted over the network. Does this means that if you use the GPU gdb you’d freeze the graphics (or crash the device)? It would be convienent to get a software GL implementation optimizated with NEON then tranmitted with TurboVNC as well so that the GPU was completely idle (from the graphics standpoint). This way it could be remotely debugged with no issues. Is my assessment correct?

I’ve tested it using demotomohiro’s binaries, and it works very well:) There can be a slight delay sometimes, but the performance is very good overall.

A couple of things though - I didn’t have a screen section in my xorg.conf, so I edited it to look like this:

Section "Screen"
   Identifier  "Screen0"
   Device "Tegra0"
   Monitor "DSI-0"
   Option "AllowEmptyInitialConfiguration"
   Option "UseEdid" "False"
EndSection

I also had to

chmod +x ~/.vnc/xstartup.turbovnc

and to get the tab key working

vi ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-keyboard-shortcuts.xml

under the section

find the line

and change it to

from http://ubuntuforums.org/archive/index.php/t-1771058.html

tested using windows 8.1 with the jetson connected to the network using a linksys ae1000 and the grinch 21.3.4

Thanks demotomohiro !

I have built updated VirtualGL, TurboVNC and libjpeg-turbo.
OpenGLSamples in NVIDIAGameWorks did’nt run on old TurboVNC with VirtualGL, but they works on new version.
Tab key works without editing any config files on new one.

https://github.com/TurboVNC/turbovnc/blob/2.0.x/ChangeLog.txt
https://github.com/VirtualGL/virtualgl/blob/2.4.x/ChangeLog.txt
https://github.com/libjpeg-turbo/libjpeg-turbo/blob/1.4.x/ChangeLog.txt

How to install(tested on l4t R21.4)

wget http://demotomohiro.github.io/hardware/jetson_tk1/pkg/libjpeg-turbo_1.4.2_armhf.deb
wget http://demotomohiro.github.io/hardware/jetson_tk1/pkg/virtualgl_2.4.1_armhf.deb
wget http://demotomohiro.github.io/hardware/jetson_tk1/pkg/turbovnc_2.0.1_armhf.deb

sudo dpkg -i libjpeg-turbo_1.4.2_armhf.deb
sudo dpkg -i virtualgl_2.4.1_armhf.deb
sudo dpkg -i turbovnc_2.0.1_armhf.deb

sudo vi /etc/ld.so.conf.d/libjpeg-turbo.conf

#Add the following line

/opt/libjpeg-turbo/lib32
sudo ldconfig
#Configure VirtualGL
#https://cdn.rawgit.com/VirtualGL/virtualgl/2.4.1/doc/index.html#hd006
sudo /opt/VirtualGL/bin/vglserver_config
sudo usermod -a -G vglusers ubuntu

#Star TurboVNC
/opt/TurboVNC/bin/vncserver
#Stop TurboVNC
/opt/TurboVNC/bin/vncserver -kill :1

#install xfce4
sudo apt-get install xfce4 xfce4-goodies gnome-icon-theme-full
vi .vnc/xstartup.turbovnc

Set following text

#!/bin/sh

unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
startxfce4 &

Run CUDA sample from vnc client
#login from vnc client

cd NVIDIA_CUDA-6.5_Samples/bin/armv7l/linux/release/gnueabihf/
/opt/VirtualGL/bin/vglrun ./oceanFFT

How to build new libjpeg-turbo, VirtualGL and TurboVNC from source code:

#install tools to build libjpeg-turbo, VirtualGL and TurboVNC.
sudo apt-get install git
sudo apt-get install autoconf
sudo apt-get install libtool
sudo apt-get install cmake-curses-gui
sudo apt-get install g++
sudo apt-get install libglu1-mesa-dev 
sudo apt-get install libpam0g-dev

#download source code of libjpeg-turbo
git clone https://github.com/libjpeg-turbo/libjpeg-turbo.git -b 1.4.x
mkdir libjpeg-turbo-build
cd libjpeg-turbo
autoreconf -fiv
cd ../libjpeg-turbo-build
#configure and build
sh ../libjpeg-turbo/configure
make
vi pkgscripts/makedpkg.tmpl
#Change "DEBARCH=armv7l" to "DEBARCH=armhf"
make deb
#install
sudo dpkg -i libjpeg-turbo_1.4.2_armhf.deb

#download source code of VirtualGL
git clone https://github.com/VirtualGL/virtualgl.git -b 2.4.x
mkdir virtualgl-build
cd virtualgl-build
cmake -G "Unix Makefiles" -DTJPEG_LIBRARY="-L/opt/libjpeg-turbo/lib32/ -lturbojpeg" ../virtualgl
#List and configure CMake options
ccmake ../virtualgl
make
vi pkgscripts/makedpkg
#Change "DEBARCH=armv7l" to "DEBARCH=armhf"
vi pkgscripts/deb-control
#Change "Architecture: armv7l" to "Architecture: armhf"
make deb
sudo dpkg -i virtualgl_2.4.1_armhf.deb

#download source code of TurboVNC
git clone https://github.com/TurboVNC/turbovnc.git -b 2.0.x
mkdir turbovnc-build
cd turbovnc-build
cmake -G "Unix Makefiles" -DTVNC_BUILDJAVA=0 -DTJPEG_LIBRARY="-L/opt/libjpeg-turbo/lib32/ -lturbojpeg" ../turbovnc
make
vi pkgscripts/makedpkg
#Change "DEBARCH=armv7l" to "DEBARCH=armhf"
vi pkgscripts/deb-control
#Change "Architecture: armv7l" to "Architecture: armhf"
make deb
sudo dpkg -i turbovnc_2.0.1_armhf.deb

sudo vi /etc/ld.so.conf.d/libjpeg-turbo.conf
#Add the following line
/opt/libjpeg-turbo/lib32

sudo ldconfig
#Configure VirtualGL
#https://cdn.rawgit.com/VirtualGL/virtualgl/2.4.1/doc/index.html#hd006
sudo /opt/VirtualGL/bin/vglserver_config
sudo usermod -a -G vglusers ubuntu

#Star TurboVNC
/opt/TurboVNC/bin/vncserver
#Stop TurboVNC
/opt/TurboVNC/bin/vncserver -kill :1

#install xfce4
sudo apt-get install xfce4 xfce4-goodies gnome-icon-theme-full
vi .vnc/xstartup.turbovnc

Set following text

#!/bin/sh

unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
startxfce4 &

Tips:
Run OpenGL program from VNC client using VirtualGL:

/opt/VirtualGL/bin/vglrun ./OpenGLProgram

Securing a TurboVNC Connection
Add “-localhost” option to vncserver.
“-localhost” option prevents remote VNC clients from connecting except when doing so through a secure tunnel.
Make sure that ssh server is running on your Jetson TK1.
On linux client,

ssh -L 5901:localhost:5901 ubuntu@tegra-ubuntu

(Add “-f -N” option if you want ssh runs in background)
Client viewer connect to localhost:5901

vncviewer localhost:1

For more details:
https://cdn.rawgit.com/TurboVNC/turbovnc/2.0/doc/index.html#hd006005

Executing program from ssh and showing windows on the desktop

export DISPLAY=:1
firefox &

Automatically starting TurboVNC server on every bootup

#Open /etc/sysconfig/tvncservers, uncomment last 2 lines and edit options.
sudo vi /etc/sysconfig/tvncservers
sudo update-rc.d tvncserver defaults

Stop running TurboVNC server on boot

sudo update-rc.d tvncserver disable

Enable running TurboVNC server on boot again

sudo update-rc.d tvncserver enable

I have built VirtualGL, TurboVNC and libjpeg-turbo for 64-bit Linux For Tegra R24.1.
But they are not test on Jetson TX1.
They were built and tested on Nvidia Shield Android TV with 64-bit Linux For Tegra R24.1.
They might work on Jetson TX1 with 64-bit L4T R24.1, because same 64-bit Sample Root Filesystem and 64-bit driver package for Jetson TX1 is used on my Shield TV.

Edit:
deb package files built on Linux For Tegra R24.2:
http://demotomohiro.github.io/hardware/jetson_tk1/pkg/l4t24.2/libjpeg-turbo_1.5.2_arm64.deb
http://demotomohiro.github.io/hardware/jetson_tk1/pkg/l4t24.2/turbovnc_2.1_arm64.deb
http://demotomohiro.github.io/hardware/jetson_tk1/pkg/l4t24.2/virtualgl_2.5.1_arm64.deb

How to install:

wget http://demotomohiro.github.io/hardware/jetson_tk1/pkg/libjpeg-turbo_1.5.1_arm64.deb
wget http://demotomohiro.github.io/hardware/jetson_tk1/pkg/virtualgl_2.5.1_arm64.deb
wget http://demotomohiro.github.io/hardware/jetson_tk1/pkg/turbovnc_2.0.91_arm64.deb

sudo dpkg -i libjpeg-turbo_1.5.1_arm64.deb
sudo dpkg -i virtualgl_2.5.1_arm64.deb
sudo dpkg -i turbovnc_2.0.91_arm64.deb

sudo vi /etc/ld.so.conf.d/libjpeg-turbo.conf

Add the following line

/opt/libjpeg-turbo/lib64
sudo ldconfig

#Configure VirtualGL
#https://cdn.rawgit.com/VirtualGL/virtualgl/2.5/doc/index.html#hd006
sudo /opt/VirtualGL/bin/vglserver_config
sudo usermod -a -G vglusers ubuntu

#Star TurboVNC
/opt/TurboVNC/bin/vncserver
#Stop TurboVNC
/opt/TurboVNC/bin/vncserver -kill :1

#install xfce4
sudo apt-get install xfce4 gnome-icon-theme-full xfce4-terminal

vi .vnc/xstartup.turbovnc

Set following text

#!/bin/sh

unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
startxfce4 &

Run OpenGL program from VNC client.

/opt/VirtualGL/bin/vglrun ./OpenGLProgram

If you see black menu or panels, disable screen saver.

How to built VirtualGL, TurboVNC and libjpeg-turbo for 64-bit Linux For Tegra R24.1.

#install necessary packages to build them.
sudo apt-get install git
sudo apt-get install autoconf
sudo apt-get install libtool
sudo apt-get install cmake
sudo apt-get install g++
sudo apt-get install libpam0g-dev
sudo apt-get install libssl-dev

#Build and install libjpeg-turbo
git clone https://github.com/libjpeg-turbo/libjpeg-turbo.git
mkdir libjpeg-turbo-build
cd libjpeg-turbo
autoreconf -fiv
cd ../libjpeg-turbo-build
sh ../libjpeg-turbo/configure
make
vi pkgscripts/makedpkg.tmpl
#Change "DEBARCH=aarch64" to "DEBARCH=arm64"
make deb
sudo dpkg -i libjpeg-turbo_1.5.1_arm64.deb
cd ../

#Build and install VirtualGL
git clone https://github.com/VirtualGL/virtualgl.git
mkdir virtualgl-build
cd virtualgl-build
cmake -G "Unix Makefiles" -DTJPEG_LIBRARY="-L/opt/libjpeg-turbo/lib64/ -lturbojpeg" ../virtualgl
make

If you got link error from “libGL.so”, check this:
https://devtalk.nvidia.com/default/topic/946136/jetson-tx1/building-an-opengl-application/

vi pkgscripts/makedpkg
#Change "DEBARCH=aarch64" to "DEBARCH=arm64"
vi pkgscripts/deb-control
#Change "Architecture: aarch64" to "Architecture: arm64"
make deb
sudo dpkg -i virtualgl_2.5.1_arm64.deb
cd ..

#Build and install TurboVNC
git clone https://github.com/TurboVNC/turbovnc.git
mkdir turbovnc-build
cd turbovnc-build
cmake -G "Unix Makefiles" -DTVNC_BUILDJAVA=0 -DTJPEG_LIBRARY="-L/opt/libjpeg-turbo/lib64/ -lturbojpeg" ../turbovnc
make

If you got error like #error “GLYPHPADBYTES must be 4”,
edit …/turbovnc/unix/Xvnc/programs/Xserver/include/servermd.h and add following code before line “#ifdef avr32

#ifdef __aarch64__

# define IMAGE_BYTE_ORDER       LSBFirst
# define BITMAP_BIT_ORDER       LSBFirst
# define GLYPHPADBYTES          4

#endif
vi pkgscripts/makedpkg
#Change "DEBARCH=aarch64" to "DEBARCH=arm64"
vi pkgscripts/deb-control
#Change "Architecture: aarch64" to "Architecture: arm64"
make deb
sudo dpkg -i turbovnc_2.0.91_arm64.deb

I did verify it and everything works very well. The only two things I had to adapt for deploying it on Jetson TK1 were:

  1. Architecture type for deb packages shall be set to:
    #In pkgscripts/makedpkg
    DEBARCH=armhf
    #In pkgscripts/deb-control
    Architecture: armhf
    
  2. Path to libjpeg-turbo library must point to its 32-bit version:
    "-L/opt/libjpeg-turbo/lib32/ -lturbojpeg"
    

On top of that I had to follow those instructions given by dirtydigs:

EDIT:

I came across a problem similar to the one previously described by JavierGranado:

I can flawlessly run GameWorksOpenGLSamples, but any example from NVIDIA_CUDA-6.5_Samples yields segmentation fault.

In my Jetson TX1 with L4T R21.4, TurboVNC 2.0.1 and VirtualGL 2.4.1 works without editing xorg.conf and ~/.vnc/xstartup.turbovnc.
Tab key works without editing ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-keyboard-shortcuts.xml.

Xorg must be running without connecting HDMI display, because default /etc/X11/xorg.conf in L4T R21.4 enables option “AllowEmptyInitialConfiguration”.

When you run OpenGL program from TurboVNC client, that program must be executed with vglrun.
For example:

/opt/VirtualGL/bin/vglrun ./oceanFFT

Are you sure that your user is added to “vglusers” group?
Do your CUDA samples work when you are using HDMI display?
Do your CUDA samples which dont use OpenGL (deviceQuery, matrixMul, etc) work without TurboVNC?