[SDL2_TTF]-Text Rendering Slow? How To Make Faster?

[SDL2_TTF]-Text Rendering Slow? How To Make Faster?

Hi,

I was working on some SDL1 OpenPandora ports for a few weeks,
but now have come back to SDL2 and wish to improve my game engine.

I’ve noticed that SDL2_TTF TTF text rendering is rather slow?
Can someone look at my source code for TTF text rendering
and suggest modifications to make it faster?

Here is the source code:

Code:
//-------------------------------------------------------------------------------------------------
void Visuals::DrawTextOntoScreenBuffer(const char *textToDisplay, TTF_Font *font, int posX, int posY
, Uint8 XJustification, Uint8 textRed, Uint8 textGreen, Uint8 textBlue
, Uint8 outlineRed, Uint8 outlineGreen, Uint8 outlineBlue)
{
SDL_Color textColor = { textRed, textGreen, textBlue, 255 };
SDL_Color outlineColor = { outlineRed, outlineGreen, outlineBlue, 255 };
SDL_Surface *text;
SDL_Surface *textOutline;
SDL_Texture *textTexture;
SDL_Texture *textOutlineTexture;
SDL_Rect destinationRect;
SDL_Rect destinationOutlineRect;
int windowWidth;
int windowHeight;

SDL_GetWindowSize(Window, &windowWidth, &windowHeight);

text = TTF_RenderText_Blended(font, textToDisplay, textColor);
textOutline = TTF_RenderText_Solid(font, textToDisplay, outlineColor);

if (XJustification == JustifyLeft)
{
    posX = posX + (text->w / 2);
}
else if (XJustification == JustifyCenter)
{
    posX = (640 / 2);
}
else if (XJustification == JustifyRight)
{
    posX = (640 - posX) - (text->w / 2);
}
else if (XJustification == JustifyCenterOnPoint)
{
    posX = posX;
}

textTexture = SDL_CreateTextureFromSurface(Renderer, text);
textOutlineTexture = SDL_CreateTextureFromSurface(Renderer, textOutline);

float winWidthFixed;
float winHeightFixed;
if (ForceAspectRatio == false)
{
    winWidthFixed = (float)windowWidth / 640;
    winHeightFixed = (float)windowHeight / 480;
}
else
{
    winWidthFixed = 1;
    winHeightFixed = 1;
}

destinationRect.x = (posX * winWidthFixed) - ( (text->w * winWidthFixed) / 2 );
destinationRect.y = (posY * winHeightFixed) - (winHeightFixed / 2) + 3;
destinationRect.w = text->w * (winWidthFixed);
destinationRect.h = text->h * (winHeightFixed);

destinationOutlineRect.x = destinationRect.x;
destinationOutlineRect.y = destinationRect.y;
destinationOutlineRect.w = destinationRect.w;
destinationOutlineRect.h = destinationRect.h;

for (Sint16 y = -3; y < 4; y+=1)
{
    for (Sint16 x = -3; x < 4; x+=1)
    {
        destinationOutlineRect.x = destinationRect.x + x;
        destinationOutlineRect.y = destinationRect.y + y;
        SDL_RenderCopyEx(Renderer, textOutlineTexture, NULL, &destinationOutlineRect, 0, NULL, SDL_FLIP_NONE);
    }
}

SDL_RenderCopyEx(Renderer, textTexture, NULL, &destinationRect, 0, NULL, SDL_FLIP_NONE);

SDL_DestroyTexture(textOutlineTexture);
SDL_DestroyTexture(textTexture);
SDL_FreeSurface(text);
SDL_FreeSurface(textOutline);

}

//-------------------------------------------------------------------------------------------------

I am using the most up to date SDL2 and support libraries including SDL2_TTF.
I am on a very slow thin client with Xubuntu 14.04 L.T.S. 64Bit host
and am compiling and running the game under a Microsoft Windows XP Pro 32Bit guest.

Any help would be appreciated, thank you!------------------------
JeZ+Lee
JessePalser <AT> Gmail <DOT> com
16BitSoft Inc.
Video Game Design Studio
www.16BitSoft.com

This is a pretty common issue when using SDL_ttf. If you want better
performance, you need to cache your renderings. That way you don’t have to
allocate and free 4 chunks of memory every time you draw, as you are.

