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