From c9c82d9daf5feda1cc47569f7e360a7e1e7240e0 Mon Sep 17 00:00:00 2001 From: elexis Date: Sat, 17 Aug 2019 11:52:57 +0000 Subject: [PATCH] Use shared_ptr to avoid copying and deleting SGUIImageEffects, 2.5x faster in a benchmark, refs ba0ebd6644. Differential Revision: https://code.wildfiregames.com/D2184 Refs 3028551b91/D2163 Tested on: gcc 9, Jenkins This was SVN commit r22682. --- source/gui/CGUI.cpp | 11 +++++------ source/gui/CGUISprite.h | 11 ++++------- source/gui/GUIRenderer.cpp | 4 ++-- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/source/gui/CGUI.cpp b/source/gui/CGUI.cpp index f13f8aed24..261a31ac96 100644 --- a/source/gui/CGUI.cpp +++ b/source/gui/CGUI.cpp @@ -999,7 +999,8 @@ void CGUI::Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile) if (m_Sprites.find(name) != m_Sprites.end()) LOGWARNING("GUI sprite name '%s' used more than once; first definition will be discarded", name.c_str()); - SGUIImageEffects* effects = NULL; + // shared_ptr to link the effect to every sprite, faster than copy. + std::shared_ptr effects; for (XMBElement child : Element.GetChildNodes()) { @@ -1013,7 +1014,7 @@ void CGUI::Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile) LOGERROR("GUI must not have more than one "); else { - effects = new SGUIImageEffects; + effects = std::make_shared(); Xeromyces_ReadEffects(child, pFile, *effects); } } @@ -1026,9 +1027,7 @@ void CGUI::Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile) if (effects) for (SGUIImage* const& img : Sprite->m_Images) if (!img->m_Effects) - img->m_Effects = new SGUIImageEffects(*effects); // do a copy just so it can be deleted correctly later - - delete effects; + img->m_Effects = effects; m_Sprites.erase(name); m_Sprites.emplace(name, Sprite); @@ -1157,7 +1156,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite LOGERROR("GUI must not have more than one "); else { - Image->m_Effects = new SGUIImageEffects; + Image->m_Effects = std::make_shared(); Xeromyces_ReadEffects(child, pFile, *Image->m_Effects); } } diff --git a/source/gui/CGUISprite.h b/source/gui/CGUISprite.h index 0ca6906864..d564087406 100644 --- a/source/gui/CGUISprite.h +++ b/source/gui/CGUISprite.h @@ -41,6 +41,8 @@ A GUI Sprite #include "lib/res/graphics/ogl_tex.h" +#include + struct SGUIImageEffects { SGUIImageEffects() : m_Greyscale(false) {} @@ -59,15 +61,10 @@ struct SGUIImage public: SGUIImage() : m_FixedHAspectRatio(0.f), m_RoundCoordinates(true), m_WrapMode(GL_REPEAT), - m_Effects(NULL), m_Border(false), m_DeltaZ(0.f) + m_Effects(), m_Border(false), m_DeltaZ(0.f) { } - ~SGUIImage() - { - delete m_Effects; - } - // Filename of the texture VfsPath m_TextureName; @@ -106,7 +103,7 @@ public: GLint m_WrapMode; // Visual effects (e.g. color modulation) - SGUIImageEffects* m_Effects; + std::shared_ptr m_Effects; // Color CGUIColor m_BackColor; diff --git a/source/gui/GUIRenderer.cpp b/source/gui/GUIRenderer.cpp index 6ef79fb024..136ecd7c93 100644 --- a/source/gui/GUIRenderer.cpp +++ b/source/gui/GUIRenderer.cpp @@ -106,7 +106,7 @@ void GUIRenderer::UpdateDrawCallCache(const CGUI* pGUI, DrawCalls& Calls, const // Allow grayscale images for disabled portraits if (SpriteName.Find("grayscale:") != -1) { - Image->m_Effects = new SGUIImageEffects; + Image->m_Effects = std::make_shared(); Image->m_Effects->m_Greyscale = true; } @@ -158,7 +158,7 @@ void GUIRenderer::UpdateDrawCallCache(const CGUI* pGUI, DrawCalls& Calls, const if (SpriteName.Find("textureAsMask:") != -1) { Image->m_TextureName = TextureName; - Image->m_Effects = new SGUIImageEffects; + Image->m_Effects = std::make_shared(); Image->m_Effects->m_SolidColor = color; } else