I'm developing a card game in Android using SurfaceView and canvas to draw the UI.
I've tried to optimize everything as much as possible but I still have two questions:
During the game I'll need to draw 40 bitmaps (the 40 cards in the italian deck), is it better to create all the bitmaps on the onCreate method of my customized SurfaceView (storing them in an array), or create them as needed (every time the user get a new card for example)?
I'm able to get over 90 fps on an old Samsung I5500 (528 MHz, with a QVGA screen), 60 fps on an Optimus Life (800 MHz and HVGA screen) and 60 fps with a Nexus One/Motorola Razr (1 GHz and dual core 1GHz with WVGA and qHD screens) but when I run the game on an Android tablet (Motorola Xoom dual core 1 GHz and 1 GB of Ram) I get only 30/40 fps... how is that possible that a 528 MHz cpu with 256 MB of RAM can handle 90+ fps and a dual core processor can't handle 60 fps? I'm not seeing any kind of GC calling at runtime....
EDIT: Just to clarify I've tried both ARGB_888 and RGB_565 without any changes in the performance...
Any suggestions?
Thanks
Some points for you to consider:
It is recommended not to create new objects while your game is running, otherwise, you may get unexpected garbage collections.
Your FPS numbers doesn't sound good, you may have measurement errors, However my guess is that you are resizing the images to fit the screen size and that affects the memory usage of your game and may cause slow rendering times on tablets.
You can use profiling tools to confirm: TraceView
OpenGL would be much faster
last tip: don't draw overlapping cards if you can, draw only the visible ones.
Good Luck
Ok so it's better to create the bitmap in the onCreate method, that is what I'm doing right now...
They are ok, I believe that the 60 fps on some devices are just some restrictions made by producers since you won't find any advantage in getting more than 60 fps (I'm making this assumption since it doesn't change rendering 1 card, 10 cards or no card... the OnDraw method is called 60 times per second, but if I add for example 50/100 cards it drops accordingly) I don't resize any card cause I use the proper folder (mdpi, hdpi, ecc) for each device, and I get the exact size of the image, without resizing it...
I've tried to look at it but from what I understand all the time of the app execution is used to draw the bitmap, not to resize or update its position here it is:
I know, but it would add complexity to the developing and I believe that using a canvas for 7 cards on the screen should be just fine….
I don't draw every card of the deck.. I just swap bitmap as needed :)
UPDATE: I've tried to run the game on a Xoom 2, Galaxy Tab 7 plus and Asus Transformer Prime and it runs just fine with 60 fps…. could it be just a problem of Tegra 2 devices?
Related
SceneKit calls its rendering delegates sixty times a second to allow a host application to adjust parameters in the contained scene to provide animation, physics, etc.
My scene is large (360,000 vertices). Almost all (~95%) of the scene is rotated slightly every minute (every 3,600 delegate calls). A very small remainder of the scene (about 300 nodes ~ 15,000 vertices) is moved once a second (every 60 delegate calls); all the nodes are created and their properties set before the application 'starts' (in viewDidLoad) and then only their positions are changed, as described above, in the delegate calls.
My frame refresh rate only just keeps at 60 fps and CPU usage is about 30% according to Xcode. All that effort is being expended in the rendering loop (there's no interaction; no other work) so I have two questions:
1) does 30% CPU seems reasonable, given this general description of my app? More specifically, since my delegate code seems simple and invoked from <2% of the rendering loops, could I really be driving SceneKit to its limits?
2) if so, are there any SceneKit tricks to clawing back some CPU? Can the delegate call rate be slowed, for example?
This is with macOS 10.12.3 and Xcode 8 (Swift 3) on a 2.8GHz/i7 2015 MacBook Pro
How about trying to flatten the nodes and it's children using flattenedClone.
Creating SCNLevelOfDetail objects for your geometries is worth a try.
Is anything else moving? Can you reduce your view's preferredFramesPerSecond?
We are attempting to display 40 windows, each containing almost the same UI, but displaying a different entity, with scene changes with animations happening every few seconds on each window. All of our tests have ended with the windows being drawn at 3 to 5 frames per second at between 10 and 20 windows open, on a reasonably old and low-powered discrete nVidia GPU and on Windows.
Things we have tried:
Disabling animations - performance improves, but not nearly enough
CPU profiling - shows over 90% of the CPU time being spent in the system DLLs and the nVidia driver; on other machines, the CPU usage is not significant, but the frame rate is still low.
QML profiling - The QT Creator profiling shows the render loop executing its steps at 60 fps and within a couple of milliseconds at most for each frame.
Images/textures are loaded once to the GPU and never reloaded
All the rendering backends - OpenGL, ANGLE and Qt Quick 2D Renderer - perform more or less the same
Is there something major we are missing?
WP 7/8 + xna games by default set to 30 FPS, I would like to know If i set it to 60 FPS , any disadvntages / Performence issues / bugs / any other. becuase i always wants to play/develop the game in 60 fps.
I just want to add a few points to Strife's otherwise excellent answer.
Physics simulations are generally more stable at higher FPS. Even if your game runs at 30 FPS, you can run your physics simulation at 60 FPS by doing two 1/60th of a second updates each frame. This gives you a better simulation, but at a high CPU cost. (Although, for physics, a fixed frame-rate is more important than a high frame rate.)
If you poll input 30 times per second, instead of 60, you will miss extremely fast changes in input state, losing some input fidelity.
Similarly, your frame rate affects the input-output latency. At a lower frame-rate it will take longer for input change to be reflected on-screen, making your game feel less responsive. This can also be an issue for audio feedback - particularly in musical applications.
Those last two points are only really important if you have a very twitchy game (Super Hexagon is a fantastic example). Although I must admit I don't know how fast the touch input on WP7/8 is actually refreshed - it's difficult information to find.
Windows Phone 7 SDK sets XNA to 30 FPS because the screen on Windows Phone 7 Devices has a 30hz refresh rate. This means the screen refreshes at 30 times a second. If you are drawing 30 times a second and you refresh 30 times a second your at the optimal rate of smoothness for that device.
The reason most people aim for 60 (or on my gaming PC, 120) is because most monitors have a 60hz refresh rate (some are now 120hz). If your FPS is HIGHER than your refresh rate you won't notice see anything else except for possible an effect known as "Screen-Tearing" which is what happens when you render more frames in a second than your screen refreshes.
In other words imagine you draw to the screen two times and then your screen refreshes once, why did you bother drawing the second time? You waste battery life, cpu usage, and gpu usage when you render faster than the refresh rate of a device. So my advice to you if your sticking with XNA is that you stick with 30 FPS because the older devices won't get any benefit by having more frames rendered and if anything you'll get graphical anomalies like screen tearing.
If you plan to target higher-end (and newer) windows phone 8 devices, drop XNA, go the Direct3D route and use Microsoft's "DirectX Toolkit" because it includes XNA's "graphics functions" like spritebatch but in C++ instead of C#.
I hope this helps.
In one of the levels of my game i have quite many big textures to draw. To give you idea what I'm talking about these are the textures sizes and the quantity in the level.
448x420 - 3, 315x400-2, 305x429 -3, 366x167-1, 356x265-4, 401x343-2, 387x251-1 plus about 20 elements with much smaller texture size.
The performance of my original implementation was 20fps. Then I created a single texture map that contained all the textures used in the level, this gave me about 3-4 extra fps. 24fps is not enough for me, what else can I try to optimize my performance?
Some things that I could think of in a minute
Does it have a dedicated GPU and Memory or using shared memory?
Have you tried expanding your textures to a power of two size (although only loading times might improve).
Are you using mipmaps or other types of texture filtering?
Howmany texels is it trying to gather?
Have you tried to use a texture of 1 by 1, just to see if that is actually your bottleneck?
In my experience, texel calls on mobile devices are quite heavy. Be sure to try and decrease the size of your textures as much as possible. Look at your project, if an object only takes about 10% of the screen, does it really need a texture of 128x128 or bigger?
I don't know what kind of project and target device you use, but textures of 448x420(non power of two?!) seem way overkill for an mobile game. In fact, I'd recon you try and stay below a total combined texture usage of 1024x1024 or something?
Do I understand correct that this is your total texture size?
(448 * 420 * 3) + (315 * 400 * 2) + (305 * 429 * 3) + (366 * 167) + (356 * 265 * 4) + (401 * 343 * 2) + (387 * 251) = 2.019.720 pixels (ignoring the ~20 elements you mentioned)
Which means assuming 32 bits textures, in theory, you are using about 64 MB of ram, only for texture storage (and not even assuming mipmaps and XNA not up-scaling to power of two textures) (not sure if XNA internally uses dds/dxt compression(?)). I can imagine this to be quite high for a mobile device.
Hope this might help solving your bottleneck.
You should try profiling your application, to check if the issues are actually in the graphics rendering or somewhere else.
There are some tools available for this, although most have limitations when working in WP7. The first recommendations would be Microsoft's Windows Phone profiler and PIX for graphics monitoring, mentioned in the post. There is also the XNA Framework Remote Performance Monitor, but as far as I can tell there is no WP7 compatible version.
I am trying to use SpriteSheet to run an animation. My frames are of 320x480 in size each, So I am able to put max 6 frames on the texture image. But my animation consists of frame number ranging from 50 to 200 sometimes, and all are of size 320x480.
But this much number of frames cannot be added on the Texture image as the size is restricted to 1024x1024.
Is there any other approach I can try out. Can I play one animation after the other.And won't it be hampering the performance.
Please, I need suggestions.
Best,
Vaibhav Tekam.
Ugh, you're going way past what the device can handle! You'll have to reconsider what you're trying to achieve and how to achieve it. Let me explain.
Every 1024x1024 texture with 32 bit colors requires 4 MB of memory. If you want a sprite animation consisting of 60 full-screen sprites, you need 10 such textures. That makes 40 MB of memory. Or 120 MB for your upper-case scenario with 180 animation frames.
Keep in mind that the 128 MB RAM memory models of the iOS devices have about 30 MB memory available for your App, at most and under ideal conditions. You will start running into memory issues with only five 1024x1024 textures. The 256 MB devices still have only about 100 MB available for your App.
Since it's supposed to be an animation, it's also not an option to load one texture, and after every 6th image, remove that texture and load the next one. Loading a 1024x1024 texture into memory takes about 1-3 seconds depending on the device. Your App will be irresponsible during that time.