Android 5.1 crash - glDrawArrays GL_POINTS - Fatal 7 (SIGBUS) code 2

A few months ago, after I updated my Nexus 4 to Android 5.1 (now 5.1.1 is a factory image wallpaper from Google), one of my games started crashing when drawing particles with glDrawArrays with GL_POINTS. I simplified, redefined Java code and replicated the failure.

The crash is always fatal 7 (SIGBUS), code 2 in what appears to be OpenGL code.

In this test for me, with 118 calls to drawPoint () in the for loop, everything seems to work fine, but it fails (next frame) if I try 119 calls to drawPoint (). Any number of calls to drawPoint () greater than 119 also falls.

This Java code works fine on the Nexus 4 virtual device. The C source code works on PC, iOS, and other Android devices without issue.

It looks like it might be a problem with the Nexus 4 driver. Any ideas?

Logcat:

--------- beginning of crash
A/libc﹕ Fatal signal 7 (SIGBUS), code 2, fault addr 0xa2876000 in tid 17998 (GLThread 14477)
I/DEBUG﹕ *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG﹕ Build fingerprint: 'google/occam/mako:5.1.1/LMY47V/1836172:user/release-keys'
I/DEBUG﹕ Revision: '11'
I/DEBUG﹕ ABI: 'arm'
I/DEBUG﹕ pid: 17822, tid: 17998, name: GLThread 14477  >>> com.joeco.pointsprites <<<
I/DEBUG﹕ signal 7 (SIGBUS), code 2 (BUS_ADRERR), fault addr 0xa2876000
I/DEBUG﹕ r0 c0004600  r1 a2876000  r2 04000000  r3 a2876000
I/DEBUG﹕ r4 b7755818  r5 00000000  r6 b776d550  r7 00000018
I/DEBUG﹕ r8 b776d550  r9 04000000  sl 00008000  fp 00000000
I/DEBUG﹕ ip fc000000  sp a4601850  lr abad3c91  pc abac38e6  cpsr 60030030
I/DEBUG﹕ backtrace:
I/DEBUG﹕ #00 pc 000ab8e6  /system/vendor/lib/egl/libGLESv2_adreno.so (oxili_write_event_write+41)
I/DEBUG﹕ #01 pc 000bbc8d  /system/vendor/lib/egl/libGLESv2_adreno.so (oxili_wa_predraw+234)
I/DEBUG﹕ #02 pc 000bbef1  /system/vendor/lib/egl/libGLESv2_adreno.so (oxili_wa_point_sprite_dummy_draw+204)
I/DEBUG﹕ #03 pc 000ba47b  /system/vendor/lib/egl/libGLESv2_adreno.so (oxili_primitive_drawarrays+318)
I/DEBUG﹕ #04 pc 000825cf  /system/vendor/lib/egl/libGLESv2_adreno.so (rb_primitive_drawarrays+298)
I/DEBUG﹕ #05 pc 0005a4f7  /system/vendor/lib/egl/libGLESv2_adreno.so (core_glDrawArraysInstancedXXX+294)
I/DEBUG﹕ #06 pc 0005a877  /system/vendor/lib/egl/libGLESv2_adreno.so (core_glDrawArrays+6)
I/DEBUG﹕ #07 pc 00049acb  /system/vendor/lib/egl/libGLESv2_adreno.so (glDrawArrays+24)
I/DEBUG﹕ #08 pc 00a5befb  /data/dalvik-cache/arm/system@framework@boot.oat

      

Code for MainActivity.java:

// MainActivity.java -- pointsprite crash -- Joe Linhoff 6/15/2015
package com.joeco.pointsprites;

import android.app.Activity;
import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.os.Bundle;
import android.os.SystemClock;

import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ByteBuffer;

import javax.microedition.khronos.opengles.GL10;

// starting point: http://developer.android.com/training/graphics/opengl/index.html

public class MainActivity extends Activity {

