1

So I have been trying to put together an Opengl ES 2.0 application. My test device is a Moto G phone. I am setting up a routines to load large terrain meshes. My approach is a Terrain class. In this class are separate terrain tiles stored in a 2D array that when combined make up the entire terrain mesh. Each tile is 64x64 vertices and is pushed on the GPU as a VBO. My plan is to get as many tiles on the GPU as possible then deal with draw performance using a LOD algorithm. As it stands however, I am able to load 40x40 tiles but anything over that I get a crash. No error, nothing. I am checking constantly for errors on each GL call but haven't found anything. I am relatively new to this all and my two thoughts as to why this is happening are:

1) I am simply overloading the GPU. What are the limits here and how can I test for them? 2) I am spending too much time within the UI thread loading these VBO's and a crash is occurring...

Can anyone fill me in on some of these limits as well as what could be triggering a crash?

Here is my Terrain Class which creates a 2D array of Tile objects:

package com.example.terraintiletest;

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

public class Terrain {

    Tile[][] mTiles;            //A 2D array of all tiles representing this terrain Mesh.
    public int tileNRows;       //How many rows of tileNSize tiles
    public int tileNCols;       //How many cols of tileNSize tiles
    public int tileNSize;       //Size of each tile in verteces. They are square.

    /* The constructor here simply creates a 2D array of Tiles given a tileSize and how many tiles wide by how many tiles high */
    Terrain(int tileSize, int tileRows, int tileCols){

            this.tileNRows = tileRows;
            this.tileNCols = tileCols;
            this.tileNSize = tileSize;

            int tilescreated = 0;
            int row,col,x,y;
            float xOff=0,yOff=0;
            int positions_ctr = 0,colour_ctr=0;

            int posLen   = tileSize*tileSize*3;
            int colLen   = tileSize*tileSize*4;
            int indLen   = ((tileSize-1) * ((tileSize*2) +2))-2;
            int posBytes = tileSize*tileSize*3*4;
            int colBytes = tileSize*tileSize*4*4;
            int indBytes = (((tileSize-1) * ((tileSize*2) +2))-2) * 2;

            float[]     poss        = new float[posLen];
            float[]     cols        = new float[colLen];
            short[][]   index       = new short[tileSize][tileSize];
            short[]     IDA         = new short[indLen];

            /* Buffer for glbufferdata */
            ByteBuffer bPos = ByteBuffer.allocateDirect(posBytes).order(ByteOrder.nativeOrder());
            FloatBuffer fPos = bPos.asFloatBuffer();
            ByteBuffer bCol = ByteBuffer.allocateDirect(colBytes).order(ByteOrder.nativeOrder());
            FloatBuffer fCol = bCol.asFloatBuffer();
            ByteBuffer bInd = ByteBuffer.allocateDirect(indBytes).order(ByteOrder.nativeOrder());
            ShortBuffer sInd = bInd.asShortBuffer();

            /* Build an Indece Buffer for triangle strips */
            int ct = 0;
            for(y=0;y<tileSize;y++){
                for(x=0;x<tileSize;x++){
                    index[y][x] = (short)ct;
                    ct++;
                }
            }

            ct = 0;
            for(y=0;y<tileSize-1;y++){
                for(x=0;x<tileSize;x++){

                    IDA[ct] = index[y+1][x];
                    ct++;
                    IDA[ct] = index[y][x]; 
                    ct++;

                    if(x==tileSize-1 && y != tileSize -2) { 
                        IDA[ct] = index[y][x];
                        ct++;
                        IDA[ct] = index[y+2][0];
                        ct++;
                    }

                }
            }

            sInd.clear();
            sInd.put(IDA);
            sInd.position(0);

            this.mTiles = new Tile[tileRows][tileCols];

            /* Create positions and colors for all tiles */
            try{

                // iterate through tiles
                for(y=0;y<tileRows;y++){
                    for(x=0;x<tileCols;x++){

                        //iterate through tile contents
                        for(row=0;row<tileSize;row++){
                            for(col=0;col<tileSize;col++){
                                poss[positions_ctr]     = xOff+col;
                                poss[positions_ctr+1]   = yOff+row;
                                poss[positions_ctr+2]   = 0.0f;

                                cols[colour_ctr]        = 1.0f;
                                cols[colour_ctr+1]      = 0.0f;
                                cols[colour_ctr+2]      = 0.0f;
                                cols[colour_ctr+3]      = 1.0f;

                                //System.out.println("tile["+x+"]["+y+"]: "+poss[positions_ctr]+","+poss[positions_ctr+1]+","+poss[positions_ctr+2]+","+cols[colour_ctr]+","+cols[colour_ctr+1]+","+cols[colour_ctr+2]+","+cols[colour_ctr+2]);
                                positions_ctr+=3;
                                colour_ctr+=4;

                            }
                        }

                        fPos.clear();
                        fCol.clear();
                        fPos.put(poss);
                        fCol.put(cols);
                        fPos.position(0);
                        fCol.position(0);

                        //Init a Tile VBO
                        this.mTiles[y][x] = new Tile(fPos, fCol, sInd, posLen, colLen, indLen);

                        tilescreated++;

                        xOff+=tileSize;
                        positions_ctr=0;
                        colour_ctr=0;
                    }
                    xOff=0;
                    yOff+=tileSize;
                }
            } catch (OutOfMemoryError err) {
                System.out.println("OUT OF MEMORY!");
                System.exit(1);
            }

            bPos.limit(0);
            bCol.limit(0);
            bInd.limit(0);
            fPos.limit(0);
            fCol.limit(0);
            sInd.limit(0);
            fPos = null;
            fCol = null;
            sInd = null;
            bPos = null;
            bCol = null;
            bInd = null;
            index = null;
            IDA = null;
            System.gc();

            System.out.println("Tiles Created:"+tilescreated);

        }

    }

