Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f91e1de

Browse files
authored
Temporary textures cleanup (#3978)
Fix issue #3977
1 parent 583e675 commit f91e1de

File tree

3 files changed

+61
-7
lines changed

3 files changed

+61
-7
lines changed

‎Client/mods/deathmatch/logic/CClientManager.cpp‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ void CClientManager::DoPulse(bool bDoStandardPulses, bool bDoVehicleManagerPulse
218218
m_pColManager->DoPulse();
219219
m_pGUIManager->DoPulse();
220220
m_pWeaponManager->DoPulse();
221+
m_pRenderElementManager->DoPulse();
221222
}
222223
else
223224
{

‎Client/mods/deathmatch/logic/CClientRenderElementManager.cpp‎

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
#include "StdInc.h"
1212
#include "CClientVectorGraphic.h"
1313

14+
constexpr std::int64_t TEMPORARY_TEXTURES_CLEANUP_PERIOD = 5000ll;
15+
constexpr std::int64_t TEMPORARY_TEXTURES_CLEANUP_THRESHOLD = 10000ll;
16+
constexpr std::size_t TEMPORARY_TEXTURES_DELETE_THRESHOLD = 10u;
17+
1418
////////////////////////////////////////////////////////////////
1519
//
1620
// CClientRenderElementManager::CClientRenderElementManager
@@ -283,20 +287,24 @@ CClientVectorGraphic* CClientRenderElementManager::CreateVectorGraphic(uint widt
283287
CClientTexture* CClientRenderElementManager::FindAutoTexture(const SString& strFullFilePath, const SString& strUniqueName)
284288
{
285289
// Check if we've already done this file
286-
CClientTexture** ppTextureElement = MapFind(m_AutoTextureMap, strUniqueName);
290+
SAutoTexture* ppTextureElement = MapFind(m_AutoTextureMap, strUniqueName);
287291
if (!ppTextureElement)
288292
{
289293
// Try to create
290294
CClientTexture* pNewTextureElement = CreateTexture(strFullFilePath);
291295
if (!pNewTextureElement)
292-
return NULL;
296+
return nullptr;
297+
298+
pNewTextureElement->MakeSystemEntity();
293299

294300
// Add to automap if created
295-
MapSet(m_AutoTextureMap, strUniqueName, pNewTextureElement);
301+
MapSet(m_AutoTextureMap, strUniqueName, SAutoTexture{pNewTextureElement});
296302
ppTextureElement = MapFind(m_AutoTextureMap, strUniqueName);
297303
}
298304

299-
return *ppTextureElement;
305+
ppTextureElement->lastUse = CTickCount::Now();
306+
307+
return ppTextureElement->texture;
300308
}
301309

302310
////////////////////////////////////////////////////////////////
@@ -318,9 +326,9 @@ void CClientRenderElementManager::Remove(CClientRenderElement* pElement)
318326
// Remove from auto texture map
319327
if (pElement->IsA(CClientTexture::GetClassId()))
320328
{
321-
for (std::map<SString, CClientTexture*>::iterator iter = m_AutoTextureMap.begin(); iter != m_AutoTextureMap.end(); ++iter)
329+
for (auto iter = m_AutoTextureMap.begin(); iter != m_AutoTextureMap.end(); ++iter)
322330
{
323-
if (iter->second == pElement)
331+
if (iter->second.texture == pElement)
324332
{
325333
m_AutoTextureMap.erase(iter);
326334
break;
@@ -350,3 +358,39 @@ void CClientRenderElementManager::Remove(CClientRenderElement* pElement)
350358
CRenderItem* pRenderItem = pElement->GetRenderItem();
351359
SAFE_RELEASE(pRenderItem);
352360
}
361+
362+
void CClientRenderElementManager::DoPulse()
363+
{
364+
if (m_texturePulseTimer.Get() < TEMPORARY_TEXTURES_CLEANUP_PERIOD)
365+
return;
366+
367+
m_texturePulseTimer.Reset();
368+
369+
const CTickCount now = CTickCount::Now();
370+
371+
std::vector<CClientTexture*> deleteCandidates;
372+
deleteCandidates.reserve(TEMPORARY_TEXTURES_DELETE_THRESHOLD);
373+
374+
for (const auto& [texName, texInfo] : m_AutoTextureMap)
375+
{
376+
const std::int64_t timeElapsedMs = (now - texInfo.lastUse).ToLongLong();
377+
if (timeElapsedMs < TEMPORARY_TEXTURES_CLEANUP_THRESHOLD)
378+
continue;
379+
380+
CTextureItem* textureItem = texInfo.texture->GetTextureItem();
381+
if (textureItem && textureItem->m_iRefCount > 1)
382+
continue;
383+
384+
// CElementDeleter::Delete causes changes in m_AutoTextureMap
385+
// and we cannot delete a texture while iterating over it
386+
deleteCandidates.push_back(texInfo.texture);
387+
388+
// The deletion procedure can be expensive
389+
// and we're interested in capping on the number of deleted texture at once
390+
if (deleteCandidates.size() == TEMPORARY_TEXTURES_DELETE_THRESHOLD)
391+
break;
392+
}
393+
394+
for (CClientTexture* texture : deleteCandidates)
395+
g_pClientGame->GetElementDeleter()->Delete(texture);
396+
}

‎Client/mods/deathmatch/logic/CClientRenderElementManager.h‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class CClientRenderElementManager
3939
CClientTexture* FindAutoTexture(const SString& strFullFilePath, const SString& strUniqueName);
4040
void Remove(CClientRenderElement* pElement);
4141

42+
void DoPulse();
43+
4244
uint GetDxFontCount() { return m_uiStatsDxFontCount; }
4345
uint GetGuiFontCount() { return m_uiStatsGuiFontCount; }
4446
uint GetTextureCount() { return m_uiStatsTextureCount; }
@@ -49,9 +51,16 @@ class CClientRenderElementManager
4951
uint GetVectorGraphicCount() { return m_uiStatsVectorGraphicCount; }
5052

5153
protected:
54+
struct SAutoTexture
55+
{
56+
CClientTexture* texture{};
57+
CTickCount lastUse;
58+
};
59+
60+
CElapsedTime m_texturePulseTimer;
5261
CClientManager* m_pClientManager;
5362
CRenderItemManagerInterface* m_pRenderItemManager;
54-
std::map<SString, CClientTexture*> m_AutoTextureMap;
63+
std::map<SString, SAutoTexture> m_AutoTextureMap;
5564
std::map<CRenderItem*, CClientRenderElement*> m_ItemElementMap;
5665
uint m_uiStatsGuiFontCount;
5766
uint m_uiStatsDxFontCount;

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /