Got Opengl error 0x505 while texture cache statistic is low - android

I am developing an android game using cocos2dx 2.2 + lua. While testing,I got a lot of 'opengl error 0x505' from logcat. According to opengl doc, this means 'out of memory'. Hence, I print out texture cache every 3 seconds using
cocos2d::CCTextureCache::sharedTextureCache()->dumpCachedTextureInfo();
The output of dumpCachedTextureInfo() shows that the highest texture cache is 70M, but no 'error 0x505' occurs. 'error 0x505' come out while the cache is low, e.g. ~35M. My question is, isn't opengl display memory and cocos2dx texture cache memory the same thing? How can 'error 0x505' occur while texture cache is not at its highest point?Looking forward to your answer or suggestion.Thanks.

I got the same error with our game (running Cocos2d-x 3.3) on some low end devices, along with some funky rendering problems. The cause in our case was a custom OpenGL fragment shader which was too big in terms of code, and reducing the size of that fixed the issue.
On a general note, the fact that the error comes from OpenGL suggests to me that the problem is GPU memory rather than RAM. And since CCTextureCache (to my knowledge) only occupies RAM, I'm guessing the problem is unrelated to that.

Related

What takes up graphics memory in Android Profiler?

When I used Android profiler I noticed that graphics were Taking a lot of memory (169 mb) which was making the app extremely slow , and I though that it was caused by Bitmaps so I deleted all the bitmaps in the app and tried again..
and I noticed that graphics were still taking up 60 - 100 mb of RAM , and I would like to know what can cause Memory Drain other than Bitmaps?
(My App uses google Maps if that helps)
Graphics: Memory used for graphics buffer queues to display pixels to the screen, including GL surfaces, GL textures, and so on. (Note that this is memory shared with the CPU, not dedicated GPU memory.)
https://developer.android.com/studio/profile/memory-profiler.html

OpenGLRenderer: GL error: Out of memory

I have written an OpenGL ES 3.1 application for Android. It runs fine on Nexus 5X ( Adreno 418 GPU ) , but on Samsung Galaxy S7 ( Mali T880 ) it dies with
E/OpenGLRenderer: Error:glFinish::execution failed
E/OpenGLRenderer: GL error: Out of memory!
in logcat.
Now, I really don't think this is because the application really uses much memory (it only has 1 texture, 2 FBOs the size of the screen, no fonts, nothing else I can think of that would use much memory). At least that's what I think the application uploads to GPU.
I would like to debug this without relying on my limited understanding of OpenGL, i.e. it would be best if there was a tool which would show me basic things like
1) the amount of memory available on GPU
2) amount of memory taken
3) taken by what
EDIT: I have solved this, with some help from the Mali Graphics Debugger suggested in the comments. It turned out to be a runaway loop in a fragment shader, which under certain circumstances (curiously not arising on Adreno) could keep on looping forever. By 'OUT_OF_MEMORY' I think it meant 'execution of fragment shader takes too effing long'.

Determine GPU rendering power on runtime

I'm developing an app that renders the camera preview straight to a custom GlSurfaceView I have created.
It's pretty basic for someone who uses OpenGL on regular base.
The problem I'm experiencing is a low fps on some of the devices and I came with a solution - to choose which shader to apply on runtime. Now, I don't want to load a OpenGl program, measure the fps and than change the program to a lighter shader because it would create definite lags.
What I would like to do is somehow determine the GPU strength before I'm linking the GL program(Right after I'm creating the openGL context).
After some hours of investigation I pretty much understood that it won't gonna be very easy - mostly because the rendering time depends on hidden dev elements like - device gpu memory, openGL pipeline which might be implemented differently for different devices.
As I see it I have only 1 or 2 options, render a texture off-screen and measure its rendering time - if its takes longer that 16 millis(recommended fps time by Romain Guy from this post) I'll use the lighter shader.
Or - checking OS version and available RAM (though it really inaccurate).
I really hope for a more elegant and accurate solution.

Open GL ES memory management