Here is my Tile class:

package com.example.terraintiletest;

import java.nio.FloatBuffer;
import java.nio.ShortBuffer;


import android.opengl.GLES20;

public class Tile {

    private final int vbo[];
    private final int ibo[];
    private final int COLOURS   = 0;
    private final int POSITIONS = 1;
    private final int FINE      = 0;

    int mProgram = 0;
    int mPositionHandle = 0;
    int mColorHandle = 0;
    int mMVPMatrixHandle = 0;
    int vertexShaderHandle = 0;
    int fragmentShaderHandle = 0;

    int indeceSize;

    final String vertexShaderCode =
        "uniform mat4 u_MVPMatrix;      \n"     // A constant representing the combined model/view/projection matrix.

      + "attribute vec4 a_Position;     \n"     // Per-vertex position information we will pass in.
      + "attribute vec4 a_Color;        \n"     // Per-vertex color information we will pass in.

      + "varying vec4 v_Color;          \n"     // This will be passed into the fragment shader.

      + "void main()                    \n"     // The entry point for our vertex shader.
      + "{                              \n"
      + "   v_Color = a_Color;          \n"     // Pass the color through to the fragment shader.
                                                // It will be interpolated across the triangle.
      + "   gl_Position = u_MVPMatrix   \n"     // gl_Position is a special variable used to store the final position.
      + "               * a_Position;   \n"     // Multiply the vertex by the matrix to get the final point in
      + "}                              \n";    // normalized screen coordinates.

    final String fragmentShaderCode =
        "precision mediump float;       \n"     // Set the default precision to medium. We don't need as high of a
                                                // precision in the fragment shader.
      + "varying vec4 v_Color;          \n"     // This is the color from the vertex shader interpolated across the
                                                // triangle per fragment.
      + "void main()                    \n"     // The entry point for our fragment shader.
      + "{                              \n"
      + "   gl_FragColor = v_Color;     \n"     // Pass the color directly through the pipeline.
      + "}                              \n";

    public Tile(FloatBuffer Zbuf, FloatBuffer Cbuf, ShortBuffer Ibuf,int azLength,int acLength,int siLength) {

        int x;
        for(x=0;x<Zbuf.capacity();x++){
            //System.out.println("Position "+Zbuf.get(x));
        }       
        for(x=0;x<Cbuf.capacity();x++){
            //System.out.println("Colour "+Cbuf.get(x));
        }
        for(x=0;x<Ibuf.capacity();x++){
            //System.out.println("Index "+Ibuf.get(x));
        }

        // Load in the vertex shader.
            vertexShaderHandle = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);

