mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 18:31:55 -04:00
fix refcnt issues with fpsmeter
This commit is contained in:
parent
3546fff47e
commit
ba517a3317
@ -63,7 +63,6 @@ CD3DFont::CD3DFont( TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags ) {
|
||||
// Desc: Font class destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CD3DFont::~CD3DFont() {
|
||||
InvalidateDeviceObjects();
|
||||
DeleteDeviceObjects();
|
||||
}
|
||||
|
||||
@ -124,7 +123,7 @@ HRESULT CD3DFont::InitDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice ) {
|
||||
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
|
||||
VARIABLE_PITCH, m_strFontName );
|
||||
if(NULL==hFont) {
|
||||
cout << "CD3DFont InitDeviceObjects(): initial CreateFont failed! GetLastError=" << GetLastError() << endl;
|
||||
dxgsg_cat.error() << "CD3DFont InitDeviceObjects(): initial CreateFont failed! GetLastError=" << GetLastError() << endl;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
@ -195,7 +194,7 @@ HRESULT CD3DFont::InitDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice ) {
|
||||
|
||||
// moved here to allow deletion of GDI objects
|
||||
if(dwTexSize == 0) {
|
||||
cout << "CD3DFont InitDeviceObjects() error: Texture didnt fit, creation failed!\n";
|
||||
dxgsg_cat.error() << "CD3DFont InitDeviceObjects() error: Texture didnt fit, creation failed!\n";
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
@ -229,7 +228,7 @@ HRESULT CD3DFont::InitDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice ) {
|
||||
VARIABLE_PITCH, m_strFontName );
|
||||
|
||||
if(NULL==hFont) {
|
||||
cout << "CD3DFont InitDeviceObjects(): optimal CreateFont failed! GetLastError=" << GetLastError() << endl;
|
||||
dxgsg_cat.error() << "CD3DFont InitDeviceObjects(): optimal CreateFont failed! GetLastError=" << GetLastError() << endl;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
@ -255,6 +254,7 @@ HRESULT CD3DFont::InitDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice ) {
|
||||
hr = m_pd3dDevice->CreateTexture( m_dwTexWidth, m_dwTexHeight, 1,
|
||||
0, D3DFMT_A4R4G4B4,
|
||||
D3DPOOL_MANAGED, &m_pTexture );
|
||||
|
||||
if(FAILED(hr)) {
|
||||
SelectObject ( hDC, hbmOld );
|
||||
SelectObject ( hDC, hfOld );
|
||||
@ -263,7 +263,7 @@ HRESULT CD3DFont::InitDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice ) {
|
||||
DeleteObject( hFont );
|
||||
DeleteDC( hDC );
|
||||
|
||||
cout << "CD3DFont InitDeviceObjs CreateTexture failed!" << D3DERRORSTRING(hr);
|
||||
dxgsg_cat.error() << "CD3DFont InitDeviceObjs CreateTexture failed!" << D3DERRORSTRING(hr);
|
||||
return hr;
|
||||
};
|
||||
|
||||
@ -341,10 +341,12 @@ HRESULT CD3DFont::RestoreDeviceObjects() {
|
||||
D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0,
|
||||
D3DPOOL_DEFAULT, // D3DUSAGE_DYNAMIC makes D3DPOOL_MANAGED impossible
|
||||
&m_pVB ) )) {
|
||||
cout << "CD3DFont CreateVB failed!" << D3DERRORSTRING(hr);
|
||||
dxgsg_cat.error() << "CD3DFont CreateVB failed!" << D3DERRORSTRING(hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
PRINT_REFCNT(dxgsg,m_pd3dDevice);
|
||||
|
||||
// Create the state blocks for rendering text
|
||||
for(UINT which=0; which<2; which++) {
|
||||
m_pd3dDevice->BeginStateBlock();
|
||||
@ -399,15 +401,26 @@ HRESULT CD3DFont::RestoreDeviceObjects() {
|
||||
// Desc: Destroys all device-dependent objects
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CD3DFont::InvalidateDeviceObjects() {
|
||||
/*
|
||||
#ifdef _DEBUG
|
||||
if(m_pVB) {
|
||||
cout << "XXXX Releasing Font VertexBuffer\n";
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
HRESULT hr;
|
||||
|
||||
SAFE_RELEASE( m_pVB );
|
||||
PRINT_REFCNT(dxgsg,m_pd3dDevice);
|
||||
|
||||
if(IS_VALID_PTR(m_pd3dDevice)) {
|
||||
// undo SetStreamSource before releasing VB
|
||||
|
||||
IDirect3DVertexBuffer8 *pStreamData=NULL;
|
||||
UINT StreamStride;
|
||||
hr = m_pd3dDevice->GetStreamSource(0,&pStreamData,&StreamStride);
|
||||
SAFE_RELEASE(pStreamData); // undo GetStreamSource AddRef
|
||||
if(pStreamData==m_pVB)
|
||||
hr = m_pd3dDevice->SetStreamSource(0,NULL,0);
|
||||
}
|
||||
|
||||
PRINT_REFCNT(dxgsg,m_pVB);
|
||||
|
||||
RELEASE(m_pVB,dxgsg,"d3dfont VB",RELEASE_ONCE);
|
||||
|
||||
PRINT_REFCNT(dxgsg,m_pd3dDevice);
|
||||
|
||||
// Delete the state blocks
|
||||
if(m_pd3dDevice) {
|
||||
@ -418,6 +431,8 @@ HRESULT CD3DFont::InvalidateDeviceObjects() {
|
||||
m_pd3dDevice->DeleteStateBlock( m_dwDrawTextStateBlock );
|
||||
}
|
||||
|
||||
PRINT_REFCNT(dxgsg,m_pd3dDevice);
|
||||
|
||||
m_dwSavedStateBlock = NULL;
|
||||
m_dwDrawTextStateBlock = NULL;
|
||||
|
||||
@ -430,8 +445,14 @@ HRESULT CD3DFont::InvalidateDeviceObjects() {
|
||||
// Desc: Destroys all device-dependent objects
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CD3DFont::DeleteDeviceObjects() {
|
||||
PRINT_REFCNT(dxgsg,m_pd3dDevice);
|
||||
|
||||
InvalidateDeviceObjects();
|
||||
|
||||
SAFE_RELEASE( m_pTexture );
|
||||
|
||||
PRINT_REFCNT(dxgsg,m_pd3dDevice);
|
||||
|
||||
m_pd3dDevice = NULL;
|
||||
|
||||
return S_OK;
|
||||
@ -560,7 +581,7 @@ HRESULT CD3DFont::DeferedDraw
|
||||
FLOAT fXScale, FLOAT fYScale, DWORD dwColor,
|
||||
TCHAR* strText, DWORD dwFlags ) {
|
||||
if(m_nDeferedCalls >= MaxCalls) {
|
||||
cout << "CD3DFont DeferedDraw() error, MaxCalls exceeded!\n";
|
||||
dxgsg_cat.error() << "CD3DFont DeferedDraw() error, MaxCalls exceeded!\n";
|
||||
return E_FAIL ;
|
||||
}
|
||||
|
||||
@ -570,7 +591,7 @@ HRESULT CD3DFont::DeferedDraw
|
||||
int nStrLen = strlen ( strText ) + 1 ;
|
||||
int nUsed = m_pTextBuffer - & m_pTextBuffer [ 0 ] ;
|
||||
if(nUsed + nStrLen > TextBufferLength) {
|
||||
cout << "CD3DFont DeferedDraw() error, TextBufferLength exceeded!\n";
|
||||
dxgsg_cat.error() << "CD3DFont DeferedDraw() error, TextBufferLength exceeded!\n";
|
||||
return E_FAIL ;
|
||||
}
|
||||
|
||||
@ -616,14 +637,17 @@ HRESULT CD3DFont::EndText ( void ) {
|
||||
|
||||
hr = m_pd3dDevice->GetStreamSource(0,&pSavedStreamData,&SavedStreamStride);
|
||||
if(FAILED(hr)) {
|
||||
cout << "CD3DFont EndText GetStreamSource() failed!" << D3DERRORSTRING(hr);
|
||||
dxgsg_cat.error() << "CD3DFont EndText GetStreamSource() failed!" << D3DERRORSTRING(hr);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// undo GetStreamSource AddRef
|
||||
SAFE_RELEASE(pSavedStreamData);
|
||||
|
||||
if((pSavedStreamData!=m_pVB)||(SavedStreamStride!=sizeof(FONT2DVERTEX))) {
|
||||
hr = m_pd3dDevice->SetStreamSource(0,m_pVB,sizeof(FONT2DVERTEX));
|
||||
if(FAILED(hr)) {
|
||||
cout << "CD3DFont EndText initial SetStreamSource() failed!" << D3DERRORSTRING(hr);
|
||||
dxgsg_cat.error() << "CD3DFont EndText initial SetStreamSource() failed!" << D3DERRORSTRING(hr);
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
@ -797,7 +821,7 @@ HRESULT CD3DFont::EndText ( void ) {
|
||||
if(IS_VALID_PTR(pSavedStreamData) && ((pSavedStreamData!=m_pVB)||(SavedStreamStride!=sizeof(FONT2DVERTEX)))) {
|
||||
hr = m_pd3dDevice->SetStreamSource(0,pSavedStreamData,SavedStreamStride);
|
||||
if(FAILED(hr)) {
|
||||
cout << "CD3DFont EndText restore SetStreamSource() failed!" << D3DERRORSTRING(hr);
|
||||
dxgsg_cat.error() << "CD3DFont EndText restore SetStreamSource() failed!" << D3DERRORSTRING(hr);
|
||||
return E_FAIL;
|
||||
}
|
||||
pSavedStreamData->Release();
|
||||
|
@ -387,8 +387,6 @@ reset(void) {
|
||||
// recreate dx objects without modifying gsg state, other than clearing state cache
|
||||
void DXGraphicsStateGuardian::
|
||||
free_dxgsg_objects(void) {
|
||||
ULONG refcnt;
|
||||
|
||||
// dont want a full reset of gsg, just a state clear
|
||||
GraphicsStateGuardian::clear_cached_state(); // want gsg to pass all state settings through
|
||||
|
||||
@ -737,9 +735,14 @@ dx_init(HCURSOR hMouseCursor) {
|
||||
hr=S_OK;
|
||||
SIZE TextRectSize;
|
||||
|
||||
PRINT_REFCNT(dxgsg,scrn.pD3DDevice);
|
||||
_pStatMeterFont = new CD3DFont(_T("Arial"),12,D3DFONT_BOLD);
|
||||
PRINT_REFCNT(dxgsg,scrn.pD3DDevice);
|
||||
if(IS_VALID_PTR(_pStatMeterFont))
|
||||
hr=_pStatMeterFont->InitDeviceObjects(scrn.pD3DDevice);
|
||||
|
||||
PRINT_REFCNT(dxgsg,scrn.pD3DDevice);
|
||||
|
||||
if(IS_VALID_PTR(_pStatMeterFont) && SUCCEEDED(hr)) {
|
||||
// instead of computing offset every frame (could change based on font chars,
|
||||
// do it once here. if we wanted top left corner instead of top right,
|
||||
@ -754,6 +757,8 @@ dx_init(HCURSOR hMouseCursor) {
|
||||
sprintf(fps_msg,FPS_MSG_FORMAT_STR,xsize,ysize,32,800.00f); // 6 == NUM_FPSMETER_LETTERS
|
||||
|
||||
hr = _pStatMeterFont->GetTextExtent(fps_msg,&TextRectSize);
|
||||
|
||||
PRINT_REFCNT(dxgsg,scrn.pD3DDevice);
|
||||
if(SUCCEEDED(hr)) {
|
||||
UINT xsize = scrn.pProps->_xsize;
|
||||
|
||||
@ -777,6 +782,7 @@ dx_init(HCURSOR hMouseCursor) {
|
||||
_current_fps = 0.0f;
|
||||
_start_frame_count = _cur_frame_count = 0;
|
||||
}
|
||||
PRINT_REFCNT(dxgsg,scrn.pD3DDevice);
|
||||
|
||||
// Make sure the DX state matches all of our initial attribute states.
|
||||
PT(DepthTestTransition) dta = new DepthTestTransition;
|
||||
@ -788,6 +794,8 @@ dx_init(HCURSOR hMouseCursor) {
|
||||
dwa->issue(this);
|
||||
cfa->issue(this);
|
||||
ta->issue(this); // no curtextcontext, this does nothing. dx should already be properly inited above anyway
|
||||
|
||||
PRINT_REFCNT(dxgsg,scrn.pD3DDevice);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -3527,7 +3535,6 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
|
||||
|
||||
(void) ConvertD3DSurftoPixBuf(SrcCopyRect,pD3DSurf,pb);
|
||||
|
||||
ULONG refcnt;
|
||||
RELEASE(pD3DSurf,dxgsg,"pD3DSurf",RELEASE_ONCE);
|
||||
|
||||
nassertv(!pb->_image.empty());
|
||||
@ -5644,25 +5651,21 @@ dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled) {
|
||||
if(bAtExitFnEverCalled)
|
||||
return;
|
||||
|
||||
ULONG refcnt;
|
||||
|
||||
// unsafe to do the D3D releases after exit() called, since DLL_PROCESS_DETACH
|
||||
// msg already delivered to d3d.dll and it's unloaded itself
|
||||
if(!bAtExitFnEverCalled) {
|
||||
|
||||
PRINTREFCNT(scrn.pD3DDevice,"exit start IIDirect3DDevice8");
|
||||
PRINT_REFCNT(dxgsg,scrn.pD3DDevice);
|
||||
|
||||
// these 2 calls release ddraw surfaces and vbuffers. unsafe unless not on exit
|
||||
release_all_textures();
|
||||
release_all_geoms();
|
||||
|
||||
PRINT_REFCNT(dxgsg,scrn.pD3DDevice);
|
||||
|
||||
SAFE_DELETE(_pStatMeterFont);
|
||||
|
||||
PRINTREFCNT(scrn.pD3DDevice,"after release_all_textures IDirect3DDevice8");
|
||||
|
||||
|
||||
// RELEASE(_fpsmeter_font_surf,dxgsg,"fpsmeter fontsurf",false);
|
||||
// PRINTREFCNT(scrn.pD3DDevice,"after fpsfont release IDirect3DDevice8");
|
||||
PRINT_REFCNT(dxgsg,scrn.pD3DDevice);
|
||||
|
||||
// Do a safe check for releasing the D3DDEVICE. RefCount should be zero.
|
||||
// if we're called from exit(), scrn.pD3DDevice may already have been released
|
||||
@ -6901,7 +6904,6 @@ End:
|
||||
|
||||
SAFE_DELETE_ARRAY( pcrArrayColor );
|
||||
SAFE_DELETE_ARRAY( pcrArrayMask );
|
||||
ULONG refcnt;
|
||||
RELEASE(pCursorBitmap,dxgsg,"pCursorBitmap",RELEASE_ONCE);
|
||||
return hr;
|
||||
}
|
||||
|
@ -1434,7 +1434,6 @@ IDirect3DTexture8 *DXTextureContext::CreateTexture(DXScreenData &scrn) {
|
||||
return _pD3DTexture8;
|
||||
|
||||
error_exit:
|
||||
ULONG refcnt;
|
||||
|
||||
RELEASE(_pD3DTexture8,dxgsg,"texture",RELEASE_ONCE);
|
||||
return NULL;
|
||||
@ -1496,7 +1495,6 @@ FillDDSurfTexturePixels(void) {
|
||||
}
|
||||
|
||||
exit_FillDDSurf:
|
||||
ULONG refcnt;
|
||||
RELEASE(pMipLevel0,dxgsg,"texture",RELEASE_ONCE);
|
||||
return hr;
|
||||
|
||||
@ -1755,8 +1753,6 @@ DeleteTexture( ) {
|
||||
dxgsg_cat.spam() << "Deleting DX texture for " << _tex->get_name() << "\n";
|
||||
}
|
||||
|
||||
ULONG refcnt;
|
||||
|
||||
RELEASE(_pD3DTexture8,dxgsg,"texture",RELEASE_ONCE);
|
||||
/*
|
||||
#ifdef DEBUG_RELEASES
|
||||
|
@ -79,13 +79,14 @@
|
||||
#define RELEASE_DOWN_TO_ZERO true
|
||||
#define RELEASE_ONCE false
|
||||
|
||||
// #define DEBUG_RELEASES
|
||||
//#define DEBUG_RELEASES
|
||||
|
||||
#ifdef DEBUG_RELEASES
|
||||
#define RELEASE(OBJECT,MODULE,DBGSTR,bDoDownToZero) \
|
||||
if(((OBJECT)!=NULL) && IS_VALID_PTR(OBJECT)) { \
|
||||
#define RELEASE(OBJECT,MODULE,DBGSTR,bDoDownToZero) { \
|
||||
ULONG refcnt; \
|
||||
if(IS_VALID_PTR(OBJECT)) { \
|
||||
refcnt = (OBJECT)->Release(); \
|
||||
MODULE##_cat.debug() << DBGSTR << " released, refcnt = " << refcnt << endl; \
|
||||
MODULE##_cat.debug() << DBGSTR << " released, refcnt = " << refcnt << " at " << __FILE__ << ":" << __LINE__ << endl; \
|
||||
if((bDoDownToZero) && (refcnt>0)) { \
|
||||
MODULE##_cat.warning() << DBGSTR << " released but still has a non-zero refcnt(" << refcnt << "), multi-releasing it down to zero!\n"; \
|
||||
do { \
|
||||
@ -95,12 +96,15 @@
|
||||
(OBJECT) = NULL; \
|
||||
} else { \
|
||||
MODULE##_cat.debug() << DBGSTR << " not released, ptr == NULL" << endl; \
|
||||
}
|
||||
}}
|
||||
|
||||
#define PRINTREFCNT(OBJECT,STR) { (OBJECT)->AddRef(); dxgsg_cat.debug() << STR << " refcnt = " << (OBJECT)->Release() << endl; }
|
||||
#define PRINT_REFCNT(MODULE,p) { ULONG refcnt; (p)->AddRef(); refcnt=(p)->Release(); \
|
||||
MODULE##_cat.debug() << #p << " has refcnt = " << refcnt << " at " << __FILE__ << ":" << __LINE__ << endl; }
|
||||
|
||||
#else
|
||||
#define RELEASE(OBJECT,MODULE,DBGSTR,bDoDownToZero) \
|
||||
if(((OBJECT)!=NULL)&&(!IsBadWritePtr((OBJECT),4))) { \
|
||||
#define RELEASE(OBJECT,MODULE,DBGSTR,bDoDownToZero) { \
|
||||
ULONG refcnt; \
|
||||
if(IS_VALID_PTR(OBJECT)) { \
|
||||
refcnt=(OBJECT)->Release(); \
|
||||
if((bDoDownToZero) && (refcnt>0)) { \
|
||||
MODULE##_cat.warning() << DBGSTR << " released but still has a non-zero refcnt(" << refcnt << "), multi-releasing it down to zero!\n"; \
|
||||
@ -109,9 +113,9 @@
|
||||
} while(refcnt>0); \
|
||||
} \
|
||||
(OBJECT) = NULL; \
|
||||
}
|
||||
}}
|
||||
|
||||
#define PRINTREFCNT(OBJECT,STR)
|
||||
#define PRINT_REFCNT(MODULE,p)
|
||||
#endif
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
|
Loading…
x
Reference in New Issue
Block a user