I'm working on an Android app using Open GL ES 2.0. I'm confused about memory management in Open GL.
My questions are:
How much memory is available to the Open GL hardware? Clearly it's going to vary from device to device.
How can I find out how much memory is in use and how
much is left?
What happens if I exceed the memory limits?
What techniques should I be using to unload data not currently being displayed?
I presume I'm going to have to implement some kind of system to unload textures that are not currently in use on an LRU basis, but I'd like some idea of what criteria to use for this.
The app silently dies at some point and I suspect it is because I'm using too much graphics memory.
Currently I'm never unloading textures and I seem to be able to load quite a few - testing on a Nexus 7 I have been able to load 134 1024x1024 RGBA textures, which I calculate to be over 500MB. I presume once the textures have been loaded into graphics memory they take up less space, but that's still a lot, and clearly I have to manage that but I'd like some tips on how to start.
Simply use gles glDeleteTextures
If you run out of memory you will gen GL_OUT_OF_MEMORY error probably. Another thing is to monitor memory usage in Android.
android memory: How do I discover memory usage of my application in Android?
See here an interesting question for opengl: how to manage memory with texture in opengl?

Android "cpu may be pegged" bug

Foreword: This severe bug can cause Android devices to lock up (unable to press Home/Back buttons, needs hard reset). It is associated with OpenGL surfaces and audio playback. Logcat repeats something to the effect of
W/SharedBufferStack( 398): waitForCondition(LockCondition) timed out (identity=9, status=0). CPU may be pegged. trying again.
once every second, hence the name of this bug. The fundamental cause of this is likely due to a deadlock when buffering data, be it sound or graphics.
I occasionally get this bug when testing my app on the Asus EEE Transformer tablet. The crash occurs when the sound thread populates MediaPlayer objects using MediaPlayer.create(context, R.raw.someid); and the GLSurface thread loads textures from bitmaps using
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.textureMap,opts);
gl.glGenTextures(1, texAtlas, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texAtlas[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
I don't think the cause is the audio, as the audio does in fact still play (the thread which loads the audio then plays it after x amount of time). If so, the cause lies in the OpenGL ES buffering using the above code.
Related Material
This SO post refers to this bug. They use OpenGL ES 2.0 and NDK. I use OpenGL ES 1.1 (albeit most devices emulate 1.1 through 2.0, so technically they are using 2.0) and I do not use the NDK. Further, they use Android 2.1 and my crash occurs on Android 3.2.1.
This site links the bug to the AudioTrack object. However, I do not use that in my app.
The Android Bug Tracker lists this as a known bug, but as of yet there is no solution (and it's not fixed in Honeycomb+).
Common Elements
Freeze occurs when buffering. The thing being buffered is usually quite large, so an image (bug occurs more frequently the larger the image) or audio is typically affected.
Freeze only occurs on some devices.
Freeze is not related to a specific Android version - has been recorded on 2.1 and 3.2.1, among others.
Freeze is not related to use of the NDK.
Freeze is not related to a single programming practice (order of buffering, file types, etc)
My question is pretty simple. Is there a workaround for this issue? If you can't prevent it, is there a way to fail elegantly and prevent the whole device being bricked?
In the case of my game the "waitForCondition" problem has been noticed on Samsung Galaxy S (Android 2.3.3). Of course I don't know if the issue has been noticed on different devices, but probably the problem exists there too. Fortunately I was able to reproduce it as one of my friends has got the device and he was kind enough to lent me one for a week.
In my case the game is practically all written in Java (few calls through NDK to OpenGL functions), so I'm not really sure if this will apply to your problem too.
Anyway it seems that the problem is somehow related to OpenGL internal buffers. In the code presented below the line which has been commented out (1) has been changed to (2) - manual config selection. I didn't test it thoroughly yet, but since that change I haven't noticed any freezes, so there is a hope..
UPDATE 1: As an additional info, I think I read somewhere that somebody had the same problem with his CPU gets pegged and his solution was to set up all the OpenGL Surface components to 8 bits (alpha component too) rather than 565 or 4 bits (I don't remember exactly what was the faulty configuration)
UPDATE 2: Also one may consider to use the following implementation of the EGLConfigChooser: GdxEglConfigChooser.java. If this doesn't help eventually use the approach presented in GLSurfaceView20.java.
UPDATE 3: Additionally simplifying the program shaders as much as it's possible helped a bit too.
// in Activity...
glView = new GLSurfaceView(this);
glView.setEGLContextClientVersion(2); // OpenGL ES 2.0
// glView.setEGLConfigChooser(false); // (1) false - no depth buffer
glView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
glView.setEGLConfigChooser(8,8,8,8,0,0); // (2) TODO: crashes on devices which doesn't support this particular configuration
glView.setRenderer(new MyRenderer(this));
Increasing the virtual memory of the device lowers the occurrences in which this issue happens. Of course this is not an option unless you are the manufacturer of the device.

Categories

Resources