Panda3D
 All Classes Functions Variables Enumerations
pStatProperties.cxx
00001 // Filename: pStatProperties.cxx
00002 // Created by:  drose (17May01)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "pStatProperties.h"
00016 #include "pStatCollectorDef.h"
00017 #include "pStatClient.h"
00018 #include "config_pstats.h"
00019 #include "configVariableBool.h"
00020 #include "configVariableDouble.h"
00021 #include "configVariableInt.h"
00022 #include "configVariableString.h"
00023 
00024 #include <ctype.h>
00025 
00026 static const int current_pstat_major_version = 3;
00027 static const int current_pstat_minor_version = 0;
00028 // Initialized at 2.0 on 5/18/01, when version numbers were first added.
00029 // Incremented to 2.1 on 5/21/01 to add support for TCP frame data.
00030 // Incremented to 3.0 on 4/28/05 to bump TCP headers to 32 bits.
00031 
00032 ////////////////////////////////////////////////////////////////////
00033 //     Function: get_current_pstat_major_version
00034 //  Description: Returns the current major version number of the
00035 //               PStats protocol.  This is the version number that
00036 //               will be reported by clients running this code, and
00037 //               that will be expected by servers running this code.
00038 //
00039 //               The major version numbers must match exactly in order
00040 //               for a communication to be successful.
00041 ////////////////////////////////////////////////////////////////////
00042 int
00043 get_current_pstat_major_version() {
00044   return current_pstat_major_version;
00045 }
00046 
00047 ////////////////////////////////////////////////////////////////////
00048 //     Function: get_current_pstat_minor_version
00049 //  Description: Returns the current minor version number of the
00050 //               PStats protocol.  This is the version number that
00051 //               will be reported by clients running this code, and
00052 //               that will be expected by servers running this code.
00053 //
00054 //               The minor version numbers need not match exactly, but
00055 //               the server must be >= the client.
00056 ////////////////////////////////////////////////////////////////////
00057 int
00058 get_current_pstat_minor_version() {
00059   return current_pstat_minor_version;
00060 }
00061 
00062 
00063 #ifdef DO_PSTATS
00064 
00065 ////////////////////////////////////////////////////////////////////
00066 //
00067 // The rest of this file defines the predefined properties (color,
00068 // sort, etc.) for the various PStatCollectors that may be defined
00069 // within Panda or even elsewhere.
00070 //
00071 // It is a little strange to defined these properties here instead of
00072 // where the collectors are actually declared, but it's handy to have
00073 // them all in one place, so we can easily see which colors are
00074 // available, etc.  It also makes the declarations a lot simpler,
00075 // since there are quite a few esoteric parameters to specify.
00076 //
00077 // We could define these in some external data file that is read in at
00078 // runtime, so that you could extend this list without having to
00079 // relink panda, but then there are the usual problems with ensuring
00080 // that the file is available to you at runtime.  The heck with it.
00081 //
00082 // At least, no other file depends on this file, so it may be modified
00083 // without forcing anything else to be recompiled.
00084 //
00085 ////////////////////////////////////////////////////////////////////
00086 
00087 typedef PStatCollectorDef::ColorDef ColorDef;
00088 
00089 struct TimeCollectorProperties {
00090   bool is_active;
00091   const char *name;
00092   ColorDef color;
00093   double suggested_scale;
00094 };
00095 
00096 struct LevelCollectorProperties {
00097   bool is_active;
00098   const char *name;
00099   ColorDef color;
00100   const char *units;
00101   double suggested_scale;
00102   double inv_factor;
00103 };
00104 
00105 static TimeCollectorProperties time_properties[] = {
00106   { 1, "Frame",                            { 0.95, 1.0, 0.35 } },
00107   { 1, "Wait",                             { 0.6, 0.6, 0.6 } },
00108   { 0, "Wait:Mutex block",                 { 0.5, 0.0, 1.0 } },
00109   { 1, "Wait:Thread sync",                 { 0.0, 1.0, 0.5 } },
00110   { 1, "Wait:Clock Wait",                  { 0.2, 0.8, 0.2 } },
00111   { 1, "Wait:Clock Wait:Sleep",            { 0.9, 0.4, 0.8 } },
00112   { 1, "Wait:Clock Wait:Spin",             { 0.2, 0.8, 1.0 } },
00113   { 1, "Wait:Flip",                        { 1.0, 0.6, 0.3 } },
00114   { 1, "Wait:Flip:Begin",                  { 0.3, 0.3, 0.9 } },
00115   { 1, "Wait:Flip:End",                    { 0.9, 0.3, 0.6 } },
00116   { 1, "App",                              { 0.0, 0.4, 0.8 },  1.0 / 30.0 },
00117   { 1, "App:Collisions",                   { 1.0, 0.5, 0.0 } },
00118   { 1, "App:Collisions:Reset",             { 0.0, 0.0, 0.5 } },
00119   { 0, "App:Data graph",                   { 0.5, 0.8, 0.4 } },
00120   { 1, "App:Show code",                    { 0.8, 0.2, 1.0 } },
00121   { 0, "App:Show code:Nametags",           { 0.8, 0.8, 1.0 } },
00122   { 0, "App:Show code:Nametags:2d",        { 0.0, 0.0, 0.5 } },
00123   { 0, "App:Show code:Nametags:2d:Contents", { 0.0, 0.5, 0.0 } },
00124   { 0, "App:Show code:Nametags:2d:Adjust",   { 0.5, 0.0, 0.5 } },
00125   { 0, "App:Show code:Nametags:3d",        { 1.0, 0.0, 0.0 } },
00126   { 0, "App:Show code:Nametags:3d:Contents", { 0.0, 0.5, 0.0 } },
00127   { 0, "App:Show code:Nametags:3d:Adjust",   { 0.5, 0.0, 0.5 } },
00128   { 1, "Cull",                             { 0.21, 0.68, 0.37 },  1.0 / 30.0 },
00129   { 1, "Cull:Setup",                       { 0.7, 0.4, 0.5 } },
00130   { 1, "Cull:Sort",                        { 0.3, 0.3, 0.6 } },
00131   { 1, "*:Show fps",                       { 0.5, 0.8, 1.0 } },
00132   { 0, "*:Munge",                          { 0.3, 0.3, 0.9 } },
00133   { 1, "*:Munge:Geom",                     { 0.4, 0.2, 0.8 } },
00134   { 1, "*:Munge:Sprites",                  { 0.2, 0.8, 0.4 } },
00135   { 0, "*:Munge:Data",                     { 0.7, 0.5, 0.2 } },
00136   { 0, "*:Munge:Rotate",                   { 0.9, 0.8, 0.5 } },
00137   { 0, "*:Munge:Decompose",                { 0.1, 0.3, 0.1 } },
00138   { 1, "*:PStats",                         { 0.4, 0.8, 1.0 } },
00139   { 1, "*:Animation",                      { 1.0, 0.0, 1.0 } },
00140   { 0, "*:Flatten",                        { 0.0, 0.7, 0.4 } },
00141   { 0, "*:State Cache",                    { 0.4, 0.7, 0.7 } },
00142   { 0, "*:NodePath",                       { 0.1, 0.6, 0.8 } },
00143   { 1, "Draw",                             { 0.83, 0.02, 0.01 },  1.0 / 30.0 },
00144   { 1, "Draw:Make current",                { 0.4, 0.2, 0.6 } },
00145   { 1, "Draw:Copy texture",                { 0.2, 0.6, 0.4 } },
00146   { 1, "Draw:Transfer data",               { 0.8, 0.0, 0.6 } },
00147   { 1, "Draw:Transfer data:Vertex buffer", { 0.0, 0.1, 0.9 } },
00148   { 1, "Draw:Transfer data:Index buffer",  { 0.1, 0.9, 0.0 } },
00149   { 1, "Draw:Transfer data:Texture",       { 0.9, 0.0, 0.1 } },
00150   { 1, "Draw:Transfer data:Display lists", { 0.5, 0.0, 0.9 } },
00151   { 1, "Draw:Clear",                       { 0.0, 0.8, 0.6 } },
00152   { 1, "Draw:Flush",                       { 0.9, 0.2, 0.7 } },
00153   { 1, "Draw:Sync",                        { 0.5, 0.7, 0.7 } },
00154   { 0, "Draw:Transform",                   { 0.0, 0.5, 0.0 } },
00155   { 0, "Draw:Primitive",                   { 0.0, 0.0, 0.5 } },
00156   { 0, "Draw:Set State",                   { 0.2, 0.6, 0.8 } },
00157   { 1, "Draw:Wait occlusion",              { 1.0, 0.5, 0.0 } },
00158   { 0, NULL }
00159 };
00160 
00161 static LevelCollectorProperties level_properties[] = {
00162   { 1, "Graphics memory",                  { 0.0, 0.0, 1.0 },  "MB", 64, 1048576 },
00163   { 1, "Vertex buffer switch",             { 0.0, 0.6, 0.8 },  "", 500 },
00164   { 1, "Vertex buffer switch:Vertex",      { 0.8, 0.0, 0.6 } },
00165   { 1, "Vertex buffer switch:Index",       { 0.8, 0.6, 0.3 } },
00166   { 1, "Geom cache size",                  { 0.6, 0.8, 0.6 },  "", 500 },
00167   { 1, "Geom cache size:Active",           { 0.9, 1.0, 0.3 },  "", 500 },
00168   { 1, "Geom cache operations",            { 1.0, 0.6, 0.6 },  "", 500 },
00169   { 1, "Geom cache operations:record",     { 0.2, 0.4, 0.8 } },
00170   { 1, "Geom cache operations:erase",      { 0.4, 0.8, 0.2 } },
00171   { 1, "Geom cache operations:evict",      { 0.8, 0.2, 0.4 } },
00172   { 1, "Data transferred",                 { 0.0, 0.2, 0.4 },  "MB", 12, 1048576 },
00173   { 1, "Primitive batches",                { 0.2, 0.5, 0.9 },  "", 500 },
00174   { 1, "Primitive batches:Other",          { 0.2, 0.2, 0.2 } },
00175   { 1, "Primitive batches:Triangles",      { 0.8, 0.8, 0.8 } },
00176   { 1, "Primitive batches:Triangle fans",  { 0.8, 0.5, 0.2 } },
00177   { 1, "Primitive batches:Triangle strips",{ 0.2, 0.5, 0.8 } },
00178   { 1, "Primitive batches:Display lists",  { 0.8, 0.5, 1.0 } },
00179   { 1, "SW Sprites",                       { 0.2, 0.7, 0.3 },  "K", 10, 1000 },
00180   { 1, "Vertices",                         { 0.5, 0.2, 0.0 },  "K", 10, 1000 },
00181   { 1, "Vertices:Other",                   { 0.2, 0.2, 0.2 } },
00182   { 1, "Vertices:Triangles",               { 0.8, 0.8, 0.8 } },
00183   { 1, "Vertices:Triangle fans",           { 0.8, 0.5, 0.2 } },
00184   { 1, "Vertices:Triangle strips",         { 0.2, 0.5, 0.8 } },
00185   { 1, "Vertices:Indexed triangle strips", { 0.5, 0.2, 0.8 } },
00186   { 1, "Vertices:Display lists",           { 0.8, 0.5, 1.0 } },
00187   { 1, "Vertices:Immediate mode",          { 1.0, 0.5, 0.0 } },
00188   { 1, "Pixels",                           { 0.8, 0.3, 0.7 },  "M", 5, 1000000 },
00189   { 1, "Nodes",                            { 0.4, 0.2, 0.8 },  "", 500.0 },
00190   { 1, "Nodes:GeomNodes",                  { 0.8, 0.2, 0.0 } },
00191   { 1, "Geoms",                            { 0.4, 0.8, 0.3 },  "", 500.0 },
00192   { 1, "Cull volumes",                     { 0.7, 0.6, 0.9 },  "", 500.0 },
00193   { 1, "Cull volumes:Transforms",          { 0.9, 0.6, 0.0 } },
00194   { 1, "State changes",                    { 1.0, 0.5, 0.2 },  "", 500.0 },
00195   { 1, "State changes:Other",              { 0.2, 0.2, 0.2 } },
00196   { 1, "State changes:Transforms",         { 0.2, 0.2, 0.8 } },
00197   { 1, "State changes:Textures",           { 0.8, 0.2, 0.2 } },
00198   { 1, "Occlusion tests",                  { 0.9, 0.8, 0.3 },  "", 500.0 },
00199   { 1, "Occlusion results",                { 0.3, 0.9, 0.8 },  "", 500.0 },
00200   { 1, "System memory",                    { 0.5, 1.0, 0.5 },  "MB", 64, 1048576 },
00201   { 1, "System memory:Heap",               { 0.2, 0.2, 1.0 } },
00202   { 1, "System memory:Heap:Overhead",      { 0.3, 0.4, 0.6 } },
00203   { 1, "System memory:Heap:Single",        { 0.8, 0.3, 0.3 } },
00204   { 1, "System memory:Heap:Array",         { 0.1, 0.3, 1.0 } },
00205   { 1, "System memory:Heap:Overhead",      { 0.9, 0.7, 0.8 } },
00206   { 1, "System memory:Heap:External",      { 0.2, 0.2, 0.5 } },
00207   { 1, "System memory:MMap",               { 0.9, 0.4, 0.7 } },
00208   { 1, "Vertex Data",                      { 1.0, 0.4, 0.0 },  "MB", 64, 1048576 },
00209   { 1, "Vertex Data:Independent",          { 0.9, 0.1, 0.9 } },
00210   { 1, "Vertex Data:Small",                { 0.2, 0.3, 0.4 } },
00211   { 1, "Vertex Data:Pending",              { 0.6, 0.8, 1.0 } },
00212   { 1, "Vertex Data:Resident",             { 0.9, 1.0, 0.7 } },
00213   { 1, "Vertex Data:Compressed",           { 0.5, 0.1, 0.4 } },
00214   { 1, "Vertex Data:Disk",                 { 0.6, 0.9, 0.1 } },
00215   { 1, "Vertex Data:Disk:Unused",          { 0.8, 0.4, 0.5 } },
00216   { 1, "Vertex Data:Disk:Used",            { 0.2, 0.1, 0.6 } },
00217   { 1, "TransformStates",                  { 1.0, 0.5, 0.5 },  "", 5000 },
00218   { 1, "TransformStates:On nodes",         { 0.2, 0.8, 1.0 } },
00219   { 1, "TransformStates:Cached",           { 1.0, 0.0, 0.2 } },
00220   { 1, "TransformStates:Unused",           { 0.2, 0.2, 0.2 } },
00221   { 1, "RenderStates",                     { 0.5, 0.5, 1.0 },  "", 1000 },
00222   { 1, "RenderStates:On nodes",            { 0.2, 0.8, 1.0 } },
00223   { 1, "RenderStates:Cached",              { 1.0, 0.0, 0.2 } },
00224   { 1, "RenderStates:Unused",              { 0.2, 0.2, 0.2 } },
00225   { 1, "PipelineCyclers",                  { 0.5, 0.5, 1.0 },  "", 50000 },
00226   { 1, "Dirty PipelineCyclers",            { 0.2, 0.2, 0.2 },  "", 5000 },
00227   { 1, "Collision Volumes",                { 1.0, 0.8, 0.5 },  "", 500 },
00228   { 1, "Collision Tests",                  { 0.5, 0.8, 1.0 },  "", 100 },
00229   { 0, NULL }
00230 };
00231 
00232 
00233 ////////////////////////////////////////////////////////////////////
00234 //     Function: initialize_collector_def_from_table
00235 //  Description: Looks up the collector in the compiled-in table
00236 //               defined above, and sets its properties appropriately
00237 //               if it is found.
00238 ////////////////////////////////////////////////////////////////////
00239 static void
00240 initialize_collector_def_from_table(const string &fullname, PStatCollectorDef *def) {
00241   int i;
00242 
00243   for (i = 0;
00244        time_properties[i].name != (const char *)NULL;
00245        i++) {
00246     const TimeCollectorProperties &tp = time_properties[i];
00247     if (fullname == tp.name) {
00248       def->_sort = i;
00249       if (!def->_active_explicitly_set) {
00250         def->_is_active = tp.is_active;
00251       }
00252       def->_suggested_color = tp.color;
00253       if (tp.suggested_scale != 0.0) {
00254         def->_suggested_scale = tp.suggested_scale;
00255       }
00256       return;
00257     }
00258   }
00259 
00260   for (i = 0;
00261        level_properties[i].name != (const char *)NULL;
00262        i++) {
00263     const LevelCollectorProperties &lp = level_properties[i];
00264     if (fullname == lp.name) {
00265       def->_sort = i;
00266       if (!def->_active_explicitly_set) {
00267         def->_is_active = lp.is_active;
00268       }
00269       def->_suggested_color = lp.color;
00270       if (lp.suggested_scale != 0.0) {
00271         def->_suggested_scale = lp.suggested_scale;
00272       }
00273       if (lp.units != (const char *)NULL) {
00274         def->_level_units = lp.units;
00275       }
00276       if (lp.inv_factor != 0.0) {
00277         def->_factor = 1.0 / lp.inv_factor;
00278       }
00279       return;
00280     }
00281   }
00282 }
00283 
00284 
00285 ////////////////////////////////////////////////////////////////////
00286 //     Function: initialize_collector_def
00287 //  Description: This is the only accessor function into this table.
00288 //               The PStatCollectorDef constructor calls it when a new
00289 //               PStatCollectorDef is created.  It should look up in
00290 //               the table and find a matching definition for this def
00291 //               by name; if one is found, the properties are applied.
00292 ////////////////////////////////////////////////////////////////////
00293 void
00294 initialize_collector_def(const PStatClient *client, PStatCollectorDef *def) {
00295   string fullname;
00296 
00297   if (def->_index == 0) {
00298     fullname = def->_name;
00299   } else {
00300     fullname = client->get_collector_fullname(def->_index);
00301   }
00302 
00303   // First, check the compiled-in defaults.
00304   initialize_collector_def_from_table(fullname, def);
00305 
00306   // Then, look to Config for more advice.  To do this, we first
00307   // change the name to something more like a Config variable name.
00308   // We replace colons and spaces with hyphens, eliminate other
00309   // punctuation, and make all letters lowercase.
00310 
00311   string config_name;
00312   string::const_iterator ni;
00313   for (ni = fullname.begin(); ni != fullname.end(); ++ni) {
00314     switch (*ni) {
00315     case ':':
00316     case ' ':
00317     case '\n':
00318     case '\r':
00319     case '\t':
00320       config_name += '-';
00321       break;
00322 
00323     default:
00324       if (isalnum(*ni)) {
00325         config_name += tolower(*ni);
00326       }
00327     }
00328   }
00329 
00330   ConfigVariableBool pstats_active
00331     ("pstats-active-" + config_name, true, "", ConfigVariable::F_dynamic);
00332   ConfigVariableInt pstats_sort
00333     ("pstats-sort-" + config_name, def->_sort, "", ConfigVariable::F_dynamic);
00334   ConfigVariableDouble pstats_scale
00335     ("pstats-scale-" + config_name, def->_suggested_scale, "", ConfigVariable::F_dynamic);
00336   ConfigVariableString pstats_units
00337     ("pstats-units-" + config_name, def->_level_units, "", ConfigVariable::F_dynamic);
00338   ConfigVariableDouble pstats_factor
00339     ("pstats-factor-" + config_name, 1.0, "", ConfigVariable::F_dynamic);
00340   ConfigVariableDouble pstats_color
00341     ("pstats-color-" + config_name, 0.0, "", ConfigVariable::F_dynamic);
00342   
00343   if (pstats_active.has_value()) {
00344     def->_is_active = pstats_active;
00345     def->_active_explicitly_set = true;
00346   }
00347 
00348   def->_sort = pstats_sort;
00349   def->_suggested_scale = pstats_scale;
00350   def->_level_units = pstats_units;
00351   if (pstats_factor.has_value()) {
00352     def->_factor = pstats_factor;
00353   }
00354 
00355   if (pstats_color.has_value()) {
00356     def->_suggested_color.r = pstats_color[0];
00357     def->_suggested_color.g = pstats_color[1];
00358     def->_suggested_color.b = pstats_color[2];
00359   }
00360 }
00361 
00362 #endif // DO_PSTATS
 All Classes Functions Variables Enumerations