Skip to content

Fix three leaks in the world texture watch - #5301

Open
Flashmyname wants to merge 3 commits into
multitheftauto:masterfrom
Flashmyname:fix/4956-texture-watch-leaks
Open

Fix three leaks in the world texture watch#5301
Flashmyname wants to merge 3 commits into
multitheftauto:masterfrom
Flashmyname:fix/4956-texture-watch-leaks

Conversation

@Flashmyname

Copy link
Copy Markdown

Summary

Three independent leaks in the world-texture watch.

  • OnStreamingAddedTxd dropped queued removed events, so a txd slot reused within one watch period never streamed out and its STexInfo objects were never destroyed.
  • HOOK_CTxdStore_RemoveTxd took the txd id from ESI, which only holds it when the game itself is the caller. CTxdPoolSA::RemoveTextureDictonarySlot calls 0x731E90 directly, so on the engineFreeTXD path the id was unrelated to the slot being released. The function is __cdecl — read the stack argument.
  • m_AllTextureList had no erase site at all: one entry per texture name ever seen, kept for the life of the client.

Motivation

Part of #4956: client memory grows without bound on servers that stream large numbers of custom models.

Test plan

2061 replaced models streaming continuously at the 256 MB limit for 25 minutes, with a second resource creating and destroying world-texture shaders throughout (705 created, 701 destroyed, no crash). Then the same run with only game_sa.dll swapped back:

  • m_AllTextureList decreased 5 times with the fix over 90 samples, and never without — not once in 403 samples over 100 minutes.
  • m_TexInfoMap went from 19423 → 26521 and never decreasing, to 19099 → 19457 and oscillating.

No process-memory reduction is claimed; that comparison is window-dependent.

Checklist

  • Your code should follow the coding guidelines.
  • Smaller pull requests are easier to review. If your pull request is beefy, your pull request should be reviewable commit-by-commit.

Copilot AI lite review requested due to automatic review settings September 1, 2026 08:16

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses three independent memory leaks in the client’s world-texture watch / shader-matching pipeline, reducing unbounded growth when servers stream large numbers of custom models and frequently create/destroy texture shaders (per #4956).

Changes:

  • Fix TXD stream-in event de-duplication so queued removed events aren’t dropped when a TXD slot is reused within the same watch period.
  • Fix the TXD-remove hook to read the TXD id from the __cdecl stack argument (instead of esi) and align the ID normalization with the “added” path.
  • Add a deletion path for m_AllTextureList entries by freeing STexNameInfo when it has no remaining references.

Note for commit hygiene: please ensure the final commit message(s) capture the motivation (leak scenarios), how you validated the hook argument/ABI expectation, and the stress-test conditions/results you used.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
Client/game_sa/CRenderWareSA.ShaderSupport.cpp Corrects TXD streaming event handling and fixes the TXD-remove hook argument source.
Client/game_sa/CRenderWareSA.ShaderMatching.h Adds a helper API to allow STexNameInfo lifetime cleanup.
Client/game_sa/CRenderWareSA.ShaderMatching.cpp Implements and integrates STexNameInfo deletion when unreferenced to prevent m_AllTextureList growth.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

The hook read the id from ESI, which at 0x731E90 still holds whatever the
caller left there. The function is __cdecl with the id at [esp+4]; read
that, and stop subtracting the TXD base since it is already a raw id.

Part of multitheftauto#4956
m_AllTextureList entries were created the first time a texture name was
seen and never freed. Delete one once both of its reference lists are
empty; together they cover every reference that can exist.

Part of multitheftauto#4956
@Flashmyname
Flashmyname force-pushed the fix/4956-texture-watch-leaks branch from 3101ca0 to 27c7e07 Compare September 2, 2026 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants