Skip to content

Commit bff42bc

Browse files
Synchronize changes from 1.6 branch [ci skip]
2566ac6 (Heap) safety fixes in CRenderItemManager::OnLostDevice, CRenderItemManager::SaveDefaultRenderTarget and CRenderItemManager::ChangeRenderTarget
2 parents dea227a + 2566ac6 commit bff42bc

File tree

1 file changed

+79
-20
lines changed

1 file changed

+79
-20
lines changed

Client/core/Graphics/CRenderItemManager.cpp

Lines changed: 79 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -122,15 +122,20 @@ void CRenderItemManager::OnDeviceCreate(IDirect3DDevice9* pDevice, float fViewpo
122122
////////////////////////////////////////////////////////////////
123123
void CRenderItemManager::OnLostDevice()
124124
{
125-
for (std::set<CRenderItem*>::iterator iter = m_CreatedItemList.begin(); iter != m_CreatedItemList.end(); iter++)
126-
(*iter)->OnLostDevice();
125+
for (std::set<CRenderItem*>::iterator iter = m_CreatedItemList.begin(); iter != m_CreatedItemList.end();)
126+
{
127+
std::set<CRenderItem*>::iterator current = iter++;
128+
(*current)->OnLostDevice();
129+
}
127130

128131
SAFE_RELEASE(m_pSavedSceneDepthSurface);
129132
SAFE_RELEASE(m_pSavedSceneRenderTargetAA);
130133
SAFE_RELEASE(g_pDeviceState->MainSceneState.DepthBuffer);
131134
SAFE_RELEASE(m_pNonAARenderTargetTexture);
132135
SAFE_RELEASE(m_pNonAARenderTarget);
133136
SAFE_RELEASE(m_pNonAADepthSurface2);
137+
SAFE_RELEASE(m_pDefaultD3DRenderTarget);
138+
SAFE_RELEASE(m_pDefaultD3DZStencilSurface);
134139
}
135140

136141
////////////////////////////////////////////////////////////////
@@ -594,17 +599,40 @@ bool CRenderItemManager::SaveDefaultRenderTarget()
594599
SaveReadableDepthBuffer();
595600

596601
// Update our info about what rendertarget is active
597-
IDirect3DSurface9* pActiveD3DRenderTarget;
598-
IDirect3DSurface9* pActiveD3DZStencilSurface;
599-
m_pDevice->GetRenderTarget(0, &pActiveD3DRenderTarget);
600-
m_pDevice->GetDepthStencilSurface(&pActiveD3DZStencilSurface);
602+
IDirect3DSurface9* pActiveD3DRenderTarget = nullptr;
603+
const HRESULT hrRenderTarget = m_pDevice->GetRenderTarget(0, &pActiveD3DRenderTarget);
604+
if (FAILED(hrRenderTarget) || !pActiveD3DRenderTarget)
605+
{
606+
SAFE_RELEASE(pActiveD3DRenderTarget);
607+
SAFE_RELEASE(m_pDefaultD3DRenderTarget);
608+
SAFE_RELEASE(m_pDefaultD3DZStencilSurface);
609+
return false;
610+
}
611+
612+
IDirect3DSurface9* pActiveD3DZStencilSurface = nullptr;
613+
const HRESULT hrDepthStencil = m_pDevice->GetDepthStencilSurface(&pActiveD3DZStencilSurface);
614+
if (FAILED(hrDepthStencil) && hrDepthStencil != D3DERR_NOTFOUND)
615+
{
616+
SAFE_RELEASE(pActiveD3DRenderTarget);
617+
SAFE_RELEASE(pActiveD3DZStencilSurface);
618+
SAFE_RELEASE(m_pDefaultD3DRenderTarget);
619+
SAFE_RELEASE(m_pDefaultD3DZStencilSurface);
620+
return false;
621+
}
622+
623+
SAFE_RELEASE(m_pDefaultD3DRenderTarget);
624+
SAFE_RELEASE(m_pDefaultD3DZStencilSurface);
601625

602626
m_pDefaultD3DRenderTarget = pActiveD3DRenderTarget;
627+
if (m_pDefaultD3DRenderTarget)
628+
m_pDefaultD3DRenderTarget->AddRef();
629+
603630
m_pDefaultD3DZStencilSurface = pActiveD3DZStencilSurface;
631+
if (m_pDefaultD3DZStencilSurface)
632+
m_pDefaultD3DZStencilSurface->AddRef();
604633

605-
// Don't hold any refs because it goes all funny during fullscreen minimize/maximize, even if they are released at onLostDevice
606-
SAFE_RELEASE(pActiveD3DRenderTarget)
607-
SAFE_RELEASE(pActiveD3DZStencilSurface)
634+
SAFE_RELEASE(pActiveD3DRenderTarget);
635+
SAFE_RELEASE(pActiveD3DZStencilSurface);
608636

609637
// Do this in case dxSetRenderTarget is being called from some unexpected place
610638
CGraphics::GetSingleton().MaybeEnteringMTARenderZone();
@@ -625,7 +653,8 @@ bool CRenderItemManager::RestoreDefaultRenderTarget()
625653
{
626654
if (ChangeRenderTarget(m_uiDefaultViewportSizeX, m_uiDefaultViewportSizeY, m_pDefaultD3DRenderTarget, m_pDefaultD3DZStencilSurface))
627655
{
628-
m_pDefaultD3DRenderTarget = nullptr;
656+
SAFE_RELEASE(m_pDefaultD3DRenderTarget);
657+
SAFE_RELEASE(m_pDefaultD3DZStencilSurface);
629658

630659
// Do this in case dxSetRenderTarget is being called from some unexpected place
631660
CGraphics::GetSingleton().MaybeLeavingMTARenderZone();
@@ -668,26 +697,53 @@ bool CRenderItemManager::ChangeRenderTarget(uint uiSizeX, uint uiSizeY, IDirect3
668697
SaveReadableDepthBuffer();
669698

670699
// Check if we need to change
671-
IDirect3DSurface9* pCurrentRenderTarget;
672-
IDirect3DSurface9* pCurrentZStencilSurface;
673-
m_pDevice->GetRenderTarget(0, &pCurrentRenderTarget);
674-
m_pDevice->GetDepthStencilSurface(&pCurrentZStencilSurface);
700+
IDirect3DSurface9* pCurrentRenderTarget = nullptr;
701+
HRESULT hrRenderTarget = m_pDevice->GetRenderTarget(0, &pCurrentRenderTarget);
702+
if (FAILED(hrRenderTarget) || !pCurrentRenderTarget)
703+
{
704+
SAFE_RELEASE(pCurrentRenderTarget);
705+
return false;
706+
}
675707

676-
bool bAlreadySet = (pD3DRenderTarget == pCurrentRenderTarget && pD3DZStencilSurface == pCurrentZStencilSurface);
708+
IDirect3DSurface9* pCurrentZStencilSurface = nullptr;
709+
HRESULT hrDepthStencil = m_pDevice->GetDepthStencilSurface(&pCurrentZStencilSurface);
710+
if (FAILED(hrDepthStencil) && hrDepthStencil != D3DERR_NOTFOUND)
711+
{
712+
SAFE_RELEASE(pCurrentRenderTarget);
713+
SAFE_RELEASE(pCurrentZStencilSurface);
714+
return false;
715+
}
677716

678-
SAFE_RELEASE(pCurrentRenderTarget);
679-
SAFE_RELEASE(pCurrentZStencilSurface);
717+
const bool bAlreadySet = (pD3DRenderTarget == pCurrentRenderTarget && pD3DZStencilSurface == pCurrentZStencilSurface);
680718

681-
// Already set?
682719
if (bAlreadySet)
720+
{
721+
SAFE_RELEASE(pCurrentRenderTarget);
722+
SAFE_RELEASE(pCurrentZStencilSurface);
683723
return true;
724+
}
684725

685726
// Tell graphics things are about to change
686727
CGraphics::GetSingleton().OnChangingRenderTarget(uiSizeX, uiSizeY);
687728

688729
// Do change
689-
m_pDevice->SetRenderTarget(0, pD3DRenderTarget);
690-
m_pDevice->SetDepthStencilSurface(pD3DZStencilSurface);
730+
hrRenderTarget = m_pDevice->SetRenderTarget(0, pD3DRenderTarget);
731+
if (FAILED(hrRenderTarget))
732+
{
733+
SAFE_RELEASE(pCurrentRenderTarget);
734+
SAFE_RELEASE(pCurrentZStencilSurface);
735+
return false;
736+
}
737+
738+
HRESULT hrSetDepth = m_pDevice->SetDepthStencilSurface(pD3DZStencilSurface);
739+
if (FAILED(hrSetDepth))
740+
{
741+
m_pDevice->SetRenderTarget(0, pCurrentRenderTarget);
742+
m_pDevice->SetDepthStencilSurface(pCurrentZStencilSurface);
743+
SAFE_RELEASE(pCurrentRenderTarget);
744+
SAFE_RELEASE(pCurrentZStencilSurface);
745+
return false;
746+
}
691747

692748
D3DVIEWPORT9 viewport;
693749
viewport.X = 0;
@@ -698,6 +754,9 @@ bool CRenderItemManager::ChangeRenderTarget(uint uiSizeX, uint uiSizeY, IDirect3
698754
viewport.MaxZ = 1.0f;
699755
m_pDevice->SetViewport(&viewport);
700756

757+
SAFE_RELEASE(pCurrentRenderTarget);
758+
SAFE_RELEASE(pCurrentZStencilSurface);
759+
701760
return true;
702761
}
703762

0 commit comments

Comments
 (0)