@@ -21,23 +21,14 @@ extern HINSTANCE g_hModule;
21
21
22
22
namespace
23
23
{
24
+ // Cached static Direct3D pointer for lockless fast-path access
25
+ std::atomic<IDirect3D9*> g_cachedStaticDirect3D{nullptr };
26
+ std::atomic<bool > g_cachedDirect3DValid{false };
24
27
25
28
IDirect3D9* GetFirstValidTrackedDirect3D (std::vector<IDirect3D9*>& trackedList)
26
29
{
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 ();
41
32
}
42
33
} // unnamed namespace
43
34
@@ -56,7 +47,7 @@ CProxyDirect3D9::CProxyDirect3D9(IDirect3D9* pInterface)
56
47
{
57
48
WriteDebugEvent (SString (" CProxyDirect3D9::CProxyDirect3D9 %08x" , this ));
58
49
59
- if (!IsValidComInterfacePointer (pInterface, ComPtrValidation::ValidationMode::ForceRefresh ))
50
+ if (!IsValidComInterfacePointer (pInterface, ComPtrValidation::ValidationMode::Default ))
60
51
{
61
52
SString message;
62
53
message.Format (" CProxyDirect3D9 ctor: received invalid IDirect3D9 pointer %p, proxy will be non-functional" , pInterface);
@@ -71,10 +62,13 @@ CProxyDirect3D9::CProxyDirect3D9(IDirect3D9* pInterface)
71
62
// Track this Direct3D9 instance for StaticGetDirect3D() lookups
72
63
if (m_pDevice)
73
64
{
74
- if (IsValidComInterfacePointer (m_pDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
65
+ if (IsValidComInterfacePointer (m_pDevice, ComPtrValidation::ValidationMode::Default ))
75
66
{
76
67
std::lock_guard<std::mutex> lock (ms_Direct3D9ListMutex);
77
68
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);
78
72
}
79
73
else
80
74
{
@@ -91,6 +85,8 @@ CProxyDirect3D9::~CProxyDirect3D9()
91
85
{
92
86
std::lock_guard<std::mutex> lock (ms_Direct3D9ListMutex);
93
87
ListRemove (ms_CreatedDirect3D9List, m_pDevice);
88
+ // Invalidate cache when removing this device
89
+ g_cachedDirect3DValid.store (false , std::memory_order_release);
94
90
}
95
91
ReleaseInterface (m_pDevice, 8752 );
96
92
}
@@ -246,8 +242,23 @@ HMONITOR CProxyDirect3D9::StaticGetAdapterMonitor(UINT Adapter)
246
242
247
243
IDirect3D9* CProxyDirect3D9::StaticGetDirect3D ()
248
244
{
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
249
254
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;
251
262
}
252
263
253
264
HRESULT CProxyDirect3D9::CreateDevice (UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags,
0 commit comments