            if (vertexShaderHandle != 0) 
            {
                // Pass in the shader source.
                GLES20.glShaderSource(vertexShaderHandle, vertexShaderCode);

                // Compile the shader.
                GLES20.glCompileShader(vertexShaderHandle);

                // Get the compilation status.
                final int[] compileStatus = new int[1];
                GLES20.glGetShaderiv(vertexShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);

                // If the compilation failed, delete the shader.
                if (compileStatus[0] == 0) 
                {               
                    GLES20.glDeleteShader(vertexShaderHandle);
                    vertexShaderHandle = 0;
                }
            }

            if (vertexShaderHandle == 0)
            {
                throw new RuntimeException("Error creating vertex shader.");
            }

            // Load in the fragment shader shader.
            fragmentShaderHandle = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);

            if (fragmentShaderHandle != 0) 
            {
                // Pass in the shader source.
                GLES20.glShaderSource(fragmentShaderHandle, fragmentShaderCode);

                // Compile the shader.
                GLES20.glCompileShader(fragmentShaderHandle);

                // Get the compilation status.
                final int[] compileStatus = new int[1];
                GLES20.glGetShaderiv(fragmentShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);

                // If the compilation failed, delete the shader.
                if (compileStatus[0] == 0) 
                {               
                    GLES20.glDeleteShader(fragmentShaderHandle);
                    fragmentShaderHandle = 0;
                }
            }

            if (fragmentShaderHandle == 0)
            {
                throw new RuntimeException("Error creating fragment shader.");
            } 

        // Create a program object and store the handle to it.
            mProgram = GLES20.glCreateProgram();

            if (mProgram != 0) 
            {
                // Bind the vertex shader to the program.
                GLES20.glAttachShader(mProgram, vertexShaderHandle);            

                // Bind the fragment shader to the program.
                GLES20.glAttachShader(mProgram, fragmentShaderHandle);

                GLES20.glBindAttribLocation(mProgram, 0, "a_Position");
                if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
                    System.out.println("FH_ERROR- "+GLES20.glGetError());
                    System.exit(1);
                }
                GLES20.glBindAttribLocation(mProgram, 1, "a_Color");
                if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
                    System.out.println("FH_ERROR- "+GLES20.glGetError());
                    System.exit(1);
                }

                GLES20.glLinkProgram(mProgram);

                // Get the link status.
                final int[] linkStatus = new int[1];
                GLES20.glGetProgramiv(mProgram, GLES20.GL_LINK_STATUS, linkStatus, 0);

                if (linkStatus[0] == 0) 
                {               
                    GLES20.glDeleteProgram(mProgram);
                    mProgram = 0;
                }
            }

            if (mProgram == 0)
            {
                throw new RuntimeException("Error creating program.");
            }

            // Set program handles. These will later be used to pass in values to the program.
            mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "u_MVPMatrix");
            if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
                System.out.println("FH_ERROR- "+GLES20.glGetError());
                System.exit(1);
            }
            mPositionHandle = GLES20.glGetAttribLocation(mProgram, "a_Position");
            if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
                System.out.println("FH_ERROR- "+GLES20.glGetError());
                System.exit(1);
            }
            mColorHandle = GLES20.glGetAttribLocation(mProgram, "a_Color");  
            if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
                System.out.println("FH_ERROR- "+GLES20.glGetError());
                System.exit(1);
            }

            //VBO create

            vbo = new int[2];
            ibo = new int[1];

            GLES20.glGenBuffers(2,vbo,0);
            if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
                System.out.println("FH_ERROR- "+GLES20.glGetError());
                System.exit(1);
            }
            GLES20.glGenBuffers(1,ibo,0);
            if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
                System.out.println("FH_ERROR- "+GLES20.glGetError());
                System.exit(1);
            }

            //Positions
            GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo[POSITIONS] );
            if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
                System.out.println("FH_ERROR- "+GLES20.glGetError());
                System.exit(1);
            }
            GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, azLength * FH_Utilities.FLOAT_SIZE,
                Zbuf, GLES20.GL_STATIC_DRAW);

            if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
                System.out.println("FH_ERROR- "+GLES20.glGetError());
                System.exit(1);
            }

            //Colours
            GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo[COLOURS] );
            if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
                System.out.println("FH_ERROR- "+GLES20.glGetError());
                System.exit(1);
            }
            GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, acLength * FH_Utilities.FLOAT_SIZE,
                Cbuf, GLES20.GL_STATIC_DRAW);

            if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
                System.out.println("FH_ERROR- "+GLES20.glGetError());
                System.exit(1);
            }

            //Indeces
            GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, ibo[FINE]);
            if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
                System.out.println("FH_ERROR- "+GLES20.glGetError());
                System.exit(1);
            }
            GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, siLength * FH_Utilities.SHORT_SIZE, Ibuf, GLES20.GL_STATIC_DRAW);

            if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
                System.out.println("FH_ERROR- "+GLES20.glGetError());
                System.exit(1);
            }

            GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);

            if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
                System.out.println("FH_ERROR- "+GLES20.glGetError());
                System.exit(1);
            }

            GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);

            if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
                System.out.println("FH_ERROR- "+GLES20.glGetError());
                System.exit(1);
            }

            indeceSize = Ibuf.capacity();

    }


    public void draw(float[] mvpMatrix) {

        if(mPositionHandle<0 || mMVPMatrixHandle<0 || mColorHandle<0 || mProgram<0) {
            System.out.println("ERROR - A Handle has failed");
            System.out.println("mPositionHandle "+mPositionHandle);
            System.out.println("mMVPMatrixHandle "+mMVPMatrixHandle);
            System.out.println("mColorHandle "+mColorHandle);
            System.out.println("mProgram "+mProgram);
            System.exit(1);
        }

        GLES20.glUseProgram(mProgram);  

        final int mPositionDataSize = 3;
        final int mColorDataSize = 4;

        GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);

        if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
            System.out.println("FH_ERROR- "+GLES20.glGetError());
            System.exit(1);
        }

        // Pass in the position information
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo[POSITIONS]);

        if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
            System.out.println("FH_ERROR- "+GLES20.glGetError());
            System.exit(1);
        }

        GLES20.glEnableVertexAttribArray(mPositionHandle);

        if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
            System.out.println("FH_ERROR- "+GLES20.glGetError());
            System.exit(1);
        }

        GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, 
            GLES20.GL_FLOAT, false, 0, 0);

        if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
            System.out.println("FH_ERROR- "+GLES20.glGetError());
            System.exit(1);
        }

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo[COLOURS]);

        if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
            System.out.println("FH_ERROR- "+GLES20.glGetError());
            System.exit(1);
        }

        GLES20.glEnableVertexAttribArray(mColorHandle);

        if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
            System.out.println("FH_ERROR- "+GLES20.glGetError());
            System.exit(1);
        }

        GLES20.glVertexAttribPointer(mColorHandle, mColorDataSize, 
            GLES20.GL_FLOAT, false, 0, 0);

        if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
            System.out.println("FH_ERROR- "+GLES20.glGetError());
            System.exit(1);
        }

        GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, ibo[FINE]);

        if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
            System.out.println("FH_ERROR- "+GLES20.glGetError());
            System.exit(1);
        }

        GLES20.glDrawElements(GLES20.GL_TRIANGLE_STRIP, indeceSize, GLES20.GL_UNSIGNED_SHORT, 0);

        if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
            System.out.println("FH_ERROR- "+GLES20.glGetError());
            System.exit(1);
        }

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);

        if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
            System.out.println("FH_ERROR- "+GLES20.glGetError());
            System.exit(1);
        }

        GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);

        if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
            System.out.println("FH_ERROR- "+GLES20.glGetError());
            System.exit(1);
        }

        //Disable vertex array
        GLES20.glDisableVertexAttribArray(mPositionHandle);

        if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
            System.out.println("FH_ERROR- "+GLES20.glGetError());
            System.exit(1);
        }
        //Disable vertex array
        GLES20.glDisableVertexAttribArray(mColorHandle);

        if(GLES20.glGetError()!=GLES20.GL_NO_ERROR){
            System.out.println("FH_ERROR- "+GLES20.glGetError());
            System.exit(1);
        }

    }


    public static int loadShader(int type, String shaderCode){

        // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
        // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
        int shader = GLES20.glCreateShader(type);

        // add the source code to the shader and compile it
        GLES20.glShaderSource(shader, shaderCode);
        GLES20.glCompileShader(shader);

        return shader;
    }


}

