Selaa lähdekoodia

more caching/munger optimizations

David Rose 21 vuotta sitten
vanhempi
sitoutus
699fe45d8b

+ 12 - 0
panda/src/dxgsg8/dxGeomMunger8.I

@@ -27,3 +27,15 @@ DXGeomMunger8(GraphicsStateGuardian *gsg, const RenderState *state) :
   ColorMunger(gsg, state, 1, qpGeomVertexDataType::NT_packed_argb)
 {
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXGeomMunger8::operator new
+//       Access: Public
+//  Description: Calls up to do_operator_new() to implement the
+//               low-overhead allocation/deallocation for this type of
+//               GeomMunger.
+////////////////////////////////////////////////////////////////////
+INLINE void *DXGeomMunger8::
+operator new(size_t size) {
+  return do_operator_new(size, _deleted_chain);
+}

+ 1 - 0
panda/src/dxgsg8/dxGeomMunger8.cxx

@@ -18,6 +18,7 @@
 
 #include "dxGeomMunger8.h"
 
+qpGeomMunger *DXGeomMunger8::_deleted_chain = NULL;
 TypeHandle DXGeomMunger8::_type_handle;
 
 ////////////////////////////////////////////////////////////////////

+ 6 - 0
panda/src/dxgsg8/dxGeomMunger8.h

@@ -40,6 +40,12 @@ protected:
   virtual void munge_geom_impl(CPT(qpGeom) &geom, CPT(qpGeomVertexData) &data);
   virtual int compare_to_impl(const qpGeomMunger *other) const;
 
+public:
+  INLINE void *operator new(size_t size);
+
+private:
+  static qpGeomMunger *_deleted_chain;
+
 public:
   static TypeHandle get_class_type() {
     return _type_handle;

+ 7 - 3
panda/src/glstuff/glGeomContext_src.cxx

@@ -28,7 +28,7 @@ CLP(GeomContext)::
   nassertv(_display_lists.empty());
 }
 
-////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
 //     Function: CLP(GeomContext)::get_display_list
 //       Access: Public
 //  Description: Looks up the display list index associated with the
@@ -46,7 +46,9 @@ get_display_list(GLuint &index, const CLP(GeomMunger) *munger,
   if (dl._index == 0) {
     dl._index = GLP(GenLists)(1);    
     list_current = false;
-    ((CLP(GeomMunger) *)munger)->_geom_contexts.insert(this);
+    if (munger != (CLP(GeomMunger) *)NULL) {
+      ((CLP(GeomMunger) *)munger)->_geom_contexts.insert(this);
+    }
   }
 
   index = dl._index;
@@ -78,7 +80,9 @@ release_display_lists() {
        ++dli) {
     CLP(GeomMunger) *munger = (*dli).first;
     const DisplayList &dl = (*dli).second;
-    munger->_geom_contexts.erase(this);
+    if (munger != (CLP(GeomMunger) *)NULL) {
+      munger->_geom_contexts.erase(this);
+    }
 
     if (GLCAT.is_debug()) {
       GLCAT.debug()

+ 12 - 0
panda/src/glstuff/glGeomMunger_src.I

@@ -41,3 +41,15 @@ INLINE GraphicsStateGuardian *CLP(GeomMunger)::
 get_gsg() const {
   return _gsg;
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLP(GeomMunger)::operator new
+//       Access: Public
+//  Description: Calls up to do_operator_new() to implement the
+//               low-overhead allocation/deallocation for this type of
+//               GeomMunger.
+////////////////////////////////////////////////////////////////////
+INLINE void *CLP(GeomMunger)::
+operator new(size_t size) {
+  return do_operator_new(size, _deleted_chain);
+}

+ 1 - 0
panda/src/glstuff/glGeomMunger_src.cxx

@@ -18,6 +18,7 @@
 
 #include "dcast.h"
 
+qpGeomMunger *CLP(GeomMunger)::_deleted_chain = NULL;
 TypeHandle CLP(GeomMunger)::_type_handle;
 
 ////////////////////////////////////////////////////////////////////

+ 5 - 0
panda/src/glstuff/glGeomMunger_src.h

@@ -43,6 +43,9 @@ protected:
   virtual int compare_to_impl(const qpGeomMunger *other) const;
   virtual int geom_compare_to_impl(const qpGeomMunger *other) const;
 
+public:
+  INLINE void *operator new(size_t size);
+
 private:
   PT(GraphicsStateGuardian) _gsg;
   CPT(TextureAttrib) _texture;
@@ -51,6 +54,8 @@ private:
   typedef pset<CLP(GeomContext) *> GeomContexts;
   GeomContexts _geom_contexts;
 
+  static qpGeomMunger *_deleted_chain;
+
 public:
   static TypeHandle get_class_type() {
     return _type_handle;

+ 2 - 5
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -2142,7 +2142,8 @@ begin_draw_primitives(const qpGeom *geom, const qpGeomMunger *munger,
 
   if (_vertex_data->get_array_info(InternalName::get_color(),
                                    array_data, num_components, numeric_type, 
-                                   start, stride)) {
+                                   start, stride) &&
+      numeric_type != qpGeomVertexDataType::NT_packed_argb) {
     const unsigned char *client_pointer = setup_array_data(array_data);
     GLP(ColorPointer)(num_components, get_numeric_type(numeric_type), 
                       stride, client_pointer + start);
@@ -2209,7 +2210,6 @@ begin_draw_primitives(const qpGeom *geom, const qpGeomMunger *munger,
 void CLP(GraphicsStateGuardian)::
 draw_triangles(const qpGeomTriangles *primitive) {
   //  setup_antialias_polygon();
-
   _vertices_tri_pcollector.add_level(primitive->get_num_vertices());
   const unsigned short *client_pointer = setup_primitive(primitive);
 
@@ -4379,9 +4379,6 @@ get_numeric_type(qpGeomVertexDataType::NumericType numeric_type) {
   case qpGeomVertexDataType::NT_uint8:
     return GL_UNSIGNED_BYTE;
     
-  case qpGeomVertexDataType::NT_packed_argb:
-    return GL_UNSIGNED_INT;
-    
   case qpGeomVertexDataType::NT_float:
     return GL_FLOAT;
   }

+ 5 - 2
panda/src/gobj/qpgeom.cxx

@@ -256,8 +256,11 @@ munge_geom(const qpGeomMunger *munger,
   PStatTimer timer(qpGeomMunger::_munge_pcollector);
 
   result = this;
-  data = munger->munge_data(get_vertex_data());
-  ((qpGeomMunger *)munger)->munge_geom_impl(result, data);
+  data = get_vertex_data();
+  if (munger != (qpGeomMunger *)NULL) {
+    data = munger->munge_data(data);
+    ((qpGeomMunger *)munger)->munge_geom_impl(result, data);
+  }
 
   {
     // Record the new result in the cache.

+ 43 - 0
panda/src/gobj/qpgeomMunger.I

@@ -123,6 +123,49 @@ munge_data(const qpGeomVertexData *data) const {
   return ((qpGeomMunger *)this)->munge_data_impl(data);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: qpGeomMunger::operator delete
+//       Access: Public
+//  Description: This balances do_operator_new(), below, and adds the
+//               deleted object to the stored deleted_chain, rather
+//               than returning its memory to the heap.
+////////////////////////////////////////////////////////////////////
+INLINE void qpGeomMunger::
+operator delete(void *ptr) {
+  qpGeomMunger *obj = (qpGeomMunger *)ptr;
+  nassertv(obj->_deleted_chain != (qpGeomMunger **)NULL);
+  nassertv(obj->_next == (qpGeomMunger *)NULL);
+  obj->_next = (*obj->_deleted_chain);
+  (*obj->_deleted_chain) = obj;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpGeomMunger::do_operator_new
+//       Access: Protected, Static
+//  Description: Intended to be called from a derived class's operator
+//               new method, this allocates a new object from the
+//               indicated deleted_chain, if there is an object
+//               available there, or from the heap if not.
+//
+//               In either case, the indicated deleted_chain pointer
+//               is cleverly stored on the new object, even before its
+//               constructor is called, so that it can be returned
+//               there when it is deleted.
+////////////////////////////////////////////////////////////////////
+INLINE void *qpGeomMunger::
+do_operator_new(size_t size, qpGeomMunger *&deleted_chain) {
+  qpGeomMunger *obj;
+  if (deleted_chain != (qpGeomMunger *)NULL) {
+    obj = deleted_chain;
+    deleted_chain = deleted_chain->_next;
+  } else {
+    obj = (qpGeomMunger *)::operator new(size);
+  }
+  obj->_deleted_chain = &deleted_chain;
+
+  return obj;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: qpGeomMunger::get_registry
 //       Access: Private

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

@@ -35,7 +35,10 @@ qpGeomMunger::
 qpGeomMunger(const GraphicsStateGuardianBase *, const RenderState *) :
   _is_registered(false)
 {
+#ifndef NDEBUG
   _registered_key = get_registry()->_mungers.end();
+  _next = NULL;
+#endif
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -47,7 +50,10 @@ qpGeomMunger::
 qpGeomMunger(const qpGeomMunger &copy) :
   _is_registered(false)
 {
+#ifndef NDEBUG
   _registered_key = get_registry()->_mungers.end();
+  _next = NULL;
+#endif
 }
 
 ////////////////////////////////////////////////////////////////////

+ 15 - 0
panda/src/gobj/qpgeomMunger.h

@@ -88,6 +88,21 @@ protected:
   virtual int compare_to_impl(const qpGeomMunger *other) const;
   virtual int geom_compare_to_impl(const qpGeomMunger *other) const;
 
+public:
+  // To minimize overhead, each type of GeomMunger will implement new
+  // and delete using their own deleted_chain.  This is the base class
+  // implementation, which requires a pointer to deleted_chain be
+  // stored on each instance.
+  INLINE void operator delete(void *ptr);
+
+protected:
+  INLINE static void *do_operator_new(size_t size, qpGeomMunger *&_deleted_chain);
+
+private:
+  qpGeomMunger **_deleted_chain;
+  // This is the next pointer along the deleted_chain.
+  qpGeomMunger *_next;
+
 private:
   class Registry;
   INLINE static Registry *get_registry();

+ 19 - 0
panda/src/pgraph/cullResult.I

@@ -54,3 +54,22 @@ get_bin(int bin_index) {
   }
   return make_new_bin(bin_index);
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: CullResult::get_geom_munger
+//       Access: Private
+//  Description: Returns a suitable GeomMunger for the indicated
+//               state.  This will ask the GSG to create a new munger
+//               if we haven't already created one for this state;
+//               otherwise, it will return the existing one.
+////////////////////////////////////////////////////////////////////
+INLINE CPT(qpGeomMunger) CullResult::
+get_geom_munger(const RenderState *state) {
+  Mungers::iterator mi = _mungers.find(state);
+  if (mi != _mungers.end()) {
+    return (*mi).second;
+  }
+  CPT(qpGeomMunger) munger = _gsg->get_geom_munger(state);
+  _mungers.insert(Mungers::value_type(state, munger));
+  return munger;
+}

+ 2 - 2
panda/src/pgraph/cullResult.cxx

@@ -128,7 +128,7 @@ add_object(CullableObject *object) {
               get_dual_transparent_state_decals() : 
               get_dual_transparent_state();
             transparent_part->_state = state->compose(transparent_state);
-            transparent_part->munge_geom(_gsg);
+            transparent_part->munge_geom(get_geom_munger(transparent_part->_state));
             CullBin *bin = get_bin(transparent_part->_state->get_bin_index());
             nassertv(bin != (CullBin *)NULL);
             bin->add_object(transparent_part);
@@ -155,7 +155,7 @@ add_object(CullableObject *object) {
 
   // Munge vertices as needed for the GSG's requirements, and the
   // object's current state.
-  object->munge_geom(_gsg);
+  object->munge_geom(get_geom_munger(object->_state));
   
   CullBin *bin = get_bin(object->_state->get_bin_index());
   nassertv(bin != (CullBin *)NULL);

+ 6 - 0
panda/src/pgraph/cullResult.h

@@ -23,11 +23,13 @@
 #include "cullBin.h"
 #include "renderState.h"
 #include "cullableObject.h"
+#include "qpgeomMunger.h"
 
 #include "referenceCount.h"
 #include "pointerTo.h"
 #include "pvector.h"
 #include "pset.h"
+#include "pmap.h"
 
 
 class GraphicsStateGuardianBase;
@@ -63,6 +65,7 @@ public:
 
 private:
   CullBin *make_new_bin(int bin_index);
+  INLINE CPT(qpGeomMunger) get_geom_munger(const RenderState *state);
 
   static CPT(RenderState) get_binary_state();
   static CPT(RenderState) get_dual_transparent_state();
@@ -71,6 +74,9 @@ private:
 
   GraphicsStateGuardianBase *_gsg;
 
+  typedef pmap<CPT(RenderState), CPT(qpGeomMunger) > Mungers;
+  Mungers _mungers;
+
   typedef pvector< PT(CullBin) > Bins;
   Bins _bins;
 };

+ 0 - 12
panda/src/pgraph/cullableObject.I

@@ -103,18 +103,6 @@ has_decals() const {
   return (_next != (CullableObject *)NULL);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: CullableObject::munge_geom
-//       Access: Public
-//  Description: Gets a GeomMunger from the GSG to transform the
-//               geom and/or its vertices to meet the GSG's vertex
-//               requirements for the current state.
-////////////////////////////////////////////////////////////////////
-INLINE void CullableObject::
-munge_geom(GraphicsStateGuardianBase *gsg) {
-  munge_geom(gsg->get_geom_munger(_state));
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: CullableObject::draw
 //       Access: Public

+ 0 - 1
panda/src/pgraph/cullableObject.h

@@ -54,7 +54,6 @@ public:
 
   INLINE bool has_decals() const;
 
-  INLINE void munge_geom(GraphicsStateGuardianBase *gsg);
   void munge_geom(const qpGeomMunger *munger);
   INLINE void draw(GraphicsStateGuardianBase *gsg);
 

+ 1 - 1
panda/src/pgraph/drawCullHandler.cxx

@@ -35,7 +35,7 @@ void DrawCullHandler::
 record_object(CullableObject *object) {
   // Munge vertices as needed for the GSG's requirements, and the
   // object's current state.
-  object->munge_geom(_gsg);
+  object->munge_geom(_gsg->get_geom_munger(object->_state));
 
   // And draw the object, then dispense with it.
   draw(object, _gsg);