• Hello [name]! Thanks for joining the GMC. Before making any posts in the Tech Support forum, can we suggest you read the forum rules? These are simple guidelines that we ask you to follow so that you can get the best help possible for your issue.

GMS 2.3+ Performance questions. Strange behaviour?

madthijs

Member
Hi guys,

I'm creating a mobile game. It's NOT pixelart so I require a high res output. For some reason performance on both my Mac and my Android device (Samsung A50) has been less than great, so I decided to do some experimentation. Here is what I found, and I'm wondering if you guys see the same thing. Or maybe I'm missing something, or maybe it is a bug. I'm running GM2.3.1 and the latest runner. Once I gather enough information I may create a bug report, but for now I'm investigating what is going on.

TLDR;
1. Increasing the output resolution (room size in this case, lets ignore viewports for a moment) negatively affects performance, even though I am drawing the same number of objects/sprites.
2. Drawing big sprites is much slower than drawing small sprites.

Samsung A50 (not the fastest thing in the world but pretty decent):
A) Resolution 720x1280, draw 200 objects with a sprite of 640x640 (all the same sprite, so no texture swap issues): ± 33 fps (Real: 200 - 300 fps)
B) Resolution 360x640, draw 200 objects with a sprite of 640x640: 60 fps (Real: 200 - 300)
C) Resolution 720x1280, draw 200 objects with a sprite of 64x64: 60 fps (Real: 500-600)
D) Resolution 360x640, draw 200 objects with a sprite of 64x64: 60 fps (Real: 500-600)

My questions are:
Why is it slower to draw a big than a small sprite? (A vs C, you'll see a big dip in fps and in real_fps)
Why is a higher output resolution slower than a lower resolution, even though I'm doing exactly the same draw calls?

FYI: The debug_overlay shows lots of GPU time left in the frame in every scenario. Except the draw event taking a little longer with the big sprites (as seen in the real fps drop), but nowhere long enough to start dropping frames!

I find this behaviour very curious. Please find the attached project. I choose the 200 number to push things where you see issues. Your PC might not have issues at 200, but at a different threshold. Also I don't thing 200 objects is insane, I've seen a lot of forum posts from people saying thousands of objects are possible (obviously depends on what they do, but in my case, they just draw a sprite, so pretty minimal).

I see the same behaviour on my MacBook btw, so it's not really Android related I guess.
Also I have no way to try thing on an earlier GM version (2.2?) without replacing my current install. Doesn't really matter as I would like to see this behaviour explained or resolved for version 2.3 anyway.

Thanks for you input,

Madthijs

PS: I cant' seem to attach a YYZ or zip file?
Download link: https://easyupload.io/k2qsoe
 

bandman28

Member
If your sprite is set to precise, the bigger the sprite, the slower. But I don't see why the fps would dip.
Also, collisions and place_meeting calls can slow down games if sprites and collisions are complex.
Again, I cannot see why the fps would drop, unless there are lots of objects in the room and the device can't handle it.
 

GMWolf

aka fel666
Why is it slower to draw a big than a small sprite? (A vs C, you'll see a big dip in fps and in real_fps)
Large sprites can mean two things:

A: they cover a larger portion of the screen. This means that the GPU needs to shade a larger number of fragments, and blend more pixels. Usually you will be limited by fill rate. Drawing large things on screen uses up full rate.

B: the source image is larger. This means Reading the texture will use more bandwidth, and thrash your cache more.



Why is a higher output resolution slower than a lower resolution, even though I'm doing exactly the same draw calls?
Once again, this has to do with the number of fragments you shade, blend, and your fill rate.
More pixels is simply more work for the gpu, it's more pixels to shade, blend, and write.
It's also more samples to do from the texture, increasing your bandwidth Usage once again.



Resolution 720x1280, draw 200 objects with a sprite of 640x640
If those sprites are covering a 640x640 region on the screen, then you then drawing over the same Pixels many times.
This is slow because the GPU needs to shade the same pixel many times over, and blend the fragments in the right order etc. Usually You want to avoid having overlapping sprites.

If you are scaling those sprites down, then you are sampling the texture really poorly, if that's the case, either make sure your sprite is the size it will be on screen, or make sure you have generate mip maps turned on, as that will improve sampling performance.
 

madthijs

Member
Hey GMWolf,

Thank you very much for your suggestions and explanation. I would not have guessed fillrate would be a problem just drawing a 'couple of sprites'.
Am I correct to assume that in GameMaker even 2D is hardware accelerated and all sprites are drawn as textured triangles?

Is there a way to reduce the fillrate, but still have overlapping sprites? Maybe by ignoring transparency/blending? Are vertex buffers something to look into?

Funny thing is my iPhone 11 does not bat an eye, but I guess the iPhones are known for their high fillrates (isn't that an advantage of their tile based rendering?).
By comparison many Android phone (midrange) have very high screen resolution but seem somewhat underpowered in the graphics department.

I'll be doing some more experimentation and post results here.
Seriously considering lowering the render resolution of my game to get to 60fps, but will try to optimize things as much as possile before I do so.
These phones all have very high res screen so upscaling stuff might not be as bad as I think.
 

GMWolf

aka fel666
Is there a way to reduce the fillrate, but still have overlapping sprites? Maybe by ignoring transparency/blending? Are vertex buffers something to look into?
Vertex buffers probably won't help.

Just make sure you sprites aren't too high res, as sampling that is slow.

Then maybe try to turn on depth testing and depth write, and rendering front to back, this should help a ton. Let me know how that goes!
 
Top