If you’ve been using our PowerVR Graphics SDK, you’re probably familiar with PVRTrace, which allows you to capture and analyse the OpenGL ES and EGL API calls made by an application, without having to sift through source code. Aside from the usual assumptions (you have already installed both the Android NDK and the Android SDK), this tutorial assumes that your Android device is NOT rooted.

For this guide, I’ll be using Linux as my main operating system, but the same methodology can be applied to Windows – just change all those shell commands for clicks and double clicks if you are using Microsoft’s OS.

A bit of theory

As you may know, Android has a set of OpenGL ES shim libraries that call to the real driver as pointed to by egl.cfg (located in /system/lib/egl/).

PVRTrace adds an extra layer of OpenGL ES shim libraries between your application and the real driver to enable some extra functionality (for example to record the OpenGL calls and data or modify some of them on the fly to override the renderstate).

Usually, PVRTrace is installed AFTER the Android shim (this requires egl.cfg to be modified and some libraries to be copied to the system so the PVRTrace shim can pretend it is the real graphics driver). Sneaky isn’t it?

If you don’t want to root the device (as required for a standard PVRTrace install that alters the file system), you’ll need to build PVRTrace in your app.

PVRTrace - OpenGL ES calls

The image below shows the new flow of the OpenGL ES calls:

In a nutshell, that’s all the theory you need to know on PVRTrace, so let’s get cracking with an example!

A step-by-step guide to getting PVRTrace running on an unrooted Android device

First of all, let’s get an application to use as our Guinea pig – the OpenGL ES 2.0 Water example from our PowerVR Graphics SDK will do – it always does!. Remember to back the original version up before modifying it, just in case something goes wrong.

PowerVR Graphics SDK - OpenGL ES 2.0 - Water

Now we are ready to go.

Step 1: Tell the NativeActivity to load the recording libraries.

This is quick: just open the .java that extends NativeActivity and statically load the PVRTrace recording libraries, see the example code below:

public class OGLES2Water extends NativeActivity
{
    @Override
    protected void onCreate (Bundle savedInstanceState) {...}

    static {
        try {
            System.load("/data/data/com.powervr.OGLES2Water/lib/libPVRTrace.so");
            System.load("/data/data/com.powervr.OGLES2Water/lib/libEGL_PVRTRACE.so");
            System.load("/data/data/com.powervr.OGLES2Water/lib/libGLESv2_PVRTRACE.so");
        }
        catch( UnsatisfiedLinkError e ) {
            System.err.println("Native code library failed to load.n" + e);
        }
    }
    public void displayExitMessage(final String text) { ...}
}

Well done, that’s almost half of the work! Let’s move on to the next step.

Step 2: Point to the PVRTrace libraries in the Android.mk.

This is where we tell the Android NDK to link your application with our PVRTrace libraries (instead of the OpenGL ES libraries) that will be packed later with the .apk.

Just change the LOCAL_LDLIBS variable to load trace:

LOCAL_LDLIBS :=  
                                      -llog 
                                      -landroid 
                                      -L/path/to/the/SDK/PVRTrace/Recorder/Android_ <abi>/ 
                                      -lEGL_PVRTRACE 
                                      -lGLESv2_PVRTRACE

Just correct the path so it points to where you have the SDK installed and the Android_ <abi> to the architecture you are building for (armeabi, armeabi-v7a, mips or x86).

That’s almost it, we just have now one optional step before building.

Step 3: OPTIONAL. The application will have to place the data somewhere and we will use the SDCard. For that we need an extra permission on the AndroidManifest.xml.

Alternatively, you can usesome other more device dependant options like /data/local/tmp that do not require extra permissions.

Add this to the AndroidManifest.xml:

            <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Note: Our PowerVR Graphics SDK examples already have that permission.

Step 4: Build the application.

So, now that everything is on place it’s time to build the native part:

ndk-build APP_ABI= <abi>

Again, remember to change the <abi> for the one you are targeting.

Once the native part is build comes the last tricky bit, to copy the PVRTrace libraries on the recently created /libs/ <abi> folder:

cp /path/to/PVRTrace/Recorder/Android_ <abi>/lib* libs/ <abi>/

OK, now we are good to build the .apk. For that just run the usual commands:

android update project -p . -t <target>
ant debug

Note: <target> is the Android SDK you are targeting, just check “android list targets” and pick the one used by your device.

That’s it, your application now has all the PVRTrace functionality built in. Time to trace!

If you have any questions about this tutorial, you can contact our DevTech support team on Imagination’s PowerVR Insider dedicated forum. Remember to follow us on Twitter (@ImaginationPR and @PowerVRInsider) and subscribe to our blog.

About the author: Guillem Vinals Gangolells

Profile photo of GuillemV

I'm a Developer Technologies Engineer for the PowerVR division in Imagination Technologies, company in which I've been working since early 2011.My main task consists in the design of developer tools as well as in the integration of the PowerVR graphics in the Android ecosystem. Leaving the technical part aside, I also travel to some international events in order to collect feedback, give technical talks and meet with other companies

View all posts by Guillem Vinals Gangolells