Prechádzať zdrojové kódy

pstats tracking for texture and vertex data on main memory

David Rose 19 rokov pred
rodič
commit
26b20ce4ac

+ 5 - 0
panda/src/express/Sources.pp

@@ -39,9 +39,11 @@
     patchfile.I patchfile.h \
     pointerTo.I pointerTo.h \
     pointerToArray.I pointerToArray.h \
+    pointerToArrayBase.I pointerToArrayBase.h \
     pointerToBase.I pointerToBase.h \
     pointerToVoid.I pointerToVoid.h \
     profileTimer.I profileTimer.h \
+    pStatCollectorForwardBase.h \
     pta_uchar.h \
     ramfile.I ramfile.h \
     referenceCount.I referenceCount.h \
@@ -95,6 +97,7 @@
     pointerToBase.cxx \
     pointerToVoid.cxx \
     profileTimer.cxx \
+    pStatCollectorForwardBase.cxx \
     pta_uchar.cxx \
     ramfile.cxx \
     referenceCount.cxx \
@@ -152,9 +155,11 @@
     patchfile.I patchfile.h \
     pointerTo.I pointerTo.h \
     pointerToArray.I pointerToArray.h \
+    pointerToArrayBase.I pointerToArrayBase.h \
     pointerToBase.I pointerToBase.h \
     pointerToVoid.I pointerToVoid.h \
     profileTimer.I profileTimer.h \
+    pStatCollectorForwardBase.h \
     pta_uchar.h \
     ramfile.I ramfile.h \
     referenceCount.I referenceCount.h \

+ 1 - 0
panda/src/express/express_composite1.cxx

@@ -30,3 +30,4 @@
 #include "pointerToBase.cxx"
 #include "pointerToVoid.cxx"
 #include "profileTimer.cxx"
+#include "pStatCollectorForwardBase.cxx"

+ 31 - 0
panda/src/express/pStatCollectorForwardBase.cxx

@@ -0,0 +1,31 @@
+// Filename: pStatCollectorForwardBase.cxx
+// Created by:  drose (30Oct06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "pStatCollectorForwardBase.h"
+
+#ifdef DO_PSTATS
+////////////////////////////////////////////////////////////////////
+//     Function: PStatCollectorForwardBase::Destructor
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+PStatCollectorForwardBase::
+~PStatCollectorForwardBase() {
+}
+#endif  // DO_PSTATS
+

+ 45 - 0
panda/src/express/pStatCollectorForwardBase.h

@@ -0,0 +1,45 @@
+// Filename: pStatCollectorForwardBase.h
+// Created by:  drose (30Oct06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef PSTATCOLLECTORFORWARDBASE_H
+#define PSTATCOLLECTORFORWARDBASE_H
+
+#include "pandabase.h"
+#include "referenceCount.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : PStatCollectorForwardBase
+// Description : This class serves as a cheap forward reference to a
+//               PStatCollector, which is defined in the pstatclient
+//               module (and is not directly accessible here in the
+//               express module).
+//
+//               This is subclassed as PStatCollectorForward, which
+//               defines the actual functionality.
+////////////////////////////////////////////////////////////////////
+class PStatCollectorForwardBase : public ReferenceCount {
+PUBLISHED:
+#ifdef DO_PSTATS
+  virtual ~PStatCollectorForwardBase();
+  virtual void add_level(double level)=0;
+#else
+  INLINE void add_level(double level) { }
+#endif
+};
+
+#endif

+ 110 - 30
panda/src/express/pointerToArray.I

@@ -30,11 +30,15 @@ pvector<Element> ConstPointerToArray<Element>::_empty_array;
 template<class Element>
 INLINE PointerToArray<Element>::
 PointerToArray() :
-  PointerToBase<NodeRefCountObj<pvector<Element> > >((NodeRefCountObj<pvector<Element> > *)NULL)
+  PointerToArrayBase<Element>((PointerToArrayElement<Element> *)NULL)
 {
 }
 
