SGS2 crashes in glDrawElements (in libGLESv1_CM_mali.so)
Posted 30 March 2012 - 03:12 PM
I spent much of last night trying to figure out why my Android Java game would cause a native crash in libGLESv1_CM_mali.so on the Samsung Galaxy S2 when coming out of sleep mode. My analysis suggests an OpenGL ES driver bug and I wonder if anyone suitably expert could advise (a) if I'm probably on the right track, and (b) how this should be reported and fixed?
The write-up is here:
Posted 04 April 2012 - 02:57 PM
It is difficult to answer since we do not have the source to analyse. But looking on the crash dump, which you have attached to your post http://sandcastle-sw.com/blog/?p=17, it includes information that the application crashes when the glDrawElements function is being called. From our best knowledge the crash may happen during the call to that function when VBO buffer is bound but functions like: glVertexPointer, glNormalPointer, ... are being called passing RAM pointers instead of buffer offsets. To be more precise about what I mean, it is worth reading this: http://www.khronos.o...k/1.1/docs/man/
If I may suggest something, try adding printouts in your game for each glVertexPointer, glNormalPointer, ... function in order to check they are passed offsets instead of pointers.
I hope this will help to investigate more deeply what causes the crashes. I do not think the problem is related to the GPU driver because the other 3D graphics applications that I have tried do not crash.
Posted 13 April 2012 - 02:23 PM
And even if I did somehow manage to do that, then nothing could *ever* work. The situation I have is where everything works beautifully, except for an occasional crash that only happens when coming out of sleep mode.
The problem happens even more on phones that have been upgraded to Android 4.0. The offset in the driver is exactly the same, so I guess it got exactly zero patches over the last 18 months. I wonder if anyone *ever* tests it, and if so, how?
Posted 20 April 2012 - 12:50 PM
You are right the Java has no pointers and you have no chance to pass a pointer by mistake. Although the pointer cannot be passed, you can still call GL functions like glVertexPointer, glNormalPointer, glTexCoordPointer, ... etc. in two different manners (using the GLES11 package). As an example let’s take a glTexCoordPointer function. There are two ways of calling it:
1. Passing a buffer (the buffer parameter, which is being interpreted by Java as the reference I believe, is being interpreted as a pointer in the driver)
public static void glTexCoordPointer (int size, int type, int stride, Buffer pointer)
2. Passing an offset as you already mentioned
public static void glTexCoordPointer (int size, int type, int stride, int offset)
The function from the first case mustn’t be used when a VBO is bound. Because the buffer (which at the end becomes a pointer) will be interpreted as an offset. This is what I meant earlier saying about the pointers and the offsets. Again I would suggest checking whether in the code is any function called in the manner from the 1st case. I believe the code you wrote works beautifully and everything looks good but sometimes it happens, that some unnecessary small primitive is rendered and moreover rendered incorrectly and the programmer even is not aware of the existence of it. Needless to say it happens very often in very complex applications that plenty GL commands are being called.
We have intercepted GL Commands in the driver and have found that VBO and non-VBO draw calls are mixed. Below is one such scenario:
glVertexPointer(3, GL_FLOAT, 0, 0x368c20);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, ...);
we see a call to glDrawElements where the driver was instructed to read from the mentioned offset (0x368c20) where the driver was instructed to read the vertices from the VBO buffer:2 from the 0x368c20 offset. At this time, the driver is trying to read a memory from the offset but the memory was not allocated by the driver in this space. The driver when tries to read a memory which was not allocated by itself causes a page fault error. How an application reacts on the page fault, it strongly depends on an OS it is running on. As far as we could check your game doesn’t have any of such big buffers in the memory space during its lifetime.
This post has been edited by Sylvek: 20 April 2012 - 12:57 PM