    public GLSurfaceView mGLView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mGLView = new MyGLSurfaceView(this);
        setContentView(mGLView);
    } // onCreate()

    class MyGLSurfaceView extends GLSurfaceView {
        private final MyGLRenderer mRenderer;
        public MyGLSurfaceView(Context context) {
            super(context);
            setEGLContextClientVersion(2); // create OpenGL ES 2.0 context
            mRenderer = new MyGLRenderer();
            setRenderer(mRenderer);
            setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
        } // MyGLSurfaceView()
    } // class MyGLSurvaceView

    public class PointGeo {

        FloatBuffer vertexBuffer;
        static final int floatsPerVertex = 3;
        float pointCoords[] = { 0.1f, 0.0f, 0.0f }; // xyz
        final int vertexCount = pointCoords.length / floatsPerVertex;
        final int vertexStride = floatsPerVertex * 4; // 4 bytes per float

        public PointGeo() {
            ByteBuffer bb = ByteBuffer.allocateDirect(pointCoords.length * 4); // each is 4 bytes
            bb.order(ByteOrder.nativeOrder()); // device native byte order
            vertexBuffer = bb.asFloatBuffer(); // create floating point buffer
            vertexBuffer.put(pointCoords); // copy coordinates into buffer
            vertexBuffer.position(0); // set to first item
        } // PointGeo()

    } // class PointGeo

    public class MyGLRenderer implements GLSurfaceView.Renderer {

        private boolean mSetup = false;
        private PointGeo mPoint;
        private int mTriangleShaderProgram;
        private int mTriangleShaderLoc_uMVPMat;
        private int mTriangleShaderLoc_vPos;
        private float[] mViewMat = new float[16];
        private float[] mModelMat = new float[16];
        private float[] mProjMat = new float[16];
        private float[] mMVPMat = new float[16];

        public void onDrawFrame(GL10 unused) {

            if(!mSetup)
                lazySetup();

            GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

            // build model matrix -- rotate
            int time = (int)SystemClock.uptimeMillis() & 8191;
            float angleInDegrees = (360.0f / 8191.0f) * time;
            Matrix.setIdentityM(mModelMat, 0);
            Matrix.rotateM(mModelMat, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);

            // draw -- 118:ok 119:crash on next frame
            for(int i=0;i<119;i++)
                drawPoint();

        } // onDrawFrame()

        void drawPoint()
        {
            // setup
            GLES20.glUseProgram(mTriangleShaderProgram);
            GLES20.glEnableVertexAttribArray(mTriangleShaderLoc_vPos);
            GLES20.glVertexAttribPointer(mTriangleShaderLoc_vPos, mPoint.floatsPerVertex,
                    GLES20.GL_FLOAT, false, mPoint.vertexStride, mPoint.vertexBuffer);

            // build mvp matrix
            Matrix.multiplyMM(mMVPMat,0,mViewMat,0,mModelMat,0);
            Matrix.multiplyMM(mMVPMat, 0, mProjMat, 0, mMVPMat, 0);
            GLES20.glUniformMatrix4fv(mTriangleShaderLoc_uMVPMat, 1, false, mMVPMat, 0);

            // draw
            GLES20.glDrawArrays(GLES20.GL_POINTS, 0, mPoint.vertexCount);

            // finish
            GLES20.glDisableVertexAttribArray(mTriangleShaderLoc_vPos);
            GLES20.glUseProgram(0);
        } // drawPoint()

        @Override
        public void onSurfaceCreated(GL10 gl10, javax.microedition.khronos.egl.EGLConfig eglConfig) {
        } // onSurfaceCreated()

        public void onSurfaceChanged(GL10 unused, int width, int height) {
            GLES20.glViewport(0, 0, width, height);

            // create projection matrix
            final float ratio = (float) width / height;
            final float left = -ratio;
            final float right = ratio;
            final float bottom = -1.0f;
            final float top = 1.0f;
            final float near = 1.0f;
            final float far = 10.0f;
            Matrix.frustumM(mProjMat, 0, left, right, bottom, top, near, far);
        } // onSurfaceChanged()

        public int loadShader(int type, String shaderCode) {
            int shader = GLES20.glCreateShader(type); // create shader
            GLES20.glShaderSource(shader, shaderCode); // add source
            GLES20.glCompileShader(shader); // compile
            return shader;
        } // loadShader()

        private final String vertexShaderCode =
                "attribute vec4 vPos;" +
                "uniform mat4 uMVPMat;" +
                "void main() {" +
                "  gl_Position = vPos*uMVPMat;" +
                "  gl_PointSize = 40.0f; " +
                "}";

        private final String fragmentShaderCode =
                "void main() {" +
                "  gl_FragColor = vec4(0.5f,0.7f,0.5f,1.f);" +
                "}";

        void lazySetup()
        {
            mSetup=true;
            mPoint = new PointGeo();
            int vshader = loadShader(GLES20.GL_VERTEX_SHADER,vertexShaderCode);
            int fshader = loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentShaderCode);
            mTriangleShaderProgram = GLES20.glCreateProgram();
            GLES20.glAttachShader(mTriangleShaderProgram, vshader);
            GLES20.glAttachShader(mTriangleShaderProgram, fshader);
            GLES20.glLinkProgram(mTriangleShaderProgram);
            int err = GLES20.glGetError();

            mTriangleShaderLoc_uMVPMat = GLES20.glGetUniformLocation(mTriangleShaderProgram, "uMVPMat");
            mTriangleShaderLoc_vPos = GLES20.glGetAttribLocation(mTriangleShaderProgram, "vPos");

            setViewMat();
            Matrix.setIdentityM(mModelMat,0);

        } // lazySetup()

        void setViewMat()
        {
            final float eyeX = 0.0f;
            final float eyeY = 0.0f;
            final float eyeZ = 5.0f;

            final float lookX = 0.0f;
            final float lookY = 0.0f;
            final float lookZ = -1.0f;

            final float upX = 0.0f;
            final float upY = 1.0f;
            final float upZ = 0.0f;
            Matrix.setLookAtM(mViewMat, 0, eyeX, eyeY, eyeZ,
                    lookX, lookY, lookZ, upX, upY, upZ);
        } // setViewMat()

    } // class MyGLRenderer

} // class MainActivity

      

+3


source to share


1 answer


you have attribute vec4 vPos;

in your VS which consists of 4 floats, but you only load 3 floats per vertex ... change your vertex shader like this:

attribute vec4 vPos;

attribute vec3 vPos;



Besides

gl_Position = vPos * uMVPMat;

gl_Position = vec4(vPos, 1.0) * uMVPMat;

0


source







All Articles