-// return an empty array of size n
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArray::empty_array
+//       Access: Published, Static
+//  Description: Return an empty array of size n
+////////////////////////////////////////////////////////////////////
 template<class Element>
 INLINE PointerToArray<Element> 
 PointerToArray<Element>::empty_array(size_type n) {
@@ -52,7 +56,7 @@ PointerToArray<Element>::empty_array(size_type n) {
 template<class Element>
 INLINE PointerToArray<Element>::
 PointerToArray(size_type n, const Element &value) :
-  PointerToBase<NodeRefCountObj<pvector<Element> > >(new NodeRefCountObj<pvector<Element> >) {
+  PointerToArrayBase<Element>(new PointerToArrayElement<Element>) {
   ((To *)(this->_void_ptr))->reserve(n);
   insert(begin(), n, value);
 }
@@ -65,10 +69,44 @@ PointerToArray(size_type n, const Element &value) :
 template<class Element>
 INLINE PointerToArray<Element>::
 PointerToArray(const PointerToArray<Element> &copy) :
-  PointerToBase<NodeRefCountObj<pvector<Element> > >(copy)
+  PointerToArrayBase<Element>(copy)
 {
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArray::get_col
+//       Access: Published
+//  Description: Returns the pointer to the PStatCollector object that
+//               tracks the total allocated size of this buffer.
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE PStatCollectorForwardBase *PointerToArray<Element>::
+get_col() const {
+#ifdef DO_PSTATS
+  if ((this->_void_ptr) != NULL) {
+    return ((To *)(this->_void_ptr))->get_col();
+  }
+#endif  // DO_PSTATS
+  return NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArray::set_col
+//       Access: Published
+//  Description: Changes the pointer to the PStatCollector object that
+//               tracks the total allocated size of this buffer.
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE void PointerToArray<Element>::
+set_col(PStatCollectorForwardBase *col) {
+#ifdef DO_PSTATS
+  if ((this->_void_ptr) == NULL) {
+    reassign(new PointerToArrayElement<Element>);
+  }
+  ((To *)(this->_void_ptr))->set_col(col);
+#endif  // DO_PSTATS
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: PointerToArray::begin
 //       Access: Public
@@ -145,7 +183,7 @@ template<class Element>
 INLINE TYPENAME PointerToArray<Element>::size_type PointerToArray<Element>::
 max_size() const {
   nassertd((this->_void_ptr) != NULL) {
-    ((PointerToArray<Element> *)this)->reassign(new NodeRefCountObj<pvector<Element> >);
+    ((PointerToArray<Element> *)this)->reassign(new PointerToArrayElement<Element>);
   }
   return ((To *)(this->_void_ptr))->max_size();
 }
@@ -170,7 +208,7 @@ template<class Element>
 INLINE void PointerToArray<Element>::
 reserve(TYPENAME PointerToArray<Element>::size_type n) {
   if ((this->_void_ptr) == NULL) {
-    reassign(new NodeRefCountObj<pvector<Element> >);
+    reassign(new PointerToArrayElement<Element>);
   }
   ((To *)(this->_void_ptr))->reserve(n);
 }
@@ -196,7 +234,7 @@ template<class Element>
 INLINE TYPENAME PointerToArray<Element>::reference PointerToArray<Element>::
 front() const {
   nassertd((this->_void_ptr) != NULL) {
-    ((PointerToArray<Element> *)this)->reassign(new NodeRefCountObj<pvector<Element> >);
+    ((PointerToArray<Element> *)this)->reassign(new PointerToArrayElement<Element>);
   }
   nassertd(!((To *)(this->_void_ptr))->empty()) {
     ((To *)(this->_void_ptr))->push_back(Element());
@@ -213,7 +251,7 @@ template<class Element>
 INLINE TYPENAME PointerToArray<Element>::reference PointerToArray<Element>::
 back() const {
   nassertd((this->_void_ptr) != NULL) {
-    ((PointerToArray<Element> *)this)->reassign(new NodeRefCountObj<pvector<Element> >);
+    ((PointerToArray<Element> *)this)->reassign(new PointerToArrayElement<Element>);
   }
   nassertd(!((To *)(this->_void_ptr))->empty()) {
     ((To *)(this->_void_ptr))->push_back(Element());
@@ -230,7 +268,7 @@ template<class Element>
 INLINE TYPENAME PointerToArray<Element>::iterator PointerToArray<Element>::
 insert(iterator position, const Element &x) {
   if ((this->_void_ptr) == NULL) {
-    reassign(new NodeRefCountObj<pvector<Element> >);
+    reassign(new PointerToArrayElement<Element>);
     position = end();
   }
   nassertr(position >= ((To *)(this->_void_ptr))->begin() &&
@@ -247,7 +285,7 @@ template<class Element>
 INLINE void PointerToArray<Element>::
 insert(iterator position, size_type n, const Element &x) {
   if ((this->_void_ptr) == NULL) {
-    reassign(new NodeRefCountObj<pvector<Element> >);
+    reassign(new PointerToArrayElement<Element>);
     position = end();
   }
   nassertv(position >= ((To *)(this->_void_ptr))->begin() &&
@@ -293,7 +331,7 @@ template<class Element>
 INLINE TYPENAME PointerToArray<Element>::reference PointerToArray<Element>::
 operator [](size_type n) const {
   nassertd((this->_void_ptr) != NULL) {
-    ((PointerToArray<Element> *)this)->reassign(new NodeRefCountObj<pvector<Element> >);
+    ((PointerToArray<Element> *)this)->reassign(new PointerToArrayElement<Element>);
   }
   nassertd(!((To *)(this->_void_ptr))->empty()) {
     ((To *)(this->_void_ptr))->push_back(Element());
@@ -354,7 +392,7 @@ template<class Element>
 INLINE void PointerToArray<Element>::
 push_back(const Element &x) {
   if ((this->_void_ptr) == NULL) {
-    reassign(new NodeRefCountObj<pvector<Element> >);
+    reassign(new PointerToArrayElement<Element>);
   }
   ((To *)(this->_void_ptr))->push_back(x);
 }
@@ -368,7 +406,7 @@ template<class Element>
 INLINE void PointerToArray<Element>::
 pop_back() {
   nassertd((this->_void_ptr) != NULL) {
-    ((PointerToArray<Element> *)this)->reassign(new NodeRefCountObj<pvector<Element> >);
+    ((PointerToArray<Element> *)this)->reassign(new PointerToArrayElement<Element>);
   }
   nassertv(!((To *)(this->_void_ptr))->empty());
   ((To *)(this->_void_ptr))->pop_back();
@@ -385,7 +423,7 @@ template<class Element>
 INLINE void PointerToArray<Element>::
 make_empty() {
   nassertd((this->_void_ptr) != NULL) {
-    ((PointerToArray<Element> *)this)->reassign(new NodeRefCountObj<pvector<Element> >);
+    ((PointerToArray<Element> *)this)->reassign(new PointerToArrayElement<Element>);
   }
   nassertv(!((To *)(this->_void_ptr))->empty());
   ((To *)(this->_void_ptr))->clear();
@@ -429,7 +467,7 @@ template<class Element>
 INLINE pvector<Element> &PointerToArray<Element>::
 v() const {
   if ((this->_void_ptr) == NULL) {
-    ((PointerToArray<Element> *)this)->reassign(new NodeRefCountObj<pvector<Element> >);
+    ((PointerToArray<Element> *)this)->reassign(new PointerToArrayElement<Element>);
   }
   return *((To *)(this->_void_ptr));
 }
@@ -488,7 +526,7 @@ template<class Element>
 INLINE void PointerToArray<Element>::
 node_ref() const {
   if ((this->_void_ptr) == NULL) {
-    ((PointerToArray<Element> *)this)->reassign(new NodeRefCountObj<pvector<Element> >);
+    ((PointerToArray<Element> *)this)->reassign(new PointerToArrayElement<Element>);
   }
   ((To *)(this->_void_ptr))->node_ref();
 }
@@ -512,7 +550,7 @@ node_unref() const {
 ////////////////////////////////////////////////////////////////////
 template<class Element>
 INLINE PointerToArray<Element> &PointerToArray<Element>::
-operator = (NodeRefCountObj<pvector<Element> > *ptr) {
+operator = (PointerToArrayElement<Element> *ptr) {
   reassign(ptr);
   return *this;
 }
@@ -539,7 +577,19 @@ operator = (const PointerToArray<Element> &copy) {
 template<class Element>
 INLINE void PointerToArray<Element>::
 clear() {
-  reassign((NodeRefCountObj<pvector<Element> > *)NULL);
+#ifdef DO_PSTATS
+  if ((this->_void_ptr) != NULL) {
+    PT(PStatCollectorForwardBase) col = ((To *)(this->_void_ptr))->get_col();
+    if (col != (PStatCollectorForwardBase *)NULL) {
+      // If we have a PStat counter, preserve it.
+      reassign(new PointerToArrayElement<Element>);
+      ((To *)(this->_void_ptr))->set_col(col);
+      return;
+    }
+  }
+#endif // DO_PSTATS
+
+  reassign((PointerToArrayElement<Element> *)NULL);
 }
 
 
@@ -552,7 +602,7 @@ clear() {
 template<class Element>
 INLINE ConstPointerToArray<Element>::
 ConstPointerToArray() :
-  PointerToBase<NodeRefCountObj<pvector<Element> > >((NodeRefCountObj<pvector<Element> > *)NULL)
+  PointerToArrayBase<Element>((PointerToArrayElement<Element> *)NULL)
 {
 }
 
@@ -564,7 +614,7 @@ ConstPointerToArray() :
 template<class Element>
 INLINE ConstPointerToArray<Element>::
 ConstPointerToArray(const PointerToArray<Element> &copy) :
-  PointerToBase<NodeRefCountObj<pvector<Element> > >(copy)
+  PointerToArrayBase<Element>(copy)
 {
 }
 
@@ -576,10 +626,27 @@ ConstPointerToArray(const PointerToArray<Element> &copy) :
 template<class Element>
 INLINE ConstPointerToArray<Element>::
 ConstPointerToArray(const ConstPointerToArray<Element> &copy) :
-  PointerToBase<NodeRefCountObj<pvector<Element> > >(copy)
+  PointerToArrayBase<Element>(copy)
 {
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ConstPointerToArray::get_col
+//       Access: Published
+//  Description: Returns the pointer to the PStatCollector object that
+//               tracks the total allocated size of this buffer.
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE PStatCollectorForwardBase *ConstPointerToArray<Element>::
+get_col() const {
+#ifdef DO_PSTATS
+  if ((this->_void_ptr) != NULL) {
+    return ((To *)(this->_void_ptr))->get_col();
+  }
+#endif  // DO_PSTATS
+  return NULL;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ConstPointerToArray::begin
 //       Access: Public
@@ -656,7 +723,7 @@ template<class Element>
 INLINE TYPENAME ConstPointerToArray<Element>::size_type ConstPointerToArray<Element>::
 max_size() const {
   nassertd((this->_void_ptr) != NULL) {
-    ((ConstPointerToArray<Element> *)this)->reassign(new NodeRefCountObj<pvector<Element> >);
+    ((ConstPointerToArray<Element> *)this)->reassign(new PointerToArrayElement<Element>);
   }
   return ((To *)(this->_void_ptr))->max_size();
 }
@@ -681,7 +748,7 @@ template<class Element>
 INLINE TYPENAME ConstPointerToArray<Element>::size_type ConstPointerToArray<Element>::
 capacity() const {
   nassertd((this->_void_ptr) != NULL) {
-    ((ConstPointerToArray<Element> *)this)->reassign(new NodeRefCountObj<pvector<Element> >);
+    ((ConstPointerToArray<Element> *)this)->reassign(new PointerToArrayElement<Element>);
   }
   return ((To *)(this->_void_ptr))->capacity();
 }
@@ -695,7 +762,7 @@ template<class Element>
 INLINE TYPENAME ConstPointerToArray<Element>::reference ConstPointerToArray<Element>::
 front() const {
   nassertd((this->_void_ptr) != NULL) {
-    ((ConstPointerToArray<Element> *)this)->reassign(new NodeRefCountObj<pvector<Element> >);
+    ((ConstPointerToArray<Element> *)this)->reassign(new PointerToArrayElement<Element>);
   }
   nassertd(!((To *)(this->_void_ptr))->empty()) {
     ((To *)(this->_void_ptr))->push_back(Element());
@@ -712,7 +779,7 @@ template<class Element>
 INLINE TYPENAME ConstPointerToArray<Element>::reference ConstPointerToArray<Element>::
 back() const {
   nassertd((this->_void_ptr) != NULL) {
-    ((ConstPointerToArray<Element> *)this)->reassign(new NodeRefCountObj<pvector<Element> >);
+    ((ConstPointerToArray<Element> *)this)->reassign(new PointerToArrayElement<Element>);
   }
   nassertd(!((To *)(this->_void_ptr))->empty()) {
     ((To *)(this->_void_ptr))->push_back(Element());
@@ -730,7 +797,7 @@ template<class Element>
 INLINE TYPENAME ConstPointerToArray<Element>::reference ConstPointerToArray<Element>::
 operator [](size_type n) const {
   nassertd((this->_void_ptr) != NULL) {
-    ((ConstPointerToArray<Element> *)this)->reassign(new NodeRefCountObj<pvector<Element> >);
+    ((ConstPointerToArray<Element> *)this)->reassign(new PointerToArrayElement<Element>);
   }
   nassertd(!((To *)(this->_void_ptr))->empty()) {
     ((To *)(this->_void_ptr))->push_back(Element());
@@ -804,7 +871,7 @@ template<class Element>
 INLINE const pvector<Element> &ConstPointerToArray<Element>::
 v() const {
   nassertd((this->_void_ptr) != NULL) {
-    ((ConstPointerToArray<Element> *)this)->reassign(new NodeRefCountObj<pvector<Element> >);
+    ((ConstPointerToArray<Element> *)this)->reassign(new PointerToArrayElement<Element>);
   }
   return *(To *)(this->_void_ptr);
 }
@@ -840,7 +907,7 @@ template<class Element>
 INLINE void ConstPointerToArray<Element>::
 node_ref() const {
   if ((this->_void_ptr) == NULL) {
-    ((ConstPointerToArray<Element> *)this)->reassign(new NodeRefCountObj<pvector<Element> >);
+    ((ConstPointerToArray<Element> *)this)->reassign(new PointerToArrayElement<Element>);
   }
   ((To *)(this->_void_ptr))->node_ref();
 }
@@ -864,7 +931,7 @@ node_unref() const {
 ////////////////////////////////////////////////////////////////////
 template<class Element>
 INLINE ConstPointerToArray<Element> &ConstPointerToArray<Element>::
-operator = (NodeRefCountObj<pvector<Element> > *ptr) {
+operator = (PointerToArrayElement<Element> *ptr) {
   reassign(ptr);
   return *this;
 }
@@ -903,6 +970,19 @@ operator = (const ConstPointerToArray<Element> &copy) {
 template<class Element>
 INLINE void ConstPointerToArray<Element>::
 clear() {
-  reassign((NodeRefCountObj<pvector<Element> > *)NULL);
+#ifdef DO_PSTATS
+  if ((this->_void_ptr) != NULL) {
+    PT(PStatCollectorForwardBase) col = ((To *)(this->_void_ptr))->get_col();
+    if (col != (PStatCollectorForwardBase *)NULL) {
+      // If we have a PStat counter, preserve it.
+      reassign(new PointerToArrayElement<Element>);
+      ((To *)(this->_void_ptr))->set_col(col);
+      return;
+    }
+  }
+
+#else  // DO_PSTATS
+  reassign((PointerToArrayElement<Element> *)NULL);
+#endif // DO_PSTATS
 }
 

+ 12 - 9
panda/src/express/pointerToArray.h

@@ -70,9 +70,7 @@
 
 #include "pandabase.h"
 
-#include "nodeReferenceCount.h"
-#include "pointerTo.h"
-#include "pvector.h"
+#include "pointerToArrayBase.h"
 
 #if defined(WIN32_VC) && !defined(__INTEL_COMPILER)
 // disable mysterious MSVC warning for static inline PTA::empty_array method
@@ -99,9 +97,9 @@
 //               different parts of the system that may not use it.
 ////////////////////////////////////////////////////////////////////
 template <class Element>
-class PointerToArray : public PointerToBase<NodeRefCountObj<pvector<Element> > > {
+class PointerToArray : public PointerToArrayBase<Element> {
 public:
-  typedef TYPENAME PointerToBase<NodeRefCountObj<pvector<Element> > >::To To;
+  typedef TYPENAME PointerToArrayBase<Element>::To To;
   typedef TYPENAME pvector<Element>::value_type value_type;
   typedef TYPENAME pvector<Element>::reference reference;
   typedef TYPENAME pvector<Element>::const_reference const_reference;
@@ -118,6 +116,9 @@ PUBLISHED:
   INLINE PointerToArray(size_type n, const Element &value);
   INLINE PointerToArray(const PointerToArray<Element> &copy);
 
+  INLINE PStatCollectorForwardBase *get_col() const;
+  INLINE void set_col(PStatCollectorForwardBase *col);
+
 public:
   // Duplicating the interface of vector.  The following member
   // functions are all const, because they do not reassign the
@@ -192,7 +193,7 @@ public:
 
   // Reassignment is by pointer, not memberwise as with a vector.
   INLINE PointerToArray<Element> &
-  operator = (NodeRefCountObj<pvector<Element> > *ptr);
+  operator = (PointerToArrayElement<Element> *ptr);
   INLINE PointerToArray<Element> &
   operator = (const PointerToArray<Element> &copy);
   INLINE void clear();
@@ -212,9 +213,9 @@ private:
 //               may not be modified.
 ////////////////////////////////////////////////////////////////////
 template <class Element>
-class ConstPointerToArray : public PointerToBase<NodeRefCountObj<pvector<Element> > > {
+class ConstPointerToArray : public PointerToArrayBase<Element> {
 public:
-  typedef TYPENAME PointerToBase<NodeRefCountObj<pvector<Element> > >::To To;
+  typedef TYPENAME PointerToArrayBase<Element>::To To;
   typedef TYPENAME pvector<Element>::value_type value_type;
   typedef TYPENAME pvector<Element>::const_reference reference;
   typedef TYPENAME pvector<Element>::const_reference const_reference;
@@ -235,6 +236,8 @@ PUBLISHED:
   INLINE ConstPointerToArray(const PointerToArray<Element> &copy);
   INLINE ConstPointerToArray(const ConstPointerToArray<Element> &copy);
 
+  INLINE PStatCollectorForwardBase *get_col() const;
+
 public:
   // Duplicating the interface of vector.
 
@@ -278,7 +281,7 @@ public:
 
   // Reassignment is by pointer, not memberwise as with a vector.
   INLINE ConstPointerToArray<Element> &
-  operator = (NodeRefCountObj<pvector<Element> > *ptr);
+  operator = (PointerToArrayElement<Element> *ptr);
   INLINE ConstPointerToArray<Element> &
   operator = (const PointerToArray<Element> &copy);
   INLINE ConstPointerToArray<Element> &

+ 224 - 0
panda/src/express/pointerToArrayBase.I

@@ -0,0 +1,224 @@
+// Filename: pointerToArrayBase.I
+// Created by:  drose (30Oct06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArrayElement::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE PointerToArrayElement<Element>::
+PointerToArrayElement() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArrayElement::Copy Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE PointerToArrayElement<Element>::
+PointerToArrayElement(const PointerToArrayElement<Element> &copy) :
+  NodeReferenceCount(copy),
+  pvector<Element>(copy)
+{
+#ifdef DO_PSTATS
+  set_col(copy._col);
+#endif  // DO_PSTATS
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArrayElement::Destructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE PointerToArrayElement<Element>::
+~PointerToArrayElement() {
+  adjust_size(size(), 0);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArrayElement::get_col
+//       Access: Public
+//  Description: Returns the pointer to the PStatCollector object that
+//               tracks the total allocated size of this buffer.
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE PStatCollectorForwardBase *PointerToArrayElement<Element>::
+get_col() const {
+#ifdef DO_PSTATS
+  return _col;
+#else
+  return NULL;
+#endif  // DO_PSTATS
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArrayElement::set_col
+//       Access: Public
+//  Description: Changes the pointer to the PStatCollector object that
+//               tracks the total allocated size of this buffer.
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE void PointerToArrayElement<Element>::
+set_col(PStatCollectorForwardBase *col) {
+#ifdef DO_PSTATS
+  if (_col != col) {
+    adjust_size(size(), 0);
+    _col = col;
+    adjust_size(0, size());
+  }
+#endif  // DO_PSTATS
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArrayElement::size
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE TYPENAME PointerToArrayElement<Element>::size_type PointerToArrayElement<Element>::
+size() const {
+  return pvector<Element>::size();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArrayElement::insert
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE TYPENAME PointerToArrayElement<Element>::iterator PointerToArrayElement<Element>::
+insert(iterator position, const Element &x) {
+  adjust_size(0, 1);
+  return pvector<Element>::insert(position, x);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArrayElement::insert
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE void PointerToArrayElement<Element>::
+insert(iterator position, size_type n, const Element &x) {
+  adjust_size(0, n);
+  pvector<Element>::insert(position, n, x);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArrayElement::erase
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE void PointerToArrayElement<Element>::
+erase(iterator position) {
+  adjust_size(1, 0);
+  pvector<Element>::erase(position);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArrayElement::erase
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE void PointerToArrayElement<Element>::
+erase(iterator first, iterator last) {
+  adjust_size(last - first, 0);
+  pvector<Element>::erase(first, last);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArrayElement::pop_back
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE void PointerToArrayElement<Element>::
+pop_back() {
+  adjust_size(1, 0);
+  pvector<Element>::pop_back();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArrayElement::clear
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE void PointerToArrayElement<Element>::
+clear() {
+  adjust_size(size(), 0);
+  pvector<Element>::clear();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArrayElement::adjust_size
+//       Access: Private
+//  Description: This internal function is used to update the
+//               connected PStatCollector (if any) with the change in
+//               size.
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE void PointerToArrayElement<Element>::
+adjust_size(size_t orig_size, size_t new_size) {
+#ifdef DO_PSTATS
+  if (_col != (PStatCollectorForwardBase *)NULL) {
+    _col->add_level((float)new_size - (float)orig_size);
+  }
+#endif  // DO_PSTATS
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArrayBase::Constructor
+//       Access: Protected
+//  Description: 
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE PointerToArrayBase<Element>::
+PointerToArrayBase(PointerToArrayElement<Element> *ptr) :
+  PointerToBase<PointerToArrayElement<Element> >(ptr)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArrayBase::Copy Constructor
+//       Access: Protected
+//  Description: 
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE PointerToArrayBase<Element>::
+PointerToArrayBase(const PointerToArrayBase<Element> &copy) :
+  PointerToBase<PointerToArrayElement<Element> >(copy)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointerToArrayBase::Destructor
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+template<class Element>
+INLINE PointerToArrayBase<Element>::
+~PointerToArrayBase() {
+}
+

+ 21 - 0
panda/src/express/pointerToArrayBase.cxx

@@ -0,0 +1,21 @@
+// Filename: pointerToArrayBase.cxx
+// Created by:  drose (30Oct06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "pointerToArrayBase.h"
+
+EXPCL_PANDA PTASetLevelFunc *pta_set_level = NULL;

+ 104 - 0
panda/src/express/pointerToArrayBase.h

@@ -0,0 +1,104 @@
+// Filename: pointerToArrayBase.h
+// Created by:  drose (30Oct06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef POINTERTOARRAYBASE_H
+#define POINTERTOARRAYBASE_H
+
+#include "pandabase.h"
+#include "pStatCollectorForwardBase.h"
+#include "nodeReferenceCount.h"
+#include "pointerTo.h"
+#include "pvector.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : PointerToArrayElement
+// Description : This defines the object that is actually stored and
+//               reference-counted internally by a PointerToArray.  It
+//               is basically a NodeReferenceCount-capable STL vector.
+//
+//               We use NodeReferenceCount (instead of just
+//               ReferenceCount), which adds node_ref() and
+//               node_unref() to the standard ref() and unref().  This
+//               is particularly useful for GeomVertexArrayData; other
+//               classes may or may not find this additional counter
+//               useful, but since it adds relatively little overhead
+//               (compared with what is presumably a largish array),
+//               we go ahead and add it here, even though it is
+//               inherited by many different parts of the system that
+//               may not use it.
+////////////////////////////////////////////////////////////////////
+template <class Element>
+class PointerToArrayElement : public NodeReferenceCount, public pvector<Element> {
+public:
+  typedef TYPENAME pvector<Element>::iterator iterator;
+  typedef TYPENAME pvector<Element>::size_type size_type;
+
+  INLINE PointerToArrayElement();
+  INLINE PointerToArrayElement(const PointerToArrayElement<Element> &copy);
+  INLINE ~PointerToArrayElement();
+  ALLOC_DELETED_CHAIN(PointerToArrayElement<Element>);
+
+  INLINE PStatCollectorForwardBase *get_col() const;
+  INLINE void set_col(PStatCollectorForwardBase *col);
+
+  INLINE size_type size() const;
+
+  INLINE iterator insert(iterator position, const Element &x);
+  INLINE void insert(iterator position, size_type n, const Element &x);
+
+  INLINE void erase(iterator position);
+  INLINE void erase(iterator first, iterator last);
+
+  INLINE void pop_back();
+  INLINE void clear();
+
+private:
+  INLINE void adjust_size(size_t orig_size, size_t new_size);
+
+#ifdef DO_PSTATS
+  PT(PStatCollectorForwardBase) _col;
+#endif
+};
+
+////////////////////////////////////////////////////////////////////
+//       Class : PointerToArrayBase
+// Description : This is the base class for PointerToArray and
+//               ConstPointerToArray.  Don't try to use it directly;
+//               use either derived class instead.
+//
+//               This extends PointerToBase to be a pointer to a
+//               PointerToArrayElement, above, which is essentially a
+//               reference-counted STL vector.
+////////////////////////////////////////////////////////////////////
+template <class Element>
+class PointerToArrayBase : public PointerToBase<PointerToArrayElement<Element> > {
+public:
+  typedef TYPENAME PointerToBase<PointerToArrayElement<Element> >::To To;
+
+protected:
+  INLINE PointerToArrayBase(PointerToArrayElement<Element> *ptr);
+  INLINE PointerToArrayBase(const PointerToArrayBase<Element> &copy);
+
+PUBLISHED:
+  INLINE ~PointerToArrayBase();
+};
+
+#include "pointerToArrayBase.I"
+
+#endif
+

+ 6 - 0
panda/src/gobj/geomVertexArrayData.cxx

@@ -26,6 +26,8 @@
 
 TypeHandle GeomVertexArrayData::_type_handle;
 
+PT(PStatCollectorForward) GeomVertexArrayData::_vdata_mem_pcollector = new PStatCollectorForward(PStatCollector("Main memory:C++:Vertex Data"));
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomVertexArrayData::Default Constructor
 //       Access: Private
@@ -435,6 +437,7 @@ finalize(BamReader *manager) {
 
   // Now is also the time to node_ref the data.
   cdata->_data.node_ref();
+  cdata->_data.set_col(_vdata_mem_pcollector);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -544,6 +547,7 @@ set_num_rows(int n) {
       _cdata->_data.node_unref();
       _cdata->_data = new_data;
       _cdata->_data.node_ref();
+      _cdata->_data.set_col(GeomVertexArrayData::_vdata_mem_pcollector);
       
     } else {
       // We've got the only reference to the data, so we can change
@@ -582,6 +586,7 @@ modify_data() {
     _cdata->_data = PTA_uchar();
     _cdata->_data.v() = orig_data.v();
     _cdata->_data.node_ref();
+    _cdata->_data.set_col(GeomVertexArrayData::_vdata_mem_pcollector);
   }
   _cdata->_modified = Geom::get_next_modified();
 
@@ -598,5 +603,6 @@ set_data(CPTA_uchar array) {
   _cdata->_data.node_unref();
   _cdata->_data = (PTA_uchar &)array;
   _cdata->_data.node_ref();
+  _cdata->_data.set_col(GeomVertexArrayData::_vdata_mem_pcollector);
   _cdata->_modified = Geom::get_next_modified();
 }

+ 5 - 0
panda/src/gobj/geomVertexArrayData.h

@@ -31,6 +31,8 @@
 #include "cycleDataStageReader.h"
 #include "cycleDataStageWriter.h"
 #include "pipelineCycler.h"
+#include "pStatCollector.h"
+#include "pStatCollectorForward.h"
 #include "pmap.h"
 
 class PreparedGraphicsObjects;
@@ -144,6 +146,9 @@ private:
   typedef CycleDataStageReader<CData> CDStageReader;
   typedef CycleDataStageWriter<CData> CDStageWriter;
 
+private:
+  static PT(PStatCollectorForward) _vdata_mem_pcollector;
+
 public:
   static void register_with_read_factory();
   virtual void write_datagram(BamWriter *manager, Datagram &dg);

+ 9 - 0
panda/src/gobj/texture.cxx

@@ -40,6 +40,7 @@
 
 #include <stddef.h>
 
+PT(PStatCollectorForward) Texture::_tex_mem_pcollector = new PStatCollectorForward(PStatCollector("Main memory:C++:Texture Data"));
 
 TypeHandle Texture::_type_handle;
 
@@ -992,6 +993,7 @@ set_ram_image(PTA_uchar image, Texture::CompressionMode compression,
       _ram_images[0]._page_size != page_size ||
       _ram_image_compression != compression) {
     _ram_images[0]._image = image;
+    _ram_images[0]._image.set_col(_tex_mem_pcollector);
     _ram_images[0]._page_size = page_size;
     _ram_image_compression = compression;
     ++_image_modified;
@@ -1091,6 +1093,7 @@ make_ram_mipmap_image(int n) {
   }
 
   _ram_images[n]._image = PTA_uchar::empty_array(get_expected_ram_mipmap_image_size(n));
+  _ram_images[n]._image.set_col(_tex_mem_pcollector);
   _ram_images[n]._page_size = get_expected_ram_mipmap_page_size(n);
   ++_image_modified;
   return _ram_images[n]._image;
@@ -1122,6 +1125,7 @@ set_ram_mipmap_image(int n, PTA_uchar image, size_t page_size) {
   if (_ram_images[n]._image != image ||
       _ram_images[n]._page_size != page_size) {
     _ram_images[n]._image = image;
+    _ram_images[n]._image.set_col(_tex_mem_pcollector);
     _ram_images[n]._page_size = page_size;
     ++_image_modified;
   }
@@ -2345,6 +2349,7 @@ do_make_ram_image() {
   _ram_images.push_back(RamImage());
   _ram_images[0]._page_size = get_expected_ram_page_size();
   _ram_images[0]._image = PTA_uchar::empty_array(get_expected_ram_image_size());
+  _ram_images[0]._image.set_col(_tex_mem_pcollector);
   _ram_image_compression = CM_off;
 }
 
@@ -2671,6 +2676,7 @@ convert_from_pnmimage(PTA_uchar &image, size_t page_size, int z,
   }
 
   nassertv(p == &image[idx] + page_size);
+  image.set_col(_tex_mem_pcollector);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -2919,6 +2925,7 @@ filter_2d_mipmap_pages(Texture::RamImage &to, const Texture::RamImage &from,
   size_t to_row_size = (size_t)to_x_size * pixel_size;
   to._page_size = (size_t)to_y_size * to_row_size;
   to._image = PTA_uchar::empty_array(to._page_size * _z_size);
+  to._image.set_col(_tex_mem_pcollector);
 
   Filter2DComponent *filter_component = (_component_type == T_unsigned_byte ? &filter_2d_unsigned_byte : filter_2d_unsigned_short);
 
@@ -3015,6 +3022,7 @@ filter_3d_mipmap_level(Texture::RamImage &to, const Texture::RamImage &from,
   size_t to_page_size = (size_t)to_y_size * to_row_size;
   to._page_size = to_page_size;
   to._image = PTA_uchar::empty_array(to_page_size * to_z_size);
+  to._image.set_col(_tex_mem_pcollector);
 
   Filter3DComponent *filter_component = (_component_type == T_unsigned_byte ? &filter_3d_unsigned_byte : filter_3d_unsigned_short);
 
@@ -3419,6 +3427,7 @@ fillin(DatagramIterator &scan, BamReader *manager, bool has_rawdata) {
         image[(int)u_idx] = scan.get_uint8();
       }
       _ram_images[n]._image = image;
+      _ram_images[n]._image.set_col(_tex_mem_pcollector);
     }
     _loaded_from_image = true;
     ++_image_modified;

+ 3 - 0
panda/src/gobj/texture.h

@@ -27,6 +27,7 @@
 #include "internalName.h"
 #include "graphicsStateGuardianBase.h"
 #include "updateSeq.h"
+#include "pStatCollectorForward.h"
 #include "pmap.h"
 
 class PNMImage;
@@ -529,6 +530,8 @@ private:
   typedef pmap<string, PT(TypedReferenceCount) > AuxData;
   AuxData _aux_data;
 
+  static PT(PStatCollectorForward) _tex_mem_pcollector;
+
   // Datagram stuff
 public:
   static void register_with_read_factory();

+ 6 - 0
panda/src/net/connection.cxx

@@ -388,6 +388,12 @@ send_datagram(const NetDatagram &datagram, int tcp_header_size) {
       header.verify_datagram(datagram);
     }
 
+    if (net_cat.is_spam()) {
+      net_cat.spam()
+        << "Sending UDP datagram with " 
+        << bytes_to_send << " bytes to " << (void *)this << "\n";
+    }
+
     PR_Unlock(_write_mutex);
     return check_send_error(result, errcode, bytes_to_send);
   }

+ 5 - 1
panda/src/pstatclient/Sources.pp

@@ -15,6 +15,7 @@
      pStatClientVersion.I  \
      pStatClientVersion.h pStatClientControlMessage.h  \
      pStatCollector.I pStatCollector.h pStatCollectorDef.h  \
+     pStatCollectorForward.I pStatCollectorForward.h \
      pStatFrameData.I pStatFrameData.h pStatProperties.h  \
      pStatServerControlMessage.h pStatThread.I pStatThread.h  \
      pStatTimer.I pStatTimer.h
@@ -23,6 +24,7 @@
      config_pstats.cxx pStatClient.cxx pStatClientImpl.cxx \
      pStatClientVersion.cxx  \
      pStatClientControlMessage.cxx pStatCollectorDef.cxx  \
+     pStatCollectorForward.cxx \
      pStatFrameData.cxx pStatProperties.cxx  \
      pStatServerControlMessage.cxx \
      pStatThread.cxx
@@ -32,7 +34,9 @@
     pStatClientImpl.I pStatClientImpl.h \
     pStatClientVersion.I pStatClientVersion.h \
     pStatClientControlMessage.h pStatCollector.I pStatCollector.h \
-    pStatCollectorDef.h pStatFrameData.I pStatFrameData.h \
+    pStatCollectorDef.h \
+    pStatCollectorForward.I pStatCollectorForward.h \
+    pStatFrameData.I pStatFrameData.h \
     pStatProperties.h \
     pStatServerControlMessage.h pStatThread.I pStatThread.h \
     pStatTimer.I pStatTimer.h

+ 7 - 7
panda/src/pstatclient/pStatClient.cxx

@@ -32,9 +32,9 @@
 #include "thread.h"
 #include "clockObject.h"
 
-PStatCollector PStatClient::_total_size_pcollector("Memory usage");
-PStatCollector PStatClient::_cpp_size_pcollector("Memory usage:C++");
-PStatCollector PStatClient::_interpreter_size_pcollector("Memory usage:Interpreter");
+PStatCollector PStatClient::_total_size_pcollector("Main memory");
+PStatCollector PStatClient::_cpp_size_pcollector("Main memory:C++");
+PStatCollector PStatClient::_interpreter_size_pcollector("Main memory:Interpreter");
 PStatCollector PStatClient::_pstats_pcollector("*:PStats");
 PStatCollector PStatClient::_clock_wait_pcollector("Wait:Clock Wait:Sleep");
 PStatCollector PStatClient::_clock_busy_wait_pcollector("Wait:Clock Wait:Spin");
@@ -730,7 +730,7 @@ clear_level(int collector_index, int thread_index) {
 //               instead, call PStatCollector::set_level().
 ////////////////////////////////////////////////////////////////////
 void PStatClient::
-set_level(int collector_index, int thread_index, float level) {
+set_level(int collector_index, int thread_index, double level) {
 #ifdef _DEBUG
   nassertv(collector_index >= 0 && collector_index < AtomicAdjust::get(_num_collectors));
   nassertv(thread_index >= 0 && thread_index < AtomicAdjust::get(_num_threads));
@@ -763,7 +763,7 @@ set_level(int collector_index, int thread_index, float level) {
 //               instead, call PStatCollector::add_level().
 ////////////////////////////////////////////////////////////////////
 void PStatClient::
-add_level(int collector_index, int thread_index, float increment) {
+add_level(int collector_index, int thread_index, double increment) {
 #ifdef _DEBUG
   nassertv(collector_index >= 0 && collector_index < AtomicAdjust::get(_num_collectors));
   nassertv(thread_index >= 0 && thread_index < AtomicAdjust::get(_num_threads));
@@ -787,7 +787,7 @@ add_level(int collector_index, int thread_index, float increment) {
 //               Normally you would not use this interface directly;
 //               instead, call PStatCollector::get_level().
 ////////////////////////////////////////////////////////////////////
-float PStatClient::
+double PStatClient::
 get_level(int collector_index, int thread_index) const {
 #ifdef _DEBUG
   nassertr(collector_index >= 0 && collector_index < AtomicAdjust::get(_num_collectors), 0.0f);
@@ -798,7 +798,7 @@ get_level(int collector_index, int thread_index) const {
   InternalThread *thread = get_thread_ptr(thread_index);
   MutexHolder holder(thread->_thread_lock);
 
-  float factor = collector->get_def(this, collector_index)->_factor;
+  double factor = collector->get_def(this, collector_index)->_factor;
 
   return collector->_per_thread[thread_index]._level / factor;
 }

+ 4 - 4
panda/src/pstatclient/pStatClient.h

@@ -124,9 +124,9 @@ private:
   void stop(int collector_index, int thread_index, float as_of);
 
   void clear_level(int collector_index, int thread_index);
-  void set_level(int collector_index, int thread_index, float level);
-  void add_level(int collector_index, int thread_index, float increment);
-  float get_level(int collector_index, int thread_index) const;
+  void set_level(int collector_index, int thread_index, double level);
+  void add_level(int collector_index, int thread_index, double increment);
+  double get_level(int collector_index, int thread_index) const;
 
   static void start_clock_wait();
   static void start_clock_busy_wait();
@@ -155,7 +155,7 @@ private:
   public:
     PerThreadData();
     bool _has_level;
-    float _level;
+    double _level;
     int _nested_count;
   };
   typedef pvector<PerThreadData> PerThread;

+ 10 - 3
panda/src/pstatclient/pStatClientImpl.cxx

@@ -45,6 +45,7 @@ PStatClientImpl::
 PStatClientImpl(PStatClient *client) :
   _clock(TrueClock::get_global_ptr()),
   _delta(0.0),
+  _last_frame(0.0),
   _client(client),
   _reader(this, 0),
   _writer(this, pstats_threaded_write ? 1 : 0)
@@ -247,11 +248,12 @@ transmit_frame_data(int thread_index) {
       datagram.add_uint32(thread->_frame_number);
       thread->_frame_data.write_datagram(datagram);
 
+      bool sent;
       if (_writer.is_valid_for_udp(datagram)) {
         if (_udp_count * _udp_count_factor < _tcp_count * _tcp_count_factor) {
           // Send this one as a UDP packet.
           nassertv(_got_udp_port);
-          _writer.send(datagram, _udp_connection, _server);
+          sent = _writer.send(datagram, _udp_connection, _server);
           _udp_count++;
 
           if (_udp_count == 0) {
@@ -262,7 +264,7 @@ transmit_frame_data(int thread_index) {
 
         } else {
           // Send this one as a TCP packet.
-          _writer.send(datagram, _tcp_connection);
+          sent = _writer.send(datagram, _tcp_connection);
           _tcp_count++;
 
           if (_tcp_count == 0) {
@@ -273,7 +275,7 @@ transmit_frame_data(int thread_index) {
         }
 
       } else {
-        _writer.send(datagram, _tcp_connection);
+        sent = _writer.send(datagram, _tcp_connection);
         // If our packets are so large that we must ship them via TCP,
         // then artificially slow down the packet rate even further.
         int packet_ratio =
@@ -283,6 +285,11 @@ transmit_frame_data(int thread_index) {
       }
 
       thread->_next_packet = now + packet_delay;
+
+      if (!sent) {
+        pstats_cat.debug()
+          << "Couldn't send packet.\n";
+      }
     }
   }
 }

+ 14 - 14
panda/src/pstatclient/pStatCollector.I

@@ -218,7 +218,7 @@ clear_level() {
 //               value.  This implicitly calls flush_level().
 ////////////////////////////////////////////////////////////////////
 INLINE void PStatCollector::
-set_level(float level) {
+set_level(double level) {
   _client->set_level(_index, 0, level);
   _level = 0.0f;
 }
@@ -237,7 +237,7 @@ set_level(float level) {
 //               flush_level() is called.
 ////////////////////////////////////////////////////////////////////
 INLINE void PStatCollector::
-add_level(float increment) {
+add_level(double increment) {
   _level += increment;
 }
 
@@ -255,7 +255,7 @@ add_level(float increment) {
 //               flush_level() is called.
 ////////////////////////////////////////////////////////////////////
 INLINE void PStatCollector::
-sub_level(float decrement) {
+sub_level(double decrement) {
   _level -= decrement;
 }
 
@@ -265,7 +265,7 @@ sub_level(float decrement) {
 //  Description: Calls add_level() and immediately calls flush_level().
 ////////////////////////////////////////////////////////////////////
 INLINE void PStatCollector::
-add_level_now(float increment) {
+add_level_now(double increment) {
   add_level(increment);
   flush_level();
 }
@@ -276,7 +276,7 @@ add_level_now(float increment) {
 //  Description: Calls sub_level() and immediately calls flush_level().
 ////////////////////////////////////////////////////////////////////
 INLINE void PStatCollector::
-sub_level_now(float decrement) {
+sub_level_now(double decrement) {
   sub_level(decrement);
   flush_level();
 }
@@ -302,7 +302,7 @@ flush_level() {
 //               collector in the main thread.  This implicitly calls
 //               flush_level().
 ////////////////////////////////////////////////////////////////////
-INLINE float PStatCollector::
+INLINE double PStatCollector::
 get_level() {
   flush_level();
   return _client->get_level(_index, 0);
@@ -333,7 +333,7 @@ clear_thread_level() {
 //               value.
 ////////////////////////////////////////////////////////////////////
 INLINE void PStatCollector::
-set_thread_level(float level) {
+set_thread_level(double level) {
 #ifndef HAVE_THREADS
   _client->set_level(_index, 0, level);
 #else  // HAVE_THREADS
@@ -351,7 +351,7 @@ set_thread_level(float level) {
 //               it is initialized to 0.
 ////////////////////////////////////////////////////////////////////
 INLINE void PStatCollector::
-add_thread_level(float increment) {
+add_thread_level(double increment) {
 #ifndef HAVE_THREADS
   _client->add_level(_index, 0, increment);
 #else  // HAVE_THREADS
@@ -369,7 +369,7 @@ add_thread_level(float increment) {
 //               thread, it is initialized to 0.
 ////////////////////////////////////////////////////////////////////
 INLINE void PStatCollector::
-sub_thread_level(float decrement) {
+sub_thread_level(double decrement) {
 #ifndef HAVE_THREADS
   _client->add_level(_index, 0, -decrement);
 #else  // HAVE_THREADS
@@ -383,7 +383,7 @@ sub_thread_level(float decrement) {
 //  Description: Returns the current level value of the given
 //               collector in the current thread.
 ////////////////////////////////////////////////////////////////////
-INLINE float PStatCollector::
+INLINE double PStatCollector::
 get_thread_level() {
 #ifndef HAVE_THREADS
   return _client->get_level(_index, 0);
@@ -484,7 +484,7 @@ clear_level(const PStatThread &thread) {
 //               value.
 ////////////////////////////////////////////////////////////////////
 INLINE void PStatCollector::
-set_level(const PStatThread &thread, float level) {
+set_level(const PStatThread &thread, double level) {
   _client->set_level(_index, thread._index, level);
 }
 
@@ -498,7 +498,7 @@ set_level(const PStatThread &thread, float level) {
 //               initialized to 0.
 ////////////////////////////////////////////////////////////////////
 INLINE void PStatCollector::
-add_level(const PStatThread &thread, float increment) {
+add_level(const PStatThread &thread, double increment) {
   _client->add_level(_index, thread._index, increment);
 }
 
@@ -512,7 +512,7 @@ add_level(const PStatThread &thread, float increment) {
 //               it is initialized to 0.
 ////////////////////////////////////////////////////////////////////
 INLINE void PStatCollector::
-sub_level(const PStatThread &thread, float decrement) {
+sub_level(const PStatThread &thread, double decrement) {
   _client->add_level(_index, thread._index, -decrement);
 }
 
@@ -521,7 +521,7 @@ sub_level(const PStatThread &thread, float decrement) {
 //       Access: Published
 //  Description: Returns the current level value of the given collector.
 ////////////////////////////////////////////////////////////////////
-INLINE float PStatCollector::
+INLINE double PStatCollector::
 get_level(const PStatThread &thread) {
   return _client->get_level(_index, thread._index);
 }

+ 25 - 25
panda/src/pstatclient/pStatCollector.h

@@ -72,19 +72,19 @@ PUBLISHED:
   INLINE void stop();
 
   INLINE void clear_level();
-  INLINE void set_level(float level);
-  INLINE void add_level(float increment);
-  INLINE void sub_level(float decrement);
-  INLINE void add_level_now(float increment);
-  INLINE void sub_level_now(float decrement);
+  INLINE void set_level(double level);
+  INLINE void add_level(double increment);
+  INLINE void sub_level(double decrement);
+  INLINE void add_level_now(double increment);
+  INLINE void sub_level_now(double decrement);
   INLINE void flush_level();
-  INLINE float get_level();
+  INLINE double get_level();
 
   INLINE void clear_thread_level();
-  INLINE void set_thread_level(float level);
-  INLINE void add_thread_level(float increment);
-  INLINE void sub_thread_level(float decrement);
-  INLINE float get_thread_level();
+  INLINE void set_thread_level(double level);
+  INLINE void add_thread_level(double increment);
+  INLINE void sub_thread_level(double decrement);
+  INLINE double get_thread_level();
 
   INLINE bool is_active(const PStatThread &thread);
   INLINE bool is_started(const PStatThread &thread);
@@ -94,17 +94,17 @@ PUBLISHED:
   INLINE void stop(const PStatThread &thread, float as_of);
 
   INLINE void clear_level(const PStatThread &thread);
-  INLINE void set_level(const PStatThread &thread, float level);
-  INLINE void add_level(const PStatThread &thread, float increment);
-  INLINE void sub_level(const PStatThread &thread, float decrement);
-  INLINE float get_level(const PStatThread &thread);
+  INLINE void set_level(const PStatThread &thread, double level);
+  INLINE void add_level(const PStatThread &thread, double increment);
+  INLINE void sub_level(const PStatThread &thread, double decrement);
+  INLINE double get_level(const PStatThread &thread);
 
   INLINE int get_index() const;
 
 private:
   PStatClient *_client;
   int _index;
-  float _level;
+  double _level;
 
 friend class PStatClient;
 
@@ -121,13 +121,13 @@ PUBLISHED:
   INLINE void stop() { }
 
   INLINE void clear_level() { }
-  INLINE void set_level(float) { }
-  INLINE void add_level(float) { }
-  INLINE void sub_level(float) { }
-  INLINE void add_level_now(float) { }
-  INLINE void sub_level_now(float) { }
+  INLINE void set_level(double) { }
+  INLINE void add_level(double) { }
+  INLINE void sub_level(double) { }
+  INLINE void add_level_now(double) { }
+  INLINE void sub_level_now(double) { }
   INLINE void flush_level() { }
-  INLINE float get_level() { return 0.0; }
+  INLINE double get_level() { return 0.0; }
 
   INLINE bool is_active(const PStatThread &) { return false; }
   INLINE void start(const PStatThread &) { }
@@ -136,10 +136,10 @@ PUBLISHED:
   INLINE void stop(const PStatThread &, float) { }
 
   INLINE void clear_level(const PStatThread &) { }
-  INLINE void set_level(const PStatThread &, float) { }
-  INLINE void add_level(const PStatThread &, float) { }
-  INLINE void sub_level(const PStatThread &, float) { }
-  INLINE float get_level(const PStatThread &) { return 0.0; }
+  INLINE void set_level(const PStatThread &, double) { }
+  INLINE void add_level(const PStatThread &, double) { }
+  INLINE void sub_level(const PStatThread &, double) { }
+  INLINE double get_level(const PStatThread &) { return 0.0; }
 
   INLINE int get_index() const { return 0; }
 

+ 2 - 2
panda/src/pstatclient/pStatCollectorDef.h

@@ -50,8 +50,8 @@ public:
   ColorDef _suggested_color;
   int _sort;
   string _level_units;
-  float _suggested_scale;
-  float _factor;
+  double _suggested_scale;
+  double _factor;
   bool _is_active;
   bool _active_explicitly_set;
 };

+ 32 - 0
panda/src/pstatclient/pStatCollectorForward.I

@@ -0,0 +1,32 @@
+// Filename: pStatCollectorForward.I
+// Created by:  drose (30Oct06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: PStatCollectorForward::Constructor
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE PStatCollectorForward::
+PStatCollectorForward(const PStatCollector &col)
+#ifdef DO_PSTATS
+  : _col(col)
+#endif  // DO_PSTATS
+{
+}
+

+ 32 - 0
panda/src/pstatclient/pStatCollectorForward.cxx

@@ -0,0 +1,32 @@
+// Filename: pStatCollectorForward.cxx
+// Created by:  drose (30Oct06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "pStatCollectorForward.h"
+
+#ifdef DO_PSTATS
+////////////////////////////////////////////////////////////////////
+//     Function: PStatCollectorForward::add_level
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+void PStatCollectorForward::
+add_level(double increment) {
+  _col.add_level_now(increment);
+}
+#endif  // DO_PSTATS
+

+ 47 - 0
panda/src/pstatclient/pStatCollectorForward.h

@@ -0,0 +1,47 @@
+// Filename: pStatCollectorForward.h
+// Created by:  drose (30Oct06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef PSTATCOLLECTORFORWARD_H
+#define PSTATCOLLECTORFORWARD_H
+
+#include "pandabase.h"
+#include "pStatCollectorForwardBase.h"
+#include "pStatCollector.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : PStatCollectorForward
+// Description : This class serves as a cheap forward reference to a
+//               PStatCollector, so that classes that are defined
+//               before the pstats module may access the
+//               PStatCollector.
+////////////////////////////////////////////////////////////////////
+class PStatCollectorForward : public PStatCollectorForwardBase {
+PUBLISHED:
+  INLINE PStatCollectorForward(const PStatCollector &col);
+
+#ifdef DO_PSTATS
+  virtual void add_level(double level);
+
+private:
+  PStatCollector _col;
+#endif
+};
+
+#include "pStatCollectorForward.I"
+
+#endif

+ 3 - 3
panda/src/pstatclient/pStatProperties.cxx

@@ -195,9 +195,9 @@ static LevelCollectorProperties level_properties[] = {
   { 1, "State changes:Transforms",         { 0.2, 0.2, 0.8 } },
   { 1, "State changes:Textures",           { 0.8, 0.2, 0.2 } },
   { 1, "Occlusion test",                   { 0.9, 0.8, 0.3 },  "", 500.0 },
-  { 1, "Memory usage",                     { 0.5, 1.0, 0.5 },  "MB", 64, 1048576 },
-  { 1, "Memory usage:C++",                 { 0.2, 0.2, 1.0 } },
-  { 1, "Memory usage:Interpreter",         { 0.8, 0.2, 0.5 } },
+  { 1, "Main memory",                      { 0.5, 1.0, 0.5 },  "MB", 64, 1048576 },
+  { 1, "Main memory:C++",                  { 0.2, 0.2, 1.0 } },
+  { 1, "Main memory:Interpreter",          { 0.8, 0.2, 0.5 } },
   { 1, "TransformStates",                  { 1.0, 0.5, 0.5 },  "", 5000 },
   { 1, "TransformStates:On nodes",         { 0.2, 0.8, 1.0 } },
   { 1, "TransformStates:Cached",           { 1.0, 0.0, 0.2 } },

+ 1 - 0
panda/src/pstatclient/pstatclient_composite2.cxx

@@ -1,5 +1,6 @@
 
 #include "pStatCollectorDef.cxx"
+#include "pStatCollectorForward.cxx"
 #include "pStatFrameData.cxx"
 #include "pStatProperties.cxx"
 #include "pStatServerControlMessage.cxx"