This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

SGS2 crashes in glDrawElements (in libGLESv1_CM_mali.so)

Note: This was originally posted on 30th March 2012 at http://forums.arm.com

Hi,


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?



Thanks,


Reuben
Parents
  • Note: This was originally posted on 20th April 2012 at http://forums.arm.com

    Hi Reuben,

    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:

    ...

      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 2);

      ...

      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.


    Cheers,

    Sylvek
Reply
  • Note: This was originally posted on 20th April 2012 at http://forums.arm.com

    Hi Reuben,

    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:

    ...

      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 2);

      ...

      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.


    Cheers,

    Sylvek
Children
No data