Monday 13 February 2012

Android: OpenGL ES: segfault displaying modified vertex array

I fixed a bug causing segfault when displaying a modified vertex array with OpenGL ES in Android.

Problem: I have an activity which contains an OpenGL view and a list view on top of it. The OpenGL view displays a vertex array by glDrawElements. Each time the user tap a list item in the list view, the onClick event handler will update the vertex array used by the OpenGL view. Segmentation fault will happen if I click the list items enough number of times (usually 4-10 times).

The vertex array is a FloatBuffer. When I modify it I call position() to move the position to the end of the buffer, then call put(value) in a loop to add new vertices. After that, I call position(0) to move the position to the beginning of the buffer.

I found that instead of using put(value), if I use put(position, value) to add new vertices, I won't get segfault. Then I noticed some weird triangles were displayed shortly when I click the list view.

Then I realized the event handler of the list view uses different threads than the thread displaying the vertex array in the OpenGL view. Therefore if I change the position attribute of the FloatBuffer, it could be used by the drawing thread and cause segfault.

Lessons learned:
1. make sure vertex array is not modified by other threads when displaying it
2. when debugging this kind of problem, try to removing problematic codes part by part until narrow down to one line of code

No comments:

Post a Comment