Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Client/mods/deathmatch/logic/CClientManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ void CClientManager::DoPulse(bool bDoStandardPulses, bool bDoVehicleManagerPulse
m_pColManager->DoPulse();
m_pGUIManager->DoPulse();
m_pWeaponManager->DoPulse();
m_pRenderElementManager->DoPulse();
}
else
{
Expand Down
56 changes: 50 additions & 6 deletions Client/mods/deathmatch/logic/CClientRenderElementManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#include "StdInc.h"
#include "CClientVectorGraphic.h"

constexpr std::int64_t TEMPORARY_TEXTURES_CLEANUP_PERIOD = 5000ll;
constexpr std::int64_t TEMPORARY_TEXTURES_CLEANUP_THRESHOLD = 10000ll;
constexpr std::size_t TEMPORARY_TEXTURES_DELETE_THRESHOLD = 10u;

////////////////////////////////////////////////////////////////
//
// CClientRenderElementManager::CClientRenderElementManager
Expand Down Expand Up @@ -283,20 +287,24 @@ CClientVectorGraphic* CClientRenderElementManager::CreateVectorGraphic(uint widt
CClientTexture* CClientRenderElementManager::FindAutoTexture(const SString& strFullFilePath, const SString& strUniqueName)
{
// Check if we've already done this file
CClientTexture** ppTextureElement = MapFind(m_AutoTextureMap, strUniqueName);
SAutoTexture* ppTextureElement = MapFind(m_AutoTextureMap, strUniqueName);
if (!ppTextureElement)
{
// Try to create
CClientTexture* pNewTextureElement = CreateTexture(strFullFilePath);
if (!pNewTextureElement)
return NULL;
return nullptr;

pNewTextureElement->MakeSystemEntity();

// Add to automap if created
MapSet(m_AutoTextureMap, strUniqueName, pNewTextureElement);
MapSet(m_AutoTextureMap, strUniqueName, SAutoTexture{pNewTextureElement});
ppTextureElement = MapFind(m_AutoTextureMap, strUniqueName);
}

return *ppTextureElement;
ppTextureElement->lastUse = CTickCount::Now();

return ppTextureElement->texture;
}

////////////////////////////////////////////////////////////////
Expand All @@ -318,9 +326,9 @@ void CClientRenderElementManager::Remove(CClientRenderElement* pElement)
// Remove from auto texture map
if (pElement->IsA(CClientTexture::GetClassId()))
{
for (std::map<SString, CClientTexture*>::iterator iter = m_AutoTextureMap.begin(); iter != m_AutoTextureMap.end(); ++iter)
for (auto iter = m_AutoTextureMap.begin(); iter != m_AutoTextureMap.end(); ++iter)
{
if (iter->second == pElement)
if (iter->second.texture == pElement)
{
m_AutoTextureMap.erase(iter);
break;
Expand Down Expand Up @@ -350,3 +358,39 @@ void CClientRenderElementManager::Remove(CClientRenderElement* pElement)
CRenderItem* pRenderItem = pElement->GetRenderItem();
SAFE_RELEASE(pRenderItem);
}

void CClientRenderElementManager::DoPulse()
{
if (m_texturePulseTimer.Get() < TEMPORARY_TEXTURES_CLEANUP_PERIOD)
return;

m_texturePulseTimer.Reset();

const CTickCount now = CTickCount::Now();

std::vector<CClientTexture*> deleteCandidates;
deleteCandidates.reserve(TEMPORARY_TEXTURES_DELETE_THRESHOLD);

for (const auto& [texName, texInfo] : m_AutoTextureMap)
{
const std::int64_t timeElapsedMs = (now - texInfo.lastUse).ToLongLong();
if (timeElapsedMs < TEMPORARY_TEXTURES_CLEANUP_THRESHOLD)
continue;

CTextureItem* textureItem = texInfo.texture->GetTextureItem();
if (textureItem && textureItem->m_iRefCount > 1)
continue;

// CElementDeleter::Delete causes changes in m_AutoTextureMap
// and we cannot delete a texture while iterating over it
deleteCandidates.push_back(texInfo.texture);

// The deletion procedure can be expensive
// and we're interested in capping on the number of deleted texture at once
if (deleteCandidates.size() == TEMPORARY_TEXTURES_DELETE_THRESHOLD)
break;
}

for (CClientTexture* texture : deleteCandidates)
g_pClientGame->GetElementDeleter()->Delete(texture);
}
11 changes: 10 additions & 1 deletion Client/mods/deathmatch/logic/CClientRenderElementManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class CClientRenderElementManager
CClientTexture* FindAutoTexture(const SString& strFullFilePath, const SString& strUniqueName);
void Remove(CClientRenderElement* pElement);

void DoPulse();

uint GetDxFontCount() { return m_uiStatsDxFontCount; }
uint GetGuiFontCount() { return m_uiStatsGuiFontCount; }
uint GetTextureCount() { return m_uiStatsTextureCount; }
Expand All @@ -49,9 +51,16 @@ class CClientRenderElementManager
uint GetVectorGraphicCount() { return m_uiStatsVectorGraphicCount; }

protected:
struct SAutoTexture
{
CClientTexture* texture{};
CTickCount lastUse;
};

CElapsedTime m_texturePulseTimer;
CClientManager* m_pClientManager;
CRenderItemManagerInterface* m_pRenderItemManager;
std::map<SString, CClientTexture*> m_AutoTextureMap;
std::map<SString, SAutoTexture> m_AutoTextureMap;
std::map<CRenderItem*, CClientRenderElement*> m_ItemElementMap;
uint m_uiStatsGuiFontCount;
uint m_uiStatsDxFontCount;
Expand Down
Loading