So, to be more specific, you should write a structure that holds onto the
rendered text textures so that you can reuse them. If your text is dynamic
and changes every frame, then you can render each glyph to a texture and
arrange them as needed in the draw call. I have a font class that does
this, but I haven’t made a plain SDL2 codepath for it yet.

Jonny DOn Thu, Nov 13, 2014 at 11:28 AM, JeZ-l-Lee < JessePalserMailingLists at gmail.com> wrote:

[SDL2_TTF]-Text Rendering Slow? How To Make Faster?

Hi,

I was working on some SDL1 OpenPandora ports for a few weeks,
but now have come back to SDL2 and wish to improve my game engine.

I’ve noticed that SDL2_TTF TTF text rendering is rather slow?
Can someone look at my source code for TTF text rendering
and suggest modifications to make it faster?

Here is the source code:

Code:

//-------------------------------------------------------------------------------------------------
void Visuals::DrawTextOntoScreenBuffer(const char *textToDisplay, TTF_Font
*font, int posX, int posY
, Uint8 XJustification, Uint8
textRed, Uint8 textGreen, Uint8 textBlue
, Uint8 outlineRed, Uint8
outlineGreen, Uint8 outlineBlue)
{
SDL_Color textColor = { textRed, textGreen, textBlue, 255 };
SDL_Color outlineColor = { outlineRed, outlineGreen, outlineBlue, 255 };
SDL_Surface *text;
SDL_Surface *textOutline;
SDL_Texture *textTexture;
SDL_Texture *textOutlineTexture;
SDL_Rect destinationRect;
SDL_Rect destinationOutlineRect;
int windowWidth;
int windowHeight;

SDL_GetWindowSize(Window, &windowWidth, &windowHeight);

text = TTF_RenderText_Blended(font, textToDisplay, textColor);
textOutline = TTF_RenderText_Solid(font, textToDisplay, outlineColor);

if (XJustification == JustifyLeft)
{
    posX = posX + (text->w / 2);
}
else if (XJustification == JustifyCenter)
{
    posX = (640 / 2);
}
else if (XJustification == JustifyRight)
{
    posX = (640 - posX) - (text->w / 2);
}
else if (XJustification == JustifyCenterOnPoint)
{
    posX = posX;
}

textTexture = SDL_CreateTextureFromSurface(Renderer, text);
textOutlineTexture = SDL_CreateTextureFromSurface(Renderer,

textOutline);

float winWidthFixed;
float winHeightFixed;
if (ForceAspectRatio == false)
{
    winWidthFixed = (float)windowWidth / 640;
    winHeightFixed = (float)windowHeight / 480;
}
else
{
    winWidthFixed = 1;
    winHeightFixed = 1;
}

destinationRect.x = (posX * winWidthFixed) - ( (text->w *

winWidthFixed) / 2 );
destinationRect.y = (posY * winHeightFixed) - (winHeightFixed / 2) + 3;
destinationRect.w = text->w * (winWidthFixed);
destinationRect.h = text->h * (winHeightFixed);

destinationOutlineRect.x = destinationRect.x;
destinationOutlineRect.y = destinationRect.y;
destinationOutlineRect.w = destinationRect.w;
destinationOutlineRect.h = destinationRect.h;

for (Sint16 y = -3; y < 4; y+=1)
{
    for (Sint16 x = -3; x < 4; x+=1)
    {
        destinationOutlineRect.x = destinationRect.x + x;
        destinationOutlineRect.y = destinationRect.y + y;
        SDL_RenderCopyEx(Renderer, textOutlineTexture, NULL,

&destinationOutlineRect, 0, NULL, SDL_FLIP_NONE);
}
}

SDL_RenderCopyEx(Renderer, textTexture, NULL, &destinationRect, 0,

NULL, SDL_FLIP_NONE);

SDL_DestroyTexture(textOutlineTexture);
SDL_DestroyTexture(textTexture);
SDL_FreeSurface(text);
SDL_FreeSurface(textOutline);

}

//-------------------------------------------------------------------------------------------------

I am using the most up to date SDL2 and support libraries including
SDL2_TTF.
I am on a very slow thin client with Xubuntu 14.04 L.T.S. 64Bit host
and am compiling and running the game under a Microsoft Windows XP Pro
32Bit guest.

Any help would be appreciated, thank you!