Logcat ERROR output:

10-17 10:58:33.851: E/AuthorizationBluetoothService(11845): Proximity feature is not enabled.
10-17 10:58:33.878: E/AuthorizationBluetoothService(11845): Proximity feature is not enabled.
10-17 10:58:38.040: E/MDMCTBK(269): MdmCutbackHndler,Could not open ''
10-17 10:58:38.067: E/MDMCTBK(269): MdmCutbackHndler,Could not open ''
10-17 10:58:42.103: E/AuthorizationBluetoothService(12984): Proximity feature is not enabled.
10-17 10:58:42.130: E/AuthorizationBluetoothService(12984): Proximity feature is not enabled.
10-17 10:58:47.113: E/dalvikvm(12909): Could not find class 'android.app.Notification$Action$Builder', referenced from method android.support.v4.app.L.a
10-17 10:58:47.135: E/PartnerBookmarksReader(12909): ATTENTION: not using partner bookmarks as none were provided
10-17 10:58:47.673: E/GoogleApiIcingClientImpl(12909): NoSuchMethodException while trying to construct DocumentContents
10-17 10:59:23.604: E/AuthorizationBluetoothService(12984): Proximity feature is not enabled.
10-17 10:59:33.840: A/ProcessStats(995): Starting service ServiceState{4320e1c0 com.motorola.ccc.devicemanagement.DeviceManagementNotifierService pkg=com.motorola.ccc.devicemanagement proc=4320e1c0} without owner
10-17 10:59:33.849: A/ProcessStats(995): Starting service ServiceState{43317ea0 com.motorola.ccc.checkin.CheckinService pkg=com.motorola.ccc.checkin proc=43317ea0} without owner
10-17 10:59:33.854: A/ProcessStats(995): Starting service ServiceState{432d64c0 com.motorola.blur.service.blur.BlurServiceMother pkg=com.motorola.ccc.cce proc=432d64c0} without owner
10-17 10:59:33.858: A/ProcessStats(995): Starting service ServiceState{431d4538 com.motorola.ccc.ota.env.OtaService pkg=com.motorola.ccc.ota proc=431d4538} without owner
10-17 10:59:33.862: A/ProcessStats(995): Starting service ServiceState{4317ed80 com.google.android.location.fused.NlpLocationReceiverService pkg=com.google.android.gms proc=4317ed80} without owner
10-17 10:59:33.867: A/ProcessStats(995): Starting service ServiceState{430f6950 com.google.android.location.geocode.GeocodeService pkg=com.google.android.gms proc=430f6950} without owner
10-17 10:59:33.870: A/ProcessStats(995): Starting service ServiceState{431be468 com.google.android.location.fused.service.FusedProviderService pkg=com.google.android.gms proc=431be468} without owner
10-17 10:59:33.874: A/ProcessStats(995): Starting service ServiceState{4317dce0 com.google.android.location.geofencer.service.GeofenceProviderService pkg=com.google.android.gms proc=4317dce0} without owner
10-17 10:59:33.878: A/ProcessStats(995): Starting service ServiceState{42ed1ce0 com.google.android.location.reporting.service.DispatchingService pkg=com.google.android.gms proc=42ed1ce0} without owner
10-17 10:59:33.882: A/ProcessStats(995): Starting service ServiceState{43104248 com.google.android.location.internal.server.GoogleLocationService pkg=com.google.android.gms proc=43104248} without owner
10-17 10:59:33.886: A/ProcessStats(995): Starting service ServiceState{430f9868 com.google.android.location.network.NetworkLocationService pkg=com.google.android.gms proc=430f9868} without owner
10-17 10:59:33.891: A/ProcessStats(995): Starting service ServiceState{43188228 com.google.android.location.internal.GoogleLocationManagerService pkg=com.google.android.gms proc=43188228} without owner
10-17 10:59:33.895: A/ProcessStats(995): Starting service ServiceState{42b2c7c0 com.google.android.backup.BackupTransportService pkg=com.google.android.backuptransport proc=42b2c7c0} without owner
10-17 10:59:33.900: A/ProcessStats(995): Starting service ServiceState{436e4208 com.android.email.service.AttachmentDownloadService pkg=com.android.email proc=436e4208} without owner
10-17 10:59:43.622: E/AuthorizationBluetoothService(12984): Proximity feature is not enabled.
10-17 10:59:43.697: E/GCoreFlp(13341): Bound FusedProviderService with LocationManager
10-17 11:00:58.035: E/MDMCTBK(269): MdmCutbackHndler,Could not open ''
10-17 11:00:58.090: E/MDMCTBK(269): MdmCutbackHndler,Could not open ''
10-17 11:01:24.382: E/ActivityThread(13467): Failed to find provider info for com.motorola.blur.setupprovider
10-17 11:01:24.488: E/ActivityThread(13467): Failed to find provider info for com.motorola.blur.setupprovider
10-17 11:01:24.643: E/OtaApp(13467): [error] > CusSM.wifiDiscoverySanityCheck failed: wifi discover time is not set nothing to process
10-17 11:01:24.680: A/ProcessStats(995): Starting service ServiceState{436e4208 com.android.email.service.AttachmentDownloadService pkg=com.android.email proc=436e4208} without owner
10-17 11:01:25.102: E/MMApiProvisionService(13467): handleResponse(): no settings sent by the server:
10-17 11:02:18.030: E/MDMCTBK(269): MdmCutbackHndler,Could not open ''
10-17 11:02:18.054: E/MDMCTBK(269): MdmCutbackHndler,Could not open ''
10-17 11:03:25.164: E/global frequency(13467): no tags to log
Fra
  • 393
  • 7
  • 19
  • ** I should have mentioned. This Terrain class is instantiated inside the onSurfaceCreated(GL10 unused, EGLConfig config) function of my own Renderer – Fra Oct 16 '14 at 19:32
  • Welcome to Stack Overflow. For your future posts, please note that Stack Snippets only work for web languages such as HTML and Javascript, for other languages they have no effect but to clutter the post with useless "run code snippet" buttons, so I've removed them. –  Oct 16 '14 at 19:33
  • So how many bytes are allocated? – Morrison Chang Oct 16 '14 at 19:34
  • 7 bytes per vertex. 28672 bytes per tile. So for 40x40 tiles that is 45875200 total bytes or 46mb. – Fra Oct 16 '14 at 19:36
  • See: http://stackoverflow.com/questions/9266952/how-to-determine-maximum-texture-memory-on-android-opengl-es. and http://stackoverflow.com/questions/7369238/max-size-for-vertex-buffer-objects-opengl-es-2-0 – Morrison Chang Oct 16 '14 at 19:57
  • Those links are helpful thanks. I am still struggling to figure out why this application is crashing though. I am not using textures to load vertices I just have raw data. – Fra Oct 16 '14 at 20:55
  • Would you be able to paste the crash trace from logcat? – Learn OpenGL ES Oct 16 '14 at 20:59
  • You're actually using about 30 bytes per vertex, so that's a total of almost 200 MBytes. Also, while this is probably not the problem, is there any reason why you're creating a shader program for each tile? 1600 shader programs is quite a lot. – Reto Koradi Oct 17 '14 at 03:45
  • Reto: Good point. 7 floats/vertex = 28bytes. Also a good point on the shader program. I will create one program and share it instead. Thanks! I have posted the output generated by the crash above in my original post. I wanted to post the warnings as well but I don't want to fill this whole page with text. I can post more if need be. Looking at the stacktrace though I really see nothing regarding memory or anything. It all seems related to other processes... – Fra Oct 17 '14 at 15:06
  • Also, is there any other way to load vertex data other than floats? Colours are fractions of 255.. Unless there was some way to tell OpenGL how to interpret single bytes(1-255) on the fly I don't know how that would be done... – Fra Oct 17 '14 at 15:28
  • Im working on my tile class. I get this message sometimes: 10-17 13:19:03.988: I/Choreographer(8464): Skipped 36 frames! The application may be doing too much work on its main thread. – Fra Oct 17 '14 at 17:20
  • Anyone know what would trip this message? I have reduced my vertices to 10bytes each. Is loading over 150mb at one go via VBO's too much to ask? – Fra Oct 20 '14 at 13:42
  • Have you tried reducing number of tiles to say "2x2" or such setup ? since memory amount will not be an issue for small tile size, you'll be able to check if issue lies elsewhere. – Harshiv Mar 04 '20 at 03:16

0 Answers0