Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

After some profiling, I've determined that one of my most expensive functions involves drawing text. As a solution, I'd like to implement a LRU type of cache that will "remember" the vertices, tex coords (etc) for a given string. This is particularly complicated because some of the resources involved reside in VRAM (most do, actually; I take a given string and convert it into a long sequence of vertices / tex coords / indices), while some reside in plain RAM.

If I knew what my limits were (in both respects) I could write a decent LRU cache system and probably buy myself a substantial performance gain. The primary target for this app is the Android platform, and as I understand it, most such devices share RAM with the GPU.

I'd appreciate any answers to this, whether they directly answer my question or not.

share|improve this question
    
If you needed performance, couldn't you use bitmap text? –  AttackingHobo Apr 13 '11 at 5:36
    
I am [using bitmap text]. My code does little more than look up char size and tex coord for each char in any given string. I'm not having a huge issue here, but this is the next biggest cpu hog on my list and I'd like to nip it in the bud, or at least make sure I'm programming to an interface that I can improve later. –  stephelton Apr 13 '11 at 5:51
add comment

2 Answers

up vote 6 down vote accepted

Having dealt with text rendering a lot, I have to say all the string LRU systems I've seen end up being, at best, a wash for performance, and at worse an enormous source of bugs and code complication. The only time it makes sense is if all your text is static, and that's rarely the case in any game these days.

Do you know what's actually taking the time? Is it...

  • Binding the font textures? If so, make sure all your characters are on the same texture, and make sure you're sorting them correctly to avoid unnecessary binds.
  • Looking up the character data? What kind of data structure are you using? If it's not a hash table, it really should be. If it is, take a look at the load factor to make sure you're getting decent hashing.
  • Accessing the character data? Accessor methods are very slow on Android and discouraged for any performance-critical code. Use public members instead.
  • Calculating the vertices and copying them into the buffer? This might be an appropriate time to break out the NDK so you can do float crunching without the overhead of Dalvik.
share|improve this answer
    
I'm already using the NDK, and my structure for character data (which is really just its width) is stored in an array, and indexed by the char itself. So the time is being spent calculating and building vertices and tex coords, and passing them to the GPU. –  stephelton Apr 13 '11 at 14:49
    
How are you building them and passing them to the GPU? –  user744 Apr 13 '11 at 15:59
    
i create an array of GLfloats, then for each char, i look up the width (where the char itself is the index into an array of widths), then i populate the above arrays with the data corresponding to that char, then i pass the whole thing to the GPU via a call to glVertexPointer(), glTexCoordPointer(), and glDrawArrays. then i delete the arrays. I could avoid creating those arrays, and i bet that would make a huge improvement... Nice :) –  stephelton Apr 13 '11 at 17:00
    
Yeah, dynamic memory allocation/deallocation is an enormous overhead on most platforms. If you can simply reuse the same array (say, by making it a static std::vector or growing realloced buffer), you should save a lot of time. –  user744 Apr 13 '11 at 17:09
add comment

Instead of determining a memory budget by guessing, I'd suggest you make the size of the cache configurable and use profiling to determine the best size for you.

Also you shouldn't need more than one index buffer - you just need one which will handle the maximum length string. You should be able to use less than the whole index buffer for shorter strings by passing the appropriate parameters to your draw call.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.