In order to naïvely render sprites, you can send single rectangles with their position, rotation, size, and texture. This is very easy, but given that reducing state changes, draw calls, and data uploads are good ways to improve rendering performance, it's clearly not an efficient solution. Some techniques like passing each sprite as a single primitive and assembling a rectangle in the geometry shader are very appealing but aren't available if targeting a platform like WebGL or even just older hardware.
On top of issues like batching and texture aliases, how do you efficiently submit geometry to render sprites?
I'm interested in answers that are rendering API agnostic, but using a specific API like OpenGL or Direct X is fine for illustration purposes.