Browse Source

fix refcnt issues with fpsmeter

cxgeorge 24 years ago
parent
commit
ba517a3317

+ 42 - 18
panda/src/dxgsg8/d3dfont8.cxx

@@ -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";
+    HRESULT hr;
+
+    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);
     }
-    #endif
-    */
 
-    SAFE_RELEASE( m_pVB );
+    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();

+ 14 - 12
panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx

@@ -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();
 
-        SAFE_DELETE(_pStatMeterFont);
-
-        PRINTREFCNT(scrn.pD3DDevice,"after release_all_textures IDirect3DDevice8");
+        PRINT_REFCNT(dxgsg,scrn.pD3DDevice);
 
+        SAFE_DELETE(_pStatMeterFont);
 
-//        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;
 }

+ 0 - 4
panda/src/dxgsg8/dxTextureContext8.cxx

@@ -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

+ 14 - 10
panda/src/dxgsg8/dxgsg8base.h

@@ -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