Android In Need of Android Optimizations

ophelius

Member
Hi,
I'm about to release my game on Google Play. On my older crappy android phone, I'm getting good results of 200-230 FPS average. But I noticed that from time to time, BG operations cause my game to start lagging the game down to 5-10 FPS. Once, even after a reboot the game was only playing at 20-30FPS anytime I tried for the whole night, even with no BG apps open and no updates being installed. In the morning it was back to normal.
Are there any Android-specific optimizations anybody knows about that may help give my game a boost before I roll it out?
Thanks
 
Last edited:

Mool

Member
try to disable all surfaces. My games laggs too, if there are to many active surfaces in VRAM. Try not to store more than 12mb in vram. Old phones will die.

disable application surf
 

ophelius

Member
try to disable all surfaces. My games laggs too, if there are to many active surfaces in VRAM. Try not to store more than 12mb in vram. Old phones will die.

disable application surf
How do things get drawn on screen with the application surface disabled? I thought everything gets rendered to it and that's what gets outputed to the screen? But that's the only surface I use, I don't create or use any other.
And as for vram, I guess I can check in the debugger? I don't use it that often so I'll have to look around.
 

Simon Gust

Member
How do things get drawn on screen with the application surface disabled? I thought everything gets rendered to it and that's what gets outputed to the screen? But that's the only surface I use, I don't create or use any other.
And as for vram, I guess I can check in the debugger? I don't use it that often so I'll have to look around.
The application surface is just a step between your draw-functions and things appearing on the screen. It's like a bus that takes your sprites to the bus stop. If you disable it, the sprites just drive there on their own.
 

ophelius

Member
The application surface is just a step between your draw-functions and things appearing on the screen. It's like a bus that takes your sprites to the bus stop. If you disable it, the sprites just drive there on their own.
Cool, I didn't know that, it seems I have some misconceptions about the rendering pipeline. I'll have to do more research on this.
So basically I disable the application surface and just have to make sure that each object is drawing itself in the Draw event? What about tile layers, do I need to manually draw those to?

Edit: Never mind, I read up on it and disabling it did give me a performance boost. I did read that you have to be careful with scaling and aspect ratios or something? Everything is scaling and looks fine on Windows and mobile after this is done. Do I have to be careful and write special code to handle devices that have a screen with a different aspect ratio? My game is drawn in 16:9, some phones are 16:10, 4:3, etc.
 
Last edited:

ophelius

Member
Yup, I modified my game into a 4:3 aspect temporarily to test how turning off the application_surface would affect the scaling, and with it turned off the image is stretched to fit my 16:19 screen, which is not what I want. This is to simulate what it might look like for someone with a different aspect than 16:9.
How do I make sure that the image is still the correct aspect, and centered on the screen when the application_surface is disabled?

Edit: So yes, according to the manual: "Switching it off will switch off all aspect ratio correction, as set in the Game Options for the target platform. This means that you should have some method in place that scales the game to the required device, window or screen dimensions."
So even though the viewport is let's say 4:3, the back buffer still gets stretched to fill your screen in the end?
 
Last edited:

Simon Gust

Member
the view_view / camera will always stretch to meet the view_port. Initially, you would also resize the application surface to the view_view size (or camera size in GMS2) but in your case now, I'm unsure, I've never developed for mobile.
You might get away with resizing the application surface, and then disable it afterwards in hope the phone eats it.
 

ophelius

Member
I noticed that the viewport settings are bypassed when the application surface is turned off. I can set it to whatever, but the final render is the size I have my camera set to, which is then stretched fully to the screen.
I just need to know how to turn off the stretching of the back buffer(where graphics are drawn directly instead of the application surface). I would have thought without GM's app surface to help do all the scaling for you, it would just place the scene maybe in the top left corner of the screen not scaled. Calculating where to position the final image centered is the easy part, I just need to know how to control the final back buffer image, how to scale it myself, how to position it myself.
 

Simon Gust

Member
I noticed that the viewport settings are bypassed when the application surface is turned off. I can set it to whatever, but the final render is the size I have my camera set to, which is then stretched fully to the screen.
I just need to know how to turn off the stretching of the back buffer(where graphics are drawn directly instead of the application surface). I would have thought without GM's app surface to help do all the scaling for you, it would just place the scene maybe in the top left corner of the screen not scaled. Calculating where to position the final image centered is the easy part, I just need to know how to control the final back buffer image, how to scale it myself, how to position it myself.
Yeah, this is where my knowledge comes to an end but also probably the things you can change inside GM and how it draws to the backbuffer.
Maybe the display_set... functions can aid you further. Or the backbuffer size is automatically determined by the camera.
 

NightFrost

Member
That's an interesting problem. The way I do it on windows platform - which is my only compile target - is to first set camera view to base game size. Application surface size is set to the largest integer multiplied view size that fits to display device (so display size is sniffed out for this math). Finally in post draw the app surface is drawn with a scaling factor that makes it fit to display device (factor 1.0 on most displays as I set my view size with that in mind) and the draw position may be offset to center content if the aspect ratios between my view and display don't match. Port sizes I don't touch at all, I would theorize they default to display size as it is running that way.

If app surface is disabled, perhaps port becomes the target size? In which case you need to figure display size, calculate how your view would fit to it, set the result as port size, and offset port draw position to center it on display. For example if your view were 200x200 square and display is 1000x500, the view would fit to it as 500x500 which you set as port, then x-offset port position by 250 to center horizontally.
 

ophelius

Member
If app surface is disabled, perhaps port becomes the target size? In which case you need to figure display size, calculate how your view would fit to it, set the result as port size, and offset port draw position to center it on display. For example if your view were 200x200 square and display is 1000x500, the view would fit to it as 500x500 which you set as port, then x-offset port position by 250 to center horizontally.
No, it doesn't look like I have control over the viewport, I tried setting it a different size in the room editor and with code: view_set_wport(view_camera[0], w); but no luck. It only still shows the contents of the camera stretched to the full display.
Also, my virtual keys now need to be modified without the app surface. Before the coordinates were based on the viewport size. Now it's based on the entire resolution of the screen. So pre-calculations would have to be made to determine where those keys need to be based on the devices screen resolution.
 

Mool

Member
Performance boost:

1. check your profiler and fix the time consuming operations (you also can look into the C++ code and spot slow operations, often it helps to change the gml code then (YYC only))
2. if u have multiple draw calls, which never change, then use a surface, but free it if u dont need it anymore (remember: keep vram small -> only android)
3. use texture pages and use draw_texture_flush between room changes to keep vram small
4. YYC if u have much logic
5. disable "clear display buffer" in room setting (but test ur game then! causes weird rendeing)
6. check my app and tell me if it happends there too! If not, then we can try to spot the problem.

good luck,

for me the VRAM was the problem. Please check that. I had huge drops.
 

ophelius

Member
Thanks, it's really the app surface causing random lags sometimes.
99% of the time the game is running at around 250FPS with app surface enabled. But OS BG processes would sometimes drop it really low, making it unplayable.
With it disabled, there were far fewer slowdowns if any, some minor ones sometimes but not a problem. Even when installing apps in the bg, before that would cause it to drop to 5-10 fps, but now it doesn't.

I've already experimented with YYC, I don't have heavy logic where that might help.

I really need to figure this out, disabling the app surface really improved performance for mobile.

I suppose I could just leave the game stretch itself because most phones are 16:9 and it stretches perfectly for that aspect ratio. So if it is running on a wider phone with a different aspect, it probably won't look that bad stretched a bit.

I just have to make sure virtual keys are calculated correctly, this is what I have:
Code:
if(OS == MOBILE){
  
    var MulX = display_get_width() / camera_get_view_width(view_camera[0]);
    var MulY = display_get_height() / camera_get_view_height(view_camera[0]);
  
    vkMobileMenuStart = vk_f1;   virtual_key_add(107*MulX, 67*MulY, 103*MulX, 26*MulY, vkMobileMenuStart);
    vkMobileMenuOptions = vk_f2;   virtual_key_add(107*MulX, 123*MulY, 103*MulX, 26*MulY, vkMobileMenuOptions);
    //... etc
}
Those numbers are the exact pixel coordinates, which are multiplied by the scale factor. So my game is designed at 320x180, and if the display is 1920x1080, the MulX/Y would be 6.
This works fine so far, can anyone foresee this not working for some devices?

Thanks for any help
 

Mool

Member
i use a other way. To be 100% sure you could enable landscape and portrait. if your keys work there, then it will work everywhere.

To test it you also could release a new version to 1%-2% of your users. They will tell u then if it works ;)
 

ophelius

Member
Thanks, the coordinates work even in portrait mode so that's good.
Though because the app surface is disabled, it stretches the game full screen portrait(tall and thin)
Is there no way to control this stretching? I can't find answers, I looked everywhere
 

Mool

Member
mmh idk what u mean. I have in my game 3 graphics settings. and i dont see any difference. What des stretch? The GUI? The game?
 

ophelius

Member
mmh idk what u mean. I have in my game 3 graphics settings. and i dont see any difference. What des stretch? The GUI? The game?
Do you have the application surface off? If you've been following this thread, this is because I'm turning it off to gain performance for mobile devices. This doesn't occur when I don't disable it, it runs fine and looks as it should.

With the application surface disabled, the game takes whatever is in your camera view and stretches it to fill the entire screen automatically, not to the size and shape of your viewport like it usually does.

When it's not disabled, running normally, GM properly stretches the camera's view to the size and shape of the viewport, and then best fits it to the actual screen, placing it in the middle with black bars if necessary.

I'm essentially trying to do what GM does for you automatically when the app surface is enabled
 
Top