From 93f85f9ef9e5eb21b89b101944f9ca4b5ee21b02 Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 19 Jul 2007 16:16:41 +0000 Subject: [PATCH] simpler do_issue_clip_plane() and do_issue_light(); more pstats calipers --- panda/src/display/graphicsStateGuardian.I | 47 --- panda/src/display/graphicsStateGuardian.cxx | 316 ++++++------------ panda/src/display/graphicsStateGuardian.h | 49 +-- .../glstuff/glGraphicsStateGuardian_src.cxx | 84 ++++- .../src/glstuff/glGraphicsStateGuardian_src.h | 6 +- panda/src/pgraph/nodePath.cxx | 12 +- panda/src/pgraph/renderEffects.cxx | 29 +- panda/src/pstatclient/pStatProperties.cxx | 1 + 8 files changed, 204 insertions(+), 340 deletions(-) diff --git a/panda/src/display/graphicsStateGuardian.I b/panda/src/display/graphicsStateGuardian.I index d2bb82073e..cf99ff8d6d 100644 --- a/panda/src/display/graphicsStateGuardian.I +++ b/panda/src/display/graphicsStateGuardian.I @@ -17,29 +17,6 @@ //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::LightInfo::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE GraphicsStateGuardian::LightInfo:: -LightInfo() { - _enabled = false; - _next_enabled = false; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::ClipPlaneInfo::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE GraphicsStateGuardian::ClipPlaneInfo:: -ClipPlaneInfo() { - _enabled = false; - _next_enabled = false; -} - - //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::release_all // Access: Public @@ -759,30 +736,6 @@ get_inv_cs_transform() const { return _inv_cs_transform; } -//////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::get_light -// Access: Protected -// Description: Returns the Light object that is bound to the -// indicated id, or empty NodePath if no Light is bound. -//////////////////////////////////////////////////////////////////// -INLINE NodePath GraphicsStateGuardian:: -get_light(int light_id) const { - nassertr(light_id >= 0 && light_id < (int)_light_info.size(), NodePath::fail()); - return _light_info[light_id]._light; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::get_clip_plane -// Access: Protected -// Description: Returns the PlaneNode object that is bound to the -// indicated id, or NULL if no PlaneNode is bound. -//////////////////////////////////////////////////////////////////// -INLINE NodePath GraphicsStateGuardian:: -get_clip_plane(int plane_id) const { - nassertr(plane_id >= 0 && plane_id < (int)_clip_plane_info.size(), NodePath::fail()); - return _clip_plane_info[plane_id]._plane; -} - //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::set_current_properties // Access: Protected diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index fea31866d5..c3bd39dd46 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -74,6 +74,29 @@ PStatCollector GraphicsStateGuardian::_flush_pcollector("Draw:Flush"); PStatCollector GraphicsStateGuardian::_wait_occlusion_pcollector("Wait:Occlusion"); +PStatCollector GraphicsStateGuardian::_draw_set_state_transform_pcollector("Draw:Set State:Transform"); +PStatCollector GraphicsStateGuardian::_draw_set_state_alpha_test_pcollector("Draw:Set State:Alpha test"); +PStatCollector GraphicsStateGuardian::_draw_set_state_antialias_pcollector("Draw:Set State:Antialias"); +PStatCollector GraphicsStateGuardian::_draw_set_state_clip_plane_pcollector("Draw:Set State:Clip plane"); +PStatCollector GraphicsStateGuardian::_draw_set_state_color_pcollector("Draw:Set State:Color"); +PStatCollector GraphicsStateGuardian::_draw_set_state_cull_face_pcollector("Draw:Set State:Cull face"); +PStatCollector GraphicsStateGuardian::_draw_set_state_depth_offset_pcollector("Draw:Set State:Depth offset"); +PStatCollector GraphicsStateGuardian::_draw_set_state_depth_test_pcollector("Draw:Set State:Depth test"); +PStatCollector GraphicsStateGuardian::_draw_set_state_depth_write_pcollector("Draw:Set State:Depth write"); +PStatCollector GraphicsStateGuardian::_draw_set_state_render_mode_pcollector("Draw:Set State:Render mode"); +PStatCollector GraphicsStateGuardian::_draw_set_state_rescale_normal_pcollector("Draw:Set State:Rescale normal"); +PStatCollector GraphicsStateGuardian::_draw_set_state_shade_model_pcollector("Draw:Set State:Shade model"); +PStatCollector GraphicsStateGuardian::_draw_set_state_blending_pcollector("Draw:Set State:Blending"); +PStatCollector GraphicsStateGuardian::_draw_set_state_shader_pcollector("Draw:Set State:Shader"); +PStatCollector GraphicsStateGuardian::_draw_set_state_texture_pcollector("Draw:Set State:Texture"); +PStatCollector GraphicsStateGuardian::_draw_set_state_tex_matrix_pcollector("Draw:Set State:Tex matrix"); +PStatCollector GraphicsStateGuardian::_draw_set_state_tex_gen_pcollector("Draw:Set State:Tex gen"); +PStatCollector GraphicsStateGuardian::_draw_set_state_material_pcollector("Draw:Set State:Material"); +PStatCollector GraphicsStateGuardian::_draw_set_state_light_pcollector("Draw:Set State:Light"); +PStatCollector GraphicsStateGuardian::_draw_set_state_stencil_pcollector("Draw:Set State:Stencil"); +PStatCollector GraphicsStateGuardian::_draw_set_state_fog_pcollector("Draw:Set State:Fog"); + + PT(TextureStage) GraphicsStateGuardian::_alpha_scale_texture_stage = NULL; TypeHandle GraphicsStateGuardian::_type_handle; @@ -315,10 +338,8 @@ reset() { _texture_involves_color_scale = false; _vertex_colors_enabled = true; _lighting_enabled = false; - _lighting_enabled_this_frame = false; - - _clip_planes_enabled = false; - _clip_planes_enabled_this_frame = false; + _num_lights_enabled = 0; + _num_clip_planes_enabled = 0; _color_scale_enabled = false; _current_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f); @@ -1132,37 +1153,17 @@ end_scene() { // Undo any lighting we had enabled last scene, to force the lights // to be reissued, in case their parameters or positions have // changed between scenes. - if (_lighting_enabled_this_frame) { - for (int i = 0; i < (int)_light_info.size(); i++) { - if (_light_info[i]._enabled) { - enable_light(i, false); - _light_info[i]._enabled = false; - } - _light_info[i]._light = NodePath(); - } - - // Also force the lighting state to unlit, so that issue_light() - // will be guaranteed to be called next frame even if we have the - // same set of light pointers we had this frame. - // modify_state(get_unlit_state()); - - _lighting_enabled_this_frame = false; + int i; + for (i = 0; i < _num_lights_enabled; ++i) { + enable_light(i, false); } + _num_lights_enabled = 0; // Ditto for the clipping planes. - if (_clip_planes_enabled_this_frame) { - for (int i = 0; i < (int)_clip_plane_info.size(); i++) { - if (_clip_plane_info[i]._enabled) { - enable_clip_plane(i, false); - _clip_plane_info[i]._enabled = false; - } - _clip_plane_info[i]._plane = (PlaneNode *)NULL; - } - - // modify_state(get_unclipped_state()); - - _clip_planes_enabled_this_frame = false; + for (i = 0; i < _num_clip_planes_enabled; ++i) { + enable_clip_plane(i, false); } + _num_clip_planes_enabled = 0; // Put the state into the 'unknown' state, forcing a reload. _state_rs = 0; @@ -1417,114 +1418,49 @@ get_cs_transform() const { //////////////////////////////////////////////////////////////////// void GraphicsStateGuardian:: do_issue_clip_plane() { - const ClipPlaneAttrib *attrib = _target._clip_plane; - int i; - int cur_max_planes = (int)_clip_plane_info.size(); - for (i = 0; i < cur_max_planes; i++) { - _clip_plane_info[i]._next_enabled = false; - } - - CPT(ClipPlaneAttrib) new_attrib = attrib->filter_to_max(_max_clip_planes); - - bool any_bound = false; - int num_enabled = 0; - int num_on_planes = new_attrib->get_num_on_planes(); - for (int li = 0; li < num_on_planes; li++) { - NodePath plane = new_attrib->get_on_plane(li); - nassertv(!plane.is_empty() && plane.node()->is_of_type(PlaneNode::get_class_type())); - PlaneNode *plane_node = (PlaneNode *)plane.node(); - if ((plane_node->get_clip_effect() & PlaneNode::CE_visible) != 0) { - num_enabled++; + int num_on_planes = 0; - // Clipping should be enabled before we apply any planes. - enable_clip_planes(true); - _clip_planes_enabled = true; - _clip_planes_enabled_this_frame = true; - - // Check to see if this plane has already been bound to an id - int cur_plane_id = -1; - for (i = 0; i < cur_max_planes; i++) { - if (_clip_plane_info[i]._plane == plane) { - // Plane has already been bound to an id, we only need to - // enable the plane, not reapply it. - cur_plane_id = -2; - enable_clip_plane(i, true); - _clip_plane_info[i]._enabled = true; - _clip_plane_info[i]._next_enabled = true; - break; + if (_target._clip_plane != (ClipPlaneAttrib *)NULL) { + CPT(ClipPlaneAttrib) new_plane = _target._clip_plane->filter_to_max(_max_clip_planes); + + num_on_planes = new_plane->get_num_on_planes(); + for (int li = 0; li < num_on_planes; li++) { + NodePath plane = new_plane->get_on_plane(li); + nassertv(!plane.is_empty()); + PlaneNode *plane_node; + DCAST_INTO_V(plane_node, plane.node()); + if ((plane_node->get_clip_effect() & PlaneNode::CE_visible) != 0) { + // Clipping should be enabled before we apply any planes. + if (!_clip_planes_enabled) { + enable_clip_planes(true); + _clip_planes_enabled = true; } - } - - // See if there are any unbound plane ids - if (cur_plane_id == -1) { - for (i = 0; i < cur_max_planes; i++) { - if (_clip_plane_info[i]._plane.is_empty()) { - _clip_plane_info[i]._plane = plane; - cur_plane_id = i; - break; - } - } - } - - // If there were no unbound plane ids, see if we can replace - // a currently unused but previously bound id - if (cur_plane_id == -1) { - for (i = 0; i < cur_max_planes; i++) { - if (!new_attrib->has_on_plane(_clip_plane_info[i]._plane)) { - _clip_plane_info[i]._plane = plane; - cur_plane_id = i; - break; - } - } - } - - // If we *still* don't have a plane id, slot a new one. - if (cur_plane_id == -1) { - if (_max_clip_planes < 0 || cur_max_planes < _max_clip_planes) { - cur_plane_id = cur_max_planes; - _clip_plane_info.push_back(ClipPlaneInfo()); - cur_max_planes++; - nassertv(cur_max_planes == (int)_clip_plane_info.size()); - } - } - - if (cur_plane_id >= 0) { - enable_clip_plane(cur_plane_id, true); - _clip_plane_info[cur_plane_id]._enabled = true; - _clip_plane_info[cur_plane_id]._next_enabled = true; - if (!any_bound) { + enable_clip_plane(num_enabled, true); + if (num_enabled == 0) { begin_bind_clip_planes(); - any_bound = true; } - // This is the first time this frame that this plane has been - // bound to this particular id. - bind_clip_plane(plane, cur_plane_id); - - } else if (cur_plane_id == -1) { - gsg_cat.warning() - << "Failed to bind " << plane << " to id.\n"; + bind_clip_plane(plane, num_enabled); + num_enabled++; } } } - // Disable all unused planes - for (i = 0; i < cur_max_planes; i++) { - if (!_clip_plane_info[i]._next_enabled) { - enable_clip_plane(i, false); - _clip_plane_info[i]._enabled = false; - } + int i; + for (i = num_enabled; i < _num_clip_planes_enabled; ++i) { + enable_clip_plane(i, false); } + _num_clip_planes_enabled = num_enabled; - // If no planes were enabled, disable clip planes in general. + // If no planes were set, disable clipping if (num_enabled == 0) { - enable_clip_planes(false); - _clip_planes_enabled = false; - } - - if (any_bound) { + if (_clip_planes_enabled) { + enable_clip_planes(false); + _clip_planes_enabled = false; + } + } else { end_bind_clip_planes(); } } @@ -1649,29 +1585,32 @@ do_issue_light() { // light list Colorf cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f); int i; - int cur_max_lights = (int)_light_info.size(); - for (i = 0; i < cur_max_lights; i++) { - _light_info[i]._next_enabled = false; - } - - bool any_bound = false; int num_enabled = 0; + int num_on_lights = 0; + + if (display_cat.is_debug()) { + display_cat.debug() + << "do_issue_light: " << _target._light << "\n"; + } if (_target._light != (LightAttrib *)NULL) { CPT(LightAttrib) new_light = _target._light->filter_to_max(_max_lights); + if (display_cat.is_debug()) { + new_light->write(display_cat.debug(false), 2); + } - int num_on_lights = new_light->get_num_on_lights(); + num_on_lights = new_light->get_num_on_lights(); for (int li = 0; li < num_on_lights; li++) { NodePath light = new_light->get_on_light(li); - nassertv(!light.is_empty() && light.node()->as_light() != (Light *)NULL); + nassertv(!light.is_empty()); Light *light_obj = light.node()->as_light(); - - num_enabled++; + nassertv(light_obj != (Light *)NULL); // Lighting should be enabled before we apply any lights. - enable_lighting(true); - _lighting_enabled = true; - _lighting_enabled_this_frame = true; + if (!_lighting_enabled) { + enable_lighting(true); + _lighting_enabled = true; + } if (light_obj->get_type() == AmbientLight::get_class_type()) { // Ambient lights don't require specific light ids; simply add @@ -1679,108 +1618,45 @@ do_issue_light() { cur_ambient_light += light_obj->get_color(); } else { - // Check to see if this light has already been bound to an id - int cur_light_id = -1; - for (i = 0; i < cur_max_lights; i++) { - if (_light_info[i]._light == light) { - // Light has already been bound to an id; reuse the same id. - cur_light_id = -2; - enable_light(i, true); - _light_info[i]._enabled = true; - _light_info[i]._next_enabled = true; - - if (!any_bound) { - begin_bind_lights(); - any_bound = true; - } - light_obj->bind(this, light, i); - break; - } + enable_light(num_enabled, true); + if (num_enabled == 0) { + begin_bind_lights(); } - // See if there are any unbound light ids - if (cur_light_id == -1) { - for (i = 0; i < cur_max_lights; i++) { - if (_light_info[i]._light.is_empty()) { - _light_info[i]._light = light; - cur_light_id = i; - break; - } - } - } - - // If there were no unbound light ids, see if we can replace - // a currently unused but previously bound id - if (cur_light_id == -1) { - for (i = 0; i < cur_max_lights; i++) { - if (!new_light->has_on_light(_light_info[i]._light)) { - _light_info[i]._light = light; - cur_light_id = i; - break; - } - } - } - - // If we *still* don't have a light id, slot a new one. - if (cur_light_id == -1) { - if (_max_lights < 0 || cur_max_lights < _max_lights) { - cur_light_id = cur_max_lights; - _light_info.push_back(LightInfo()); - cur_max_lights++; - nassertv(cur_max_lights == (int)_light_info.size()); - } - } - - if (cur_light_id >= 0) { - enable_light(cur_light_id, true); - _light_info[cur_light_id]._enabled = true; - _light_info[cur_light_id]._next_enabled = true; - - if (!any_bound) { - begin_bind_lights(); - any_bound = true; - } - - // This is the first time this frame that this light has been - // bound to this particular id. - light_obj->bind(this, light, cur_light_id); - - } else if (cur_light_id == -1) { - gsg_cat.warning() - << "Failed to bind " << light << " to id.\n"; - } + light_obj->bind(this, light, num_enabled); + num_enabled++; } } } - // Disable all unused lights - for (i = 0; i < cur_max_lights; i++) { - if (!_light_info[i]._next_enabled) { - enable_light(i, false); - _light_info[i]._enabled = false; - } + for (i = num_enabled; i < _num_lights_enabled; ++i) { + enable_light(i, false); } + _num_lights_enabled = num_enabled; - // If no lights were enabled, disable lighting - if (num_enabled == 0) { + // If no lights were set, disable lighting + if (num_on_lights == 0) { if (_color_scale_via_lighting && (_has_material_force_color || _light_color_scale != LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f))) { // Unless we need lighting anyway to apply a color or color // scale. - enable_lighting(true); - _lighting_enabled = true; - _lighting_enabled_this_frame = true; + if (!_lighting_enabled) { + enable_lighting(true); + _lighting_enabled = true; + } set_ambient_light(Colorf(1.0f, 1.0f, 1.0f, 1.0f)); } else { - enable_lighting(false); - _lighting_enabled = false; + if (_lighting_enabled) { + enable_lighting(false); + _lighting_enabled = false; + } } } else { set_ambient_light(cur_ambient_light); } - if (any_bound) { + if (num_enabled != 0) { end_bind_lights(); } } diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index dcb41586fa..226a2f9132 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -267,14 +267,12 @@ public: #endif protected: - INLINE NodePath get_light(int light_id) const; virtual void enable_lighting(bool enable); virtual void set_ambient_light(const Colorf &color); virtual void enable_light(int light_id, bool enable); virtual void begin_bind_lights(); virtual void end_bind_lights(); - INLINE NodePath get_clip_plane(int plane_id) const; virtual void enable_clip_planes(bool enable); virtual void enable_clip_plane(int plane_id, bool enable); virtual void begin_bind_clip_planes(); @@ -447,28 +445,33 @@ public: static PStatCollector _flush_pcollector; static PStatCollector _wait_occlusion_pcollector; + // A whole slew of collectors to measure the cost of individual + // state changes. These are disabled by default. + static PStatCollector _draw_set_state_transform_pcollector; + static PStatCollector _draw_set_state_alpha_test_pcollector; + static PStatCollector _draw_set_state_antialias_pcollector; + static PStatCollector _draw_set_state_clip_plane_pcollector; + static PStatCollector _draw_set_state_color_pcollector; + static PStatCollector _draw_set_state_cull_face_pcollector; + static PStatCollector _draw_set_state_depth_offset_pcollector; + static PStatCollector _draw_set_state_depth_test_pcollector; + static PStatCollector _draw_set_state_depth_write_pcollector; + static PStatCollector _draw_set_state_render_mode_pcollector; + static PStatCollector _draw_set_state_rescale_normal_pcollector; + static PStatCollector _draw_set_state_shade_model_pcollector; + static PStatCollector _draw_set_state_blending_pcollector; + static PStatCollector _draw_set_state_shader_pcollector; + static PStatCollector _draw_set_state_texture_pcollector; + static PStatCollector _draw_set_state_tex_matrix_pcollector; + static PStatCollector _draw_set_state_tex_gen_pcollector; + static PStatCollector _draw_set_state_material_pcollector; + static PStatCollector _draw_set_state_light_pcollector; + static PStatCollector _draw_set_state_stencil_pcollector; + static PStatCollector _draw_set_state_fog_pcollector; + private: - class LightInfo { - public: - INLINE LightInfo(); - NodePath _light; - bool _enabled; - bool _next_enabled; - }; - - pvector _light_info; - bool _lighting_enabled_this_frame; - - class ClipPlaneInfo { - public: - INLINE ClipPlaneInfo(); - NodePath _plane; - bool _enabled; - bool _next_enabled; - }; - - pvector _clip_plane_info; - bool _clip_planes_enabled_this_frame; + int _num_lights_enabled; + int _num_clip_planes_enabled; PT(GraphicsPipe) _pipe; GraphicsEngine *_engine; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 59c002a780..ff1ad1e61b 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -4036,10 +4036,14 @@ do_issue_blending() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: bind_light(PointLight *light_obj, const NodePath &light, int light_id) { + static PStatCollector _draw_set_state_light_bind_point_pcollector("Draw:Set State:Light:Bind:Point"); + PStatTimer timer(_draw_set_state_light_bind_point_pcollector); + + float light_color[4]; GLenum id = get_light_id(light_id); static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f); GLP(Lightfv)(id, GL_AMBIENT, black.get_data()); - GLP(Lightfv)(id, GL_DIFFUSE, get_light_color(light_obj)); + GLP(Lightfv)(id, GL_DIFFUSE, get_light_color(light_color, light_obj)); GLP(Lightfv)(id, GL_SPECULAR, light_obj->get_specular_color().get_data()); // Position needs to specify x, y, z, and w @@ -4076,10 +4080,14 @@ bind_light(PointLight *light_obj, const NodePath &light, int light_id) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) { + static PStatCollector _draw_set_state_light_bind_directional_pcollector("Draw:Set State:Light:Bind:Directional"); + PStatTimer timer(_draw_set_state_light_bind_directional_pcollector); + + float light_color[4]; GLenum id = get_light_id( light_id ); static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f); GLP(Lightfv)(id, GL_AMBIENT, black.get_data()); - GLP(Lightfv)(id, GL_DIFFUSE, get_light_color(light_obj)); + GLP(Lightfv)(id, GL_DIFFUSE, get_light_color(light_color, light_obj)); GLP(Lightfv)(id, GL_SPECULAR, light_obj->get_specular_color().get_data()); // Position needs to specify x, y, z, and w. @@ -4117,13 +4125,17 @@ bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: bind_light(Spotlight *light_obj, const NodePath &light, int light_id) { + static PStatCollector _draw_set_state_light_bind_spotlight_pcollector("Draw:Set State:Light:Bind:Spotlight"); + PStatTimer timer(_draw_set_state_light_bind_spotlight_pcollector); + Lens *lens = light_obj->get_lens(); nassertv(lens != (Lens *)NULL); + float light_color[4]; GLenum id = get_light_id(light_id); static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f); GLP(Lightfv)(id, GL_AMBIENT, black.get_data()); - GLP(Lightfv)(id, GL_DIFFUSE, get_light_color(light_obj)); + GLP(Lightfv)(id, GL_DIFFUSE, get_light_color(light_color, light_obj)); GLP(Lightfv)(id, GL_SPECULAR, light_obj->get_specular_color().get_data()); // Position needs to specify x, y, z, and w @@ -5564,20 +5576,22 @@ print_gfx_visual() { //////////////////////////////////////////////////////////////////// // Function: GLGraphicsStateGuardian::get_light_color // Access: Public -// Description: Returns the array of four floats that should be -// issued as the light's color, as scaled by the current -// value of _light_color_scale, in the case of -// color_scale_via_lighting. +// Description: Fills the array of four floats with the values that +// that should be issued as the light's color, as scaled +// by the current value of _light_color_scale, in the +// case of color_scale_via_lighting. Returns +// light_color. //////////////////////////////////////////////////////////////////// -const float *CLP(GraphicsStateGuardian):: -get_light_color(Light *light) const { - static Colorf c; - c = light->get_color(); - c.set(c[0] * _light_color_scale[0], - c[1] * _light_color_scale[1], - c[2] * _light_color_scale[2], - c[3] * _light_color_scale[3]); - return c.get_data(); +float *CLP(GraphicsStateGuardian):: +get_light_color(float light_color[4], Light *light) const { + const Colorf &c = light->get_color(); + + light_color[0] = c[0] * _light_color_scale[0]; + light_color[1] = c[1] * _light_color_scale[1]; + light_color[2] = c[2] * _light_color_scale[2]; + light_color[3] = c[3] * _light_color_scale[3]; + + return light_color; } //////////////////////////////////////////////////////////////////// @@ -5590,6 +5604,9 @@ get_light_color(Light *light) const { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: enable_lighting(bool enable) { + static PStatCollector _draw_set_state_light_enable_lighting_pcollector("Draw:Set State:Light:Enable lighting"); + PStatTimer timer(_draw_set_state_light_enable_lighting_pcollector); + if (enable) { GLP(Enable)(GL_LIGHTING); } else { @@ -5607,6 +5624,9 @@ enable_lighting(bool enable) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: set_ambient_light(const Colorf &color) { + static PStatCollector _draw_set_state_light_ambient_pcollector("Draw:Set State:Light:Ambient"); + PStatTimer timer(_draw_set_state_light_ambient_pcollector); + Colorf c = color; c.set(c[0] * _light_color_scale[0], c[1] * _light_color_scale[1], @@ -5624,6 +5644,9 @@ set_ambient_light(const Colorf &color) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: enable_light(int light_id, bool enable) { + static PStatCollector _draw_set_state_light_enable_light_pcollector("Draw:Set State:Light:Enable light"); + PStatTimer timer(_draw_set_state_light_enable_light_pcollector); + if (enable) { GLP(Enable)(get_light_id(light_id)); } else { @@ -5645,6 +5668,9 @@ enable_light(int light_id, bool enable) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: begin_bind_lights() { + static PStatCollector _draw_set_state_light_begin_bind_pcollector("Draw:Set State:Light:Begin bind"); + PStatTimer timer(_draw_set_state_light_begin_bind_pcollector); + // We need to temporarily load a new matrix so we can define the // light in a known coordinate system. We pick the transform of the // root. (Alternatively, we could leave the current transform where @@ -5671,6 +5697,9 @@ begin_bind_lights() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: end_bind_lights() { + static PStatCollector _draw_set_state_light_end_bind_pcollector("Draw:Set State:Light:End bind"); + PStatTimer timer(_draw_set_state_light_end_bind_pcollector); + GLP(MatrixMode)(GL_MODELVIEW); GLP(PopMatrix)(); } @@ -5787,9 +5816,10 @@ set_state_and_transform(const RenderState *target, #endif _state_pcollector.add_level(1); - PStatTimer timer(_draw_set_state_pcollector); + PStatTimer timer1(_draw_set_state_pcollector); if (transform != _internal_transform) { + PStatTimer timer(_draw_set_state_transform_pcollector); _state_pcollector.add_level(1); _internal_transform = transform; do_issue_transform(); @@ -5804,22 +5834,26 @@ set_state_and_transform(const RenderState *target, _state_rs = 0; if (_target._alpha_test != _state._alpha_test) { + PStatTimer timer(_draw_set_state_alpha_test_pcollector); do_issue_alpha_test(); _state._alpha_test = _target._alpha_test; } if (_target._antialias != _state._antialias) { + PStatTimer timer(_draw_set_state_antialias_pcollector); do_issue_antialias(); _state._antialias = _target._antialias; } if (_target._clip_plane != _state._clip_plane) { + PStatTimer timer(_draw_set_state_clip_plane_pcollector); do_issue_clip_plane(); _state._clip_plane = _target._clip_plane; } if (_target._color != _state._color || _target._color_scale != _state._color_scale) { + PStatTimer timer(_draw_set_state_color_pcollector); do_issue_color(); do_issue_color_scale(); _state._color = _target._color; @@ -5827,36 +5861,43 @@ set_state_and_transform(const RenderState *target, } if (_target._cull_face != _state._cull_face) { + PStatTimer timer(_draw_set_state_cull_face_pcollector); do_issue_cull_face(); _state._cull_face = _target._cull_face; } if (_target._depth_offset != _state._depth_offset) { + PStatTimer timer(_draw_set_state_depth_offset_pcollector); do_issue_depth_offset(); _state._depth_offset = _target._depth_offset; } if (_target._depth_test != _state._depth_test) { + PStatTimer timer(_draw_set_state_depth_test_pcollector); do_issue_depth_test(); _state._depth_test = _target._depth_test; } if (_target._depth_write != _state._depth_write) { + PStatTimer timer(_draw_set_state_depth_write_pcollector); do_issue_depth_write(); _state._depth_write = _target._depth_write; } if (_target._render_mode != _state._render_mode) { + PStatTimer timer(_draw_set_state_render_mode_pcollector); do_issue_render_mode(); _state._render_mode = _target._render_mode; } if (_target._rescale_normal != _state._rescale_normal) { + PStatTimer timer(_draw_set_state_rescale_normal_pcollector); do_issue_rescale_normal(); _state._rescale_normal = _target._rescale_normal; } if (_target._shade_model != _state._shade_model) { + PStatTimer timer(_draw_set_state_shade_model_pcollector); do_issue_shade_model(); _state._shade_model = _target._shade_model; } @@ -5864,6 +5905,7 @@ set_state_and_transform(const RenderState *target, if ((_target._transparency != _state._transparency)|| (_target._color_write != _state._color_write)|| (_target._color_blend != _state._color_blend)) { + PStatTimer timer(_draw_set_state_blending_pcollector); do_issue_blending(); _state._transparency = _target._transparency; _state._color_write = _target._color_write; @@ -5871,12 +5913,14 @@ set_state_and_transform(const RenderState *target, } if (_target._shader != _state._shader) { + PStatTimer timer(_draw_set_state_shader_pcollector); do_issue_shader(); _state._shader = _target._shader; _state._texture = 0; } if (_target._texture != _state._texture) { + PStatTimer timer(_draw_set_state_texture_pcollector); determine_effective_texture(); int prev_active = _num_active_texture_stages; do_issue_texture(); @@ -5902,32 +5946,38 @@ set_state_and_transform(const RenderState *target, } if (_target._tex_matrix != _state._tex_matrix) { + PStatTimer timer(_draw_set_state_tex_matrix_pcollector); do_issue_tex_matrix(); _state._tex_matrix = _target._tex_matrix; } if (_effective_tex_gen != _state._tex_gen) { + PStatTimer timer(_draw_set_state_tex_gen_pcollector); do_issue_tex_gen(); _state._tex_gen = _effective_tex_gen; } if (_target._material != _state._material) { + PStatTimer timer(_draw_set_state_material_pcollector); do_issue_material(); _state._material = _target._material; } if (_target._light != _state._light) { + PStatTimer timer(_draw_set_state_light_pcollector); do_issue_light(); _state._light = _target._light; } if (_target._stencil != _state._stencil) { + PStatTimer timer(_draw_set_state_stencil_pcollector); do_issue_stencil(); _state._stencil = _target._stencil; } if (_current_shader_context == 0) { if (_target._fog != _state._fog) { + PStatTimer timer(_draw_set_state_fog_pcollector); do_issue_fog(); _state._fog = _target._fog; } diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 795ebf3c45..d98b104393 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -179,11 +179,7 @@ public: void print_gfx_visual(); - //For those interested in what the guardian thinks is the current - //enabled/disable GL State compared to what GL says it is - void dump_state(); - - const float *get_light_color(Light *light) const; + float *get_light_color(float light_color[4], Light *light) const; #ifdef SUPPORT_IMMEDIATE_MODE void draw_immediate_simple_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode); diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index e222518cee..b834cc715b 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/panda/src/pgraph/nodePath.cxx @@ -66,6 +66,8 @@ #include "bamFile.h" #include "preparedGraphicsObjects.h" #include "dcast.h" +#include "pStatCollector.h" +#include "pStatTimer.h" // stack seems to overflow on Intel C++ at 7000. If we need more than // 7000, need to increase stack size. @@ -706,6 +708,8 @@ get_transform(Thread *current_thread) const { CPT(TransformState) NodePath:: get_transform(const NodePath &other, Thread *current_thread) const { nassertr(_error_type == ET_ok && other._error_type == ET_ok, TransformState::make_identity()); + static PStatCollector _get_transform_pcollector("*:NodePath:get_transform"); + PStatTimer timer(_get_transform_pcollector); if (other.is_empty()) { return get_net_transform(current_thread); @@ -713,7 +717,7 @@ get_transform(const NodePath &other, Thread *current_thread) const { if (is_empty()) { return other.get_net_transform(current_thread)->invert_compose(TransformState::make_identity()); } - + nassertr(verify_complete(current_thread), TransformState::make_identity()); nassertr(other.verify_complete(current_thread), TransformState::make_identity()); @@ -744,6 +748,7 @@ get_transform(const NodePath &other, Thread *current_thread) const { a_transform = r_get_net_transform(_head, current_thread); b_transform = r_get_net_transform(other._head, current_thread); } + return b_transform->invert_compose(a_transform); } @@ -5523,7 +5528,7 @@ verify_complete(Thread *current_thread) const { } #ifdef HAVE_THREADS - if (Thread::is_threading_supported()) { + if (Thread::is_true_threads()) { // In a threaded environment, we can't reliably test this, since a // sub-thread may be mucking with the NodePath's ancestry as we // try to validate it. NodePaths are inherently not thread-safe, @@ -5532,6 +5537,9 @@ verify_complete(Thread *current_thread) const { } #endif // HAVE_THREADS + static PStatCollector _verify_complete_pcollector("*:NodePath:verify_complete"); + PStatTimer timer(_verify_complete_pcollector); + const NodePathComponent *comp = _head; nassertr(comp != (const NodePathComponent *)NULL, false); diff --git a/panda/src/pgraph/renderEffects.cxx b/panda/src/pgraph/renderEffects.cxx index 85423ca00d..8f26de304b 100644 --- a/panda/src/pgraph/renderEffects.cxx +++ b/panda/src/pgraph/renderEffects.cxx @@ -193,32 +193,9 @@ bool RenderEffects:: operator < (const RenderEffects &other) const { // We must compare all the properties of the effects, not just // the type; thus, we compare them one at a time using compare_to(). - - // We could use STL's lexicographical_compare() function here, but - // it seems to generate aberrant behavior on OSX and Linux. We - // suspect a compiler bug in gcc. Instead, we implement the - // comparison by hand. - Effects::const_iterator ai = _effects.begin(); - Effects::const_iterator bi = other._effects.begin(); - while (ai != _effects.end() && bi != other._effects.end()) { - int compare = (*ai).compare_to(*bi); - if (compare != 0) { - return compare < 0; - } - ++ai; - ++bi; - } - if (ai != _effects.end()) { - // bi ran out first.. - return false; - } - if (bi != other._effects.end()) { - // ai ran out first. - return true; - } - - // Lists are equivalent. - return false; + return lexicographical_compare(_effects.begin(), _effects.end(), + other._effects.begin(), other._effects.end(), + CompareTo()); } diff --git a/panda/src/pstatclient/pStatProperties.cxx b/panda/src/pstatclient/pStatProperties.cxx index 153e1b7fbe..d57da6ad4a 100644 --- a/panda/src/pstatclient/pStatProperties.cxx +++ b/panda/src/pstatclient/pStatProperties.cxx @@ -142,6 +142,7 @@ static TimeCollectorProperties time_properties[] = { { 1, "*:Animation", { 1.0, 0.0, 1.0 } }, { 0, "*:Flatten", { 0.0, 0.7, 0.4 } }, { 0, "*:State Cache", { 0.4, 0.7, 0.7 } }, + { 0, "*:NodePath", { 0.1, 0.6, 0.8 } }, { 1, "Draw", { 0.83, 0.02, 0.01 }, 1.0 / 30.0 }, { 1, "Draw:Make current", { 0.4, 0.2, 0.6 } }, { 1, "Draw:Copy texture", { 0.2, 0.6, 0.4 } },