work on pstats reporting

This commit is contained in:
David Rose 2003-12-04 18:13:50 +00:00
parent cfcd70ad32
commit cfad1d8c3e
13 changed files with 62 additions and 85 deletions

View File

@ -33,6 +33,7 @@
#ifndef CPPPARSER #ifndef CPPPARSER
PStatCollector CollisionTraverser::_collisions_pcollector("App:Collisions"); PStatCollector CollisionTraverser::_collisions_pcollector("App:Collisions");
PStatCollector CollisionTraverser::_reset_prev_pcollector("App:Collisions:Reset");
#endif #endif
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -41,7 +42,10 @@ PStatCollector CollisionTraverser::_collisions_pcollector("App:Collisions");
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
CollisionTraverser:: CollisionTraverser::
CollisionTraverser() { CollisionTraverser(const string &name) :
Namable(name),
_this_pcollector(_collisions_pcollector, name)
{
_respect_prev_transform = respect_prev_transform; _respect_prev_transform = respect_prev_transform;
#ifdef DO_COLLISION_RECORDING #ifdef DO_COLLISION_RECORDING
_recorder = (CollisionRecorder *)NULL; _recorder = (CollisionRecorder *)NULL;
@ -265,7 +269,7 @@ remove_collider(CollisionNode *node) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CollisionTraverser:: void CollisionTraverser::
traverse(const NodePath &root) { traverse(const NodePath &root) {
PStatTimer timer(_collisions_pcollector); PStatTimer timer(_this_pcollector);
#ifdef DO_COLLISION_RECORDING #ifdef DO_COLLISION_RECORDING
if (has_recorder()) { if (has_recorder()) {
@ -311,6 +315,7 @@ traverse(const NodePath &root) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CollisionTraverser:: void CollisionTraverser::
reset_prev_transform(const NodePath &root) { reset_prev_transform(const NodePath &root) {
PStatTimer timer(_reset_prev_pcollector);
r_reset_prev_transform(root.node()); r_reset_prev_transform(root.node());
} }
@ -808,8 +813,10 @@ remove_handler(CollisionTraverser::Handlers::iterator hi) {
void CollisionTraverser:: void CollisionTraverser::
r_reset_prev_transform(PandaNode *node) { r_reset_prev_transform(PandaNode *node) {
node->reset_prev_transform(); node->reset_prev_transform();
int num_children = node->get_num_children();
PandaNode::Children children = node->get_children();
int num_children = children.get_num_children();
for (int i = 0; i < num_children; i++) { for (int i = 0; i < num_children; i++) {
r_reset_prev_transform(node->get_child(i)); r_reset_prev_transform(children.get_child(i));
} }
} }

View File

@ -49,9 +49,9 @@ class CollisionEntry;
// indicated root, calling the appropriate // indicated root, calling the appropriate
// CollisionHandler for each detected collision. // CollisionHandler for each detected collision.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
class EXPCL_PANDA CollisionTraverser { class EXPCL_PANDA CollisionTraverser : public Namable {
PUBLISHED: PUBLISHED:
CollisionTraverser(); CollisionTraverser(const string &name = "ctrav");
~CollisionTraverser(); ~CollisionTraverser();
INLINE void set_respect_prev_transform(bool flag); INLINE void set_respect_prev_transform(bool flag);
@ -136,6 +136,8 @@ private:
// Statistics // Statistics
static PStatCollector _collisions_pcollector; static PStatCollector _collisions_pcollector;
static PStatCollector _reset_prev_pcollector;
PStatCollector _this_pcollector;
}; };
INLINE ostream &operator << (ostream &out, const CollisionTraverser &trav) { INLINE ostream &operator << (ostream &out, const CollisionTraverser &trav) {

View File

@ -41,6 +41,10 @@
#ifndef CPPPARSER #ifndef CPPPARSER
PStatCollector GraphicsEngine::_cull_pcollector("Cull"); PStatCollector GraphicsEngine::_cull_pcollector("Cull");
PStatCollector GraphicsEngine::_draw_pcollector("Draw"); PStatCollector GraphicsEngine::_draw_pcollector("Draw");
PStatCollector GraphicsEngine::_transform_states_pcollector("TransformStates");
PStatCollector GraphicsEngine::_transform_states_unused_pcollector("TransformStates:Unused");
PStatCollector GraphicsEngine::_render_states_pcollector("RenderStates");
PStatCollector GraphicsEngine::_render_states_unused_pcollector("RenderStates:Unused");
#endif // CPPPARSER #endif // CPPPARSER
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -355,6 +359,17 @@ render_frame() {
ClockObject::get_global_clock()->tick(); ClockObject::get_global_clock()->tick();
PStatClient::main_tick(); PStatClient::main_tick();
// Reset our pcollectors that track data across the frame.
CullTraverser::_nodes_pcollector.clear_level();
CullTraverser::_geom_nodes_pcollector.clear_level();
_transform_states_pcollector.set_level(TransformState::get_num_states());
_render_states_pcollector.set_level(RenderState::get_num_states());
if (pstats_unused_states) {
_transform_states_unused_pcollector.set_level(TransformState::get_num_unused_states());
_render_states_unused_pcollector.set_level(RenderState::get_num_unused_states());
}
// Now signal all of our threads to begin their next frame. // Now signal all of our threads to begin their next frame.
_app.do_frame(this); _app.do_frame(this);
for (ti = _threads.begin(); ti != _threads.end(); ++ti) { for (ti = _threads.begin(); ti != _threads.end(); ++ti) {

View File

@ -182,6 +182,10 @@ private:
static PStatCollector _cull_pcollector; static PStatCollector _cull_pcollector;
static PStatCollector _draw_pcollector; static PStatCollector _draw_pcollector;
static PStatCollector _transform_states_pcollector;
static PStatCollector _transform_states_unused_pcollector;
static PStatCollector _render_states_pcollector;
static PStatCollector _render_states_unused_pcollector;
friend class WindowRenderer; friend class WindowRenderer;
}; };

View File

@ -51,25 +51,14 @@ PStatCollector GraphicsStateGuardian::_total_texmem_pcollector("Texture memory")
PStatCollector GraphicsStateGuardian::_used_texmem_pcollector("Texture memory:In use"); PStatCollector GraphicsStateGuardian::_used_texmem_pcollector("Texture memory:In use");
PStatCollector GraphicsStateGuardian::_texmgrmem_total_pcollector("Texture manager"); PStatCollector GraphicsStateGuardian::_texmgrmem_total_pcollector("Texture manager");
PStatCollector GraphicsStateGuardian::_texmgrmem_resident_pcollector("Texture manager:Resident"); PStatCollector GraphicsStateGuardian::_texmgrmem_resident_pcollector("Texture manager:Resident");
PStatCollector GraphicsStateGuardian::_vertices_pcollector("Vertices");
PStatCollector GraphicsStateGuardian::_vertices_tristrip_pcollector("Vertices:Triangle strips"); PStatCollector GraphicsStateGuardian::_vertices_tristrip_pcollector("Vertices:Triangle strips");
PStatCollector GraphicsStateGuardian::_vertices_trifan_pcollector("Vertices:Triangle fans"); PStatCollector GraphicsStateGuardian::_vertices_trifan_pcollector("Vertices:Triangle fans");
PStatCollector GraphicsStateGuardian::_vertices_tri_pcollector("Vertices:Triangles"); PStatCollector GraphicsStateGuardian::_vertices_tri_pcollector("Vertices:Triangles");
PStatCollector GraphicsStateGuardian::_vertices_other_pcollector("Vertices:Other"); PStatCollector GraphicsStateGuardian::_vertices_other_pcollector("Vertices:Other");
PStatCollector GraphicsStateGuardian::_state_changes_pcollector("State changes");
PStatCollector GraphicsStateGuardian::_transform_state_pcollector("State changes:Transforms"); PStatCollector GraphicsStateGuardian::_transform_state_pcollector("State changes:Transforms");
PStatCollector GraphicsStateGuardian::_texture_state_pcollector("State changes:Textures"); PStatCollector GraphicsStateGuardian::_texture_state_pcollector("State changes:Textures");
PStatCollector GraphicsStateGuardian::_nodes_pcollector("Nodes"); PStatCollector GraphicsStateGuardian::_other_state_pcollector("State changes:Other");
PStatCollector GraphicsStateGuardian::_geom_nodes_pcollector("Nodes:GeomNodes");
PStatCollector GraphicsStateGuardian::_frustum_cull_volumes_pcollector("Cull volumes");
PStatCollector GraphicsStateGuardian::_frustum_cull_transforms_pcollector("Cull volumes:Transforms");
PStatCollector GraphicsStateGuardian::_set_state_pcollector("Draw:Set state");
PStatCollector GraphicsStateGuardian::_draw_primitive_pcollector("Draw:Primitive"); PStatCollector GraphicsStateGuardian::_draw_primitive_pcollector("Draw:Primitive");
PStatCollector GraphicsStateGuardian::_transform_states_pcollector("TransformStates");
PStatCollector GraphicsStateGuardian::_transform_states_unused_pcollector("TransformStates:Unused");
PStatCollector GraphicsStateGuardian::_render_states_pcollector("RenderStates");
PStatCollector GraphicsStateGuardian::_render_states_unused_pcollector("RenderStates:Unused");
#endif #endif
@ -1407,23 +1396,9 @@ init_frame_pstats() {
_vertices_tri_pcollector.clear_level(); _vertices_tri_pcollector.clear_level();
_vertices_other_pcollector.clear_level(); _vertices_other_pcollector.clear_level();
_state_changes_pcollector.clear_level();
_transform_state_pcollector.clear_level(); _transform_state_pcollector.clear_level();
_texture_state_pcollector.clear_level(); _texture_state_pcollector.clear_level();
_other_state_pcollector.clear_level();
_nodes_pcollector.clear_level();
_geom_nodes_pcollector.clear_level();
// Not to mention the view-frustum-cull counters.
_frustum_cull_volumes_pcollector.clear_level();
_frustum_cull_transforms_pcollector.clear_level();
_transform_states_pcollector.set_level(TransformState::get_num_states());
_render_states_pcollector.set_level(RenderState::get_num_states());
if (pstats_unused_states) {
_transform_states_unused_pcollector.set_level(TransformState::get_num_unused_states());
_render_states_unused_pcollector.set_level(RenderState::get_num_unused_states());
}
} }
} }
@ -1479,26 +1454,6 @@ add_to_geom_node_record(GeomNodeContext *gnc) {
} }
} }
} }
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::record_state_change
// Access: Protected
// Description: Indicates a state change request for a property of
// the given type.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
record_state_change(TypeHandle type) {
_state_changes_pcollector.add_level(1);
// We can't use the get_class_type() methods since we don't have
// those header files available yet.
string name = type.get_name();
if (name == "TransformTransition") {
_transform_state_pcollector.add_level(1);
} else if (name == "TextureTransition") {
_texture_state_pcollector.add_level(1);
}
}
#endif // DO_PSTATS #endif // DO_PSTATS
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -207,7 +207,7 @@ protected:
void add_to_texture_record(TextureContext *tc); void add_to_texture_record(TextureContext *tc);
void add_to_geom_record(GeomContext *gc); void add_to_geom_record(GeomContext *gc);
void add_to_geom_node_record(GeomNodeContext *gnc); void add_to_geom_node_record(GeomNodeContext *gnc);
void record_state_change(TypeHandle type);
pset<TextureContext *> _current_textures; pset<TextureContext *> _current_textures;
pset<GeomContext *> _current_geoms; pset<GeomContext *> _current_geoms;
pset<GeomNodeContext *> _current_geom_nodes; pset<GeomNodeContext *> _current_geom_nodes;
@ -282,24 +282,14 @@ public:
static PStatCollector _used_texmem_pcollector; static PStatCollector _used_texmem_pcollector;
static PStatCollector _texmgrmem_total_pcollector; static PStatCollector _texmgrmem_total_pcollector;
static PStatCollector _texmgrmem_resident_pcollector; static PStatCollector _texmgrmem_resident_pcollector;
static PStatCollector _vertices_pcollector;
static PStatCollector _vertices_tristrip_pcollector; static PStatCollector _vertices_tristrip_pcollector;
static PStatCollector _vertices_trifan_pcollector; static PStatCollector _vertices_trifan_pcollector;
static PStatCollector _vertices_tri_pcollector; static PStatCollector _vertices_tri_pcollector;
static PStatCollector _vertices_other_pcollector; static PStatCollector _vertices_other_pcollector;
static PStatCollector _state_changes_pcollector;
static PStatCollector _transform_state_pcollector; static PStatCollector _transform_state_pcollector;
static PStatCollector _texture_state_pcollector; static PStatCollector _texture_state_pcollector;
static PStatCollector _nodes_pcollector; static PStatCollector _other_state_pcollector;
static PStatCollector _geom_nodes_pcollector;
static PStatCollector _frustum_cull_volumes_pcollector;
static PStatCollector _frustum_cull_transforms_pcollector;
static PStatCollector _set_state_pcollector;
static PStatCollector _draw_primitive_pcollector; static PStatCollector _draw_primitive_pcollector;
static PStatCollector _transform_states_pcollector;
static PStatCollector _transform_states_unused_pcollector;
static PStatCollector _render_states_pcollector;
static PStatCollector _render_states_unused_pcollector;
private: private:
class LightInfo { class LightInfo {

View File

@ -3845,6 +3845,8 @@ enable_texturing(bool val) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian7:: void DXGraphicsStateGuardian7::
issue_transform(const TransformState *transform) { issue_transform(const TransformState *transform) {
DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1));
_pScrn->pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, _pScrn->pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD,
(LPD3DMATRIX)transform->get_mat().get_data()); (LPD3DMATRIX)transform->get_mat().get_data());
} }
@ -3883,6 +3885,7 @@ issue_tex_matrix(const TexMatrixAttrib *attrib) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian7:: void DXGraphicsStateGuardian7::
issue_texture(const TextureAttrib *attrib) { issue_texture(const TextureAttrib *attrib) {
DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
if (attrib->is_off()) { if (attrib->is_off()) {
enable_texturing(false); enable_texturing(false);
} else { } else {

View File

@ -3573,6 +3573,8 @@ enable_texturing(bool val) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8:: void DXGraphicsStateGuardian8::
issue_transform(const TransformState *transform) { issue_transform(const TransformState *transform) {
DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1));
// if we're using ONLY vertex shaders, could get avoid calling SetTrans // if we're using ONLY vertex shaders, could get avoid calling SetTrans
D3DMATRIX *pMat = (D3DMATRIX*)transform->get_mat().get_data(); D3DMATRIX *pMat = (D3DMATRIX*)transform->get_mat().get_data();
_pD3DDevice->SetTransform(D3DTS_WORLD,pMat); _pD3DDevice->SetTransform(D3DTS_WORLD,pMat);
@ -3625,6 +3627,7 @@ issue_tex_matrix(const TexMatrixAttrib *attrib) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8:: void DXGraphicsStateGuardian8::
issue_texture(const TextureAttrib *attrib) { issue_texture(const TextureAttrib *attrib) {
DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
if (attrib->is_off()) { if (attrib->is_off()) {
enable_texturing(false); enable_texturing(false);
} else { } else {

View File

@ -2131,6 +2131,7 @@ issue_transform(const TransformState *transform) {
glgsg_cat.spam() glgsg_cat.spam()
<< "glLoadMatrix(GL_MODELVIEW): " << transform->get_mat() << endl; << "glLoadMatrix(GL_MODELVIEW): " << transform->get_mat() << endl;
#endif #endif
DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1));
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(transform->get_mat().get_data()); glLoadMatrixf(transform->get_mat().get_data());
@ -2156,6 +2157,7 @@ issue_tex_matrix(const TexMatrixAttrib *attrib) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void GLGraphicsStateGuardian:: void GLGraphicsStateGuardian::
issue_texture(const TextureAttrib *attrib) { issue_texture(const TextureAttrib *attrib) {
DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
if (attrib->is_off()) { if (attrib->is_off()) {
enable_texturing(false); enable_texturing(false);
} else { } else {

View File

@ -2,7 +2,7 @@
dtoolutil:c dtoolbase:c dtool:m dtoolutil:c dtoolbase:c dtool:m
#define LOCAL_LIBS \ #define LOCAL_LIBS \
lerp event gsgbase gobj putil linmath \ lerp event gsgbase gobj putil linmath \
downloader express pandabase downloader express pandabase pstatclient
#begin lib_target #begin lib_target
#define TARGET pgraph #define TARGET pgraph

View File

@ -32,6 +32,10 @@
#include "cullFaceAttrib.h" #include "cullFaceAttrib.h"
#include "depthOffsetAttrib.h" #include "depthOffsetAttrib.h"
#ifndef CPPPARSER
PStatCollector CullTraverser::_nodes_pcollector("Nodes");
PStatCollector CullTraverser::_geom_nodes_pcollector("Nodes:GeomNodes");
#endif // CPPPARSER
TypeHandle CullTraverser::_type_handle; TypeHandle CullTraverser::_type_handle;
@ -135,6 +139,7 @@ traverse(CullTraverserData &data) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CullTraverser:: void CullTraverser::
traverse_below(CullTraverserData &data) { traverse_below(CullTraverserData &data) {
_nodes_pcollector.add_level(1);
PandaNode *node = data.node(); PandaNode *node = data.node();
const RenderEffects *node_effects = node->get_effects(); const RenderEffects *node_effects = node->get_effects();
bool has_decal = node_effects->has_decal(); bool has_decal = node_effects->has_decal();
@ -145,6 +150,7 @@ traverse_below(CullTraverserData &data) {
} else { } else {
if (node->is_geom_node()) { if (node->is_geom_node()) {
_geom_nodes_pcollector.add_level(1);
GeomNode *geom_node = DCAST(GeomNode, node); GeomNode *geom_node = DCAST(GeomNode, node);
// Get all the Geoms, with no decalling. // Get all the Geoms, with no decalling.

View File

@ -29,6 +29,7 @@
#include "pointerTo.h" #include "pointerTo.h"
#include "drawMask.h" #include "drawMask.h"
#include "typedObject.h" #include "typedObject.h"
#include "pStatCollector.h"
class PandaNode; class PandaNode;
class CullHandler; class CullHandler;
@ -77,6 +78,11 @@ public:
void traverse(CullTraverserData &data); void traverse(CullTraverserData &data);
void traverse_below(CullTraverserData &data); void traverse_below(CullTraverserData &data);
public:
// Statistics
static PStatCollector _nodes_pcollector;
static PStatCollector _geom_nodes_pcollector;
private: private:
void show_bounds(CullTraverserData &data); void show_bounds(CullTraverserData &data);
PT(Geom) make_bounds_viz(const BoundingVolume &vol); PT(Geom) make_bounds_viz(const BoundingVolume &vol);

View File

@ -108,6 +108,7 @@ static TimeCollectorProperties time_properties[] = {
{ 1, "App", { 0.0, 0.8, 0.4 }, 1.0 / 30.0 }, { 1, "App", { 0.0, 0.8, 0.4 }, 1.0 / 30.0 },
{ 1, "App:Animation", { 1.0, 0.0, 1.0 } }, { 1, "App:Animation", { 1.0, 0.0, 1.0 } },
{ 1, "App:Collisions", { 1.0, 0.5, 0.0 } }, { 1, "App:Collisions", { 1.0, 0.5, 0.0 } },
{ 1, "App:Collisions:Reset", { 0.0, 0.0, 0.5 } },
{ 0, "App:Data graph", { 0.5, 0.8, 0.4 } }, { 0, "App:Data graph", { 0.5, 0.8, 0.4 } },
{ 1, "App:Show code", { 0.8, 0.2, 1.0 } }, { 1, "App:Show code", { 0.8, 0.2, 1.0 } },
{ 0, "App:Show code:Nametags", { 0.8, 0.8, 1.0 } }, { 0, "App:Show code:Nametags", { 0.8, 0.8, 1.0 } },
@ -118,27 +119,9 @@ static TimeCollectorProperties time_properties[] = {
{ 0, "App:Show code:Nametags:3d:Contents", { 0.0, 0.5, 0.0 } }, { 0, "App:Show code:Nametags:3d:Contents", { 0.0, 0.5, 0.0 } },
{ 0, "App:Show code:Nametags:3d:Adjust", { 0.5, 0.0, 0.5 } }, { 0, "App:Show code:Nametags:3d:Adjust", { 0.5, 0.0, 0.5 } },
{ 1, "Cull", { 0.0, 1.0, 0.0 }, 1.0 / 30.0 }, { 1, "Cull", { 0.0, 1.0, 0.0 }, 1.0 / 30.0 },
{ 0, "Cull:Traverse", { 0.0, 1.0, 1.0 } },
{ 0, "Cull:Geom node", { 1.0, 0.0, 1.0 } },
{ 0, "Cull:Direct node", { 1.0, 0.5, 0.0 } },
{ 0, "Cull:Apply initial", { 0.2, 1.0, 0.8 } },
{ 0, "Cull:Draw", { 1.0, 1.0, 0.0 } },
{ 0, "Cull:Clean", { 0.0, 0.0, 1.0 } },
{ 0, "Cull:Bins", { 0.8, 1.0, 0.8 } },
{ 0, "Cull:Bins:BTF", { 1.0, 0.5, 0.5 } },
{ 0, "Cull:Bins:Unsorted", { 0.5, 0.5, 1.0 } },
{ 0, "Cull:Bins:Fixed", { 0.5, 1.0, 0.5 } },
{ 1, "Draw", { 1.0, 0.0, 0.0 }, 1.0 / 30.0 }, { 1, "Draw", { 1.0, 0.0, 0.0 }, 1.0 / 30.0 },
{ 0, "Draw:Primitive", { 0.0, 0.0, 0.5 } }, { 0, "Draw:Primitive", { 0.0, 0.0, 0.5 } },
{ 0, "Draw:Set state", { 0.5, 0.0, 0.0 } },
{ 1, "Draw:Quick", { 1.0, 0.0, 0.8 } },
{ 1, "Draw:Direct", { 0.0, 0.4, 1.0 } },
{ 1, "Draw:Cull", { 0.4, 1.0, 0.0 } },
{ 0, "Draw:Clear", { 0.5, 0.7, 0.7 } },
{ 0, "Draw:Show fps", { 0.5, 0.8, 1.0 } }, { 0, "Draw:Show fps", { 0.5, 0.8, 1.0 } },
{ 0, "Draw:Make current", { 1.0, 0.6, 0.3 } },
{ 0, "WRT", { 0.0, 0.0, 1.0 } },
{ 0, "WRT:Subtree", { 0.3, 1.0, 0.3 } },
{ 0, NULL } { 0, NULL }
}; };
@ -164,6 +147,7 @@ static LevelCollectorProperties level_properties[] = {
{ 1, "Cull volumes", { 0.7, 0.6, 0.9 }, "", 500.0 }, { 1, "Cull volumes", { 0.7, 0.6, 0.9 }, "", 500.0 },
{ 1, "Cull volumes:Transforms", { 0.9, 0.6, 0.0 } }, { 1, "Cull volumes:Transforms", { 0.9, 0.6, 0.0 } },
{ 1, "State changes", { 1.0, 0.5, 0.2 }, "", 500.0 }, { 1, "State changes", { 1.0, 0.5, 0.2 }, "", 500.0 },
{ 1, "State changes:Other", { 0.2, 0.2, 0.2 } },
{ 1, "State changes:Transforms", { 0.2, 0.2, 0.8 } }, { 1, "State changes:Transforms", { 0.2, 0.2, 0.8 } },
{ 1, "State changes:Textures", { 0.8, 0.2, 0.2 } }, { 1, "State changes:Textures", { 0.8, 0.2, 0.2 } },
{ 1, "Memory usage", { 0.5, 1.0, 0.5 }, "MB", 64, 1048576 }, { 1, "Memory usage", { 0.5, 1.0, 0.5 }, "MB", 64, 1048576 },