JeZ+Lee
JessePalser Gmail com
16BitSoft Inc.
Video Game Design Studio
www.16BitSoft.com


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Jon, the people want NFont for SDL2 and SDL_gpu =D

2014-11-13 10:04 GMT-07:00 Jonathan Dearborn :> This is a pretty common issue when using SDL_ttf. If you want better

performance, you need to cache your renderings. That way you don’t have to
allocate and free 4 chunks of memory every time you draw, as you are.

So, to be more specific, you should write a structure that holds onto the
rendered text textures so that you can reuse them. If your text is dynamic
and changes every frame, then you can render each glyph to a texture and
arrange them as needed in the draw call. I have a font class that does
this, but I haven’t made a plain SDL2 codepath for it yet.

Jonny D

On Thu, Nov 13, 2014 at 11:28 AM, JeZ-l-Lee < JessePalserMailingLists at gmail.com> wrote:

[SDL2_TTF]-Text Rendering Slow? How To Make Faster?

Hi,

I was working on some SDL1 OpenPandora ports for a few weeks,
but now have come back to SDL2 and wish to improve my game engine.

I’ve noticed that SDL2_TTF TTF text rendering is rather slow?
Can someone look at my source code for TTF text rendering
and suggest modifications to make it faster?

Here is the source code:

Code:

//-------------------------------------------------------------------------------------------------
void Visuals::DrawTextOntoScreenBuffer(const char *textToDisplay,
TTF_Font *font, int posX, int posY
, Uint8 XJustification, Uint8
textRed, Uint8 textGreen, Uint8 textBlue
, Uint8 outlineRed, Uint8
outlineGreen, Uint8 outlineBlue)
{
SDL_Color textColor = { textRed, textGreen, textBlue, 255 };
SDL_Color outlineColor = { outlineRed, outlineGreen, outlineBlue, 255 };
SDL_Surface *text;
SDL_Surface *textOutline;
SDL_Texture *textTexture;
SDL_Texture *textOutlineTexture;
SDL_Rect destinationRect;
SDL_Rect destinationOutlineRect;
int windowWidth;
int windowHeight;

SDL_GetWindowSize(Window, &windowWidth, &windowHeight);

text = TTF_RenderText_Blended(font, textToDisplay, textColor);
textOutline = TTF_RenderText_Solid(font, textToDisplay, outlineColor);

if (XJustification == JustifyLeft)
{
    posX = posX + (text->w / 2);
}
else if (XJustification == JustifyCenter)
{
    posX = (640 / 2);
}
else if (XJustification == JustifyRight)
{
    posX = (640 - posX) - (text->w / 2);
}
else if (XJustification == JustifyCenterOnPoint)
{
    posX = posX;
}

textTexture = SDL_CreateTextureFromSurface(Renderer, text);
textOutlineTexture = SDL_CreateTextureFromSurface(Renderer,

textOutline);

float winWidthFixed;
float winHeightFixed;
if (ForceAspectRatio == false)
{
    winWidthFixed = (float)windowWidth / 640;
    winHeightFixed = (float)windowHeight / 480;
}
else
{
    winWidthFixed = 1;
    winHeightFixed = 1;
}

destinationRect.x = (posX * winWidthFixed) - ( (text->w *

winWidthFixed) / 2 );
destinationRect.y = (posY * winHeightFixed) - (winHeightFixed / 2) +
3;
destinationRect.w = text->w * (winWidthFixed);
destinationRect.h = text->h * (winHeightFixed);

destinationOutlineRect.x = destinationRect.x;
destinationOutlineRect.y = destinationRect.y;
destinationOutlineRect.w = destinationRect.w;
destinationOutlineRect.h = destinationRect.h;

for (Sint16 y = -3; y < 4; y+=1)
{
    for (Sint16 x = -3; x < 4; x+=1)
    {
        destinationOutlineRect.x = destinationRect.x + x;
        destinationOutlineRect.y = destinationRect.y + y;
        SDL_RenderCopyEx(Renderer, textOutlineTexture, NULL,

&destinationOutlineRect, 0, NULL, SDL_FLIP_NONE);
}
}

SDL_RenderCopyEx(Renderer, textTexture, NULL, &destinationRect, 0,

NULL, SDL_FLIP_NONE);

SDL_DestroyTexture(textOutlineTexture);
SDL_DestroyTexture(textTexture);
SDL_FreeSurface(text);
SDL_FreeSurface(textOutline);

}

//-------------------------------------------------------------------------------------------------

I am using the most up to date SDL2 and support libraries including
SDL2_TTF.
I am on a very slow thin client with Xubuntu 14.04 L.T.S. 64Bit host
and am compiling and running the game under a Microsoft Windows XP Pro
32Bit guest.

Any help would be appreciated, thank you!


JeZ+Lee
JessePalser Gmail com
16BitSoft Inc.
Video Game Design Studio
www.16BitSoft.com


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Javier Flores - @javierecf

Well, I was sorta planning on it… :wink:

Jonny DOn Thu, Nov 13, 2014 at 12:47 PM, Javier Flores wrote:

Jon, the people want NFont for SDL2 and SDL_gpu =D

2014-11-13 10:04 GMT-07:00 Jonathan Dearborn <@Jonathan_Dearborn>:

This is a pretty common issue when using SDL_ttf. If you want better

performance, you need to cache your renderings. That way you don’t have to
allocate and free 4 chunks of memory every time you draw, as you are.

So, to be more specific, you should write a structure that holds onto the
rendered text textures so that you can reuse them. If your text is dynamic
and changes every frame, then you can render each glyph to a texture and
arrange them as needed in the draw call. I have a font class that does
this, but I haven’t made a plain SDL2 codepath for it yet.

Jonny D

On Thu, Nov 13, 2014 at 11:28 AM, JeZ-l-Lee < JessePalserMailingLists at gmail.com> wrote:

[SDL2_TTF]-Text Rendering Slow? How To Make Faster?

Hi,

I was working on some SDL1 OpenPandora ports for a few weeks,
but now have come back to SDL2 and wish to improve my game engine.

I’ve noticed that SDL2_TTF TTF text rendering is rather slow?
Can someone look at my source code for TTF text rendering
and suggest modifications to make it faster?

Here is the source code:

Code:

//-------------------------------------------------------------------------------------------------
void Visuals::DrawTextOntoScreenBuffer(const char *textToDisplay,
TTF_Font *font, int posX, int posY
, Uint8 XJustification, Uint8
textRed, Uint8 textGreen, Uint8 textBlue
, Uint8 outlineRed, Uint8
outlineGreen, Uint8 outlineBlue)
{
SDL_Color textColor = { textRed, textGreen, textBlue, 255 };
SDL_Color outlineColor = { outlineRed, outlineGreen, outlineBlue, 255 };
SDL_Surface *text;
SDL_Surface *textOutline;
SDL_Texture *textTexture;
SDL_Texture *textOutlineTexture;
SDL_Rect destinationRect;
SDL_Rect destinationOutlineRect;
int windowWidth;
int windowHeight;

SDL_GetWindowSize(Window, &windowWidth, &windowHeight);

text = TTF_RenderText_Blended(font, textToDisplay, textColor);
textOutline = TTF_RenderText_Solid(font, textToDisplay,

outlineColor);

if (XJustification == JustifyLeft)
{
    posX = posX + (text->w / 2);
}
else if (XJustification == JustifyCenter)
{
    posX = (640 / 2);
}
else if (XJustification == JustifyRight)
{
    posX = (640 - posX) - (text->w / 2);
}
else if (XJustification == JustifyCenterOnPoint)
{
    posX = posX;
}

textTexture = SDL_CreateTextureFromSurface(Renderer, text);
textOutlineTexture = SDL_CreateTextureFromSurface(Renderer,

textOutline);

float winWidthFixed;
float winHeightFixed;
if (ForceAspectRatio == false)
{
    winWidthFixed = (float)windowWidth / 640;
    winHeightFixed = (float)windowHeight / 480;
}
else
{
    winWidthFixed = 1;
    winHeightFixed = 1;
}

destinationRect.x = (posX * winWidthFixed) - ( (text->w *

winWidthFixed) / 2 );
destinationRect.y = (posY * winHeightFixed) - (winHeightFixed / 2) +
3;
destinationRect.w = text->w * (winWidthFixed);
destinationRect.h = text->h * (winHeightFixed);

destinationOutlineRect.x = destinationRect.x;
destinationOutlineRect.y = destinationRect.y;
destinationOutlineRect.w = destinationRect.w;
destinationOutlineRect.h = destinationRect.h;

for (Sint16 y = -3; y < 4; y+=1)
{
    for (Sint16 x = -3; x < 4; x+=1)
    {
        destinationOutlineRect.x = destinationRect.x + x;
        destinationOutlineRect.y = destinationRect.y + y;
        SDL_RenderCopyEx(Renderer, textOutlineTexture, NULL,

&destinationOutlineRect, 0, NULL, SDL_FLIP_NONE);
}
}

SDL_RenderCopyEx(Renderer, textTexture, NULL, &destinationRect, 0,

NULL, SDL_FLIP_NONE);

SDL_DestroyTexture(textOutlineTexture);
SDL_DestroyTexture(textTexture);
SDL_FreeSurface(text);
SDL_FreeSurface(textOutline);

}

