Android OpenGL-ES 3d game optimisation - android

I have a game engine, but its very slow. I get on a 60-80 textured squares (2 triangles with blends) about 30-40 FPS on my galaxy s. This is a live wallpaper. I get on my Legend only 10-20 FPS on 80 items...
I used VBO's, culling and other optimisations. (i tried texture atlas, the same speed as binding textures...)
what can i do there?
1, if I use native opengl render code, that will speed up my rendering?
2, if i use PVRTC compressed textures, not png-s, that will speed up the rendering? how i can do that?
what can i do?

Yes... I believe you should see a substantial speed up if you switch over to to using the NDK for OpenGL. As for PVRTC... I'm not 100% sure if that's the way to go. That is a format optimized for PowerVR chipsets... so yes... that's great for the Galaxy S variety of phones... but every phone with a Snapdragon processor run a different GPU (Adreno). I have no idea if the Adreno GPU would make good use of it.

No GPU, to my knowledge, natively supports PNG images as a texture format. These are invariably decompressed by the API/driver to ARGB (probably # 32bpp), so there will be a hit in terms of memory space and, more importantly, bandwidth consumption. PNG really only buys you a reduction in terms of distribution of the application and flash memory storage space.
Provided you aren't insanely obsessive about image quality, using some form of (lossy) texture compression, say PVRTC (4bpp or 2bpp) or, maybe, ETC (4bpp), will probably be a win for performance.

Related

Android OpenGL Performance Drop

I am experimenting with the Camera to MP4 example here:
https://bigflake.com/mediacodec/CameraToMpegTest.java.txt
My test app uses roughly the same code, and when I record at 1280x720 then everything is fine.
But for some reason switching to use 1920x1080 then the FPS drops and CPU usage increases.
Profiling CPU usage the problem seems to be the GLES20.glDrawArrays call.
It goes from using about 2% of CPU cycles to almost 40%. The only thing that's different is the camera preview resolution.
It seems to be crossing some sort of cache or memory re-allocation boundary. I don't have much OpenGL experience, and am not sure how I could debug this. Any advice on what I could look for?
EDIT:
Enabling Androids GPU usage overlay indicates no noticeable difference.

How to handle memory limitation of GPU for high resolution image processing on GPU?

I am making a camera app and this app will be provide some filters to users. Currently my code is on NDK and it works Ok, however i want to make it a bit faster. It seems GPU and opengl Es 2.0 is way to go. My only concern with GPU is that their memory limitation. Since modern cameras take 5-10 mp images while GPU memory limitation is far less than that. I was wondering if there is a way to work around that limitation. The only logical option seems to me is dividing the image smaller part, and then processing them on GPU and finally assamble them to final image. My question is, if this approach still would be good for performance and also is there any other option to image processing high resolution images on mobile GPUs.
Edit: I need to clarify that i want to use GPU for image processing so my goal is not to render results to screen. I will render it to another texture and save it to disk.
Your tiling idea has been used since the Nintendo Entertainment System, which has a Ricoh 2A03 at 1.79 MHz, so it's a good approach. Google uses tiling to manage map displays, and even games like Crysis tend to limit their texture sizes of most of their textures to something like 1024x1024 (1 megapixel). And yep, 10 megapixels requires 30 megs of RAM, so some devices may have problems, especially since if you use a source and a dest texture, that would mean 60 megs of RAM are required.
Just keep in mind that texture sizes tend to use a power of 2 ( 2, 4, 8, 16, 32, 64, etc). You'll sometimes get better quality at least if you chop it up and tile up the image.
You don't need to apply real-time filters into 10 mp images...
because there aren't such displays(or maybe there are but not in popular use amongst us). :)
So you only need to apply filters on pixels that are being displayed(1900x1280?).
Tiling technique you mentioned still will be of use with some scenarios. Deferred rendering is such an example. X-Box 360 employed both techniques(tiling with deferred) on daily basis. Without tiling it wouldn't be possible because of high memory requirements for deferred technique.

OpenGL ES 2 - one big vs multiple small textures atlas. What's better performance wise?

I'm developing a game in Android using an already existing engine.
I have to use big textures for my animations, and i'm wondering what's better performance wise.
The new version of the engine supports npot textures(in case you ask yourself why i'm using such resolutions).
Is it better to have multiple 2330x1100 texture atlases or only one 2330x(1100 x number_of_textures_i_need) texture atlas?
Does this choice influence load time?(i think the memory they require is the same, since they contain the same number of pixel)
I read somewhere that switching textures can be a slow operation..
side quests:
1) are pot textures more efficient(in an enviroment build so that it can handle npot textures)?
2) can i hit some dimension/memory limit using just one texture?
one big texture should be better because loading and activating is slow because of the memory upload to the video memory. It also should use less energy and so enhances user experience ;-)
Try it - and write a long running test to prove it.

