Search Unity

Screen flickering when using glTexSubImage2D in native Android (on some devices)

Discussion in 'Android' started by PaulT, Jul 24, 2011.

  1. PaulT

    PaulT

    Joined:
    Oct 25, 2008
    Posts:
    17
    Hi all,

    Currently I am working on a client project with Unity Android that involves the use of a device camera and is part of a native Android application (so I am compiling using Eclipse). Because Unity does not (yet?) support native device camera input, I have used the GL loop to get camera images into Unity. In various resources I have found that this is the advised approach. I've also been able to put this to work and I now have a live camera feed available inside Unity.
    This works like a charm on my nexus one. The behavior on my Samsung Galaxy Tab however is quite different. There the screen is heavily flickering. It looks like internally the screen width decreases with 10px and then turns back to normal. Sometimes I even get black screens. When I open up my recent applications window as an overlay on the Unity application (holding home button), then even the overlay gets affected by it and it starts flickering. So I guess something is going terribly wrong in OpenGL.
    The odd thing though is that as soon as I lock my screen and unlock it again, the flickering disappears. As I am in not an OpenGL (ES) expert at all, it could very well be the case that I am doing something wrong. The fact that the problem is solved after a screen lock confuses me and makes me think the issue could as well be a Unity issue.
    The problem only occurs when I update a subimage from a texture. It does not occur when I am using gl.glTexImage2D or GLUtils.texImage2D. Using glTexImage2D over glTexSubImage is not an option, as that gives me troubles with camera frames that are not power of two.

    Today I have worked on making a basic version in order to be sure it is caused by this part of the code. So my current scene only contains a plane with a texture. That texture is for sake of simplicity just a static image which I redraw every frame (with a single image I could also go for drawing once, but that has the same result in terms of screen flickering).

    In order to hook in with the gl render loop that Unity uses, I have extended the UnityPlayer class and overridden methods related to GL rendering.

    Code (csharp):
    1.  
    2. public class ExtendedUnityPlayer extends UnityPlayer {
    3.    
    4.     private boolean mTextureInitialized;
    5.     private Bitmap mBitmap;
    6.    
    7.     public ExtendedUnityPlayer(Context context) {
    8.         super(context);
    9.        
    10.         mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.testimage);
    11.     }
    12.    
    13.     protected void initializeTexture (GL10 gl) {
    14.         int theTextureSize = 256;
    15.        
    16.         byte[] theEmptyFrame = new byte[theTextureSize*theTextureSize*3];
    17.         gl.glColor4f(0.5f, 0.5f, 1.0f, 1.0f);
    18.         gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGB, theTextureSize, theTextureSize, 0, GL10.GL_RGB, GL10.GL_UNSIGNED_BYTE, ByteBuffer.wrap(theEmptyFrame));
    19.        
    20.         mTextureInitialized = true;    
    21.     }
    22.  
    23.     @Override
    24.     public void onSurfaceCreated(GL10 gl, EGLConfig glConfig) {
    25.         super.onSurfaceCreated(gl, glConfig);
    26.         mTextureInitialized = false;
    27.     }
    28.  
    29.     @Override
    30.     public void onDrawFrame(GL10 gl) {
    31.         if(SharedObject.getSharedInstance().getTextureID()!=-1)
    32.         {
    33.             gl.glEnable(GL10.GL_TEXTURE_2D);
    34.             gl.glBindTexture(GL10.GL_TEXTURE_2D, SharedObject.getSharedInstance().getTextureID());
    35.            
    36.             if(!mTextureInitialized) {
    37.                 initializeTexture(gl);
    38.             } else {
    39.                 GLUtils.texSubImage2D(GL10.GL_TEXTURE_2D, 0, 0, 0, mBitmap);
    40.             }
    41.            
    42.             gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
    43.             gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
    44.    
    45.             gl.glDisable(GL10.GL_TEXTURE_2D);
    46.         }
    47.        
    48.         super.onDrawFrame(gl);
    49.     }
    50.  
    51.     @Override
    52.     public void onSurfaceChanged(GL10 gl, int width, int height) {
    53.         super.onSurfaceChanged(gl, width, height);
    54.         mTextureInitialized = false;
    55.     }
    56. }
    57.  
    I hope this extensive description helps in getting clear what is going on and how it might be solved. Hopefully someone has a clue for me on how to solve it on my side, or maybe someone at Unity can confirm this is an issue with Unity. In case it might help, I would be happy sharing the project files from this basic setup.

    Thanks in advance!

    Paul
     
  2. PaulT

    PaulT

    Joined:
    Oct 25, 2008
    Posts:
    17
    Unfortunately there doesn't seem to be anyone who experienced the same. By accident I solved this today by switching to OpenGL ES 2.0 as the minimum Graphics API level.
    At this stage I'm not sure what that involves in excluding users. I'll do some research on that. But it still doesn't make sense it should just work like it does after a screenlock.

    So how did I find out? I've had the chance today to test with a Packard Bell Liberty Tab. With that tab I ran into an issue where Unity is hanging at the splash screen. Then I found this forum post: http://forum.unity3d.com/threads/78407-Hangs-on-Splash-screen which suggests switching to OpenGL ES 2.0. I did and it solved my issue hanging at the splash screen. I noticed however that this issue has some shared behaviors with the issue I described in my post here. After I lock and unlock the screen, the application did not hang on the splash screen anymore and everything runs fine. After trying this thing out on my Galaxy Tab, everything suddenly worked fine as well and the screenflickering disappears.

    I see that the hanging splash screen issue has been solved in 3.4. Can I assume that my issue will also be solved in the next Unity update?