Fix reference counting for GameOverlayRenderer (Steam Overlay)

This commit is contained in:
Robert Krawczyk 2021-03-20 17:38:59 +01:00
parent 308d4a9464
commit e9bbbf04b5
2 changed files with 36 additions and 54 deletions

View file

@ -9,25 +9,29 @@ interface hkIDirect3D9 final : public IDirect3D9 {
public: public:
// original interface // original interface
STDMETHOD(QueryInterface)(REFIID riid, void** ppvObj); STDMETHOD(QueryInterface)(REFIID riid, void** ppvObj);
ULONG STDMETHODCALLTYPE AddRef() { ULONG STDMETHODCALLTYPE AddRef() {
uint32_t refCount = m_refCount++; m_refPrivate++;
if (!refCount) m_refCount = m_pWrapped->AddRef();
AddRefPrivate(); if (m_refCount > m_refPrivate) {
return refCount + 1; // you should not see this ever
} PrintLog("WARNING: Internal reference counting to low, adjusting %u->%u", m_refPrivate.load(), m_refCount.load());
m_refPrivate = m_refCount + 1;
}
ULONG STDMETHODCALLTYPE Release() { return m_refCount + 1;
ULONG refCount = this->m_refCount; }
if (refCount != 0ul) {
this->m_refCount--;
refCount--;
if (refCount == 0ul) ULONG STDMETHODCALLTYPE Release() {
this->ReleasePrivate(); if (m_refPrivate == 0ul)
} delete this;
return refCount; if (m_refPrivate != 0ul) {
} m_refPrivate--;
m_refCount = m_pWrapped->Release();
}
return m_refCount + 1;
}
STDMETHOD(RegisterSoftwareDevice)(void* pInitializeFunction); STDMETHOD(RegisterSoftwareDevice)(void* pInitializeFunction);
STDMETHOD_(UINT, GetAdapterCount)(); STDMETHOD_(UINT, GetAdapterCount)();
STDMETHOD(GetAdapterIdentifier)(UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9* pIdentifier); STDMETHOD(GetAdapterIdentifier)(UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9* pIdentifier);
@ -47,7 +51,6 @@ public:
hkIDirect3D9(IDirect3D9* pIDirect3D9) hkIDirect3D9(IDirect3D9* pIDirect3D9)
: m_pWrapped(pIDirect3D9) : m_pWrapped(pIDirect3D9)
{ {
m_pWrapped->AddRef();
} }
virtual ~hkIDirect3D9(){while (m_pWrapped->Release());} virtual ~hkIDirect3D9(){while (m_pWrapped->Release());}
@ -57,18 +60,6 @@ private:
IDirect3D9* m_pWrapped; IDirect3D9* m_pWrapped;
std::atomic<uint32_t> m_refCount = { 0ul }; std::atomic<uint32_t> m_refCount = { 0ul };
std::atomic<uint32_t> m_refPrivate = { 1ul }; std::atomic<uint32_t> m_refPrivate = { 1ul };
void AddRefPrivate() {
++m_refPrivate;
}
void ReleasePrivate() {
uint32_t refPrivate = --m_refPrivate;
if (!refPrivate) {
m_refPrivate += 0x80000000;
delete this;
}
}
}; };

View file

@ -9,23 +9,27 @@ public:
// original interface // original interface
STDMETHOD(QueryInterface)(REFIID riid, void** ppvObj); STDMETHOD(QueryInterface)(REFIID riid, void** ppvObj);
ULONG STDMETHODCALLTYPE AddRef() { ULONG STDMETHODCALLTYPE AddRef() {
uint32_t refCount = m_refCount++; m_refPrivate++;
if (!refCount) m_refCount = m_pWrapped->AddRef();
AddRefPrivate(); if (m_refCount > m_refPrivate) {
return refCount + 1; // you should not see this ever
PrintLog("WARNING: Internal reference counting to low, adjusting %u->%u", m_refPrivate.load(), m_refCount.load());
m_refPrivate = m_refCount + 1;
}
return m_refCount + 1;
} }
ULONG STDMETHODCALLTYPE Release() { ULONG STDMETHODCALLTYPE Release() {
ULONG refCount = this->m_refCount; if (m_refPrivate == 0ul)
if (refCount != 0ul) { delete this;
this->m_refCount--;
refCount--;
if (refCount == 0ul) if (m_refPrivate != 0ul) {
this->ReleasePrivate(); m_refPrivate--;
m_refCount = m_pWrapped->Release();
} }
return m_refCount + 1;
return refCount;
} }
STDMETHOD(TestCooperativeLevel)(); STDMETHOD(TestCooperativeLevel)();
STDMETHOD_(UINT, GetAvailableTextureMem)(); STDMETHOD_(UINT, GetAvailableTextureMem)();
@ -147,7 +151,6 @@ public:
hkIDirect3DDevice9(IDirect3DDevice9* pIDirect3DDevice9) hkIDirect3DDevice9(IDirect3DDevice9* pIDirect3DDevice9)
: m_pWrapped(pIDirect3DDevice9) : m_pWrapped(pIDirect3DDevice9)
{ {
m_pWrapped->AddRef();
} }
virtual ~hkIDirect3DDevice9() { while (m_pWrapped->Release()); } virtual ~hkIDirect3DDevice9() { while (m_pWrapped->Release()); }
@ -156,17 +159,5 @@ private:
IDirect3DDevice9* m_pWrapped; IDirect3DDevice9* m_pWrapped;
std::atomic<uint32_t> m_refCount = { 0ul }; std::atomic<uint32_t> m_refCount = { 0ul };
std::atomic<uint32_t> m_refPrivate = { 1ul }; std::atomic<uint32_t> m_refPrivate = { 1ul };
void AddRefPrivate() {
++m_refPrivate;
}
void ReleasePrivate() {
uint32_t refPrivate = --m_refPrivate;
if (!refPrivate) {
m_refPrivate += 0x80000000;
delete this;
}
}
}; };