1010 *****************************************************************************/
1111
1212#include " StdInc.h"
13+ #include " CProxyComHelpers.h"
1314#include " ComPtrValidation.h"
1415#include < dwmapi.h>
16+ #include < mutex>
17+ #include < atomic>
1518#include < resource.h>
1619
1720extern HINSTANCE g_hModule;
1821
1922namespace
2023{
21- template <typename T>
22- void ReleaseInterface (T*& pointer, const char * context = nullptr )
23- {
24- if (!pointer)
25- return ;
26-
27- T* heldPointer = pointer;
28-
29- const bool valid = IsValidComInterfacePointer (pointer, ComPtrValidation::ValidationMode::ForceRefresh);
30-
31- if (valid)
32- {
33- heldPointer->Release ();
34- }
35- else
36- {
37- SString label;
38- label = context ? context : " ReleaseInterface" ;
39- SString message;
40- message.Format (" %s: skipping Release on invalid COM pointer %p" , label.c_str (), heldPointer);
41- AddReportLog (8752 , message, 5 );
42- ComPtrValidation::Invalidate (heldPointer);
43- }
44-
45- pointer = nullptr ;
46- }
47-
48- template <typename T>
49- void ReplaceInterface (T*& destination, T* source, const char * context = nullptr )
50- {
51- if (destination == source)
52- return ;
53-
54- if (source && !IsValidComInterfacePointer (source, ComPtrValidation::ValidationMode::ForceRefresh))
55- {
56- SString label;
57- label = context ? context : " ReplaceInterface" ;
58- SString message;
59- message.Format (" %s: rejected invalid COM pointer %p" , label.c_str (), source);
60- AddReportLog (8753 , message, 5 );
61- return ;
62- }
63-
64- ReleaseInterface (destination, context);
65- destination = source;
66- if (destination)
67- destination->AddRef ();
68- }
6924
7025IDirect3D9* GetFirstValidTrackedDirect3D (std::vector<IDirect3D9*>& trackedList)
7126{
@@ -88,7 +43,9 @@ IDirect3D9* GetFirstValidTrackedDirect3D(std::vector<IDirect3D9*>& trackedList)
8843
8944HRESULT HandleCreateDeviceResult (HRESULT hResult, IDirect3D9* pDirect3D, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags,
9045 D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface);
46+
9147std::vector<IDirect3D9*> ms_CreatedDirect3D9List;
48+ std::mutex ms_Direct3D9ListMutex;
9249bool CreateDeviceSecondCallCheck (HRESULT& hOutResult, IDirect3D9* pDirect3D, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags,
9350 D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface);
9451void ApplyBorderlessColorCorrection (CProxyDirect3DDevice9* proxyDevice, const D3DPRESENT_PARAMETERS& presentationParameters);
@@ -108,15 +65,15 @@ CProxyDirect3D9::CProxyDirect3D9(IDirect3D9* pInterface)
10865 return ;
10966 }
11067
111- // Take ownership of the interface pointer
112- // ReplaceInterface will AddRef(), giving us our own reference
113- // Caller retains their reference
114- ReplaceInterface (m_pDevice, pInterface, " CProxyDirect3D9 ctor" );
68+ pInterface->AddRef ();
69+ m_pDevice = pInterface;
11570
71+ // Track this Direct3D9 instance for StaticGetDirect3D() lookups
11672 if (m_pDevice)
11773 {
11874 if (IsValidComInterfacePointer (m_pDevice, ComPtrValidation::ValidationMode::ForceRefresh))
11975 {
76+ std::lock_guard<std::mutex> lock (ms_Direct3D9ListMutex);
12077 ms_CreatedDirect3D9List.push_back (m_pDevice);
12178 }
12279 else
@@ -131,8 +88,11 @@ CProxyDirect3D9::CProxyDirect3D9(IDirect3D9* pInterface)
13188CProxyDirect3D9::~CProxyDirect3D9 ()
13289{
13390 WriteDebugEvent (SString (" CProxyDirect3D9::~CProxyDirect3D9 %08x" , this ));
134- ListRemove (ms_CreatedDirect3D9List, m_pDevice);
135- ReleaseInterface (m_pDevice, " CProxyDirect3D9 dtor" );
91+ {
92+ std::lock_guard<std::mutex> lock (ms_Direct3D9ListMutex);
93+ ListRemove (ms_CreatedDirect3D9List, m_pDevice);
94+ }
95+ ReleaseInterface (m_pDevice, 8752 );
13696}
13797
13898/* ** IUnknown methods ***/
@@ -150,7 +110,7 @@ HRESULT CProxyDirect3D9::QueryInterface(REFIID riid, void** ppvObj)
150110
151111ULONG CProxyDirect3D9::AddRef ()
152112{
153- LONG lNewRefCount = InterlockedIncrement (& m_lRefCount) ;
113+ LONG lNewRefCount = m_lRefCount. fetch_add ( 1 , std::memory_order_relaxed) + 1 ;
154114
155115 if (m_pDevice)
156116 m_pDevice->AddRef ();
@@ -160,7 +120,7 @@ ULONG CProxyDirect3D9::AddRef()
160120
161121ULONG CProxyDirect3D9::Release ()
162122{
163- LONG lNewRefCount = InterlockedDecrement (& m_lRefCount) ;
123+ LONG lNewRefCount = m_lRefCount. fetch_sub ( 1 , std::memory_order_acq_rel) - 1 ;
164124
165125 if (lNewRefCount < 0 )
166126 {
@@ -276,6 +236,7 @@ HMONITOR CProxyDirect3D9::GetAdapterMonitor(UINT Adapter)
276236
277237HMONITOR CProxyDirect3D9::StaticGetAdapterMonitor (UINT Adapter)
278238{
239+ std::lock_guard<std::mutex> lock (ms_Direct3D9ListMutex);
279240 IDirect3D9* pDirect3D = GetFirstValidTrackedDirect3D (ms_CreatedDirect3D9List);
280241 if (!pDirect3D)
281242 return NULL ;
@@ -285,6 +246,7 @@ HMONITOR CProxyDirect3D9::StaticGetAdapterMonitor(UINT Adapter)
285246
286247IDirect3D9* CProxyDirect3D9::StaticGetDirect3D ()
287248{
249+ std::lock_guard<std::mutex> lock (ms_Direct3D9ListMutex);
288250 return GetFirstValidTrackedDirect3D (ms_CreatedDirect3D9List);
289251}
290252
@@ -393,7 +355,7 @@ HRESULT CProxyDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND
393355 SString message;
394356 message.Format (" CProxyDirect3D9::CreateDevice - rejected invalid IDirect3DDevice9 pointer %p" , pCreatedDevice);
395357 AddReportLog (8755 , message, 5 );
396- ReleaseInterface (pCreatedDevice, " CProxyDirect3D9::CreateDevice invalid return" );
358+ ReleaseInterface (pCreatedDevice, 8755 , " CProxyDirect3D9::CreateDevice invalid return" );
397359 *ppReturnedDeviceInterface = nullptr ;
398360 hResult = D3DERR_INVALIDDEVICE;
399361 }
@@ -607,7 +569,7 @@ HRESULT CreateDeviceInsist(uint uiMinTries, uint uiTimeout, IDirect3D9* pDirect3
607569 SString message;
608570 message.Format (" CreateDeviceInsist: rejected invalid IDirect3DDevice9 pointer %p" , pCreatedDevice);
609571 AddReportLog (8755 , message, 5 );
610- ReleaseInterface (pCreatedDevice, " CreateDeviceInsist invalid return" );
572+ ReleaseInterface (pCreatedDevice, 8755 , " CreateDeviceInsist invalid return" );
611573 *ppReturnedDeviceInterface = nullptr ;
612574 hResult = D3DERR_INVALIDDEVICE;
613575 }
@@ -889,7 +851,7 @@ void AddCapsReport(UINT Adapter, IDirect3D9* pDirect3D, IDirect3DDevice9* pD3DDe
889851 }
890852 }
891853
892- ReleaseInterface (pDirect3DOther, " AddCapsReport GetDirect3D" );
854+ ReleaseInterface (pDirect3DOther, 8799 , " AddCapsReport GetDirect3D" );
893855
894856 // Get caps from D3D
895857 D3DCAPS9 D3DCaps9;
@@ -923,7 +885,7 @@ void AddCapsReport(UINT Adapter, IDirect3D9* pDirect3D, IDirect3DDevice9* pD3DDe
923885 VertexElements[0 ].Type = DeclTypesList[i].VertexType ;
924886 IDirect3DVertexDeclaration9* pD3DVertexDecl = nullptr ;
925887 hr = pD3DDevice9->CreateVertexDeclaration (VertexElements, &pD3DVertexDecl);
926- ReleaseInterface (pD3DVertexDecl, " AddCapsReport CreateVertexDeclaration" );
888+ ReleaseInterface (pD3DVertexDecl, 8799 , " AddCapsReport CreateVertexDeclaration" );
927889
928890 // Check against device caps
929891 bool bCapsSaysOk = (DeviceCaps9.DeclTypes & DeclTypesList[i].CapsType ) ? true : false ;
@@ -1073,7 +1035,7 @@ HRESULT HandleCreateDeviceResult(HRESULT hResult, IDirect3D9* pDirect3D, UINT Ad
10731035 SString message;
10741036 message.Format (" HandleCreateDeviceResult: rejected invalid IDirect3DDevice9 pointer %p" , pCreatedDevice);
10751037 AddReportLog (8755 , message, 5 );
1076- ReleaseInterface (pCreatedDevice, " HandleCreateDeviceResult invalid return" );
1038+ ReleaseInterface (pCreatedDevice, 8755 , " HandleCreateDeviceResult invalid return" );
10771039 *ppReturnedDeviceInterface = nullptr ;
10781040 hResult = D3DERR_INVALIDDEVICE;
10791041 }
@@ -1205,7 +1167,7 @@ void CCore::OnPreCreateDevice(IDirect3D9* pDirect3D, UINT Adapter, D3DDEVTYPE De
12051167 WriteDebugEvent (ToString (Adapter, DeviceType, hFocusWindow, BehaviorFlags, *pPresentationParameters));
12061168 IDirect3DDevice9* pReturnedDeviceInterface = NULL ;
12071169 HRESULT hResult = pDirect3D->CreateDevice (Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, &pReturnedDeviceInterface);
1208- ReleaseInterface (pReturnedDeviceInterface, " CCore::OnPreCreateDevice temp release" );
1170+ ReleaseInterface (pReturnedDeviceInterface, 8799 , " CCore::OnPreCreateDevice temp release" );
12091171 WriteDebugEvent (SString (" Unmodified result is: %08x" , hResult));
12101172 }
12111173
@@ -1285,7 +1247,7 @@ HRESULT CCore::OnPostCreateDevice(HRESULT hResult, IDirect3D9* pDirect3D, UINT A
12851247
12861248 AddCapsReport (Adapter, pDirect3D, pDevice, false );
12871249
1288- ReleaseInterface (pDevice, " CCore::OnPostCreateDevice temp release" );
1250+ ReleaseInterface (pDevice, 8799 , " CCore::OnPostCreateDevice temp release" );
12891251 *ppReturnedDeviceInterface = pDevice;
12901252
12911253 //
@@ -1328,7 +1290,7 @@ HRESULT CCore::OnPostCreateDevice(HRESULT hResult, IDirect3D9* pDirect3D, UINT A
13281290 {
13291291 AddReportLog (8755 ,
13301292 SString (" CCore::OnPostCreateDevice: rejected invalid IDirect3DDevice9 pointer %p" , pCreatedDevice), 5 );
1331- ReleaseInterface (pCreatedDevice, " CCore::OnPostCreateDevice invalid return" );
1293+ ReleaseInterface (pCreatedDevice, 8755 , " CCore::OnPostCreateDevice invalid return" );
13321294 *ppReturnedDeviceInterface = nullptr ;
13331295 hResult = D3DERR_INVALIDDEVICE;
13341296 }
0 commit comments