From 666da801a133574ba305f8adf61288a210868297 Mon Sep 17 00:00:00 2001 From: Jan Haller Date: Sat, 29 Mar 2014 16:46:15 +0100 Subject: [PATCH] Cached sf::Text attributes Two optimizations: - If a value remains the same, nothing happens - Recompute geometry only before drawing and bound access, not after each set Closes #413 --- include/SFML/Graphics/Text.hpp | 22 ++++++----- src/SFML/Graphics/Text.cpp | 68 ++++++++++++++++++++++------------ 2 files changed, 58 insertions(+), 32 deletions(-) diff --git a/include/SFML/Graphics/Text.hpp b/include/SFML/Graphics/Text.hpp index 73753419a..c9a188ed2 100644 --- a/include/SFML/Graphics/Text.hpp +++ b/include/SFML/Graphics/Text.hpp @@ -275,21 +275,25 @@ private : virtual void draw(RenderTarget& target, RenderStates states) const; //////////////////////////////////////////////////////////// - /// \brief Update the text's geometry + /// \brief Make sure the text's geometry is updated + /// + /// All the attributes related to rendering are cached, such + /// that the geometry is only updated when necessary. /// //////////////////////////////////////////////////////////// - void updateGeometry(); + void ensureGeometryUpdate() const; //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - String m_string; ///< String to display - const Font* m_font; ///< Font used to display the string - unsigned int m_characterSize; ///< Base size of characters, in pixels - Uint32 m_style; ///< Text style (see Style enum) - Color m_color; ///< Text color - VertexArray m_vertices; ///< Vertex array containing the text's geometry - FloatRect m_bounds; ///< Bounding rectangle of the text (in local coordinates) + String m_string; ///< String to display + const Font* m_font; ///< Font used to display the string + unsigned int m_characterSize; ///< Base size of characters, in pixels + Uint32 m_style; ///< Text style (see Style enum) + Color m_color; ///< Text color + mutable VertexArray m_vertices; ///< Vertex array containing the text's geometry + mutable FloatRect m_bounds; ///< Bounding rectangle of the text (in local coordinates) + mutable bool m_geometryNeedUpdate; ///< Does the geometry need to be recomputed? }; } // namespace sf diff --git a/src/SFML/Graphics/Text.cpp b/src/SFML/Graphics/Text.cpp index 238cf168d..119ad2a7a 100644 --- a/src/SFML/Graphics/Text.cpp +++ b/src/SFML/Graphics/Text.cpp @@ -35,13 +35,14 @@ namespace sf { //////////////////////////////////////////////////////////// Text::Text() : -m_string (), -m_font (NULL), -m_characterSize(30), -m_style (Regular), -m_color (255, 255, 255), -m_vertices (Quads), -m_bounds () +m_string (), +m_font (NULL), +m_characterSize (30), +m_style (Regular), +m_color (255, 255, 255), +m_vertices (Quads), +m_bounds (), +m_geometryNeedUpdate(false) { } @@ -49,23 +50,27 @@ m_bounds () //////////////////////////////////////////////////////////// Text::Text(const String& string, const Font& font, unsigned int characterSize) : -m_string (string), -m_font (&font), -m_characterSize(characterSize), -m_style (Regular), -m_color (255, 255, 255), -m_vertices (Quads), -m_bounds () +m_string (string), +m_font (&font), +m_characterSize (characterSize), +m_style (Regular), +m_color (255, 255, 255), +m_vertices (Quads), +m_bounds (), +m_geometryNeedUpdate(true) { - updateGeometry(); + } //////////////////////////////////////////////////////////// void Text::setString(const String& string) { - m_string = string; - updateGeometry(); + if (m_string != string) + { + m_string = string; + m_geometryNeedUpdate = true; + } } @@ -75,7 +80,7 @@ void Text::setFont(const Font& font) if (m_font != &font) { m_font = &font; - updateGeometry(); + m_geometryNeedUpdate = true; } } @@ -86,7 +91,7 @@ void Text::setCharacterSize(unsigned int size) if (m_characterSize != size) { m_characterSize = size; - updateGeometry(); + m_geometryNeedUpdate = true; } } @@ -97,7 +102,7 @@ void Text::setStyle(Uint32 style) if (m_style != style) { m_style = style; - updateGeometry(); + m_geometryNeedUpdate = true; } } @@ -108,8 +113,14 @@ void Text::setColor(const Color& color) if (color != m_color) { m_color = color; - for (unsigned int i = 0; i < m_vertices.getVertexCount(); ++i) - m_vertices[i].color = m_color; + + // Change vertex colors directly, no need to update whole geometry + // (if geometry is updated anyway, we can skip this step) + if (!m_geometryNeedUpdate) + { + for (unsigned int i = 0; i < m_vertices.getVertexCount(); ++i) + m_vertices[i].color = m_color; + } } } @@ -199,6 +210,8 @@ Vector2f Text::findCharacterPos(std::size_t index) const //////////////////////////////////////////////////////////// FloatRect Text::getLocalBounds() const { + ensureGeometryUpdate(); + return m_bounds; } @@ -215,6 +228,8 @@ void Text::draw(RenderTarget& target, RenderStates states) const { if (m_font) { + ensureGeometryUpdate(); + states.transform *= getTransform(); states.texture = &m_font->getTexture(m_characterSize); target.draw(m_vertices, states); @@ -223,8 +238,15 @@ void Text::draw(RenderTarget& target, RenderStates states) const //////////////////////////////////////////////////////////// -void Text::updateGeometry() +void Text::ensureGeometryUpdate() const { + // Do nothing, if geometry has not changed + if (!m_geometryNeedUpdate) + return; + + // Mark geometry as updated + m_geometryNeedUpdate = false; + // Clear the previous geometry m_vertices.clear(); m_bounds = FloatRect();