//-------------------------------------------------------------------------------------------------

I am using the most up to date SDL2 and support libraries including
SDL2_TTF.
I am on a very slow thin client with Xubuntu 14.04 L.T.S. 64Bit host
and am compiling and running the game under a Microsoft Windows XP Pro
32Bit guest.

Any help would be appreciated, thank you!


JeZ+Lee
JessePalser Gmail com
16BitSoft Inc.
Video Game Design Studio
www.16BitSoft.com


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Javier Flores - @javierecf


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

I think it slow because of the Freetype 2 which is used internally by SDL_ttf. TrueType processing is quite complicated and it takes time to compute. The best way of using SDL_ttf would be to create a new texture only when text changes (caching).

Anyway try profiling the code. It probably somewhere else :).

Alright, I put together a version of NFont that uses SDL_Renderer
(NFontR). You can check it out on the Google Code page:
https://code.google.com/p/nfont/

It does all the stuff you should expect! Caching, alignment, line feed,
UTF-8, coloring, and a permissive license. The only catch is that I
haven’t updated the C version in a long time, so C++ only.

I hope you like it,
Jonny D

nice!, im gonna give it a try. (i could totally use some caching on my in
game editor)

2014-11-14 10:03 GMT-07:00 Jonathan Dearborn :> Alright, I put together a version of NFont that uses SDL_Renderer

(NFontR). You can check it out on the Google Code page:
https://code.google.com/p/nfont/

It does all the stuff you should expect! Caching, alignment, line feed,
UTF-8, coloring, and a permissive license. The only catch is that I
haven’t updated the C version in a long time, so C++ only.

I hope you like it,
Jonny D


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Javier Flores - @javierecf

Neat! Though, just so you know there is demand, I would be very
interested in the C version. I ship libraries as binaries and do a lot
with scripting language bindings, so the stable and predictable ABI of
C is really important to me.

Thanks,
EricOn 11/14/14, Jonathan Dearborn wrote:

Alright, I put together a version of NFont that uses SDL_Renderer
(NFontR). You can check it out on the Google Code page:
https://code.google.com/p/nfont/

It does all the stuff you should expect! Caching, alignment, line feed,
UTF-8, coloring, and a permissive license. The only catch is that I
haven’t updated the C version in a long time, so C++ only.

I hope you like it,
Jonny D


Beginning iPhone Games Development
http://playcontrol.net/iphonegamebook/

Same here, C++ is a mess, i only use classes when absolutely neccesary, and
a modern stable nfont version for c would be great!.

2014-11-14 13:46 GMT-07:00 Eric Wing :> On 11/14/14, Jonathan Dearborn wrote:

Alright, I put together a version of NFont that uses SDL_Renderer
(NFontR). You can check it out on the Google Code page:
https://code.google.com/p/nfont/

It does all the stuff you should expect! Caching, alignment, line feed,
UTF-8, coloring, and a permissive license. The only catch is that I
haven’t updated the C version in a long time, so C++ only.

I hope you like it,
Jonny D

Neat! Though, just so you know there is demand, I would be very
interested in the C version. I ship libraries as binaries and do a lot
with scripting language bindings, so the stable and predictable ABI of
C is really important to me.

Thanks,
Eric

Beginning iPhone Games Development
http://playcontrol.net/iphonegamebook/


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Javier Flores - @javierecf

Hi,

Mark this topic SOLVED!

I’ve released a beta of our SDL2 game: “TetriCrisis 4 110% A.I. Turbo” here:
http://forums.libsdl.org/viewtopic.php?t=10833

Game uses our new TTF text optimization and is open-source!
Enjoy…

JeZxLee