What is the maximum allocatable memory for Textures in OpenGL for Android 2.3?

as the title already says how much memory can I allocate for textures in opengl for Android 2.3 ?
I would like to know this as I didn't see any real number regarding this anywhere. I allocated on a galaxy tab up to 96 MB successfully for dozens of textures but after 96 MB rendering is slowing down to an extreme crawl. I use the same algorithm for the tests and only increase the allocated textures but the rendering performance above 96MB is less than 5% of what it is with 96 MB or less.
Is there a reason for this ?
Is this for all android 2.3 devices or is there a difference between them ?
How much memory can I safely allocate for opengl textures for most 2.3 and above android devices ?
Thanks in advance...
96 MB is a lot of texture data, you should see if you can decrease that a bit.
Anyway, here is a post from earlier today about texture sizes and limitations.
You can get a lot of information on individual devices on glbenchmark.com.
You should also take a look on the android docs on openGl.
This limitation depends on gpu hardware. There is a lot of limitation on gpu to OpenGL. You should design for this restrictions.

What is the best method to render video frames?

what is the best choice for rendering video frames obtained from a decoder bundled into my app (FFmpeg, etc..) ?
I would naturally tend to choose OpenGL as mentioned in Android Video Player Using NDK, OpenGL ES, and FFmpeg.
But in OpenGL in Android for video display, a comment notes that OpenGL isn't the best method for rendering video.
What then? The jnigraphics native library? And a non-GL SurfaceView?
Please note that I would like to use a native API for rendering the frames, such as OpenGL or jnigraphics. But Java code for setting up a SurfaceView and such is ok.
PS: MediaPlayer is irrelevant here, I'm talking about decoding and displaying the frames by myself. I can't rely on the default Android codecs.
I'm going to attempt to elaborate on and consolidate the answers here based on my own experiences.
Why openGL
When people think of rendering video with openGL, most are attempting to exploit the GPU to do color space conversion and alpha blending.
For instance converting YV12 video frames to RGB. Color space conversions like YV12 -> RGB require that you calculate the value of each pixel individually. Imagine for a frame of 1280 x 720 pixels how many operations this ends up being.
What I've just described is really what SIMD was made for - performing the same operation on multiple pieces of data in parallel. The GPU is a natural fit for color space conversion.
Why !openGL
The downside is the process by which you get texture data into the GPU. Consider that for each frame you have to Load the texture data into memory (CPU operation) and then you have to Copy this texture data into the GPU (CPU operation). It is this Load/Copy that can make using openGL slower than alternatives.
If you are playing low resolution videos then I suppose it's possible you won't see the speed difference because your CPU won't bottleneck. However, if you try with HD you will more than likely hit this bottleneck and notice a significant performance hit.
The way this bottleneck has been traditionally worked around is by using Pixel Buffer Objects (allocating GPU memory to store texture Loads). Unfortunately GLES2 does not have Pixel Buffer Objects.
Other Options
For the above reasons, many have chosen to use software-decoding combined with available CPU extensions like NEON for color space conversion. An implementation of YUV 2 RGB for NEON exists here. The means by which you draw the frames, SDL vs openGL should not matter for RGB since you are copying the same number of pixels in both cases.
You can determine if your target device supports NEON enhancements by running cat /proc/cpuinfo from adb shell and looking for NEON in the features output.
I have gone down the FFmpeg/OpenGLES path before, and it's not very fun.
You might try porting ffplay.c from the FFmpeg project, which has been done before using an Android port of the SDL. That way you aren't building your decoder from scratch, and you won't have to deal with the idiosyncracies of AudioTrack, which is an audio API unique to Android.
In any case, it's a good idea to do as little NDK development as possible and rely on porting, since the ndk-gdb debugging experience is pretty lousy right now in my opinion.
That being said, I think OpenGLES performance is the least of your worries. I found the performance to be fine, although I admit I only tested on a few devices. The decoding itself is fairly intensive, and I wasn't able to do very aggressive buffering (from the SD card) while playing the video.
Actually I have deployed a custom video player system and almost all of my work was done on the NDK side. We are getting full frame video 720P and above including our custom DRM system. OpenGL is not your answer as on Android Pixbuffers are not supported, so you are bascially blasting your textures every frame and that screws up OpenGLESs caching system. You frankly need to shove the video frames through the Native supported Bitmap on Froyo and above. Before Froyo your hosed. I also wrote a lot of NEON intrinsics for color conversion, rescaling, etc to increase throughput. I can push 50-60 frames through this model on HD Video.

Categories

Resources