@@ -21,23 +21,14 @@ extern HINSTANCE g_hModule;
2121
2222namespace
2323{
24+ // Cached static Direct3D pointer for lockless fast-path access
25+ std::atomic<IDirect3D9*> g_cachedStaticDirect3D{nullptr };
26+ std::atomic<bool > g_cachedDirect3DValid{false };
2427
2528IDirect3D9* GetFirstValidTrackedDirect3D (std::vector<IDirect3D9*>& trackedList)
2629{
27- for (auto iter = trackedList.begin (); iter != trackedList.end ();)
28- {
29- IDirect3D9* candidate = *iter;
30- if (candidate && IsValidComInterfacePointer (candidate, ComPtrValidation::ValidationMode::ForceRefresh))
31- return candidate;
32-
33- SString message;
34- message.Format (" CProxyDirect3D9: removing invalid tracked IDirect3D9 pointer %p" , candidate);
35- AddReportLog (8756 , message, 5 );
36- ComPtrValidation::Invalidate (candidate);
37- iter = trackedList.erase (iter);
38- }
39-
40- return nullptr ;
30+ // Return first element without expensive COM validation (called frequently)
31+ return trackedList.empty () ? nullptr : trackedList.front ();
4132}
4233} // unnamed namespace
4334
@@ -56,7 +47,7 @@ CProxyDirect3D9::CProxyDirect3D9(IDirect3D9* pInterface)
5647{
5748 WriteDebugEvent (SString (" CProxyDirect3D9::CProxyDirect3D9 %08x" , this ));
5849
59- if (!IsValidComInterfacePointer (pInterface, ComPtrValidation::ValidationMode::ForceRefresh ))
50+ if (!IsValidComInterfacePointer (pInterface, ComPtrValidation::ValidationMode::Default ))
6051 {
6152 SString message;
6253 message.Format (" CProxyDirect3D9 ctor: received invalid IDirect3D9 pointer %p, proxy will be non-functional" , pInterface);
@@ -71,10 +62,13 @@ CProxyDirect3D9::CProxyDirect3D9(IDirect3D9* pInterface)
7162 // Track this Direct3D9 instance for StaticGetDirect3D() lookups
7263 if (m_pDevice)
7364 {
74- if (IsValidComInterfacePointer (m_pDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
65+ if (IsValidComInterfacePointer (m_pDevice, ComPtrValidation::ValidationMode::Default ))
7566 {
7667 std::lock_guard<std::mutex> lock (ms_Direct3D9ListMutex);
7768 ms_CreatedDirect3D9List.push_back (m_pDevice);
69+ // Update cache for lockless StaticGetDirect3D access
70+ g_cachedStaticDirect3D.store (m_pDevice, std::memory_order_release);
71+ g_cachedDirect3DValid.store (true , std::memory_order_release);
7872 }
7973 else
8074 {
@@ -91,6 +85,8 @@ CProxyDirect3D9::~CProxyDirect3D9()
9185 {
9286 std::lock_guard<std::mutex> lock (ms_Direct3D9ListMutex);
9387 ListRemove (ms_CreatedDirect3D9List, m_pDevice);
88+ // Invalidate cache when removing this device
89+ g_cachedDirect3DValid.store (false , std::memory_order_release);
9490 }
9591 ReleaseInterface (m_pDevice, 8752 );
9692}
@@ -246,8 +242,23 @@ HMONITOR CProxyDirect3D9::StaticGetAdapterMonitor(UINT Adapter)
246242
247243IDirect3D9* CProxyDirect3D9::StaticGetDirect3D ()
248244{
245+ // Fast path: use cached pointer without lock (called frequently)
246+ if (g_cachedDirect3DValid.load (std::memory_order_acquire))
247+ {
248+ IDirect3D9* pDirect3D = g_cachedStaticDirect3D.load (std::memory_order_acquire);
249+ if (pDirect3D)
250+ return pDirect3D;
251+ }
252+
253+ // Slow path: refresh cache under lock
249254 std::lock_guard<std::mutex> lock (ms_Direct3D9ListMutex);
250- return GetFirstValidTrackedDirect3D (ms_CreatedDirect3D9List);
255+ IDirect3D9* pDirect3D = GetFirstValidTrackedDirect3D (ms_CreatedDirect3D9List);
256+ if (pDirect3D)
257+ {
258+ g_cachedStaticDirect3D.store (pDirect3D, std::memory_order_release);
259+ g_cachedDirect3DValid.store (true , std::memory_order_release);
260+ }
261+ return pDirect3D;
251262}
252263
253264HRESULT CProxyDirect3D9::CreateDevice (UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags,
0 commit comments