From 4c685666c527134c11b023581ecffc7f28b62abb Mon Sep 17 00:00:00 2001 From: Chris Thrasher Date: Wed, 25 Dec 2024 19:38:23 -0600 Subject: [PATCH] Remove caching from `sf::Transformable` and `sf::View` This reduces the size of both classes by 130 bytes which has positive impacts on cache locality. This change also removes all the internal invariants from both classes allowing them to be converted to aggregate types in the future. --- include/SFML/Graphics/Transformable.hpp | 16 +++---- include/SFML/Graphics/View.hpp | 18 +++---- src/SFML/Graphics/Transformable.cpp | 63 ++++++++---------------- src/SFML/Graphics/View.cpp | 64 ++++++++----------------- 4 files changed, 54 insertions(+), 107 deletions(-) diff --git a/include/SFML/Graphics/Transformable.hpp b/include/SFML/Graphics/Transformable.hpp index a6d7be65b..602f5afc2 100644 --- a/include/SFML/Graphics/Transformable.hpp +++ b/include/SFML/Graphics/Transformable.hpp @@ -214,7 +214,7 @@ public: /// \see `getInverseTransform` /// //////////////////////////////////////////////////////////// - [[nodiscard]] const Transform& getTransform() const; + [[nodiscard]] Transform getTransform() const; //////////////////////////////////////////////////////////// /// \brief get the inverse of the combined transform of the object @@ -224,20 +224,16 @@ public: /// \see `getTransform` /// //////////////////////////////////////////////////////////// - [[nodiscard]] const Transform& getInverseTransform() const; + [[nodiscard]] Transform getInverseTransform() const; private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - Vector2f m_origin; //!< Origin of translation/rotation/scaling of the object - Vector2f m_position; //!< Position of the object in the 2D world - Angle m_rotation; //!< Orientation of the object - Vector2f m_scale{1, 1}; //!< Scale of the object - mutable Transform m_transform; //!< Combined transformation of the object - mutable Transform m_inverseTransform; //!< Combined transformation of the object - mutable bool m_transformNeedUpdate{true}; //!< Does the transform need to be recomputed? - mutable bool m_inverseTransformNeedUpdate{true}; //!< Does the transform need to be recomputed? + Vector2f m_origin; //!< Origin of translation/rotation/scaling of the object + Vector2f m_position; //!< Position of the object in the 2D world + Angle m_rotation; //!< Orientation of the object + Vector2f m_scale{1, 1}; //!< Scale of the object }; } // namespace sf diff --git a/include/SFML/Graphics/View.hpp b/include/SFML/Graphics/View.hpp index 450973f0c..09a75d1be 100644 --- a/include/SFML/Graphics/View.hpp +++ b/include/SFML/Graphics/View.hpp @@ -240,7 +240,7 @@ public: /// \see `getInverseTransform` /// //////////////////////////////////////////////////////////// - [[nodiscard]] const Transform& getTransform() const; + [[nodiscard]] Transform getTransform() const; //////////////////////////////////////////////////////////// /// \brief Get the inverse projection transform of the view @@ -252,21 +252,17 @@ public: /// \see `getTransform` /// //////////////////////////////////////////////////////////// - [[nodiscard]] const Transform& getInverseTransform() const; + [[nodiscard]] Transform getInverseTransform() const; private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - Vector2f m_center{500, 500}; //!< Center of the view, in scene coordinates - Vector2f m_size{1000, 1000}; //!< Size of the view, in scene coordinates - Angle m_rotation; //!< Angle of rotation of the view rectangle - FloatRect m_viewport{{0, 0}, {1, 1}}; //!< Viewport rectangle, expressed as a factor of the render-target's size - FloatRect m_scissor{{0, 0}, {1, 1}}; //!< Scissor rectangle, expressed as a factor of the render-target's size - mutable Transform m_transform; //!< Precomputed projection transform corresponding to the view - mutable Transform m_inverseTransform; //!< Precomputed inverse projection transform corresponding to the view - mutable bool m_transformUpdated{}; //!< Internal state telling if the transform needs to be updated - mutable bool m_invTransformUpdated{}; //!< Internal state telling if the inverse transform needs to be updated + Vector2f m_center{500, 500}; //!< Center of the view, in scene coordinates + Vector2f m_size{1000, 1000}; //!< Size of the view, in scene coordinates + Angle m_rotation; //!< Angle of rotation of the view rectangle + FloatRect m_viewport{{0, 0}, {1, 1}}; //!< Viewport rectangle, expressed as a factor of the render-target's size + FloatRect m_scissor{{0, 0}, {1, 1}}; //!< Scissor rectangle, expressed as a factor of the render-target's size }; } // namespace sf diff --git a/src/SFML/Graphics/Transformable.cpp b/src/SFML/Graphics/Transformable.cpp index 55df9080b..91c8823ab 100644 --- a/src/SFML/Graphics/Transformable.cpp +++ b/src/SFML/Graphics/Transformable.cpp @@ -35,9 +35,7 @@ namespace sf //////////////////////////////////////////////////////////// void Transformable::setPosition(Vector2f position) { - m_position = position; - m_transformNeedUpdate = true; - m_inverseTransformNeedUpdate = true; + m_position = position; } @@ -45,27 +43,20 @@ void Transformable::setPosition(Vector2f position) void Transformable::setRotation(Angle angle) { m_rotation = angle.wrapUnsigned(); - - m_transformNeedUpdate = true; - m_inverseTransformNeedUpdate = true; } //////////////////////////////////////////////////////////// void Transformable::setScale(Vector2f factors) { - m_scale = factors; - m_transformNeedUpdate = true; - m_inverseTransformNeedUpdate = true; + m_scale = factors; } //////////////////////////////////////////////////////////// void Transformable::setOrigin(Vector2f origin) { - m_origin = origin; - m_transformNeedUpdate = true; - m_inverseTransformNeedUpdate = true; + m_origin = origin; } @@ -119,44 +110,30 @@ void Transformable::scale(Vector2f factor) //////////////////////////////////////////////////////////// -const Transform& Transformable::getTransform() const +Transform Transformable::getTransform() const { - // Recompute the combined transform if needed - if (m_transformNeedUpdate) - { - const float angle = -m_rotation.asRadians(); - const float cosine = std::cos(angle); - const float sine = std::sin(angle); - const float sxc = m_scale.x * cosine; - const float syc = m_scale.y * cosine; - const float sxs = m_scale.x * sine; - const float sys = m_scale.y * sine; - const float tx = -m_origin.x * sxc - m_origin.y * sys + m_position.x; - const float ty = m_origin.x * sxs - m_origin.y * syc + m_position.y; + const float angle = -m_rotation.asRadians(); + const float cosine = std::cos(angle); + const float sine = std::sin(angle); + const float sxc = m_scale.x * cosine; + const float syc = m_scale.y * cosine; + const float sxs = m_scale.x * sine; + const float sys = m_scale.y * sine; + const float tx = -m_origin.x * sxc - m_origin.y * sys + m_position.x; + const float ty = m_origin.x * sxs - m_origin.y * syc + m_position.y; - // clang-format off - m_transform = Transform( sxc, sys, tx, - -sxs, syc, ty, - 0.f, 0.f, 1.f); - // clang-format on - m_transformNeedUpdate = false; - } - - return m_transform; + // clang-format off + return { sxc, sys, tx, + -sxs, syc, ty, + 0.f, 0.f, 1.f}; + // clang-format on } //////////////////////////////////////////////////////////// -const Transform& Transformable::getInverseTransform() const +Transform Transformable::getInverseTransform() const { - // Recompute the inverse transform if needed - if (m_inverseTransformNeedUpdate) - { - m_inverseTransform = getTransform().getInverse(); - m_inverseTransformNeedUpdate = false; - } - - return m_inverseTransform; + return getTransform().getInverse(); } } // namespace sf diff --git a/src/SFML/Graphics/View.cpp b/src/SFML/Graphics/View.cpp index 020230220..808296fd7 100644 --- a/src/SFML/Graphics/View.cpp +++ b/src/SFML/Graphics/View.cpp @@ -48,9 +48,7 @@ View::View(Vector2f center, Vector2f size) : m_center(center), m_size(size) //////////////////////////////////////////////////////////// void View::setCenter(Vector2f center) { - m_center = center; - m_transformUpdated = false; - m_invTransformUpdated = false; + m_center = center; } @@ -58,9 +56,6 @@ void View::setCenter(Vector2f center) void View::setSize(Vector2f size) { m_size = size; - - m_transformUpdated = false; - m_invTransformUpdated = false; } @@ -68,9 +63,6 @@ void View::setSize(Vector2f size) void View::setRotation(Angle angle) { m_rotation = angle.wrapUnsigned(); - - m_transformUpdated = false; - m_invTransformUpdated = false; } @@ -152,48 +144,34 @@ void View::zoom(float factor) //////////////////////////////////////////////////////////// -const Transform& View::getTransform() const +Transform View::getTransform() const { - // Recompute the matrix if needed - if (!m_transformUpdated) - { - // Rotation components - const float angle = m_rotation.asRadians(); - const float cosine = std::cos(angle); - const float sine = std::sin(angle); - const float tx = -m_center.x * cosine - m_center.y * sine + m_center.x; - const float ty = m_center.x * sine - m_center.y * cosine + m_center.y; + // Rotation components + const float angle = m_rotation.asRadians(); + const float cosine = std::cos(angle); + const float sine = std::sin(angle); + const float tx = -m_center.x * cosine - m_center.y * sine + m_center.x; + const float ty = m_center.x * sine - m_center.y * cosine + m_center.y; - // Projection components - const float a = 2.f / m_size.x; - const float b = -2.f / m_size.y; - const float c = -a * m_center.x; - const float d = -b * m_center.y; + // Projection components + const float a = 2.f / m_size.x; + const float b = -2.f / m_size.y; + const float c = -a * m_center.x; + const float d = -b * m_center.y; - // Rebuild the projection matrix - // clang-format off - m_transform = Transform( a * cosine, a * sine, a * tx + c, - -b * sine, b * cosine, b * ty + d, - 0.f, 0.f, 1.f); - // clang-format on - m_transformUpdated = true; - } - - return m_transform; + // Rebuild the projection matrix + // clang-format off + return { a * cosine, a * sine, a * tx + c, + -b * sine, b * cosine, b * ty + d, + 0.f, 0.f, 1.f}; + // clang-format on } //////////////////////////////////////////////////////////// -const Transform& View::getInverseTransform() const +Transform View::getInverseTransform() const { - // Recompute the matrix if needed - if (!m_invTransformUpdated) - { - m_inverseTransform = getTransform().getInverse(); - m_invTransformUpdated = true; - } - - return m_inverseTransform; + return getTransform().getInverse(); } } // namespace sf