Thread Handling in the Vuforia Native SDKs

Vuforia Engine samples use a separate GL thread for rendering 3D content on each frame. Developers need to understand which methods are called from this thread (vs. the main thread) and how to communicate between them for certain tasks.

Android native methods

In the Android samples, most native methods can be divided into two categories: those called from the main thread and those called from the GL thread. In ImageTargets.cpp, any method that starts with Java_com_vuforia_samples_ImageTargets_ImageTargetsRenderer is called from the GL thread. These methods are called from the onSurfaceCreated, onSurfaceChanged, or onDrawFrame callback methods in ImageTargetsRenderer.java, which are called by Android on a separate OpenGL thread.

Most of the methods that start with Java_com_vuforia_samples_ImageTargets_ImageTargets are called from the main thread. One exception is the loadTrackerData method, which is called from an AsyncTask in ImageTargets.java.

OpenGL methods

On Android, OpenGL methods should only be called from the GL thread. This is why, for instance, the samples create textures in two steps, first copying the info from Java on the main thread ( initApplicationNative) and then generating the textures on the GL thread ( initRendering).

The iOS samples divide the work a little differently. All OpenGL setup (creating textures, loading models, etc.) happens on the main thread. Then a background thread is used to call renderFrameVuforiaeach frame. This means that two separate threads are modifying the same OpenGL context, which is only safe when you can guarantee that the two threads will not modify it simultaneously.

Changing the UI

In the samples, tracking events are handled on the GL thread by the renderFrame method (renderFrameVuforia on iOS). This is where we typically query which trackables are active and use their pose to render 3D content on top.

On both Android and iOS, methods that modify the UI should only be called on the main thread. So if you want to modify the UI in response to a tracking event (e.g. a target being found), you'll need to communicate across threads. There are several ways to do this in Android, see the "Painless Threading" article in the Android documentation: http://android-developers.blogspot.it/2009/05/painless-threading.html.

For some sample code that uses Handlers to send a message to the main thread, see this article: How To Display Toast on Target Detection and Open Website

On iOS, you can use the NSObject performSelectorOnMainThread method:

[self performSelectorOnMainThread:@selector(methodName) withObject:nil];

 

Vuforia UpdateCallback

The Vuforia_onUpdate method is called by Vuforia Engine when new tracking data is available (see the Vuforia::UpdateCallback class and the Vuforia::registerCallback method). On Android, this is typically called on the main thread. On iOS, it is typically called on a background thread. It is safest to assume this method is not called on the main thread and uses thread-safe procedures accordingly.