9

I'm facing a big problem. I'm using a Transformer tf101 tab with Android 4.0.3 on it.

My app is using a custom OpenGL ES 2.0 surface. I'm rendering multiple planes with textures. this textures are changing approx. 20 times per second and are updated by passing byte arrays. However, in certain cases, the screen begins flickering and does not render the new textures. Additional UI Elements are still responsive and do their work as intended. It seems the OpenGL context ignores all commands and is unresponsive.

When this happens, a few lines show up in my logCat:

08-20 10:31:15.390: D/NvOsDebugPrintf(2898): NvRmChannelSubmit: NvError_IoctlFailed with error code 1

followed by

08-20 10:31:15.390: D/NvOsDebugPrintf(2898): NvRmChannelSubmit failed (err = 13, SyncPointValue = 879005, returning = 0)

and a few of them:

08-20 10:31:15.390: D/NvOsDebugPrintf(2898): NvRmChannelSubmit failed (err = 196623, SyncPointValue = 0)

Here is how i create my Textured Plane:

    m_nTextureStorage[0] = 0;

    GLES20.glGenTextures( 1, m_nTextureStorage, 0);
    GLES20.glActiveTexture( GLES20.GL_TEXTURE0 );
    GLES20.glBindTexture( GLES20.GL_TEXTURE_2D, m_nTextureStorage[ 0 ] );

    // Set filtering
    GLES20.glTexParameterf( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST );
    GLES20.glTexParameterf( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST );
    GLES20.glTexParameteri( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE );
    GLES20.glTexParameteri( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE );

and here is how i draw it:

GLES20.glEnable(GLES20.GL_TEXTURE_2D);
        GLES20.glEnable(GLES20.GL_DEPTH_TEST);
        GLES20.glActiveTexture( GLES20.GL_TEXTURE0 );

        //GLES20.glUniformMatrix4fv(m_HMVPMatrixUniform, 1, false, mvpMatrix, 0); 
        GLES20.glUseProgram( m_nProgramHandle );
        ByteBuffer oDataBuf = ByteBuffer.wrap( m_sTexture );

        m_HTextureUniform = GLES20.glGetUniformLocation( m_nProgramHandle, "uTexture" );
        m_HTextureCoordinate = GLES20.glGetAttribLocation( m_nProgramHandle, "TexCoordinate" );
        GLES20.glUniform1iv( m_HTextureUniform, 2, m_nTextureStorage, 0 );

        // get handle to the vertex shader's vPosition member
        m_nPositionHandle = GLES20.glGetAttribLocation( m_nProgramHandle, "vPosition" );


        // Prepare the triangle data
        GLES20.glTexImage2D( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, 640, 480,
                             0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, oDataBuf );

        // Prepare the triangle data
        GLES20.glVertexAttribPointer( m_nPositionHandle, 3, GLES20.GL_FLOAT, false, 12, m_oVertexBuffer );
        GLES20.glEnableVertexAttribArray( m_nPositionHandle );

        GLES20.glVertexAttribPointer( m_HTextureCoordinate, 2, GLES20.GL_FLOAT, false, 12, m_oTextureBuffer); 
        GLES20.glEnableVertexAttribArray( m_HTextureCoordinate );

        m_nMVPMatrixHandle = GLES20.glGetUniformLocation( m_nProgramHandle, "uMVPMatrix");

        // Apply the projection and view transformation
        GLES20.glUniformMatrix4fv( m_nMVPMatrixHandle, 1, false, mvpMatrix, 0);

        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);

The OpenGL Renderer simply calls the draw function of my TexturedPlane by passing the mvpMatrix. Im not deleting any textures since i've read that the android system will take care of that automatically.

I think it has something todo with the GPU going OOM, but im not sure since i haven't found anything related to the posted error messages.

Thanks it advance!

UPDATE:

The Rendermode was set to RENDER_WHEN_DIRTY . After Changing it to RENDERMODE_CONTINOUSLY the problem disappears.. Weird. Since this is just a workaround and no solution, I'm still asking for help ;)

Leaving the Rendermode at continuously is no option, since this consumes to much processor time and makes no sense, since rendering is only necessary when new textures a generated.

Hafnernuss
  • 2,659
  • 2
  • 29
  • 41
  • How is m_sTexture being produced? – Maz Aug 20 '12 at 09:16
  • dynamically as new byte[ 640 * 480 ]; This is done only once. I'm quite new to java and OpenGL. However, i noticed that when the flickering starts, the Surface renders the last 3 Frames that have been passed.... This states that those frames are still stored somewhere in the GPU memory. – Hafnernuss Aug 20 '12 at 09:21
  • update: it seems that the flickering is more likely to occur when the process of texture creation takes a lot of time. Creating new textures can take up to a second. If this is the case, the flickering starts after a few seconds. If the texture generation takes under 50ms, the flickering never occurs... Could this mean the flickering is triggered by some sort of synchronization issues, since the OpenGL Rendering and the texture creation run in different threads? – Hafnernuss Aug 20 '12 at 09:48
  • Are you sure that all gl related function calls occurred in the rendering thread? – Tutankhamen Aug 20 '12 at 12:29
  • very good point. No im not. My Renderer is able to handle various "Objects". E.G. Planes, Crosses for marking areas and so on. These Objects are created outside this Rendering Thread. gl calls are done in the constructors. However, no "objects" are initzialized before the OpenGL is up and running.... But since i am using Reentrant Locks i am sure that only 1 Thread is accessing the OpenGL, right? – Hafnernuss Aug 20 '12 at 12:38
  • Still no solution for this. has nobody an idea? – Hafnernuss Aug 22 '12 at 13:04
  • Do you get a lot of Garbage Collection events in the LogCat? – Mohamed_AbdAllah Sep 12 '12 at 09:08
  • FWIW Hafnernuss, it sounds like you maybe you are using one context on multiple threads ("But since i am using Reentrant Locks i am sure that only 1 Thread is accessing the OpenGL") which is not strictly supported – nmr Jan 14 '15 at 20:40

2 Answers2

3

Finally found the solution.

When i call glFlush() after every rendering circle, it works fine. I no render every plane on a different texture channel, it works perfectly so far. Thanks for the help.

Hafnernuss
  • 2,659
  • 2
  • 29
  • 41
0

When you call ..:

GLES20.glUniform1iv( m_HTextureUniform, 2, m_nTextureStorage, 0 );

I think that binds a particular texture unit to the sampler uniform. But you're passing a texture name/object/handle/whatever (which is not a texture unit.) Maybe it's just coincidence, and you only ever pass in 0 (which is possibly the texture name in m_nTextureStorage,) which is coincidentally the correct/desired value?

Or maybe this results in the user-space driver crashing.

Community
  • 1
  • 1
nmr
  • 16,625
  • 10
  • 53
  • 67