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"
20#include "configVariableDouble.h"
21#include "configVariableInt.h"
22#include "configVariableString.h"
23
24#include <ctype.h>
25
26 using std::string;
27
28 static const int current_pstat_major_version = 3;
29 static 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 */
44 int
45 get_current_pstat_major_version() {
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 */
57 int
58 get_current_pstat_minor_version() {
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
80 typedef PStatCollectorDef::ColorDef ColorDef;
81
82 struct TimeCollectorProperties {
83 bool is_active;
84 const char *name;
85 ColorDef color;
86 double suggested_scale;
87};
88
89 struct 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
98 static 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
156 static 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 */
233 static 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 */
285 void
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
ConfigVariableBool
This is a convenience class to specialize ConfigVariable as a boolean type.
Definition configVariableBool.h:23
ConfigVariableColor
This is a convenience class to specialize ConfigVariable as a set of floating-point types representin...
Definition configVariableColor.h:35
ConfigVariableDouble
This is a convenience class to specialize ConfigVariable as a floating- point type.
Definition configVariableDouble.h:24
ConfigVariableInt
This is a convenience class to specialize ConfigVariable as an integer type.
Definition configVariableInt.h:24
ConfigVariableString
This is a convenience class to specialize ConfigVariable as a string type.
Definition configVariableString.h:23
PStatClient
Manages the communications to report statistics via a network connection to a remote PStatServer.
Definition pStatClient.h:266
PStatCollectorDef
Defines the details about the Collectors: the name, the suggested color, etc.
Definition pStatCollectorDef.h:29
string::const_iterator
STL iterator class.
configVariableBool.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
configVariableColor.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
configVariableDouble.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
configVariableInt.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
configVariableString.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
config_pstatclient.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pStatClient.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pStatCollectorDef.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_current_pstat_major_version
int get_current_pstat_major_version()
Returns the current major version number of the PStats protocol.
Definition pStatProperties.cxx:45
get_current_pstat_minor_version
int get_current_pstat_minor_version()
Returns the current minor version number of the PStats protocol.
Definition pStatProperties.cxx:58
pStatProperties.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PStatCollectorDef::ColorDef
Definition pStatCollectorDef.h:38