Panda3D
pStatProperties.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file pStatProperties.cxx
10 * @author drose
11 * @date 2001-05-17
12 */
13
14#include "pStatProperties.h"
15#include "pStatCollectorDef.h"
16#include "pStatClient.h"
17#include "config_pstatclient.h"
18#include "configVariableBool.h"
19#include "configVariableColor.h"
21#include "configVariableInt.h"
23
24#include <ctype.h>
25
26using std::string;
27
28static const int current_pstat_major_version = 3;
29static const int current_pstat_minor_version = 0;
30// Initialized at 2.0 on 51801, when version numbers were first added.
31// Incremented to 2.1 on 52101 to add support for TCP frame data. Incremented
32// to 3.0 on 42805 to bump TCP headers to 32 bits.
33
34/**
35 * Returns the current major version number of the PStats protocol. This is
36 * the version number that will be reported by clients running this code, and
37 * that will be expected by servers running this code.
38 *
39 * The major version numbers must match exactly in order for a communication
40 * to be successful.
41 */
42int
44 return current_pstat_major_version;
45}
46
47/**
48 * Returns the current minor version number of the PStats protocol. This is
49 * the version number that will be reported by clients running this code, and
50 * that will be expected by servers running this code.
51 *
52 * The minor version numbers need not match exactly, but the server must be >=
53 * the client.
54 */
55int
57 return current_pstat_minor_version;
58}
59
60
61#ifdef DO_PSTATS
62
63/*
64 * The rest of this file defines the predefined properties (color, sort, etc.)
65 * for the various PStatCollectors that may be defined within Panda or even
66 * elsewhere. It is a little strange to defined these properties here instead
67 * of where the collectors are actually declared, but it's handy to have them
68 * all in one place, so we can easily see which colors are available, etc. It
69 * also makes the declarations a lot simpler, since there are quite a few
70 * esoteric parameters to specify. We could define these in some external
71 * data file that is read in at runtime, so that you could extend this list
72 * without having to relink panda, but then there are the usual problems with
73 * ensuring that the file is available to you at runtime. The heck with it.
74 * At least, no other file depends on this file, so it may be modified without
75 * forcing anything else to be recompiled.
76 */
77
78typedef PStatCollectorDef::ColorDef ColorDef;
79
80struct TimeCollectorProperties {
81 bool is_active;
82 const char *name;
83 ColorDef color;
84 double suggested_scale;
85};
86
87struct LevelCollectorProperties {
88 bool is_active;
89 const char *name;
90 ColorDef color;
91 const char *units;
92 double suggested_scale;
93 double inv_factor;
94};
95
96static TimeCollectorProperties time_properties[] = {
97 { 1, "Frame", { 0.95, 1.0, 0.35 } },
98 { 1, "Wait", { 0.6, 0.6, 0.6 } },
99 { 0, "Wait:Mutex block", { 0.5, 0.0, 1.0 } },
100 { 1, "Wait:Thread sync", { 0.0, 1.0, 0.5 } },
101 { 1, "Wait:Clock Wait", { 0.2, 0.8, 0.2 } },
102 { 1, "Wait:Clock Wait:Sleep", { 0.9, 0.4, 0.8 } },
103 { 1, "Wait:Clock Wait:Spin", { 0.2, 0.8, 1.0 } },
104 { 1, "Wait:Flip", { 1.0, 0.6, 0.3 } },
105 { 1, "Wait:Flip:Begin", { 0.3, 0.3, 0.9 } },
106 { 1, "Wait:Flip:End", { 0.9, 0.3, 0.6 } },
107 { 1, "App", { 0.0, 0.4, 0.8 }, 1.0 / 30.0 },
108 { 1, "App:Collisions", { 1.0, 0.5, 0.0 } },
109 { 1, "App:Collisions:Reset", { 0.0, 0.0, 0.5 } },
110 { 0, "App:Data graph", { 0.5, 0.8, 0.4 } },
111 { 1, "App:Show code", { 0.8, 0.2, 1.0 } },
112 { 0, "App:Show code:Nametags", { 0.8, 0.8, 1.0 } },
113 { 0, "App:Show code:Nametags:2d", { 0.0, 0.0, 0.5 } },
114 { 0, "App:Show code:Nametags:2d:Contents", { 0.0, 0.5, 0.0 } },
115 { 0, "App:Show code:Nametags:2d:Adjust", { 0.5, 0.0, 0.5 } },
116 { 0, "App:Show code:Nametags:3d", { 1.0, 0.0, 0.0 } },
117 { 0, "App:Show code:Nametags:3d:Contents", { 0.0, 0.5, 0.0 } },
118 { 0, "App:Show code:Nametags:3d:Adjust", { 0.5, 0.0, 0.5 } },
119 { 1, "Cull", { 0.21, 0.68, 0.37 }, 1.0 / 30.0 },
120 { 1, "Cull:Setup", { 0.7, 0.4, 0.5 } },
121 { 1, "Cull:Sort", { 0.3, 0.3, 0.6 } },
122 { 1, "*", { 0.1, 0.1, 0.5 } },
123 { 1, "*:Show fps", { 0.5, 0.8, 1.0 } },
124 { 1, "*:Munge", { 0.3, 0.3, 0.9 } },
125 { 1, "*:Munge:Geom", { 0.4, 0.2, 0.8 } },
126 { 1, "*:Munge:Sprites", { 0.2, 0.8, 0.4 } },
127 { 0, "*:Munge:Data", { 0.7, 0.5, 0.2 } },
128 { 0, "*:Munge:Rotate", { 0.9, 0.8, 0.5 } },
129 { 0, "*:Munge:Decompose", { 0.1, 0.3, 0.1 } },
130 { 1, "*:PStats", { 0.4, 0.8, 1.0 } },
131 { 1, "*:Animation", { 1.0, 0.0, 1.0 } },
132 { 0, "*:Flatten", { 0.0, 0.7, 0.4 } },
133 { 0, "*:State Cache", { 0.4, 0.7, 0.7 } },
134 { 0, "*:NodePath", { 0.1, 0.6, 0.8 } },
135 { 1, "Draw", { 0.83, 0.02, 0.01 }, 1.0 / 30.0 },
136 { 1, "Draw:Make current", { 0.4, 0.2, 0.6 } },
137 { 1, "Draw:Copy texture", { 0.2, 0.6, 0.4 } },
138 { 1, "Draw:Transfer data", { 0.8, 0.0, 0.6 } },
139 { 1, "Draw:Transfer data:Vertex buffer", { 0.0, 0.1, 0.9 } },
140 { 1, "Draw:Transfer data:Index buffer", { 0.1, 0.9, 0.0 } },
141 { 1, "Draw:Transfer data:Texture", { 0.9, 0.0, 0.1 } },
142 { 1, "Draw:Transfer data:Display lists", { 0.5, 0.0, 0.9 } },
143 { 1, "Draw:Clear", { 0.0, 0.8, 0.6 } },
144 { 1, "Draw:Flush", { 0.9, 0.2, 0.7 } },
145 { 1, "Draw:Sync", { 0.5, 0.7, 0.7 } },
146 { 0, "Draw:Transform", { 0.0, 0.5, 0.0 } },
147 { 1, "Draw:Primitive", { 0.0, 0.0, 0.5 } },
148 { 1, "Draw:Set State", { 0.2, 0.6, 0.8 } },
149 { 1, "Draw:Wait occlusion", { 1.0, 0.5, 0.0 } },
150 { 1, "Draw:Bind FBO", { 0.0, 0.8, 0.8 } },
151 { 0, nullptr }
152};
153
154static LevelCollectorProperties level_properties[] = {
155 { 1, "Graphics memory", { 0.0, 0.0, 1.0 }, "MB", 64, 1048576 },
156 { 1, "Buffer switch", { 0.0, 0.6, 0.8 }, "", 500 },
157 { 1, "Buffer switch:Vertex", { 0.8, 0.0, 0.6 } },
158 { 1, "Buffer switch:Index", { 0.8, 0.6, 0.3 } },
159 { 1, "Geom cache size", { 0.6, 0.8, 0.6 }, "", 500 },
160 { 1, "Geom cache size:Active", { 0.9, 1.0, 0.3 }, "", 500 },
161 { 1, "Geom cache operations", { 1.0, 0.6, 0.6 }, "", 500 },
162 { 1, "Geom cache operations:record", { 0.2, 0.4, 0.8 } },
163 { 1, "Geom cache operations:erase", { 0.4, 0.8, 0.2 } },
164 { 1, "Geom cache operations:evict", { 0.8, 0.2, 0.4 } },
165 { 1, "Data transferred", { 0.0, 0.2, 0.4 }, "MB", 12, 1048576 },
166 { 1, "Primitive batches", { 0.2, 0.5, 0.9 }, "", 500 },
167 { 1, "Primitive batches:Other", { 0.2, 0.2, 0.2 } },
168 { 1, "Primitive batches:Triangles", { 0.8, 0.8, 0.8 } },
169 { 1, "Primitive batches:Triangle fans", { 0.8, 0.5, 0.2 } },
170 { 1, "Primitive batches:Triangle strips",{ 0.2, 0.5, 0.8 } },
171 { 1, "Primitive batches:Display lists", { 0.8, 0.5, 1.0 } },
172 { 1, "SW Sprites", { 0.2, 0.7, 0.3 }, "K", 10, 1000 },
173 { 1, "Vertices", { 0.5, 0.2, 0.0 }, "K", 10, 1000 },
174 { 1, "Vertices:Other", { 0.2, 0.2, 0.2 } },
175 { 1, "Vertices:Triangles", { 0.8, 0.8, 0.8 } },
176 { 1, "Vertices:Triangle fans", { 0.8, 0.5, 0.2 } },
177 { 1, "Vertices:Triangle strips", { 0.2, 0.5, 0.8 } },
178 { 1, "Vertices:Indexed triangle strips", { 0.5, 0.2, 0.8 } },
179 { 1, "Vertices:Display lists", { 0.8, 0.5, 1.0 } },
180 { 1, "Vertices:Immediate mode", { 1.0, 0.5, 0.0 } },
181 { 1, "Pixels", { 0.8, 0.3, 0.7 }, "M", 5, 1000000 },
182 { 1, "Nodes", { 0.4, 0.2, 0.8 }, "", 500.0 },
183 { 1, "Nodes:GeomNodes", { 0.8, 0.2, 0.0 } },
184 { 1, "Geoms", { 0.4, 0.8, 0.3 }, "", 500.0 },
185 { 1, "Cull volumes", { 0.7, 0.6, 0.9 }, "", 500.0 },
186 { 1, "Cull volumes:Transforms", { 0.9, 0.6, 0.0 } },
187 { 1, "State changes", { 1.0, 0.5, 0.2 }, "", 500.0 },
188 { 1, "State changes:Other", { 0.2, 0.2, 0.2 } },
189 { 1, "State changes:Transforms", { 0.2, 0.2, 0.8 } },
190 { 1, "State changes:Textures", { 0.8, 0.2, 0.2 } },
191 { 1, "Occlusion tests", { 0.9, 0.8, 0.3 }, "", 500.0 },
192 { 1, "Occlusion results", { 0.3, 0.9, 0.8 }, "", 500.0 },
193 { 1, "System memory", { 0.5, 1.0, 0.5 }, "MB", 64, 1048576 },
194 { 1, "System memory:Heap", { 0.2, 0.2, 1.0 } },
195 { 1, "System memory:Heap:Overhead", { 0.3, 0.4, 0.6 } },
196 { 1, "System memory:Heap:Single", { 0.8, 0.3, 0.3 } },
197 { 1, "System memory:Heap:Array", { 0.1, 0.3, 1.0 } },
198 { 1, "System memory:Heap:Overhead", { 0.9, 0.7, 0.8 } },
199 { 1, "System memory:Heap:External", { 0.2, 0.2, 0.5 } },
200 { 1, "System memory:MMap", { 0.9, 0.4, 0.7 } },
201 { 1, "Vertex Data", { 1.0, 0.4, 0.0 }, "MB", 64, 1048576 },
202 { 1, "Vertex Data:Independent", { 0.9, 0.1, 0.9 } },
203 { 1, "Vertex Data:Small", { 0.2, 0.3, 0.4 } },
204 { 1, "Vertex Data:Pending", { 0.6, 0.8, 1.0 } },
205 { 1, "Vertex Data:Resident", { 0.9, 1.0, 0.7 } },
206 { 1, "Vertex Data:Compressed", { 0.5, 0.1, 0.4 } },
207 { 1, "Vertex Data:Disk", { 0.6, 0.9, 0.1 } },
208 { 1, "Vertex Data:Disk:Unused", { 0.8, 0.4, 0.5 } },
209 { 1, "Vertex Data:Disk:Used", { 0.2, 0.1, 0.6 } },
210 { 1, "TransformStates", { 1.0, 0.5, 0.5 }, "", 5000 },
211 { 1, "TransformStates:On nodes", { 0.2, 0.8, 1.0 } },
212 { 1, "TransformStates:Cached", { 1.0, 0.0, 0.2 } },
213 { 1, "TransformStates:Unused", { 0.2, 0.2, 0.2 } },
214 { 1, "RenderStates", { 0.5, 0.5, 1.0 }, "", 1000 },
215 { 1, "RenderStates:On nodes", { 0.2, 0.8, 1.0 } },
216 { 1, "RenderStates:Cached", { 1.0, 0.0, 0.2 } },
217 { 1, "RenderStates:Unused", { 0.2, 0.2, 0.2 } },
218 { 1, "PipelineCyclers", { 0.5, 0.5, 1.0 }, "", 50000 },
219 { 1, "Dirty PipelineCyclers", { 0.2, 0.2, 0.2 }, "", 5000 },
220 { 1, "Collision Volumes", { 1.0, 0.8, 0.5 }, "", 500 },
221 { 1, "Collision Tests", { 0.5, 0.8, 1.0 }, "", 100 },
222 { 1, "Command latency", { 0.8, 0.2, 0.0 }, "ms", 10, 1.0 / 1000.0 },
223 { 0, nullptr }
224};
225
226
227/**
228 * Looks up the collector in the compiled-in table defined above, and sets its
229 * properties appropriately if it is found.
230 */
231static void
232initialize_collector_def_from_table(const string &fullname, PStatCollectorDef *def) {
233 int i;
234
235 for (i = 0;
236 time_properties[i].name != nullptr;
237 i++) {
238 const TimeCollectorProperties &tp = time_properties[i];
239 if (fullname == tp.name) {
240 def->_sort = i;
241 if (!def->_active_explicitly_set) {
242 def->_is_active = tp.is_active;
243 }
244 def->_suggested_color = tp.color;
245 if (tp.suggested_scale != 0.0) {
246 def->_suggested_scale = tp.suggested_scale;
247 }
248 return;
249 }
250 }
251
252 for (i = 0;
253 level_properties[i].name != nullptr;
254 i++) {
255 const LevelCollectorProperties &lp = level_properties[i];
256 if (fullname == lp.name) {
257 def->_sort = i;
258 if (!def->_active_explicitly_set) {
259 def->_is_active = lp.is_active;
260 }
261 def->_suggested_color = lp.color;
262 if (lp.suggested_scale != 0.0) {
263 def->_suggested_scale = lp.suggested_scale;
264 }
265 if (lp.units != nullptr) {
266 def->_level_units = lp.units;
267 }
268 if (lp.inv_factor != 0.0) {
269 def->_factor = 1.0 / lp.inv_factor;
270 }
271 return;
272 }
273 }
274}
275
276
277/**
278 * This is the only accessor function into this table. The PStatCollectorDef
279 * constructor calls it when a new PStatCollectorDef is created. It should
280 * look up in the table and find a matching definition for this def by name;
281 * if one is found, the properties are applied.
282 */
283void
284initialize_collector_def(const PStatClient *client, PStatCollectorDef *def) {
285 string fullname;
286
287 if (def->_index == 0) {
288 fullname = def->_name;
289 } else {
290 fullname = client->get_collector_fullname(def->_index);
291 }
292
293 // First, check the compiled-in defaults.
294 initialize_collector_def_from_table(fullname, def);
295
296 // Then, look to Config for more advice. To do this, we first change the
297 // name to something more like a Config variable name. We replace colons
298 // and spaces with hyphens, eliminate other punctuation, and make all
299 // letters lowercase.
300
301 string config_name;
302 string::const_iterator ni;
303 for (ni = fullname.begin(); ni != fullname.end(); ++ni) {
304 switch (*ni) {
305 case ':':
306 case ' ':
307 case '\n':
308 case '\r':
309 case '\t':
310 config_name += '-';
311 break;
312
313 default:
314 if (isalnum(*ni)) {
315 config_name += tolower(*ni);
316 }
317 }
318 }
319
320 ConfigVariableBool pstats_active
321 ("pstats-active-" + config_name, true, "", ConfigVariable::F_dynamic);
322 ConfigVariableInt pstats_sort
323 ("pstats-sort-" + config_name, def->_sort, "", ConfigVariable::F_dynamic);
324 ConfigVariableDouble pstats_scale
325 ("pstats-scale-" + config_name, def->_suggested_scale, "", ConfigVariable::F_dynamic);
326 ConfigVariableString pstats_units
327 ("pstats-units-" + config_name, def->_level_units, "", ConfigVariable::F_dynamic);
328 ConfigVariableDouble pstats_factor
329 ("pstats-factor-" + config_name, 1.0, "", ConfigVariable::F_dynamic);
330 ConfigVariableColor pstats_color
331 ("pstats-color-" + config_name, LColor::zero(), "", ConfigVariable::F_dynamic);
332
333 if (pstats_active.has_value()) {
334 def->_is_active = pstats_active;
335 def->_active_explicitly_set = true;
336 }
337
338 def->_sort = pstats_sort;
339 def->_suggested_scale = pstats_scale;
340 def->_level_units = pstats_units;
341 if (pstats_factor.has_value()) {
342 def->_factor = pstats_factor;
343 }
344
345 if (pstats_color.has_value()) {
346 def->_suggested_color.r = pstats_color[0];
347 def->_suggested_color.g = pstats_color[1];
348 def->_suggested_color.b = pstats_color[2];
349 }
350}
351
352#endif // DO_PSTATS
This is a convenience class to specialize ConfigVariable as a boolean type.
This is a convenience class to specialize ConfigVariable as a set of floating-point types representin...
This is a convenience class to specialize ConfigVariable as a floating- point type.
This is a convenience class to specialize ConfigVariable as an integer type.
This is a convenience class to specialize ConfigVariable as a string type.
Manages the communications to report statistics via a network connection to a remote PStatServer.
Definition: pStatClient.h:263
Defines the details about the Collectors: the name, the suggested color, etc.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_current_pstat_major_version()
Returns the current major version number of the PStats protocol.
int get_current_pstat_minor_version()
Returns the current minor version number of the PStats protocol.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.