I've been developing a game targeted at android. I know not to think about program optimization until the project is finished, but I have to wonder how many textures most phones can handle safely without melting or murdering battery. I've seen that the max SIZE of a texture should be 1024 or 2048 pixels squared (I've been combining sprite-sheets into 1024x1024 atlas's) but I can't help but wonder if there is a limit to how many of these I can use at runtime. I understand it should depend on the GPU but what spec determines it?
The only limit on texture count is memory
The vast majority of mobile devices (and desktops with integrated graphics rather than a dedicated graphics card) use a shared memory architecture where VRAM - that's RAM reserved for video - is part of system RAM. Textures used by graphics APIs are simply pointers to a block of VRAM; there's no artificial limits imposed by the APIs themselves.
A typical source of confusion here is there's a very limited number of texture units. These are circuits in the GPU hardware which can 'bind' to a particular texture and perform the sampling for us. Importantly though, the limit only applies to a single shader. In effect if a system has, for example, 32 texture units, then a single shader can use at most 32 textures simultaneously. Note that there is also another similar limit that affects how many textures a particular stage of the shader can use simultaneously (the textures per stage limit).
Quick aside note: A simple way to improve memory usage is to use texture compression. Most mobiles support some form of texture compression nowadays and many engines enable it by default (those texture units can sample straight from compressed data).
Those texture units are dedicated pieces of hardware and as a result are physically restricted on the size of textures they can deal with. The circuits that perform sampling are designed to operate on images with a power-of-2 size. This is why devices have limited texture sizes, ranging from around 512 up, and they're always a power of 2. 1080 is an awkward size for an atlas as it's not a power of 2 (so the hardware might decide to upscale it all the way to 2048).
The limit depends on:
- the phone's memory bandwidth
- the GPU's cache size
- how large (in bytes) the textures are
- the phone's memory size accessible to the GPU
- how much of the texture you're using per frame
- what mipmap level is being used (if any)
- how well ordered your draw calls are so the GPU cache can work effectively
- how much opaque draws you have vs blend or alpha test (hidden surface removal)
- what the screen resolution is
- how complex the shaders are (bottlenecks?)
- how busy the CPU is
It's not a question of how many. It's not a question of how large. It's a question of all those factors combined.
You could have 4000 16x16 textures displayed and a phone could probably handle that faster than four 1024x1024 textures drawn over the screen.
Both CPU and GPU share the same memory bus on most mobile platforms which means if one is using the bus to read or write memory the other has to wait it's turn.
So you can run a test and see that the GPU is fine drawing N triangles with AxB textures at a certain frame rate, and run a test for CPU speed, but when you combine both GPU (drawing) and CPU processing (audio, loading/decompression, physics, particles & 3D model animations) suddenly the GPU performance drops. Or it could be the other way around where the GPU has priority over the CPU to access memory, or a mix of both depending on the system.
GPU and CPU usually run in parallel but they still have to "fight" over memory access on a shared memory system.