PerfHud ES is the best OpenGL ES debugger I’ve used, but it can be a bit tricky to set up. And now that I’m on Linux, even more so.

NVidia’s Page – Troubleshooting Notes on Forum #1

The latest PerfHud ES is now part of the Tegra Android Development Pack (2.2 as of this writing). An older version is available standalone (2.1), but the latest is now part of the pack. The pack itself is actually a download manager, so it’s a lightweight download if you uncheck other features.

To get it working, I had to do the following:

1. Add adb to my path, by adding it to ~/.profile

Something like:

export PATH="/opt/android-sdk/platform-tools:$PATH"

Which just happens to be where my Android SDK is, and adb is found in the platform-tools folder.

In context of my whole ~/.profile file.

# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.

# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
	. "$HOME/.bashrc"
    fi
fi

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

export PATH="/opt/android-sdk/platform-tools:$PATH"

Again, that last line is all I added.

2. Log out of Ubuntu, log back in.

You should now be able to an ‘adb devices’ from a terminal to see all connected Android devices.

3. Connect an NVidia device, and do the following to enable PerfHUD.

adb shell setprop debug.perfhudes 1

This needs to be done every time the device reboots.

4. Start the app you want to debug (Mine is an SDL App). **IMPORTANT** DO THIS FIRST!

5. Start PerfHUD ES. **NOTE** DO THIS SECOND!

The order of these 2 steps matters. I was not able to get PerfHUD ES to connect to my NVidia Shield unless I started the app first. And after, if I even shutdown the app, I need to exit PerfHUD ES and repeat to reconnect.

6. Connect to the running session. You’ll first see a message in the lower right corner of PerfHUD ES that you are not connected. Click that.

NVP01

If everything worked correctly, you’ll now be able to click on the currently running instance of the app.

NVP2

Click that, and click connect. Moments later the profiling should begin.

NVP03

Click over to the Frame debugger. That’s where all the fun stuff is. Scrub through each draw command; View geometry, textures and shaders; and so on.

Code Changes?

I’m not sure if this is required or not anymore (probably). If the frame profiling stuff is acting up, you may need to add the following snippet to your code.

#ifdef USES_EGL 
	{
	    typedef khronos_int64_t EGLint64NV;
	    typedef khronos_uint64_t EGLuint64NV;
	    typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC)(void);
	    typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC)(void);
	    PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC eglGetSystemTimeFrequencyNV;
	    PFNEGLGETSYSTEMTIMENVPROC eglGetSystemTimeNV;

	    eglGetSystemTimeFrequencyNV = (PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC)eglGetProcAddress("eglGetSystemTimeFrequencyNV");
		eglGetSystemTimeNV = (PFNEGLGETSYSTEMTIMENVPROC)eglGetProcAddress("eglGetSystemTimeNV");
		//if available use the extension. This enables the frame profiler in PerfHUD ES
		if (eglGetSystemTimeFrequencyNV && eglGetSystemTimeNV) {
			eglGetSystemTimeFrequencyNV();
			eglGetSystemTimeNV();
		}
	}
#endif // USES_EGL //

The ‘USES_EGL’ is a #define of mine. Feel free to omit it. You’re going to the “egl.h” header though.

Hosted on Ubuntu 14.04 (prerelease), with an Intel HD 3000 GPU. No NVidia card (or OpenCL) required. 🙂