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'.
Related
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.
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.
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?
We have an app where we draw many things (mostly OpenStreetMap Tiles but also other images) with OpenGL ES 2.0. This works pretty good, but from time to time the app crashes without any information - this means: The app just closes, not a message that it is crashed and also there is no message in logcat.
From experiments we've figured out, that the app crashes after loading too many textures into OpenGL (glGenTextures/glBindTexture)
In an experiment on a Samsung galaxy S3 we are able to load up to 1800 textures with a size of 256x256 in RGB888 standard. After that our app crashes without any error logs. Shouldn't we receive an error(GL_OUT_OF_MEMORY) when we are constantly checking for OpenGL Errors (GLES20.glGetError) while loading textures?
Generally asked:
Is there a way to determine the maximum size available in gpu memory or at least, how do we get a warning as soon as we are running out of memory? (The problem is we do not know WHEN we should start deleting handles and we want to keep most of them as long as possible...)
Thanks in advance for any replies.
So after some research we found a solution.
But first of all:
These methods won't help and either won't these.
The methods mentioned in the first post will get you absolutely useless numbers which won't help you at all and may not even be correct (since my galaxy S3 got a much higher number than a nexus 7. But in our tests the nexus 7 could load the same amount or even more textures than the S3).
Then let's move on to our solution - which we are still not sure is the best, but it will work:
It look likes you can keep as many textures in OpenGL as you have free total RAM. Yes total RAM, not heap and not something other related to your app! It's really the amount of free RAM of your whole system, there are NO restrictions!
So once you figure that out you just read out the amount of free RAM you have:
ActivityManager actvityManager = (ActivityManager) mapView.getActivity().getSystemService( Activity.ACTIVITY_SERVICE );
ActivityManager.MemoryInfo mInfo = new ActivityManager.MemoryInfo ();
actvityManager.getMemoryInfo( mInfo );
Log.v("neom","mema " + mInfo.availMem/1024/1024);
Best place to do that is probably in your onSurfaceCreated method or somethign like that.
The amount of memory you get there is the total free RAM you currently have. Mostly this value is too low, in almost any case you can even allocate more memory than you get there (in our tests we could always allocate about 30%-50% more RAM than the availMem gave us until the app crashed (tested on Nexus 7 (+28%), Galaxy S3 (+36%), Transformer T1 (+57%), Nexus S (+57%))). Reason for this is: Android will free memory from unused stuff, background processes and so on, before it really runs out of memory.
So what does this mean?
You can (almost) safely keep as many "bytes-of-textures" in OpenGL as you have free RAM. For example: Lets say you have 375 MB free RAM and textures which each have a size of 256kb, you could keep about 1500 Textures in OpenGL before you start deleting some of them (with an LRU cache or something like that). You could even keep more, but I think you are pretty safe with this amount.
Sureley you could also get the availmem more frequently and just fit your cache size or what ever you are doing to this new amount of memory - but I think it suffices if you do it once in onSurfaceCreated - especially since this will be read out again if you switch to another app and back.
I've been developing a game for Android for the past few months, and it's just about finished. I recently acquired a Motorola Droid for testing purposes, as I developed the game using a HTC Incredible. On my Incredible I can get a pretty solid 59 fps throughout the game. On the Droid, the game becomes very choppy with an average of about 40 fps. Both phones are running Android 2.2.
I looked up the tech specs are here are the only differences I noted that might affect gameplay: 1 GHz processor vs 550 MHz and 512 MB RAM vs 256 MB RAM.
Just for giggles, I thought I would strip down the game to a very minimal state to see if it was my coding to blame. I stripped it down to the point where the only thing being down was drawing the main menu and moving various bitmaps around the screen. Not a hair over 45 fps.
So, is this the approximate cap for the Motorola Droid? If so...my game is pretty simple and non-CPU intensive, so what can I do? There are thousands of other Android games that are much more demanding than my own, yet they seem to run very smoothly.
Is it the fact that I'm using Android's built-in Canvas and not Open-GL or some other alternative? Would anybody recommend doing that?
Could somebody enlighten me to what might be my problem here?
Thanks in advance.
OpenGL ES is the way to go. Canvas is most likely implemented on top of OpenGL ES anyway, and not very efficiently by the sounds of it.
40fps is pretty good, the human eye can only detect jerkiness when the framerate falls below 25fps. Anything above 15fps is considered 'full motion'.
If you can see jitter then it may be the game pausing while the garbage collector kicks in - you can reduce this by reducing the number of objects that you create and you should be able to see it happening by using ddms.
Other than that perhaps there is a glitch calculating the frame rate?