diff --git a/panda/src/cull/cullTraverser.cxx b/panda/src/cull/cullTraverser.cxx index 660f493a15..eb2388c135 100644 --- a/panda/src/cull/cullTraverser.cxx +++ b/panda/src/cull/cullTraverser.cxx @@ -31,6 +31,15 @@ TypeHandle CullTraverser::_type_handle; #ifndef CPPPARSER PStatCollector CullTraverser::_cull_pcollector("Cull"); PStatCollector CullTraverser::_draw_pcollector("Draw"); +PStatCollector CullTraverser::_cull_traverse_pcollector("Cull:Traverse"); +PStatCollector CullTraverser::_cull_geom_node_pcollector("Cull:Geom node"); +PStatCollector CullTraverser::_cull_direct_node_pcollector("Cull:Direct node"); +PStatCollector CullTraverser::_cull_draw_get_bin_pcollector("Cull:Apply initial"); +PStatCollector CullTraverser::_cull_draw_pcollector("Cull:Draw"); +PStatCollector CullTraverser::_cull_clean_pcollector("Cull:Clean"); +PStatCollector CullTraverser::_cull_bins_unsorted_pcollector("Cull:Bins:Unsorted"); +PStatCollector CullTraverser::_cull_bins_fixed_pcollector("Cull:Bins:Fixed"); +PStatCollector CullTraverser::_cull_bins_btf_pcollector("Cull:Bins:BTF"); #endif //////////////////////////////////////////////////////////////////// @@ -310,6 +319,8 @@ setup_initial_bins() { //////////////////////////////////////////////////////////////////// void CullTraverser:: draw() { + PStatTimer timer(_cull_draw_pcollector); + if (cull_cat.is_debug()) { // Count up the nonempty states for debug output. int num_states = 0; @@ -325,18 +336,24 @@ draw() { << "Initiating draw with " << num_states << " nonempty states of " << _states.size() << " total.\n"; } - + SubBins::const_iterator sbi; - for (sbi = _sub_bins.begin(); sbi != _sub_bins.end(); ++sbi) { - (*sbi).second->clear_current_states(); + { + PStatTimer timer(_cull_clean_pcollector); + for (sbi = _sub_bins.begin(); sbi != _sub_bins.end(); ++sbi) { + (*sbi).second->clear_current_states(); + } } States::iterator si; for (si = _states.begin(); si != _states.end(); ++si) { CullState *cs = (*si); if (!cs->is_empty()) { - cs->apply_to(_initial_state); - + { + PStatTimer timer(_cull_draw_get_bin_pcollector); + cs->apply_to(_initial_state); + } + static string default_bin_name = "default"; string bin_name = default_bin_name; GeomBin *requested_bin = _default_bin; @@ -345,21 +362,20 @@ draw() { // Check the requested bin for the Geoms in this state. const GeomBinAttribute *bin_attrib; if (get_attribute_into(bin_attrib, cs->get_attributes(), - GeomBinTransition::get_class_type())) { - draw_order = bin_attrib->get_draw_order(); - bin_name = bin_attrib->get_bin(); - requested_bin = get_bin(bin_name); + GeomBinTransition::get_class_type())) { + draw_order = bin_attrib->get_draw_order(); + bin_name = bin_attrib->get_bin(); + requested_bin = get_bin(bin_name); } - + if (requested_bin == (GeomBin *)NULL) { - // If we don't have a bin by this name, create one. - cull_cat.warning() - << "Bin " << bin_name << " is unknown; creating a default bin.\n"; - - requested_bin = new GeomBinNormal(bin_name); - requested_bin->set_traverser(this); + // If we don't have a bin by this name, create one. + cull_cat.warning() + << "Bin " << bin_name << " is unknown; creating a default bin.\n"; + + requested_bin = new GeomBinNormal(bin_name); + requested_bin->set_traverser(this); } - requested_bin->record_current_state(_gsg, cs, draw_order, this); } } @@ -388,6 +404,8 @@ draw() { //////////////////////////////////////////////////////////////////// void CullTraverser:: clean_out_old_states() { + PStatTimer timer(_cull_clean_pcollector); + _lookup.clean_out_old_nodes(); States::iterator si, snext; @@ -416,6 +434,12 @@ clean_out_old_states() { void CullTraverser:: add_geom_node(GeomNode *node, const AllTransitionsWrapper &trans, const CullLevelState &level_state) { + // Using the PStatTimer here to start and stop the collector + // implicitly gives VC++ a headache and an internal compiler error, + // but explicitly starting and stopping it is ok. + //PStatTimer timer(_cull_geom_node_pcollector); + _cull_geom_node_pcollector.start(); + nassertv(node != (GeomNode *)NULL); const ArcChain &arc_chain = get_arc_chain(); nassertv(!arc_chain.empty()); @@ -447,6 +471,7 @@ add_geom_node(GeomNode *node, const AllTransitionsWrapper &trans, } cs->record_current_geom_node(arc_chain); + _cull_geom_node_pcollector.stop(); } //////////////////////////////////////////////////////////////////// @@ -461,6 +486,8 @@ add_geom_node(GeomNode *node, const AllTransitionsWrapper &trans, void CullTraverser:: add_direct_node(Node *node, const AllTransitionsWrapper &trans, const CullLevelState &level_state) { + PStatTimer timer(_cull_direct_node_pcollector); + nassertv(node != (Node *)NULL); const ArcChain &arc_chain = get_arc_chain(); nassertv(!arc_chain.empty()); @@ -502,6 +529,8 @@ forward_arc(NodeRelation *arc, NullTransitionWrapper &, return false; } + PStatTimer timer(_cull_traverse_pcollector); + Node *node = arc->get_child(); if (implicit_app_traversal) { diff --git a/panda/src/cull/cullTraverser.h b/panda/src/cull/cullTraverser.h index 36ebf59847..877ded6b17 100644 --- a/panda/src/cull/cullTraverser.h +++ b/panda/src/cull/cullTraverser.h @@ -122,6 +122,15 @@ public: // Statistics static PStatCollector _cull_pcollector; static PStatCollector _draw_pcollector; + static PStatCollector _cull_traverse_pcollector; + static PStatCollector _cull_geom_node_pcollector; + static PStatCollector _cull_direct_node_pcollector; + static PStatCollector _cull_draw_get_bin_pcollector; + static PStatCollector _cull_draw_pcollector; + static PStatCollector _cull_clean_pcollector; + static PStatCollector _cull_bins_unsorted_pcollector; + static PStatCollector _cull_bins_fixed_pcollector; + static PStatCollector _cull_bins_btf_pcollector; public: static TypeHandle get_class_type() { diff --git a/panda/src/cull/geomBinBackToFront.cxx b/panda/src/cull/geomBinBackToFront.cxx index 17aec5788b..e0acbca733 100644 --- a/panda/src/cull/geomBinBackToFront.cxx +++ b/panda/src/cull/geomBinBackToFront.cxx @@ -11,10 +11,7 @@ #include #include #include - -#ifdef DO_PSTATS #include -#endif TypeHandle GeomBinBackToFront::_type_handle; @@ -41,6 +38,8 @@ clear_current_states() { void GeomBinBackToFront:: record_current_state(GraphicsStateGuardian *gsg, CullState *cs, int, CullTraverser *trav) { + PStatTimer timer(CullTraverser::_cull_bins_btf_pcollector); + // Get the transform matrix from the state. TransformAttribute *trans_attrib = NULL; get_attribute_into(trans_attrib, cs->get_attributes(), @@ -138,9 +137,8 @@ record_current_state(GraphicsStateGuardian *gsg, CullState *cs, int, //////////////////////////////////////////////////////////////////// void GeomBinBackToFront:: draw(CullTraverser *trav) { -#ifdef DO_PSTATS PStatTimer timer(CullTraverser::_draw_pcollector); -#endif + if (cull_cat.is_spam()) { cull_cat.spam() << "GeomBinBackToFront drawing " << _node_entries.size() << " entries.\n"; diff --git a/panda/src/cull/geomBinFixed.cxx b/panda/src/cull/geomBinFixed.cxx index bf6c163a4d..0b632fa40c 100644 --- a/panda/src/cull/geomBinFixed.cxx +++ b/panda/src/cull/geomBinFixed.cxx @@ -12,10 +12,7 @@ #include #include #include - -#ifdef DO_PSTATS #include -#endif TypeHandle GeomBinFixed::_type_handle; @@ -42,6 +39,8 @@ clear_current_states() { void GeomBinFixed:: record_current_state(GraphicsStateGuardian *, CullState *cs, int draw_order, CullTraverser *) { + PStatTimer timer(CullTraverser::_cull_bins_fixed_pcollector); + // Get the transform matrix from the state. TransformAttribute *trans_attrib = NULL; get_attribute_into(trans_attrib, cs->get_attributes(), @@ -67,9 +66,8 @@ record_current_state(GraphicsStateGuardian *, CullState *cs, //////////////////////////////////////////////////////////////////// void GeomBinFixed:: draw(CullTraverser *trav) { -#ifdef DO_PSTATS PStatTimer timer(CullTraverser::_draw_pcollector); -#endif + NodeEntries::iterator nei; for (nei = _node_entries.begin(); nei != _node_entries.end(); ++nei) { (*nei).draw(trav); diff --git a/panda/src/cull/geomBinUnsorted.cxx b/panda/src/cull/geomBinUnsorted.cxx index 0146ad0c51..5ac57098cc 100644 --- a/panda/src/cull/geomBinUnsorted.cxx +++ b/panda/src/cull/geomBinUnsorted.cxx @@ -9,10 +9,7 @@ #include #include #include - -#ifdef DO_PSTATS #include -#endif TypeHandle GeomBinUnsorted::_type_handle; @@ -47,13 +44,15 @@ clear_current_states() { //////////////////////////////////////////////////////////////////// // Function: GeomBinUnsorted::record_current_state // Access: Public, Virtual -// Description: Called each frame by the CullTraverser to indicated +// Description: Called each frame by the CullTraverser to indicate // that the given CullState (and all of its current // GeomNodes) is visible this frame. //////////////////////////////////////////////////////////////////// void GeomBinUnsorted:: record_current_state(GraphicsStateGuardian *, CullState *cs, int, CullTraverser *) { + PStatTimer timer(CullTraverser::_cull_bins_unsorted_pcollector); + // This shouldn't be called twice for a particular CullState on this // bin, since we don't preserve any CullStates between frames. nassertv(cs->get_bin() != this); @@ -69,9 +68,8 @@ record_current_state(GraphicsStateGuardian *, CullState *cs, int, //////////////////////////////////////////////////////////////////// void GeomBinUnsorted:: draw(CullTraverser *trav) { -#ifdef DO_PSTATS PStatTimer timer(CullTraverser::_draw_pcollector); -#endif + GraphicsStateGuardian *gsg = trav->get_gsg(); if (cull_cat.is_spam()) { diff --git a/panda/src/pstatclient/pStatCollectorDef.cxx b/panda/src/pstatclient/pStatCollectorDef.cxx index 20de3477fb..f75f8f7bb0 100644 --- a/panda/src/pstatclient/pStatCollectorDef.cxx +++ b/panda/src/pstatclient/pStatCollectorDef.cxx @@ -23,6 +23,7 @@ PStatCollectorDef() { _suggested_scale = 0.0; _factor = 1.0; _is_active = true; + _active_explicitly_set = false; } //////////////////////////////////////////////////////////////////// @@ -41,6 +42,7 @@ PStatCollectorDef(int index, const string &name) : _suggested_scale = 0.0; _factor = 1.0; _is_active = true; + _active_explicitly_set = false; } //////////////////////////////////////////////////////////////////// @@ -58,6 +60,7 @@ set_parent(const PStatCollectorDef &parent) { _suggested_scale = parent._suggested_scale; _factor = parent._factor; _is_active = parent._is_active; + _active_explicitly_set = parent._active_explicitly_set; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pstatclient/pStatCollectorDef.h b/panda/src/pstatclient/pStatCollectorDef.h index 155faab1ee..2fa1770d36 100644 --- a/panda/src/pstatclient/pStatCollectorDef.h +++ b/panda/src/pstatclient/pStatCollectorDef.h @@ -38,6 +38,7 @@ public: float _suggested_scale; float _factor; bool _is_active; + bool _active_explicitly_set; }; #endif diff --git a/panda/src/pstatclient/pStatProperties.cxx b/panda/src/pstatclient/pStatProperties.cxx index dc45f22794..eec56db1a7 100644 --- a/panda/src/pstatclient/pStatProperties.cxx +++ b/panda/src/pstatclient/pStatProperties.cxx @@ -94,9 +94,19 @@ static TimeCollectorProperties time_properties[] = { { 1, "App", { 0.0, 1.0, 1.0 }, 1.0 / 30.0 }, { 1, "App:Animation", { 1.0, 0.0, 1.0 } }, { 1, "App:Collisions", { 1.0, 0.5, 0.0 } }, - { 1, "App:Data graph", { 0.5, 0.8, 0.4 } }, + { 0, "App:Data graph", { 0.5, 0.8, 0.4 } }, { 1, "App:Show code", { 0.8, 0.2, 1.0 } }, { 1, "Cull", { 0.0, 1.0, 0.0 }, 1.0 / 30.0 }, + { 0, "Cull:Traverse", { 0.0, 1.0, 1.0 } }, + { 0, "Cull:Geom node", { 1.0, 0.0, 1.0 } }, + { 0, "Cull:Direct node", { 1.0, 0.5, 0.0 } }, + { 0, "Cull:Apply initial", { 0.2, 1.0, 0.8 } }, + { 0, "Cull:Draw", { 1.0, 1.0, 0.0 } }, + { 0, "Cull:Clean", { 0.0, 0.0, 1.0 } }, + { 0, "Cull:Bins", { 0.8, 1.0, 0.8 } }, + { 0, "Cull:Bins:BTF", { 1.0, 0.5, 0.5 } }, + { 0, "Cull:Bins:Unsorted", { 0.5, 0.5, 1.0 } }, + { 0, "Cull:Bins:Fixed", { 0.5, 1.0, 0.5 } }, { 1, "Draw", { 1.0, 0.0, 0.0 }, 1.0 / 30.0 }, { 1, "Draw:Swap buffers", { 0.5, 1.0, 0.8 } }, { 1, "Draw:Clear", { 0.5, 0.7, 0.7 } }, @@ -144,7 +154,9 @@ initialize_collector_def_from_table(const string &fullname, PStatCollectorDef *d const TimeCollectorProperties &tp = time_properties[i]; if (fullname == tp.name) { def->_sort = i; - def->_is_active = tp.is_active; + if (!def->_active_explicitly_set) { + def->_is_active = tp.is_active; + } def->_suggested_color.set(tp.color.r, tp.color.g, tp.color.b); if (tp.suggested_scale != 0.0) { def->_suggested_scale = tp.suggested_scale; @@ -159,7 +171,9 @@ initialize_collector_def_from_table(const string &fullname, PStatCollectorDef *d const LevelCollectorProperties &lp = level_properties[i]; if (fullname == lp.name) { def->_sort = i; - def->_is_active = lp.is_active; + if (!def->_active_explicitly_set) { + def->_is_active = lp.is_active; + } def->_suggested_color.set(lp.color.r, lp.color.g, lp.color.b); if (lp.suggested_scale != 0.0) { def->_suggested_scale = lp.suggested_scale; @@ -221,8 +235,12 @@ initialize_collector_def(PStatClient *client, PStatCollectorDef *def) { } } - def->_is_active = - config_pstats.GetBool("pstats-active-" + config_name, def->_is_active); + if (!config_pstats.GetString("pstats-active-" + config_name, "").empty()) { + def->_is_active = + config_pstats.GetBool("pstats-active-" + config_name, true); + def->_active_explicitly_set = true; + } + def->_sort = config_pstats.GetInt("pstats-sort-" + config_name, def->_sort); def->_suggested_scale =