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