From ddd104646249a91e5aa427431a9d8cdfde67acbe Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 26 Apr 2006 07:31:23 +0000 Subject: [PATCH] factor out Thread::get_current_thread() some more --- panda/src/char/character.cxx | 3 +- panda/src/char/character.h | 3 +- panda/src/collide/collisionNode.cxx | 4 +- panda/src/collide/collisionNode.h | 2 +- panda/src/cull/cullBinBackToFront.cxx | 8 +- panda/src/cull/cullBinBackToFront.h | 4 +- panda/src/cull/cullBinFixed.cxx | 8 +- panda/src/cull/cullBinFixed.h | 4 +- panda/src/cull/cullBinFrontToBack.cxx | 8 +- panda/src/cull/cullBinFrontToBack.h | 4 +- panda/src/cull/cullBinOcclusionTest.cxx | 12 +- panda/src/cull/cullBinOcclusionTest.h | 4 +- panda/src/cull/cullBinStateSorted.cxx | 8 +- panda/src/cull/cullBinStateSorted.h | 4 +- panda/src/cull/cullBinUnsorted.cxx | 4 +- panda/src/cull/cullBinUnsorted.h | 2 +- panda/src/cull/drawCullHandler.cxx | 2 +- panda/src/dgraph/dataGraphTraverser.cxx | 11 +- panda/src/dgraph/dataGraphTraverser.h | 4 +- panda/src/display/displayRegion.I | 13 +- panda/src/display/displayRegion.cxx | 6 +- panda/src/display/displayRegion.h | 8 +- panda/src/display/graphicsEngine.cxx | 83 ++-- panda/src/display/graphicsEngine.h | 2 +- panda/src/display/graphicsOutput.cxx | 4 +- panda/src/display/graphicsOutput.h | 4 +- panda/src/display/graphicsStateGuardian.cxx | 8 +- panda/src/display/graphicsStateGuardian.h | 4 +- panda/src/display/parasiteBuffer.cxx | 8 +- panda/src/display/parasiteBuffer.h | 4 +- panda/src/display/standardMunger.cxx | 3 +- panda/src/display/standardMunger.h | 3 +- panda/src/distort/projectionScreen.cxx | 10 +- panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx | 8 +- panda/src/dxgsg8/dxGraphicsStateGuardian8.h | 4 +- panda/src/dxgsg8/wdxGraphicsBuffer8.cxx | 8 +- panda/src/dxgsg8/wdxGraphicsBuffer8.h | 4 +- panda/src/dxgsg8/wdxGraphicsWindow8.cxx | 4 +- panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 8 +- panda/src/dxgsg9/dxGraphicsStateGuardian9.h | 4 +- panda/src/dxgsg9/wdxGraphicsBuffer9.cxx | 8 +- panda/src/dxgsg9/wdxGraphicsBuffer9.h | 4 +- panda/src/dxgsg9/wdxGraphicsWindow9.cxx | 8 +- panda/src/framework/pandaFramework.cxx | 7 +- panda/src/framework/pandaFramework.h | 2 +- panda/src/glstuff/glGraphicsBuffer_src.cxx | 8 +- panda/src/glstuff/glGraphicsBuffer_src.h | 4 +- .../glstuff/glGraphicsStateGuardian_src.cxx | 39 +- .../src/glstuff/glGraphicsStateGuardian_src.h | 7 +- panda/src/glxdisplay/glxGraphicsBuffer.cxx | 10 +- panda/src/glxdisplay/glxGraphicsBuffer.h | 4 +- panda/src/glxdisplay/glxGraphicsWindow.cxx | 10 +- panda/src/glxdisplay/glxGraphicsWindow.h | 4 +- panda/src/gobj/bufferResidencyTracker.cxx | 6 +- panda/src/gobj/bufferResidencyTracker.h | 4 +- panda/src/gobj/geom.I | 16 +- panda/src/gobj/geom.cxx | 22 +- panda/src/gobj/geom.h | 13 +- panda/src/gobj/geomMunger.cxx | 13 +- panda/src/gobj/geomMunger.h | 6 +- panda/src/gobj/geomPrimitive.cxx | 10 +- panda/src/gobj/geomPrimitive.h | 3 +- panda/src/gobj/geomVertexData.cxx | 5 +- panda/src/gobj/geomVertexData.h | 2 +- panda/src/gobj/geomVertexReader.I | 29 +- panda/src/gobj/geomVertexReader.h | 17 +- panda/src/gobj/geomVertexWriter.I | 28 +- panda/src/gobj/geomVertexWriter.h | 17 +- panda/src/gobj/preparedGraphicsObjects.cxx | 20 +- panda/src/gobj/preparedGraphicsObjects.h | 5 +- panda/src/grutil/multitexReducer.cxx | 11 +- panda/src/parametrics/ropeNode.cxx | 17 +- panda/src/parametrics/ropeNode.h | 5 +- panda/src/parametrics/sheetNode.cxx | 17 +- panda/src/parametrics/sheetNode.h | 5 +- panda/src/pgraph/cullBin.cxx | 12 +- panda/src/pgraph/cullBin.h | 4 +- panda/src/pgraph/cullResult.cxx | 11 +- panda/src/pgraph/cullResult.h | 2 +- panda/src/pgraph/cullTraverser.I | 11 + panda/src/pgraph/cullTraverser.cxx | 15 +- panda/src/pgraph/cullTraverser.h | 4 +- panda/src/pgraph/cullTraverserData.I | 6 +- panda/src/pgraph/cullTraverserData.h | 2 +- panda/src/pgraph/cullableObject.cxx | 72 ++-- panda/src/pgraph/geomNode.cxx | 24 +- panda/src/pgraph/geomNode.h | 5 +- panda/src/pgraph/nodePath.I | 113 +++--- panda/src/pgraph/nodePath.cxx | 321 ++++++++------- panda/src/pgraph/nodePath.h | 135 ++++--- panda/src/pgraph/nodePathComponent.cxx | 37 +- panda/src/pgraph/nodePathComponent.h | 14 +- panda/src/pgraph/pandaNode.I | 174 +++++--- panda/src/pgraph/pandaNode.cxx | 378 +++++++++--------- panda/src/pgraph/pandaNode.h | 150 +++---- panda/src/pgraph/planeNode.cxx | 4 +- panda/src/pgraph/planeNode.h | 2 +- panda/src/pgraph/portalNode.cxx | 4 +- panda/src/pgraph/portalNode.h | 2 +- panda/src/pgraph/workingNodePath.cxx | 14 +- panda/src/pgui/pgItem.cxx | 4 +- panda/src/pgui/pgItem.h | 2 +- panda/src/pgui/pgVirtualFrame.cxx | 5 +- panda/src/pgui/pgVirtualFrame.h | 3 +- panda/src/pstatclient/pStatClient.I | 18 +- panda/src/pstatclient/pStatClient.cxx | 28 +- panda/src/pstatclient/pStatClient.h | 2 +- panda/src/pstatclient/pStatClientImpl.I | 25 +- panda/src/pstatclient/pStatClientImpl.cxx | 11 +- panda/src/pstatclient/pStatClientImpl.h | 9 +- panda/src/pstatclient/pStatCollector.h | 2 + panda/src/pstatclient/pStatThread.I | 11 +- panda/src/pstatclient/pStatTimer.I | 20 +- panda/src/pstatclient/pStatTimer.h | 5 +- panda/src/putil/clockObject.I | 31 +- panda/src/putil/clockObject.cxx | 22 +- panda/src/putil/clockObject.h | 22 +- panda/src/testbed/pview.cxx | 11 +- panda/src/text/textAssembler.cxx | 17 +- panda/src/text/textAssembler.h | 2 +- panda/src/text/textNode.cxx | 11 +- panda/src/text/textNode.h | 5 +- panda/src/tform/driveInterface.cxx | 2 +- panda/src/wgldisplay/wglGraphicsBuffer.cxx | 8 +- panda/src/wgldisplay/wglGraphicsBuffer.h | 4 +- panda/src/wgldisplay/wglGraphicsWindow.cxx | 8 +- panda/src/wgldisplay/wglGraphicsWindow.h | 4 +- 127 files changed, 1375 insertions(+), 1118 deletions(-) diff --git a/panda/src/char/character.cxx b/panda/src/char/character.cxx index f7793919e1..dad4fa72f9 100644 --- a/panda/src/char/character.cxx +++ b/panda/src/char/character.cxx @@ -277,7 +277,8 @@ copy_joints(PartGroup *copy, PartGroup *orig) { // override this function. //////////////////////////////////////////////////////////////////// void Character:: -r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map) { +r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map, + Thread *current_thread) { // We assume there will be no instancing going on below the // Character node. If there is, too bad; it will get flattened out. diff --git a/panda/src/char/character.h b/panda/src/char/character.h index 3a904056eb..07fc645eae 100644 --- a/panda/src/char/character.h +++ b/panda/src/char/character.h @@ -82,7 +82,8 @@ private: typedef pmap GeomJointMap; typedef pmap GeomSliderMap; - virtual void r_copy_children(const PandaNode *from, InstanceMap &inst_map); + virtual void r_copy_children(const PandaNode *from, InstanceMap &inst_map, + Thread *current_thread); void fill_joint_map(JointMap &joint_map, PartGroup *copy, PartGroup *orig); void r_copy_char(PandaNode *dest, const PandaNode *source, const Character *from, NodeMap &node_map, diff --git a/panda/src/collide/collisionNode.cxx b/panda/src/collide/collisionNode.cxx index d46df709bd..f576719802 100644 --- a/panda/src/collide/collisionNode.cxx +++ b/panda/src/collide/collisionNode.cxx @@ -371,9 +371,9 @@ get_collide_geom() const { // thing. //////////////////////////////////////////////////////////////////// PT(BoundingVolume) CollisionNode:: -compute_internal_bounds(int pipeline_stage) const { +compute_internal_bounds(int pipeline_stage, Thread *current_thread) const { // First, get ourselves a fresh, empty bounding volume. - PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage); + PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage, current_thread); nassertr(bound != (BoundingVolume *)NULL, bound); // Now actually compute the bounding volume by putting it around all diff --git a/panda/src/collide/collisionNode.h b/panda/src/collide/collisionNode.h index 1937fedf86..213a91bc80 100644 --- a/panda/src/collide/collisionNode.h +++ b/panda/src/collide/collisionNode.h @@ -75,7 +75,7 @@ PUBLISHED: INLINE static CollideMask get_default_collide_mask(); protected: - virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const; + virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage, Thread *current_thread) const; private: CPT(RenderState) get_last_pos_state(); diff --git a/panda/src/cull/cullBinBackToFront.cxx b/panda/src/cull/cullBinBackToFront.cxx index 2c2c6f8f60..f3c6a5403b 100644 --- a/panda/src/cull/cullBinBackToFront.cxx +++ b/panda/src/cull/cullBinBackToFront.cxx @@ -59,7 +59,7 @@ make_bin(const string &name, GraphicsStateGuardianBase *gsg) { // the bin for rendering. //////////////////////////////////////////////////////////////////// void CullBinBackToFront:: -add_object(CullableObject *object) { +add_object(CullableObject *object, Thread *current_thread) { // Determine the center of the bounding volume. CPT(BoundingVolume) volume = object->_geom->get_bounds(); @@ -86,8 +86,8 @@ add_object(CullableObject *object) { // draw. //////////////////////////////////////////////////////////////////// void CullBinBackToFront:: -finish_cull(SceneSetup *) { - PStatTimer timer(_cull_this_pcollector); +finish_cull(SceneSetup *, Thread *current_thread) { + PStatTimer timer(_cull_this_pcollector, current_thread); sort(_objects.begin(), _objects.end()); } @@ -99,7 +99,7 @@ finish_cull(SceneSetup *) { //////////////////////////////////////////////////////////////////// void CullBinBackToFront:: draw(Thread *current_thread) { - PStatTimer timer(_draw_this_pcollector); + PStatTimer timer(_draw_this_pcollector, current_thread); Objects::const_iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi)._object; diff --git a/panda/src/cull/cullBinBackToFront.h b/panda/src/cull/cullBinBackToFront.h index 6fe980e633..7a03ef7063 100644 --- a/panda/src/cull/cullBinBackToFront.h +++ b/panda/src/cull/cullBinBackToFront.h @@ -43,8 +43,8 @@ public: static CullBin *make_bin(const string &name, GraphicsStateGuardianBase *gsg); - virtual void add_object(CullableObject *object); - virtual void finish_cull(SceneSetup *scene_setup); + virtual void add_object(CullableObject *object, Thread *current_thread); + virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread); virtual void draw(Thread *current_thread); private: diff --git a/panda/src/cull/cullBinFixed.cxx b/panda/src/cull/cullBinFixed.cxx index a7de0694d5..3456616bbd 100644 --- a/panda/src/cull/cullBinFixed.cxx +++ b/panda/src/cull/cullBinFixed.cxx @@ -59,7 +59,7 @@ make_bin(const string &name, GraphicsStateGuardianBase *gsg) { // the bin for rendering. //////////////////////////////////////////////////////////////////// void CullBinFixed:: -add_object(CullableObject *object) { +add_object(CullableObject *object, Thread *current_thread) { int draw_order = object->_state->get_draw_order(); _objects.push_back(ObjectData(object, draw_order)); } @@ -74,8 +74,8 @@ add_object(CullableObject *object) { // draw. //////////////////////////////////////////////////////////////////// void CullBinFixed:: -finish_cull(SceneSetup *) { - PStatTimer timer(_cull_this_pcollector); +finish_cull(SceneSetup *, Thread *current_thread) { + PStatTimer timer(_cull_this_pcollector, current_thread); stable_sort(_objects.begin(), _objects.end()); } @@ -87,7 +87,7 @@ finish_cull(SceneSetup *) { //////////////////////////////////////////////////////////////////// void CullBinFixed:: draw(Thread *current_thread) { - PStatTimer timer(_draw_this_pcollector); + PStatTimer timer(_draw_this_pcollector, current_thread); Objects::const_iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi)._object; diff --git a/panda/src/cull/cullBinFixed.h b/panda/src/cull/cullBinFixed.h index a0b3a98b3f..a9455e9024 100644 --- a/panda/src/cull/cullBinFixed.h +++ b/panda/src/cull/cullBinFixed.h @@ -45,8 +45,8 @@ public: static CullBin *make_bin(const string &name, GraphicsStateGuardianBase *gsg); - virtual void add_object(CullableObject *object); - virtual void finish_cull(SceneSetup *scene_setup); + virtual void add_object(CullableObject *object, Thread *current_thread); + virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread); virtual void draw(Thread *current_thread); private: diff --git a/panda/src/cull/cullBinFrontToBack.cxx b/panda/src/cull/cullBinFrontToBack.cxx index 01ecb46ba5..4bda787cc4 100644 --- a/panda/src/cull/cullBinFrontToBack.cxx +++ b/panda/src/cull/cullBinFrontToBack.cxx @@ -59,7 +59,7 @@ make_bin(const string &name, GraphicsStateGuardianBase *gsg) { // the bin for rendering. //////////////////////////////////////////////////////////////////// void CullBinFrontToBack:: -add_object(CullableObject *object) { +add_object(CullableObject *object, Thread *current_thread) { // Determine the center of the bounding volume. CPT(BoundingVolume) volume = object->_geom->get_bounds(); @@ -86,8 +86,8 @@ add_object(CullableObject *object) { // draw. //////////////////////////////////////////////////////////////////// void CullBinFrontToBack:: -finish_cull(SceneSetup *) { - PStatTimer timer(_cull_this_pcollector); +finish_cull(SceneSetup *, Thread *current_thread) { + PStatTimer timer(_cull_this_pcollector, current_thread); sort(_objects.begin(), _objects.end()); } @@ -99,7 +99,7 @@ finish_cull(SceneSetup *) { //////////////////////////////////////////////////////////////////// void CullBinFrontToBack:: draw(Thread *current_thread) { - PStatTimer timer(_draw_this_pcollector); + PStatTimer timer(_draw_this_pcollector, current_thread); Objects::const_iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi)._object; diff --git a/panda/src/cull/cullBinFrontToBack.h b/panda/src/cull/cullBinFrontToBack.h index 635f88b014..f952af43b0 100644 --- a/panda/src/cull/cullBinFrontToBack.h +++ b/panda/src/cull/cullBinFrontToBack.h @@ -43,8 +43,8 @@ public: static CullBin *make_bin(const string &name, GraphicsStateGuardianBase *gsg); - virtual void add_object(CullableObject *object); - virtual void finish_cull(SceneSetup *scene_setup); + virtual void add_object(CullableObject *object, Thread *current_thread); + virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread); virtual void draw(Thread *current_thread); private: diff --git a/panda/src/cull/cullBinOcclusionTest.cxx b/panda/src/cull/cullBinOcclusionTest.cxx index eaee817edb..aba3a6fcf8 100644 --- a/panda/src/cull/cullBinOcclusionTest.cxx +++ b/panda/src/cull/cullBinOcclusionTest.cxx @@ -116,7 +116,7 @@ make_next() const { // the bin for rendering. //////////////////////////////////////////////////////////////////// void CullBinOcclusionTest:: -add_object(CullableObject *object) { +add_object(CullableObject *object, Thread *current_thread) { // Determine the world-space bounding sphere for the object. CPT(BoundingVolume) volume = object->_geom->get_bounds(); if (volume->is_empty()) { @@ -151,8 +151,8 @@ add_object(CullableObject *object) { // draw. //////////////////////////////////////////////////////////////////// void CullBinOcclusionTest:: -finish_cull(SceneSetup *scene_setup) { - PStatTimer timer(_cull_this_pcollector); +finish_cull(SceneSetup *scene_setup, Thread *current_thread) { + PStatTimer timer(_cull_this_pcollector, current_thread); // Now we have a loose list of objects that are to be rendered. // We'd rather have them in an octree, which has much better @@ -196,7 +196,7 @@ finish_cull(SceneSetup *scene_setup) { //////////////////////////////////////////////////////////////////// void CullBinOcclusionTest:: draw(Thread *current_thread) { - PStatTimer timer(_draw_this_pcollector); + PStatTimer timer(_draw_this_pcollector, current_thread); // We'll want to know the near plane distance. _near_distance = _gsg->get_scene()->get_lens()->get_near(); @@ -494,7 +494,7 @@ occlusion_test(CullBinOcclusionTest &bin, Thread *current_thread) { CPT(Geom) viz = get_octree_solid_test(); CPT(GeomVertexData) munged_data = viz->get_vertex_data(); - munger->munge_geom(viz, munged_data); + munger->munge_geom(viz, munged_data, current_thread); bin._gsg->set_state_and_transform(state, internal_transform); @@ -632,7 +632,7 @@ draw_wireframe(CullBinOcclusionTest &bin, Thread *current_thread) { CPT(Geom) viz = get_octree_wireframe_viz(); CPT(GeomVertexData) munged_data = viz->get_vertex_data(); - munger->munge_geom(viz, munged_data); + munger->munge_geom(viz, munged_data, current_thread); bin._gsg->set_state_and_transform(state, internal_transform); viz->draw(bin._gsg, munger, munged_data, current_thread); diff --git a/panda/src/cull/cullBinOcclusionTest.h b/panda/src/cull/cullBinOcclusionTest.h index db60b5b040..ad563949b3 100644 --- a/panda/src/cull/cullBinOcclusionTest.h +++ b/panda/src/cull/cullBinOcclusionTest.h @@ -57,8 +57,8 @@ public: static CullBin *make_bin(const string &name, GraphicsStateGuardianBase *gsg); virtual PT(CullBin) make_next() const; - virtual void add_object(CullableObject *object); - virtual void finish_cull(SceneSetup *scene_setup); + virtual void add_object(CullableObject *object, Thread *current_thread); + virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread); virtual void draw(Thread *current_thread); private: diff --git a/panda/src/cull/cullBinStateSorted.cxx b/panda/src/cull/cullBinStateSorted.cxx index 9568140bad..a7f0da0987 100644 --- a/panda/src/cull/cullBinStateSorted.cxx +++ b/panda/src/cull/cullBinStateSorted.cxx @@ -58,7 +58,7 @@ make_bin(const string &name, GraphicsStateGuardianBase *gsg) { // the bin for rendering. //////////////////////////////////////////////////////////////////// void CullBinStateSorted:: -add_object(CullableObject *object) { +add_object(CullableObject *object, Thread *current_thread) { _objects.push_back(ObjectData(object)); } @@ -72,8 +72,8 @@ add_object(CullableObject *object) { // draw. //////////////////////////////////////////////////////////////////// void CullBinStateSorted:: -finish_cull(SceneSetup *) { - PStatTimer timer(_cull_this_pcollector); +finish_cull(SceneSetup *, Thread *current_thread) { + PStatTimer timer(_cull_this_pcollector, current_thread); sort(_objects.begin(), _objects.end()); } @@ -86,7 +86,7 @@ finish_cull(SceneSetup *) { //////////////////////////////////////////////////////////////////// void CullBinStateSorted:: draw(Thread *current_thread) { - PStatTimer timer(_draw_this_pcollector); + PStatTimer timer(_draw_this_pcollector, current_thread); Objects::const_iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi)._object; diff --git a/panda/src/cull/cullBinStateSorted.h b/panda/src/cull/cullBinStateSorted.h index c52405e606..d4ea4ebfbc 100644 --- a/panda/src/cull/cullBinStateSorted.h +++ b/panda/src/cull/cullBinStateSorted.h @@ -47,8 +47,8 @@ public: static CullBin *make_bin(const string &name, GraphicsStateGuardianBase *gsg); - virtual void add_object(CullableObject *object); - virtual void finish_cull(SceneSetup *scene_setup); + virtual void add_object(CullableObject *object, Thread *current_thread); + virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread); virtual void draw(Thread *current_thread); private: diff --git a/panda/src/cull/cullBinUnsorted.cxx b/panda/src/cull/cullBinUnsorted.cxx index 557d59c30b..463ad29411 100644 --- a/panda/src/cull/cullBinUnsorted.cxx +++ b/panda/src/cull/cullBinUnsorted.cxx @@ -55,7 +55,7 @@ make_bin(const string &name, GraphicsStateGuardianBase *gsg) { // the bin for rendering. //////////////////////////////////////////////////////////////////// void CullBinUnsorted:: -add_object(CullableObject *object) { +add_object(CullableObject *object, Thread *current_thread) { _objects.push_back(object); } @@ -67,7 +67,7 @@ add_object(CullableObject *object) { //////////////////////////////////////////////////////////////////// void CullBinUnsorted:: draw(Thread *current_thread) { - PStatTimer timer(_draw_this_pcollector); + PStatTimer timer(_draw_this_pcollector, current_thread); Objects::iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi); diff --git a/panda/src/cull/cullBinUnsorted.h b/panda/src/cull/cullBinUnsorted.h index 1f00f8cc03..506a9c90f8 100644 --- a/panda/src/cull/cullBinUnsorted.h +++ b/panda/src/cull/cullBinUnsorted.h @@ -38,7 +38,7 @@ public: static CullBin *make_bin(const string &name, GraphicsStateGuardianBase *gsg); - virtual void add_object(CullableObject *object); + virtual void add_object(CullableObject *object, Thread *current_thread); virtual void draw(Thread *current_thread); private: diff --git a/panda/src/cull/drawCullHandler.cxx b/panda/src/cull/drawCullHandler.cxx index 373bfd3f85..713a3f8161 100644 --- a/panda/src/cull/drawCullHandler.cxx +++ b/panda/src/cull/drawCullHandler.cxx @@ -38,6 +38,6 @@ record_object(CullableObject *object, const CullTraverser *traverser) { object->munge_geom(_gsg, _gsg->get_geom_munger(object->_state), traverser); // And draw the object, then dispense with it. - draw(object, _gsg, Thread::get_current_thread()); + draw(object, _gsg, traverser->get_current_thread()); delete object; } diff --git a/panda/src/dgraph/dataGraphTraverser.cxx b/panda/src/dgraph/dataGraphTraverser.cxx index 195dd088c0..81e96b728c 100644 --- a/panda/src/dgraph/dataGraphTraverser.cxx +++ b/panda/src/dgraph/dataGraphTraverser.cxx @@ -47,7 +47,7 @@ set_data(int parent_index, const DataNodeTransmit &data) { // Description: //////////////////////////////////////////////////////////////////// DataGraphTraverser:: -DataGraphTraverser() { +DataGraphTraverser(Thread *current_thread) : _current_thread(current_thread) { } //////////////////////////////////////////////////////////////////// @@ -69,9 +69,8 @@ void DataGraphTraverser:: traverse(PandaNode *node) { if (node->is_of_type(DataNode::get_class_type())) { DataNode *data_node = DCAST(DataNode, node); - int num_parents = data_node->get_num_parents(); // We must start the traversal at the root of the graph. - nassertv(num_parents == 0); + nassertv(data_node->get_num_parents(_current_thread) == 0); r_transmit(data_node, (DataNodeTransmit *)NULL); @@ -91,7 +90,7 @@ traverse(PandaNode *node) { //////////////////////////////////////////////////////////////////// void DataGraphTraverser:: traverse_below(PandaNode *node, const DataNodeTransmit &output) { - PandaNode::Children cr = node->get_children(); + PandaNode::Children cr = node->get_children(_current_thread); int num_children = cr.get_num_children(); for (int i = 0; i < num_children; i++) { @@ -101,7 +100,7 @@ traverse_below(PandaNode *node, const DataNodeTransmit &output) { // If it's a DataNode-type child, we need to pass it the data. // Maybe it has only one parent, and can accept the data // immediately. - int num_parents = data_node->get_num_parents(); + int num_parents = data_node->get_num_parents(_current_thread); if (num_parents == 1) { // The easy, common case: only one parent. We make our output // into a one-element array of inputs by turning it into a @@ -112,7 +111,7 @@ traverse_below(PandaNode *node, const DataNodeTransmit &output) { // instances together, meaning we must hold onto this node // until we have reached it through all paths. CollectedData &collected_data = _multipass_data[data_node]; - int parent_index = data_node->find_parent(node); + int parent_index = data_node->find_parent(node, _current_thread); nassertv(parent_index != -1); collected_data.set_data(parent_index, output); diff --git a/panda/src/dgraph/dataGraphTraverser.h b/panda/src/dgraph/dataGraphTraverser.h index 1c607213c4..df7b8d6a8c 100644 --- a/panda/src/dgraph/dataGraphTraverser.h +++ b/panda/src/dgraph/dataGraphTraverser.h @@ -38,7 +38,7 @@ class PandaNode; //////////////////////////////////////////////////////////////////// class EXPCL_PANDA DataGraphTraverser { PUBLISHED: - DataGraphTraverser(); + DataGraphTraverser(Thread *current_thread); ~DataGraphTraverser(); void traverse(PandaNode *node); @@ -50,6 +50,8 @@ private: typedef pvector DataVector; + Thread *_current_thread; + class CollectedData { public: INLINE CollectedData(); diff --git a/panda/src/display/displayRegion.I b/panda/src/display/displayRegion.I index 4c547fc09c..c51d3cbd74 100644 --- a/panda/src/display/displayRegion.I +++ b/panda/src/display/displayRegion.I @@ -305,8 +305,9 @@ get_pixel_height() const { // to all upstream pipeline stages. //////////////////////////////////////////////////////////////////// INLINE void DisplayRegion:: -set_cull_result(CullResult *cull_result, SceneSetup *scene_setup) { - CDCullWriter cdata(_cycler_cull, true); +set_cull_result(CullResult *cull_result, SceneSetup *scene_setup, + Thread *current_thread) { + CDCullWriter cdata(_cycler_cull, true, current_thread); cdata->_cull_result = cull_result; cdata->_scene_setup = scene_setup; } @@ -321,8 +322,8 @@ set_cull_result(CullResult *cull_result, SceneSetup *scene_setup) { // directly. //////////////////////////////////////////////////////////////////// INLINE CullResult *DisplayRegion:: -get_cull_result() const { - CDCullReader cdata(_cycler_cull); +get_cull_result(Thread *current_thread) const { + CDCullReader cdata(_cycler_cull, current_thread); return cdata->_cull_result; } @@ -336,8 +337,8 @@ get_cull_result() const { // directly. //////////////////////////////////////////////////////////////////// INLINE SceneSetup *DisplayRegion:: -get_scene_setup() const { - CDCullReader cdata(_cycler_cull); +get_scene_setup(Thread *current_thread) const { + CDCullReader cdata(_cycler_cull, current_thread); return cdata->_scene_setup; } diff --git a/panda/src/display/displayRegion.cxx b/panda/src/display/displayRegion.cxx index a80792e63a..8ed2c5b98c 100644 --- a/panda/src/display/displayRegion.cxx +++ b/panda/src/display/displayRegion.cxx @@ -470,13 +470,15 @@ save_screenshot(const Filename &filename, const string &image_comment) { //////////////////////////////////////////////////////////////////// bool DisplayRegion:: get_screenshot(PNMImage &image) { + Thread *current_thread = Thread::get_current_thread(); + GraphicsOutput *window = get_window(); nassertr(window != (GraphicsOutput *)NULL, false); GraphicsStateGuardian *gsg = window->get_gsg(); nassertr(gsg != (GraphicsStateGuardian *)NULL, false); - if (!window->begin_frame(GraphicsOutput::FM_refresh)) { + if (!window->begin_frame(GraphicsOutput::FM_refresh, current_thread)) { return false; } @@ -489,7 +491,7 @@ get_screenshot(PNMImage &image) { return false; } - window->end_frame(GraphicsOutput::FM_refresh); + window->end_frame(GraphicsOutput::FM_refresh, current_thread); if (!tex->store(image)) { return false; diff --git a/panda/src/display/displayRegion.h b/panda/src/display/displayRegion.h index 0aec79207e..c8eb2536af 100644 --- a/panda/src/display/displayRegion.h +++ b/panda/src/display/displayRegion.h @@ -119,10 +119,10 @@ PUBLISHED: bool get_screenshot(PNMImage &image); public: - INLINE void set_cull_result( - CullResult *cull_result, SceneSetup *scene_setup); - INLINE CullResult *get_cull_result() const; - INLINE SceneSetup *get_scene_setup() const; + INLINE void set_cull_result(CullResult *cull_result, SceneSetup *scene_setup, + Thread *current_thread); + INLINE CullResult *get_cull_result(Thread *current_thread) const; + INLINE SceneSetup *get_scene_setup(Thread *current_thread) const; private: class CData; diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index b47b38346a..5b5e30d3eb 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -478,7 +478,7 @@ remove_all_windows() { _app.do_close(this, current_thread); _app.do_pending(this, current_thread); - terminate_threads(); + terminate_threads(current_thread); } //////////////////////////////////////////////////////////////////// @@ -623,7 +623,7 @@ render_frame() { // Grab each thread's mutex again after all windows have flipped, // and wait for the thread to finish. { - PStatTimer timer(_wait_pcollector); + PStatTimer timer(_wait_pcollector, current_thread); Threads::const_iterator ti; for (ti = _threads.begin(); ti != _threads.end(); ++ti) { RenderThread *thread = (*ti).second; @@ -652,7 +652,7 @@ render_frame() { // between frames. ObjectDeletor *deletor = ObjectDeletor::get_global_ptr(); if (deletor != (ObjectDeletor *)NULL) { - PStatTimer timer(_delete_pcollector); + PStatTimer timer(_delete_pcollector, current_thread); deletor->flush(); } @@ -664,13 +664,13 @@ render_frame() { // Now cycle the pipeline and officially begin the next frame. #ifdef THREADED_PIPELINE { - PStatTimer timer(_cycle_pcollector); + PStatTimer timer(_cycle_pcollector, current_thread); _pipeline->cycle(); } #endif // THREADED_PIPELINE - global_clock->tick(); - if (global_clock->check_errors()) { + global_clock->tick(current_thread); + if (global_clock->check_errors(current_thread)) { throw_event("clock_error"); } @@ -735,7 +735,7 @@ render_frame() { if (yield_timeslice) { // Nap for a moment to yield the timeslice, to be polite to other // running applications. - PStatTimer timer(_yield_pcollector); + PStatTimer timer(_yield_pcollector, current_thread); struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; @@ -776,7 +776,7 @@ open_windows() { _app.do_windows(this, current_thread); _app.do_pending(this, current_thread); - PStatTimer timer(_wait_pcollector); + PStatTimer timer(_wait_pcollector, current_thread); Threads::const_iterator ti; for (ti = _threads.begin(); ti != _threads.end(); ++ti) { RenderThread *thread = (*ti).second; @@ -964,13 +964,13 @@ set_window_sort(GraphicsOutput *window, int sort) { void GraphicsEngine:: cull_and_draw_together(const GraphicsEngine::Windows &wlist, Thread *current_thread) { - PStatTimer timer(_cull_pcollector); + PStatTimer timer(_cull_pcollector, current_thread); Windows::const_iterator wi; for (wi = wlist.begin(); wi != wlist.end(); ++wi) { GraphicsOutput *win = (*wi); if (win->is_active() && win->get_gsg()->is_active()) { - if (win->begin_frame(GraphicsOutput::FM_render)) { + if (win->begin_frame(GraphicsOutput::FM_render, current_thread)) { win->clear(current_thread); int num_display_regions = win->get_num_active_display_regions(); @@ -980,16 +980,16 @@ cull_and_draw_together(const GraphicsEngine::Windows &wlist, cull_and_draw_together(win, dr, current_thread); } } - win->end_frame(GraphicsOutput::FM_render); + win->end_frame(GraphicsOutput::FM_render, current_thread); if (_auto_flip) { if (win->flip_ready()) { { - PStatTimer timer(GraphicsEngine::_flip_begin_pcollector); + PStatTimer timer(GraphicsEngine::_flip_begin_pcollector, current_thread); win->begin_flip(); } { - PStatTimer timer(GraphicsEngine::_flip_end_pcollector); + PStatTimer timer(GraphicsEngine::_flip_end_pcollector, current_thread); win->end_flip(); } } @@ -1052,7 +1052,7 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr, //////////////////////////////////////////////////////////////////// void GraphicsEngine:: cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) { - PStatTimer timer(_cull_pcollector); + PStatTimer timer(_cull_pcollector, current_thread); // Keep track of the cameras we have already used in this thread to // render DisplayRegions. @@ -1088,8 +1088,9 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) { // result will be the same, so just use the result from // the other DisplayRegion. DisplayRegion *other_dr = (*aci).second; - dr->set_cull_result(other_dr->get_cull_result(), - setup_scene(win->get_gsg(), dr_reader)); + dr->set_cull_result(other_dr->get_cull_result(current_thread), + setup_scene(win->get_gsg(), dr_reader), + current_thread); } if (dr_reader != (DisplayRegionPipelineReader *)NULL) { @@ -1115,8 +1116,8 @@ cull_to_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) { PT(CullResult) cull_result; PT(SceneSetup) scene_setup; { - PStatTimer timer(_cull_setup_pcollector); - cull_result = dr->get_cull_result(); + PStatTimer timer(_cull_setup_pcollector, current_thread); + cull_result = dr->get_cull_result(current_thread); if (cull_result != (CullResult *)NULL) { cull_result = cull_result->make_next(); } else { @@ -1131,10 +1132,10 @@ cull_to_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) { do_cull(&cull_handler, scene_setup, gsg, current_thread); { - PStatTimer timer(_cull_sort_pcollector); - cull_result->finish_cull(scene_setup); + PStatTimer timer(_cull_sort_pcollector, current_thread); + cull_result->finish_cull(scene_setup, current_thread); // Save the results for next frame. - dr->set_cull_result(cull_result, scene_setup); + dr->set_cull_result(cull_result, scene_setup, current_thread); } } } @@ -1154,7 +1155,7 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) { for (wi = wlist.begin(); wi != wlist.end(); ++wi) { GraphicsOutput *win = (*wi); if (win->is_active() && win->get_gsg()->is_active()) { - if (win->begin_frame(GraphicsOutput::FM_render)) { + if (win->begin_frame(GraphicsOutput::FM_render, current_thread)) { win->clear(current_thread); int num_display_regions = win->get_num_active_display_regions(); @@ -1164,16 +1165,16 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) { draw_bins(win, dr, current_thread); } } - win->end_frame(GraphicsOutput::FM_render); + win->end_frame(GraphicsOutput::FM_render, current_thread); if (_auto_flip) { if (win->flip_ready()) { { - PStatTimer timer(GraphicsEngine::_flip_begin_pcollector); + PStatTimer timer(GraphicsEngine::_flip_begin_pcollector, current_thread); win->begin_flip(); } { - PStatTimer timer(GraphicsEngine::_flip_end_pcollector); + PStatTimer timer(GraphicsEngine::_flip_end_pcollector, current_thread); win->end_flip(); } } @@ -1195,8 +1196,8 @@ draw_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) { GraphicsStateGuardian *gsg = win->get_gsg(); nassertv(gsg != (GraphicsStateGuardian *)NULL); - PT(CullResult) cull_result = dr->get_cull_result(); - PT(SceneSetup) scene_setup = dr->get_scene_setup(); + PT(CullResult) cull_result = dr->get_cull_result(current_thread); + PT(SceneSetup) scene_setup = dr->get_scene_setup(current_thread); if (cull_result != (CullResult *)NULL && scene_setup != (SceneSetup *)NULL) { do_draw(cull_result, scene_setup, win, dr, current_thread); } @@ -1214,8 +1215,8 @@ make_contexts(const GraphicsEngine::Windows &wlist, Thread *current_thread) { Windows::const_iterator wi; for (wi = wlist.begin(); wi != wlist.end(); ++wi) { GraphicsOutput *win = (*wi); - if (win->begin_frame(GraphicsOutput::FM_refresh)) { - win->end_frame(GraphicsOutput::FM_refresh); + if (win->begin_frame(GraphicsOutput::FM_refresh, current_thread)) { + win->end_frame(GraphicsOutput::FM_refresh, current_thread); } } } @@ -1249,14 +1250,14 @@ flip_windows(const GraphicsEngine::Windows &wlist, Thread *current_thread) { for (wi = wlist.begin(); wi != wlist.end(); ++wi) { GraphicsOutput *win = (*wi); if (win->flip_ready()) { - PStatTimer timer(GraphicsEngine::_flip_begin_pcollector); + PStatTimer timer(GraphicsEngine::_flip_begin_pcollector, current_thread); win->begin_flip(); } } for (wi = wlist.begin(); wi != wlist.end(); ++wi) { GraphicsOutput *win = (*wi); if (win->flip_ready()) { - PStatTimer timer(GraphicsEngine::_flip_end_pcollector); + PStatTimer timer(GraphicsEngine::_flip_end_pcollector, current_thread); win->end_flip(); } } @@ -1273,7 +1274,7 @@ do_sync_frame(Thread *current_thread) { nassertv(_lock.debug_is_locked()); // Statistics - PStatTimer timer(_sync_pcollector); + PStatTimer timer(_sync_pcollector, current_thread); nassertv(_flip_state == FS_draw); @@ -1300,7 +1301,7 @@ do_flip_frame(Thread *current_thread) { nassertv(_lock.debug_is_locked()); // Statistics - PStatTimer timer(_flip_pcollector); + PStatTimer timer(_flip_pcollector, current_thread); nassertv(_flip_state == FS_draw || _flip_state == FS_sync); @@ -1308,7 +1309,7 @@ do_flip_frame(Thread *current_thread) { // necessary. Grabbing the mutex (and waiting for TS_wait) should // achieve that. { - PStatTimer timer(_wait_pcollector); + PStatTimer timer(_wait_pcollector, current_thread); Threads::const_iterator ti; for (ti = _threads.begin(); ti != _threads.end(); ++ti) { RenderThread *thread = (*ti).second; @@ -1347,7 +1348,7 @@ do_flip_frame(Thread *current_thread) { //////////////////////////////////////////////////////////////////// PT(SceneSetup) GraphicsEngine:: setup_scene(GraphicsStateGuardian *gsg, DisplayRegionPipelineReader *dr) { - PStatTimer timer(_cull_setup_pcollector); + PStatTimer timer(_cull_setup_pcollector, dr->get_current_thread()); GraphicsOutput *window = dr->get_window(); // The window pointer shouldn't be NULL, since we presumably got to @@ -1431,7 +1432,7 @@ setup_scene(GraphicsStateGuardian *gsg, DisplayRegionPipelineReader *dr) { void GraphicsEngine:: do_cull(CullHandler *cull_handler, SceneSetup *scene_setup, GraphicsStateGuardian *gsg, Thread *current_thread) { - CullTraverser trav(gsg); + CullTraverser trav(gsg, current_thread); trav.set_cull_handler(cull_handler); trav.set_depth_offset_decals(depth_offset_decals && gsg->depth_offset_decals()); trav.set_scene(scene_setup); @@ -1471,7 +1472,7 @@ void GraphicsEngine:: do_draw(CullResult *cull_result, SceneSetup *scene_setup, GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) { // Statistics - PStatTimer timer(_draw_pcollector); + PStatTimer timer(_draw_pcollector, current_thread); DisplayRegionPipelineReader *dr_reader = new DisplayRegionPipelineReader(dr, current_thread); @@ -1662,12 +1663,12 @@ do_resort_windows() { // them to clean up. //////////////////////////////////////////////////////////////////// void GraphicsEngine:: -terminate_threads() { +terminate_threads(Thread *current_thread) { MutexHolder holder(_lock); // We spend almost our entire time in this method just waiting for // threads. Time it appropriately. - PStatTimer timer(_wait_pcollector); + PStatTimer timer(_wait_pcollector, current_thread); // First, wait for all the threads to finish their current frame. // Grabbing the mutex should achieve that. @@ -1903,7 +1904,7 @@ resort_windows() { //////////////////////////////////////////////////////////////////// void GraphicsEngine::WindowRenderer:: do_frame(GraphicsEngine *engine, Thread *current_thread) { - PStatTimer timer(engine->_do_frame_pcollector); + PStatTimer timer(engine->_do_frame_pcollector, current_thread); MutexHolder holder(_wl_lock); do_callbacks(CB_pre_frame); @@ -2165,7 +2166,7 @@ thread_main() { _cv_done.signal(); { - PStatTimer timer(_wait_pcollector); + PStatTimer timer(_wait_pcollector, current_thread); _cv_start.wait(); } } diff --git a/panda/src/display/graphicsEngine.h b/panda/src/display/graphicsEngine.h index b4b7d99e89..000e2a2a44 100644 --- a/panda/src/display/graphicsEngine.h +++ b/panda/src/display/graphicsEngine.h @@ -179,7 +179,7 @@ private: const GraphicsThreadingModel &threading_model); void do_remove_window(GraphicsOutput *window, Thread *current_thread); void do_resort_windows(); - void terminate_threads(); + void terminate_threads(Thread *current_thread); #ifdef DO_PSTATS typedef map CyclerTypeCounters; diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index 0587e0dcbb..d5c54b92e5 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -914,7 +914,7 @@ reset_window(bool swapchain) { // should be skipped. //////////////////////////////////////////////////////////////////// bool GraphicsOutput:: -begin_frame(FrameMode mode) { +begin_frame(FrameMode mode, Thread *current_thread) { return false; } @@ -926,7 +926,7 @@ begin_frame(FrameMode mode) { // should do whatever finalization is required. //////////////////////////////////////////////////////////////////// void GraphicsOutput:: -end_frame(FrameMode mode) { +end_frame(FrameMode mode, Thread *current_thread) { } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/graphicsOutput.h b/panda/src/display/graphicsOutput.h index 0e2d9ed4e9..4341d1c83c 100644 --- a/panda/src/display/graphicsOutput.h +++ b/panda/src/display/graphicsOutput.h @@ -209,8 +209,8 @@ public: // thread other than the draw thread. These methods are normally // called by the GraphicsEngine. void clear(Thread *current_thread); - virtual bool begin_frame(FrameMode mode); - virtual void end_frame(FrameMode mode); + virtual bool begin_frame(FrameMode mode, Thread *current_thread); + virtual void end_frame(FrameMode mode, Thread *current_thread); // These entry points have been removed. Use begin_frame/end_frame instead. // virtual void begin_render_texture(); diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 895c801815..fa8b2f1851 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -1015,8 +1015,8 @@ prepare_lens() { // be called). //////////////////////////////////////////////////////////////////// bool GraphicsStateGuardian:: -begin_frame() { - _prepared_objects->begin_frame(this); +begin_frame(Thread *current_thread) { + _prepared_objects->begin_frame(this, current_thread); #ifdef DO_PSTATS // For Pstats to track our current texture memory usage, we have to @@ -1121,8 +1121,8 @@ end_scene() { // rendering the frame, and before the window flips. //////////////////////////////////////////////////////////////////// void GraphicsStateGuardian:: -end_frame() { - _prepared_objects->end_frame(); +end_frame(Thread *current_thread) { + _prepared_objects->end_frame(current_thread); // Flush any PStatCollectors. _data_transferred_pcollector.flush_level(); diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index d030619117..ebc8db6b0d 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -181,10 +181,10 @@ public: virtual CPT(TransformState) calc_projection_mat(const Lens *lens); virtual bool prepare_lens(); - virtual bool begin_frame(); + virtual bool begin_frame(Thread *current_thread); virtual bool begin_scene(); virtual void end_scene(); - virtual void end_frame(); + virtual void end_frame(Thread *current_thread); void set_current_properties(FrameBufferProperties *properties); diff --git a/panda/src/display/parasiteBuffer.cxx b/panda/src/display/parasiteBuffer.cxx index 7f135c3543..2d9b708563 100644 --- a/panda/src/display/parasiteBuffer.cxx +++ b/panda/src/display/parasiteBuffer.cxx @@ -107,10 +107,10 @@ get_host() { // should be skipped. //////////////////////////////////////////////////////////////////// bool ParasiteBuffer:: -begin_frame(FrameMode mode) { +begin_frame(FrameMode mode, Thread *current_thread) { begin_frame_spam(); - if (!_host->begin_frame(FM_parasite)) { + if (!_host->begin_frame(FM_parasite, current_thread)) { return false; } @@ -134,7 +134,7 @@ begin_frame(FrameMode mode) { // should do whatever finalization is required. //////////////////////////////////////////////////////////////////// void ParasiteBuffer:: -end_frame(FrameMode mode) { +end_frame(FrameMode mode, Thread *current_thread) { end_frame_spam(); nassertv(_gsg != (GraphicsStateGuardian *)NULL); @@ -143,7 +143,7 @@ end_frame(FrameMode mode) { return; } - _host->end_frame(FM_parasite); + _host->end_frame(FM_parasite, current_thread); if (mode == FM_render) { for (int i=0; iget_supported_geom_rendering(); int unsupported_bits = geom->get_geom_rendering() & ~supported_geom_rendering; diff --git a/panda/src/display/standardMunger.h b/panda/src/display/standardMunger.h index 3520a6ffcc..3e94131fb1 100644 --- a/panda/src/display/standardMunger.h +++ b/panda/src/display/standardMunger.h @@ -46,7 +46,8 @@ public: protected: virtual CPT(GeomVertexData) munge_data_impl(const GeomVertexData *data); virtual int compare_to_impl(const GeomMunger *other) const; - virtual bool munge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &data); + virtual bool munge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &data, + Thread *current_thread); virtual int geom_compare_to_impl(const GeomMunger *other) const; virtual CPT(RenderState) munge_state_impl(const RenderState *state); diff --git a/panda/src/distort/projectionScreen.cxx b/panda/src/distort/projectionScreen.cxx index f8c5005fff..ac9eccb142 100644 --- a/panda/src/distort/projectionScreen.cxx +++ b/panda/src/distort/projectionScreen.cxx @@ -519,6 +519,8 @@ recompute_geom(Geom *geom, const LMatrix4f &rel_mat) { 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f); + Thread *current_thread = Thread::get_current_thread(); + Lens *lens = _projector_node->get_lens(); nassertv(lens != (Lens *)NULL); @@ -546,11 +548,11 @@ recompute_geom(Geom *geom, const LMatrix4f &rel_mat) { PT(GeomVertexData) modify_vdata = geom->modify_vertex_data(); // Maybe the vdata has animation that we should consider. - CPT(GeomVertexData) animated_vdata = geom->get_vertex_data()->animate_vertices(); + CPT(GeomVertexData) animated_vdata = geom->get_vertex_data(current_thread)->animate_vertices(current_thread); - GeomVertexWriter texcoord(modify_vdata, _texcoord_name); - GeomVertexWriter color(modify_vdata); - GeomVertexReader vertex(animated_vdata, InternalName::get_vertex()); + GeomVertexWriter texcoord(modify_vdata, _texcoord_name, current_thread); + GeomVertexWriter color(modify_vdata, current_thread); + GeomVertexReader vertex(animated_vdata, InternalName::get_vertex(), current_thread); if (_vignette_on) { color.set_column(InternalName::get_color()); diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index a7109e1d03..e78f1481bb 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -672,8 +672,8 @@ prepare_lens() { // be called). //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian8:: -begin_frame() { - return GraphicsStateGuardian::begin_frame(); +begin_frame(Thread *current_thread) { + return GraphicsStateGuardian::begin_frame(current_thread); } //////////////////////////////////////////////////////////////////// @@ -759,7 +759,7 @@ end_scene() { // rendering the frame, and before the window flips. //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian8:: -end_frame() { +end_frame(Thread *current_thread) { #if defined(DO_PSTATS) if (_texmgrmem_total_pcollector.is_active()) { @@ -777,7 +777,7 @@ end_frame() { // Note: regular GraphicsWindow::end_frame is being called, // but we override gsg::end_frame, so need to explicitly call it here // (currently it's an empty fn) - GraphicsStateGuardian::end_frame(); + GraphicsStateGuardian::end_frame(current_thread); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index 8e2d5f223f..cfc5f9f59e 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -71,8 +71,8 @@ public: virtual CPT(TransformState) calc_projection_mat(const Lens *lens); virtual bool prepare_lens(); - virtual bool begin_frame(); - virtual bool begin_scene(); + virtual bool begin_frame(Thread *current_thread, Thread *current_thread); + virtual bool begin_scene(Thread *current_thread, Thread *current_thread); virtual void end_scene(); virtual void end_frame(); diff --git a/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx b/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx index 55c5d82257..c63aff45b1 100644 --- a/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx +++ b/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx @@ -83,7 +83,7 @@ wdxGraphicsBuffer8:: // should be skipped. //////////////////////////////////////////////////////////////////// bool wdxGraphicsBuffer8:: -begin_frame(FrameMode mode) { +begin_frame(FrameMode mode, Thread *current_thread) { begin_frame_spam(); if (_gsg == (GraphicsStateGuardian *)NULL) { @@ -96,7 +96,7 @@ begin_frame(FrameMode mode) { } _gsg->set_current_properties(&get_fb_properties()); - return _gsg->begin_frame(); + return _gsg->begin_frame(current_thread); } //////////////////////////////////////////////////////////////////// @@ -107,7 +107,7 @@ begin_frame(FrameMode mode) { // should do whatever finalization is required. //////////////////////////////////////////////////////////////////// void wdxGraphicsBuffer8:: -end_frame(FrameMode mode) { +end_frame(FrameMode mode, Thread *current_thread) { end_frame_spam(); nassertv(_gsg != (GraphicsStateGuardian *)NULL); @@ -117,7 +117,7 @@ end_frame(FrameMode mode) { copy_to_textures(); } - _gsg->end_frame(); + _gsg->end_frame(current_thread); if (mode == FM_render) { trigger_flip(); diff --git a/panda/src/dxgsg8/wdxGraphicsBuffer8.h b/panda/src/dxgsg8/wdxGraphicsBuffer8.h index f5df9f81fd..51c5552fd8 100644 --- a/panda/src/dxgsg8/wdxGraphicsBuffer8.h +++ b/panda/src/dxgsg8/wdxGraphicsBuffer8.h @@ -44,8 +44,8 @@ public: GraphicsOutput *host); virtual ~wdxGraphicsBuffer8(); - virtual bool begin_frame(FrameMode mode); - virtual void end_frame(FrameMode mode); + virtual bool begin_frame(FrameMode mode, Thread *current_thread); + virtual void end_frame(FrameMode mode, Thread *current_thread); virtual void select_cube_map(int cube_map_index); diff --git a/panda/src/dxgsg8/wdxGraphicsWindow8.cxx b/panda/src/dxgsg8/wdxGraphicsWindow8.cxx index 62126733ad..5c83bfd256 100644 --- a/panda/src/dxgsg8/wdxGraphicsWindow8.cxx +++ b/panda/src/dxgsg8/wdxGraphicsWindow8.cxx @@ -76,7 +76,7 @@ wdxGraphicsWindow8:: // should be skipped. //////////////////////////////////////////////////////////////////// bool wdxGraphicsWindow8:: -begin_frame(FrameMode mode) { +begin_frame(FrameMode mode, Thread *current_thread) { begin_frame_spam(); if (_gsg == (GraphicsStateGuardian *)NULL) { return false; @@ -100,7 +100,7 @@ begin_frame(FrameMode mode) { } _gsg->set_current_properties(&get_fb_properties()); - bool return_val = _gsg->begin_frame(); + bool return_val = _gsg->begin_frame(current_thread); _dxgsg->set_render_target(); return return_val; } diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 2a6cb6ba0a..b50377f0f3 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -893,11 +893,11 @@ prepare_lens() { // be called). //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian9:: -begin_frame() { +begin_frame(Thread *current_thread) { DBG_S dxgsg9_cat.debug ( ) << "^^^^^^^^^^^ begin_frame \n"; DBG_E - GraphicsStateGuardian::begin_frame(); + GraphicsStateGuardian::begin_frame(current_thread); if (_lru) { @@ -1020,7 +1020,7 @@ DBG_S dxgsg9_cat.debug ( ) << "DXGraphicsStateGuardian9::end_scene\n"; DBG_E // rendering the frame, and before the window flips. //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: -end_frame() { +end_frame(Thread *current_thread) { DBG_S dxgsg9_cat.debug ( ) << "@@@@@@@@@@ end_frame \n"; DBG_E @@ -1133,7 +1133,7 @@ DBG_S dxgsg9_cat.debug ( ) << "@@@@@@@@@@ end_frame \n"; DBG_E // Note: regular GraphicsWindow::end_frame is being called, // but we override gsg::end_frame, so need to explicitly call it here // (currently it's an empty fn) - GraphicsStateGuardian::end_frame(); + GraphicsStateGuardian::end_frame(current_thread); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index 4ca8d5e34b..faa08797f2 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -107,8 +107,8 @@ public: virtual CPT(TransformState) calc_projection_mat(const Lens *lens); virtual bool prepare_lens(); - virtual bool begin_frame(); - virtual bool begin_scene(); + virtual bool begin_frame(Thread *current_thread, Thread *current_thread); + virtual bool begin_scene(Thread *current_thread, Thread *current_thread); virtual void end_scene(); virtual void end_frame(); diff --git a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx index 1f9d0f5ed2..66bd429e56 100644 --- a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx @@ -80,7 +80,7 @@ wdxGraphicsBuffer9:: // should be skipped. //////////////////////////////////////////////////////////////////// bool wdxGraphicsBuffer9:: -begin_frame(FrameMode mode) { +begin_frame(FrameMode mode, Thread *current_thread) { DBG_S dxgsg9_cat.debug ( ) << "wdxGraphicsBuffer9::begin_frame\n"; DBG_E begin_frame_spam(); @@ -94,7 +94,7 @@ begin_frame(FrameMode mode) { } _gsg->set_current_properties(&get_fb_properties()); - return _gsg->begin_frame(); + return _gsg->begin_frame(current_thread); } //////////////////////////////////////////////////////////////////// @@ -105,7 +105,7 @@ begin_frame(FrameMode mode) { // should do whatever finalization is required. //////////////////////////////////////////////////////////////////// void wdxGraphicsBuffer9:: -end_frame(FrameMode mode) { +end_frame(FrameMode mode, Thread *current_thread) { end_frame_spam(); nassertv(_gsg != (GraphicsStateGuardian *)NULL); @@ -115,7 +115,7 @@ end_frame(FrameMode mode) { copy_to_textures(); } - _gsg->end_frame(); + _gsg->end_frame(current_thread); if (mode == FM_render) { trigger_flip(); diff --git a/panda/src/dxgsg9/wdxGraphicsBuffer9.h b/panda/src/dxgsg9/wdxGraphicsBuffer9.h index 76b2765e88..e93590cf83 100644 --- a/panda/src/dxgsg9/wdxGraphicsBuffer9.h +++ b/panda/src/dxgsg9/wdxGraphicsBuffer9.h @@ -44,8 +44,8 @@ public: GraphicsOutput *host); virtual ~wdxGraphicsBuffer9(); - virtual bool begin_frame(FrameMode mode); - virtual void end_frame(FrameMode mode); + virtual bool begin_frame(FrameMode mode, Thread *current_thread); + virtual void end_frame(FrameMode mode, Thread *current_thread); virtual void select_cube_map(int cube_map_index); virtual void process_events(); diff --git a/panda/src/dxgsg9/wdxGraphicsWindow9.cxx b/panda/src/dxgsg9/wdxGraphicsWindow9.cxx index ccdae94328..679be835bb 100755 --- a/panda/src/dxgsg9/wdxGraphicsWindow9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsWindow9.cxx @@ -96,7 +96,7 @@ make_current() { // should be skipped. //////////////////////////////////////////////////////////////////// bool wdxGraphicsWindow9:: -begin_frame(FrameMode mode) { +begin_frame(FrameMode mode, Thread *current_thread) { begin_frame_spam(); if (_gsg == (GraphicsStateGuardian *)NULL) { return false; @@ -120,7 +120,7 @@ begin_frame(FrameMode mode) { } _gsg->set_current_properties(&get_fb_properties()); - bool return_val = _gsg->begin_frame(); + bool return_val = _gsg->begin_frame(current_thread); _dxgsg->set_render_target(); return return_val; } @@ -133,7 +133,7 @@ begin_frame(FrameMode mode) { // should do whatever finalization is required. //////////////////////////////////////////////////////////////////// void wdxGraphicsWindow9:: -end_frame(FrameMode mode) { +end_frame(FrameMode mode, Thread *current_thread) { end_frame_spam(); nassertv(_gsg != (GraphicsStateGuardian *)NULL); @@ -142,7 +142,7 @@ end_frame(FrameMode mode) { copy_to_textures(); } - _gsg->end_frame(); + _gsg->end_frame(current_thread); if (mode == FM_render) { trigger_flip(); diff --git a/panda/src/framework/pandaFramework.cxx b/panda/src/framework/pandaFramework.cxx index 9404f3acab..4fb06dbb97 100644 --- a/panda/src/framework/pandaFramework.cxx +++ b/panda/src/framework/pandaFramework.cxx @@ -744,9 +744,9 @@ enable_default_keys() { // called only from main_loop(). //////////////////////////////////////////////////////////////////// bool PandaFramework:: -do_frame() { +do_frame(Thread *current_thread) { nassertr(_is_open, false); - DataGraphTraverser dg_trav; + DataGraphTraverser dg_trav(current_thread); dg_trav.traverse(_data_root.node()); throw_event("NewFrame"); @@ -783,7 +783,8 @@ do_frame() { //////////////////////////////////////////////////////////////////// void PandaFramework:: main_loop() { - while (do_frame()) { + Thread *current_thread = Thread::get_current_thread(); + while (do_frame(current_thread)) { } } diff --git a/panda/src/framework/pandaFramework.h b/panda/src/framework/pandaFramework.h index 82492c90f6..55c522386f 100644 --- a/panda/src/framework/pandaFramework.h +++ b/panda/src/framework/pandaFramework.h @@ -108,7 +108,7 @@ public: void enable_default_keys(); - virtual bool do_frame(); + virtual bool do_frame(Thread *current_thread); void main_loop(); INLINE void set_exit_flag(); diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index 1b58e50ded..8a9b81ff01 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -66,12 +66,12 @@ CLP(GraphicsBuffer):: // should be skipped. //////////////////////////////////////////////////////////////////// bool CLP(GraphicsBuffer):: -begin_frame(FrameMode mode) { +begin_frame(FrameMode mode, Thread *current_thread) { if (!_is_valid) { return false; } - if (!_host->begin_frame(FM_parasite)) { + if (!_host->begin_frame(FM_parasite, current_thread)) { return false; } @@ -366,7 +366,7 @@ generate_mipmaps() { // should do whatever finalization is required. //////////////////////////////////////////////////////////////////// void CLP(GraphicsBuffer):: -end_frame(FrameMode mode) { +end_frame(FrameMode mode, Thread *current_thread) { end_frame_spam(); nassertv(_gsg != (GraphicsStateGuardian *)NULL); @@ -383,7 +383,7 @@ end_frame(FrameMode mode) { generate_mipmaps(); } - _host->end_frame(FM_parasite); + _host->end_frame(FM_parasite, current_thread); if (mode == FM_render) { trigger_flip(); diff --git a/panda/src/glstuff/glGraphicsBuffer_src.h b/panda/src/glstuff/glGraphicsBuffer_src.h index 48aec27ac0..8832c79cc3 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.h +++ b/panda/src/glstuff/glGraphicsBuffer_src.h @@ -64,8 +64,8 @@ public: GraphicsOutput *host); virtual ~CLP(GraphicsBuffer)(); - virtual bool begin_frame(FrameMode mode); - virtual void end_frame(FrameMode mode); + virtual bool begin_frame(FrameMode mode, Thread *current_thread); + virtual void end_frame(FrameMode mode, Thread *current_thread); virtual void select_cube_map(int cube_map_index); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 0a79b1318c..e6a2a1c544 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1253,8 +1253,8 @@ prepare_lens() { // be called). //////////////////////////////////////////////////////////////////// bool CLP(GraphicsStateGuardian):: -begin_frame() { - if (!GraphicsStateGuardian::begin_frame()) { +begin_frame(Thread *current_thread) { + if (!GraphicsStateGuardian::begin_frame(current_thread)) { return false; } @@ -1276,7 +1276,7 @@ begin_frame() { // rendering the frame, and before the window flips. //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: -end_frame() { +end_frame(Thread *current_thread) { #ifdef DO_PSTATS // Check for textures, etc., that are no longer resident. These // calls might be measurably expensive, and they don't have any @@ -1295,7 +1295,7 @@ end_frame() { } #endif - GraphicsStateGuardian::end_frame(); + GraphicsStateGuardian::end_frame(current_thread); // Flush any PCollectors specific to this kind of GSG. _primitive_batches_display_list_pcollector.flush_level(); @@ -1867,7 +1867,7 @@ disable_standard_vertex_arrays() //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: draw_triangles(const GeomPrimitivePipelineReader *reader) { - PStatTimer timer(_draw_primitive_pcollector); + PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); #ifndef NDEBUG if (GLCAT.is_spam()) { @@ -1912,7 +1912,7 @@ draw_triangles(const GeomPrimitivePipelineReader *reader) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: draw_tristrips(const GeomPrimitivePipelineReader *reader) { - PStatTimer timer(_draw_primitive_pcollector); + PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); report_my_gl_errors(); @@ -1996,7 +1996,7 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: draw_trifans(const GeomPrimitivePipelineReader *reader) { - PStatTimer timer(_draw_primitive_pcollector); + PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); #ifndef NDEBUG if (GLCAT.is_spam()) { GLCAT.spam() << "draw_trifans: " << *(reader->get_object()) << "\n"; @@ -2053,7 +2053,7 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: draw_lines(const GeomPrimitivePipelineReader *reader) { - PStatTimer timer(_draw_primitive_pcollector); + PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); #ifndef NDEBUG if (GLCAT.is_spam()) { GLCAT.spam() << "draw_lines: " << *(reader->get_object()) << "\n"; @@ -2095,7 +2095,7 @@ draw_lines(const GeomPrimitivePipelineReader *reader) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: draw_linestrips(const GeomPrimitivePipelineReader *reader) { - PStatTimer timer(_draw_primitive_pcollector); + PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); #ifndef NDEBUG if (GLCAT.is_spam()) { GLCAT.spam() << "draw_linestrips: " << *(reader->get_object()) << "\n"; @@ -2111,7 +2111,7 @@ draw_linestrips(const GeomPrimitivePipelineReader *reader) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: draw_points(const GeomPrimitivePipelineReader *reader) { - PStatTimer timer(_draw_primitive_pcollector); + PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); #ifndef NDEBUG if (GLCAT.is_spam()) { GLCAT.spam() << "draw_points: " << *(reader->get_object()) << "\n"; @@ -2617,9 +2617,10 @@ prepare_vertex_buffer(GeomVertexArrayData *data) { // rendering. //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: -apply_vertex_buffer(VertexBufferContext *vbc) { +apply_vertex_buffer(VertexBufferContext *vbc, + const GeomVertexArrayDataPipelineReader *reader) { nassertv(_supports_buffers); - nassertv(vbc->get_data()->get_modified() != UpdateSeq::initial()); + nassertv(reader->get_modified() != UpdateSeq::initial()); CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext), vbc); @@ -2634,8 +2635,8 @@ apply_vertex_buffer(VertexBufferContext *vbc) { } if (gvbc->was_modified()) { - PStatTimer timer(_load_vertex_buffer_pcollector); - int num_bytes = gvbc->get_data()->get_data_size_bytes(); + PStatTimer timer(_load_vertex_buffer_pcollector, reader->get_current_thread()); + int num_bytes = reader->get_data_size_bytes(); if (GLCAT.is_spam()) { GLCAT.spam() << "copying " << num_bytes @@ -2644,12 +2645,12 @@ apply_vertex_buffer(VertexBufferContext *vbc) { if (num_bytes != 0) { if (gvbc->changed_size() || gvbc->changed_usage_hint()) { _glBufferData(GL_ARRAY_BUFFER, num_bytes, - gvbc->get_data()->get_data(), - get_usage(gvbc->get_data()->get_usage_hint())); + reader->get_data(), + get_usage(reader->get_usage_hint())); } else { _glBufferSubData(GL_ARRAY_BUFFER, 0, num_bytes, - gvbc->get_data()->get_data()); + reader->get_data()); } _data_transferred_pcollector.add_level(num_bytes); } @@ -2738,7 +2739,7 @@ setup_array_data(const GeomVertexArrayDataPipelineReader *array_reader) { // Prepare the buffer object and bind it. VertexBufferContext *vbc = ((GeomVertexArrayData *)array_reader->get_object())->prepare_now(get_prepared_objects(), this); nassertr(vbc != (VertexBufferContext *)NULL, array_reader->get_data()); - apply_vertex_buffer(vbc); + apply_vertex_buffer(vbc, array_reader); // NULL is the OpenGL convention for the first byte of the buffer object. return NULL; @@ -2803,7 +2804,7 @@ apply_index_buffer(IndexBufferContext *ibc, } if (gibc->was_modified()) { - PStatTimer timer(_load_index_buffer_pcollector); + PStatTimer timer(_load_index_buffer_pcollector, reader->get_current_thread()); int num_bytes = reader->get_data_size_bytes(); if (GLCAT.is_spam()) { GLCAT.spam() diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 46a9ae7f7d..c1a562d37e 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -100,8 +100,8 @@ public: virtual CPT(TransformState) calc_projection_mat(const Lens *lens); virtual bool prepare_lens(); - virtual bool begin_frame(); - virtual void end_frame(); + virtual bool begin_frame(Thread *current_thread); + virtual void end_frame(Thread *current_thread); virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomMunger *munger, @@ -129,7 +129,8 @@ public: void record_deleted_display_list(GLuint index); virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data); - void apply_vertex_buffer(VertexBufferContext *vbc); + void apply_vertex_buffer(VertexBufferContext *vbc, + const GeomVertexArrayDataPipelineReader *reader); virtual void release_vertex_buffer(VertexBufferContext *vbc); const unsigned char *setup_array_data(const GeomVertexArrayDataPipelineReader *data); diff --git a/panda/src/glxdisplay/glxGraphicsBuffer.cxx b/panda/src/glxdisplay/glxGraphicsBuffer.cxx index b67efc7309..98e22afc6b 100644 --- a/panda/src/glxdisplay/glxGraphicsBuffer.cxx +++ b/panda/src/glxdisplay/glxGraphicsBuffer.cxx @@ -75,8 +75,8 @@ glxGraphicsBuffer:: // should be skipped. //////////////////////////////////////////////////////////////////// bool glxGraphicsBuffer:: -begin_frame(FrameMode mode) { - PStatTimer timer(_make_current_pcollector); +begin_frame(FrameMode mode, Thread *current_thread) { + PStatTimer timer(_make_current_pcollector, current_thread); begin_frame_spam(); if (_gsg == (GraphicsStateGuardian *)NULL) { @@ -99,7 +99,7 @@ begin_frame(FrameMode mode) { } _gsg->set_current_properties(&get_fb_properties()); - return _gsg->begin_frame(); + return _gsg->begin_frame(current_thread); } //////////////////////////////////////////////////////////////////// @@ -110,7 +110,7 @@ begin_frame(FrameMode mode) { // should do whatever finalization is required. //////////////////////////////////////////////////////////////////// void glxGraphicsBuffer:: -end_frame(FrameMode mode) { +end_frame(FrameMode mode, Thread *current_thread) { end_frame_spam(); nassertv(_gsg != (GraphicsStateGuardian *)NULL); @@ -119,7 +119,7 @@ end_frame(FrameMode mode) { copy_to_textures(); } - _gsg->end_frame(); + _gsg->end_frame(current_thread); if (mode == FM_render) { trigger_flip(); diff --git a/panda/src/glxdisplay/glxGraphicsBuffer.h b/panda/src/glxdisplay/glxGraphicsBuffer.h index bee7165d63..054637d6af 100644 --- a/panda/src/glxdisplay/glxGraphicsBuffer.h +++ b/panda/src/glxdisplay/glxGraphicsBuffer.h @@ -43,8 +43,8 @@ public: GraphicsOutput *host); virtual ~glxGraphicsBuffer(); - virtual bool begin_frame(FrameMode mode); - virtual void end_frame(FrameMode mode); + virtual bool begin_frame(FrameMode mode, Thread *current_thread); + virtual void end_frame(FrameMode mode, Thread *current_thread); protected: virtual void close_buffer(); diff --git a/panda/src/glxdisplay/glxGraphicsWindow.cxx b/panda/src/glxdisplay/glxGraphicsWindow.cxx index 1a3b92b7b0..2d0af74551 100644 --- a/panda/src/glxdisplay/glxGraphicsWindow.cxx +++ b/panda/src/glxdisplay/glxGraphicsWindow.cxx @@ -116,8 +116,8 @@ move_pointer(int device, int x, int y) { // should be skipped. //////////////////////////////////////////////////////////////////// bool glxGraphicsWindow:: -begin_frame(FrameMode mode) { - PStatTimer timer(_make_current_pcollector); +begin_frame(FrameMode mode, Thread *current_thread) { + PStatTimer timer(_make_current_pcollector, current_thread); begin_frame_spam(); if (_gsg == (GraphicsStateGuardian *)NULL) { @@ -145,7 +145,7 @@ begin_frame(FrameMode mode) { } _gsg->set_current_properties(&get_fb_properties()); - return _gsg->begin_frame(); + return _gsg->begin_frame(current_thread); } //////////////////////////////////////////////////////////////////// @@ -156,7 +156,7 @@ begin_frame(FrameMode mode) { // should do whatever finalization is required. //////////////////////////////////////////////////////////////////// void glxGraphicsWindow:: -end_frame(FrameMode mode) { +end_frame(FrameMode mode, Thread *current_thread) { end_frame_spam(); nassertv(_gsg != (GraphicsStateGuardian *)NULL); @@ -165,7 +165,7 @@ end_frame(FrameMode mode) { copy_to_textures(); } - _gsg->end_frame(); + _gsg->end_frame(current_thread); if (mode == FM_render) { trigger_flip(); diff --git a/panda/src/glxdisplay/glxGraphicsWindow.h b/panda/src/glxdisplay/glxGraphicsWindow.h index 52a14d5ab3..fbf11941f7 100644 --- a/panda/src/glxdisplay/glxGraphicsWindow.h +++ b/panda/src/glxdisplay/glxGraphicsWindow.h @@ -41,8 +41,8 @@ public: virtual ~glxGraphicsWindow(); virtual bool move_pointer(int device, int x, int y); - virtual bool begin_frame(FrameMode mode); - virtual void end_frame(FrameMode mode); + virtual bool begin_frame(FrameMode mode, Thread *current_thread); + virtual void end_frame(FrameMode mode, Thread *current_thread); virtual void begin_flip(); virtual void process_events(); diff --git a/panda/src/gobj/bufferResidencyTracker.cxx b/panda/src/gobj/bufferResidencyTracker.cxx index c5a70212fd..3f8fd9bbbe 100644 --- a/panda/src/gobj/bufferResidencyTracker.cxx +++ b/panda/src/gobj/bufferResidencyTracker.cxx @@ -45,9 +45,9 @@ BufferResidencyTracker(const string &pgo_name, const string &type_name) : // initializes the active/inactive status. //////////////////////////////////////////////////////////////////// void BufferResidencyTracker:: -begin_frame() { +begin_frame(Thread *current_thread) { #ifdef DO_PSTATS - int this_frame = ClockObject::get_global_clock()->get_frame_count(); + int this_frame = ClockObject::get_global_clock()->get_frame_count(current_thread); if (_active_frame != this_frame) { _active_frame = this_frame; @@ -68,7 +68,7 @@ begin_frame() { // updates the PStatCollectors appropriately. //////////////////////////////////////////////////////////////////// void BufferResidencyTracker:: -end_frame() { +end_frame(Thread *current_thread) { _inactive_nonresident_collector.set_level(_chains[S_inactive_nonresident].get_total_size()); _active_nonresident_collector.set_level(_chains[S_active_nonresident].get_total_size()); _inactive_resident_collector.set_level(_chains[S_inactive_resident].get_total_size()); diff --git a/panda/src/gobj/bufferResidencyTracker.h b/panda/src/gobj/bufferResidencyTracker.h index 44fee92e3b..97ab9616bb 100644 --- a/panda/src/gobj/bufferResidencyTracker.h +++ b/panda/src/gobj/bufferResidencyTracker.h @@ -41,8 +41,8 @@ class EXPCL_PANDA BufferResidencyTracker { public: BufferResidencyTracker(const string &pgo_name, const string &type_name); - void begin_frame(); - void end_frame(); + void begin_frame(Thread *current_thread); + void end_frame(Thread *current_thread); INLINE BufferContextChain &get_inactive_nonresident(); INLINE BufferContextChain &get_active_nonresident(); diff --git a/panda/src/gobj/geom.I b/panda/src/gobj/geom.I index 6adeda7b7e..f3a9cd2efd 100644 --- a/panda/src/gobj/geom.I +++ b/panda/src/gobj/geom.I @@ -86,8 +86,8 @@ get_usage_hint() const { // modify) the geom's underlying data. //////////////////////////////////////////////////////////////////// INLINE CPT(GeomVertexData) Geom:: -get_vertex_data() const { - CDReader cdata(_cycler); +get_vertex_data(Thread *current_thread) const { + CDReader cdata(_cycler, current_thread); return cdata->_data; } @@ -279,11 +279,11 @@ INLINE void Geom:: calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, const GeomVertexData *vertex_data, - bool got_mat, const LMatrix4f &mat) const { - int pipeline_stage = Thread::get_current_pipeline_stage(); + bool got_mat, const LMatrix4f &mat, + Thread *current_thread) const { do_calc_tight_bounds(min_point, max_point, found_any, vertex_data, got_mat, mat, - pipeline_stage); + current_thread); } //////////////////////////////////////////////////////////////////// @@ -301,9 +301,11 @@ calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, //////////////////////////////////////////////////////////////////// INLINE void Geom:: calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, - bool &found_any) const { + bool &found_any, Thread *current_thread) const { calc_tight_bounds(min_point, max_point, found_any, - get_vertex_data(), false, LMatrix4f::ident_mat()); + get_vertex_data(current_thread), false, + LMatrix4f::ident_mat(), + current_thread); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/geom.cxx b/panda/src/gobj/geom.cxx index 86c3777716..3665e2f9d4 100644 --- a/panda/src/gobj/geom.cxx +++ b/panda/src/gobj/geom.cxx @@ -715,15 +715,14 @@ check_valid(const GeomVertexData *vertex_data) const { // Description: Returns the bounding volume for the Geom. //////////////////////////////////////////////////////////////////// CPT(BoundingVolume) Geom:: -get_bounds() const { - int pipeline_stage = Thread::get_current_pipeline_stage(); - CDStageReader cdata(_cycler, pipeline_stage); +get_bounds(Thread *current_thread) const { + CDReader cdata(_cycler, current_thread); if (cdata->_internal_bounds_stale) { - CDStageWriter cdataw(((Geom *)this)->_cycler, pipeline_stage, cdata); + CDWriter cdataw(((Geom *)this)->_cycler, cdata, false); if (cdataw->_user_bounds != (BoundingVolume *)NULL) { cdataw->_internal_bounds = cdataw->_user_bounds; } else { - cdataw->_internal_bounds = compute_internal_bounds(pipeline_stage); + cdataw->_internal_bounds = compute_internal_bounds(current_thread); } cdataw->_internal_bounds_stale = false; return cdataw->_internal_bounds; @@ -966,7 +965,7 @@ get_next_modified() { // This includes all of the vertices. //////////////////////////////////////////////////////////////////// PT(BoundingVolume) Geom:: -compute_internal_bounds(int pipeline_stage) const { +compute_internal_bounds(Thread *current_thread) const { // First, get ourselves a fresh, empty bounding volume. PT(BoundingVolume) bound = new BoundingSphere; GeometricBoundingVolume *gbv = DCAST(GeometricBoundingVolume, bound); @@ -975,8 +974,9 @@ compute_internal_bounds(int pipeline_stage) const { // calc_tight_bounds to determine our minmax first. LPoint3f points[2]; bool found_any = false; - do_calc_tight_bounds(points[0], points[1], found_any, get_vertex_data(), - false, LMatrix4f::ident_mat(), pipeline_stage); + do_calc_tight_bounds(points[0], points[1], found_any, + get_vertex_data(current_thread), + false, LMatrix4f::ident_mat(), current_thread); if (found_any) { // Then we put the bounding volume around both of those points. // Technically, we should put it around the eight points at the @@ -1002,15 +1002,15 @@ do_calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, const GeomVertexData *vertex_data, bool got_mat, const LMatrix4f &mat, - int pipeline_stage) const { - CDStageReader cdata(_cycler, pipeline_stage); + Thread *current_thread) const { + CDReader cdata(_cycler, current_thread); Primitives::const_iterator pi; for (pi = cdata->_primitives.begin(); pi != cdata->_primitives.end(); ++pi) { (*pi)->calc_tight_bounds(min_point, max_point, found_any, vertex_data, - got_mat, mat); + got_mat, mat, current_thread); } } diff --git a/panda/src/gobj/geom.h b/panda/src/gobj/geom.h index 995278e6d0..51208efd95 100644 --- a/panda/src/gobj/geom.h +++ b/panda/src/gobj/geom.h @@ -74,7 +74,7 @@ PUBLISHED: INLINE UsageHint get_usage_hint() const; void set_usage_hint(UsageHint usage_hint); - INLINE CPT(GeomVertexData) get_vertex_data() const; + INLINE CPT(GeomVertexData) get_vertex_data(Thread *current_thread = Thread::get_current_thread()) const; PT(GeomVertexData) modify_vertex_data(); void set_vertex_data(const GeomVertexData *data); void offset_vertices(const GeomVertexData *data, int offset); @@ -105,7 +105,7 @@ PUBLISHED: bool check_valid() const; bool check_valid(const GeomVertexData *vertex_data) const; - CPT(BoundingVolume) get_bounds() const; + CPT(BoundingVolume) get_bounds(Thread *current_thread = Thread::get_current_thread()) const; INLINE void mark_bounds_stale() const; INLINE void set_bounds(const BoundingVolume *volume); INLINE void clear_bounds(); @@ -132,9 +132,10 @@ public: INLINE void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, const GeomVertexData *vertex_data, - bool got_mat, const LMatrix4f &mat) const; + bool got_mat, const LMatrix4f &mat, + Thread *current_thread) const; INLINE void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, - bool &found_any) const; + bool &found_any, Thread *current_thread) const; static UpdateSeq get_next_modified(); @@ -146,13 +147,13 @@ private: class CData; INLINE void mark_internal_bounds_stale(CData *cdata); - PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const; + PT(BoundingVolume) compute_internal_bounds(Thread *current_thread) const; void do_calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, const GeomVertexData *vertex_data, bool got_mat, const LMatrix4f &mat, - int pipeline_stage) const; + Thread *current_thread) const; void clear_prepared(PreparedGraphicsObjects *prepared_objects); bool check_will_be_valid(const GeomVertexData *vertex_data) const; diff --git a/panda/src/gobj/geomMunger.cxx b/panda/src/gobj/geomMunger.cxx index c2ab0d49cc..a1510b1f25 100644 --- a/panda/src/gobj/geomMunger.cxx +++ b/panda/src/gobj/geomMunger.cxx @@ -103,7 +103,8 @@ remove_data(const GeomVertexData *data) { // same; so this result may be cached. //////////////////////////////////////////////////////////////////// void GeomMunger:: -munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data) { +munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data, + Thread *current_thread) { CPT(GeomVertexData) source_data = data; // Look up the munger in the geom's cache--maybe we've recently @@ -123,7 +124,7 @@ munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data) { entry->refresh(); // Now check that it's fresh. - Geom::CDCacheReader cdata(entry->_cycler); + Geom::CDCacheReader cdata(entry->_cycler, current_thread); nassertv(cdata->_source == geom); if (cdata->_geom_result != (Geom *)NULL && geom->get_modified() <= cdata->_geom_result->get_modified() && @@ -142,11 +143,11 @@ munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data) { } // Ok, invoke the munger. - PStatTimer timer(_munge_pcollector); + PStatTimer timer(_munge_pcollector, current_thread); CPT(Geom) orig_geom = geom; data = munge_data(data); - munge_geom_impl(geom, data); + munge_geom_impl(geom, data, current_thread); // Record the new result in the cache. if (entry == (Geom::CacheEntry *)NULL) { @@ -162,7 +163,7 @@ munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data) { } // Finally, store the cached result on the entry. - Geom::CDCacheWriter cdata(entry->_cycler, true); + Geom::CDCacheWriter cdata(entry->_cycler, true, current_thread); cdata->_source = (Geom *)orig_geom.p(); cdata->set_result(geom, data); } @@ -239,7 +240,7 @@ munge_data_impl(const GeomVertexData *data) { // Description: Converts a Geom and/or its data as necessary. //////////////////////////////////////////////////////////////////// bool GeomMunger:: -munge_geom_impl(CPT(Geom) &, CPT(GeomVertexData) &) { +munge_geom_impl(CPT(Geom) &, CPT(GeomVertexData) &, Thread *) { // The default implementation does nothing (the work has already // been done in munge_format_impl() and munge_data_impl()). return true; diff --git a/panda/src/gobj/geomMunger.h b/panda/src/gobj/geomMunger.h index dc25199d54..eb71ff851b 100644 --- a/panda/src/gobj/geomMunger.h +++ b/panda/src/gobj/geomMunger.h @@ -72,7 +72,8 @@ public: INLINE CPT(GeomVertexData) munge_data(const GeomVertexData *data) const; void remove_data(const GeomVertexData *data); - void munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data); + void munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data, + Thread *current_thread); public: INLINE int compare_to(const GeomMunger &other) const; @@ -85,7 +86,8 @@ protected: virtual CPT(GeomVertexFormat) munge_format_impl(const GeomVertexFormat *orig, const GeomVertexAnimationSpec &animation); virtual CPT(GeomVertexData) munge_data_impl(const GeomVertexData *data); - virtual bool munge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &data); + virtual bool munge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &data, + Thread *current_thread); virtual int compare_to_impl(const GeomMunger *other) const; virtual int geom_compare_to_impl(const GeomMunger *other) const; diff --git a/panda/src/gobj/geomPrimitive.cxx b/panda/src/gobj/geomPrimitive.cxx index 0e5eaac9dd..96eb0ac249 100644 --- a/panda/src/gobj/geomPrimitive.cxx +++ b/panda/src/gobj/geomPrimitive.cxx @@ -1122,14 +1122,16 @@ void GeomPrimitive:: calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, const GeomVertexData *vertex_data, - bool got_mat, const LMatrix4f &mat) const { - GeomVertexReader reader(vertex_data, InternalName::get_vertex()); + bool got_mat, const LMatrix4f &mat, + Thread *current_thread) const { + GeomVertexReader reader(vertex_data, InternalName::get_vertex(), + current_thread); if (!reader.has_column()) { // No vertex data. return; } - CDReader cdata(_cycler); + CDReader cdata(_cycler, current_thread); if (cdata->_vertices == (GeomVertexArrayData *)NULL) { // Nonindexed case. @@ -1173,7 +1175,7 @@ calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, } else { // Indexed case. - GeomVertexReader index(cdata->_vertices, 0); + GeomVertexReader index(cdata->_vertices, 0, current_thread); if (got_mat) { while (!index.is_at_end()) { diff --git a/panda/src/gobj/geomPrimitive.h b/panda/src/gobj/geomPrimitive.h index c6ba60e152..69a8a6b9fe 100644 --- a/panda/src/gobj/geomPrimitive.h +++ b/panda/src/gobj/geomPrimitive.h @@ -192,7 +192,8 @@ public: void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, const GeomVertexData *vertex_data, - bool got_mat, const LMatrix4f &mat) const; + bool got_mat, const LMatrix4f &mat, + Thread *current_thread) const; protected: virtual CPT(GeomPrimitive) decompose_impl() const; diff --git a/panda/src/gobj/geomVertexData.cxx b/panda/src/gobj/geomVertexData.cxx index 2c43581a8f..a9763c472d 100644 --- a/panda/src/gobj/geomVertexData.cxx +++ b/panda/src/gobj/geomVertexData.cxx @@ -883,8 +883,8 @@ set_color(const Colorf &color, int num_components, // graphics backend to update vertex buffers optimally). //////////////////////////////////////////////////////////////////// CPT(GeomVertexData) GeomVertexData:: -animate_vertices() const { - CDReader cdata(_cycler); +animate_vertices(Thread *current_thread) const { + CDReader cdata(_cycler, current_thread); if (cdata->_format->get_animation().get_animation_type() != AT_panda) { return this; @@ -1717,7 +1717,6 @@ make_array_readers() { } _got_array_readers = true; - nassertv(get_array_reader(0)->get_data_size_bytes() == get_array(0)->get_data_size_bytes()); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/geomVertexData.h b/panda/src/gobj/geomVertexData.h index 01e255f78e..a216e47353 100644 --- a/panda/src/gobj/geomVertexData.h +++ b/panda/src/gobj/geomVertexData.h @@ -139,7 +139,7 @@ PUBLISHED: set_color(const Colorf &color, int num_components, NumericType numeric_type, Contents contents) const; - CPT(GeomVertexData) animate_vertices() const; + CPT(GeomVertexData) animate_vertices(Thread *current_thread) const; PT(GeomVertexData) replace_column(InternalName *name, int num_components, diff --git a/panda/src/gobj/geomVertexReader.I b/panda/src/gobj/geomVertexReader.I index 1fc03bbcff..44a9fe9ae0 100644 --- a/panda/src/gobj/geomVertexReader.I +++ b/panda/src/gobj/geomVertexReader.I @@ -26,9 +26,9 @@ // it. //////////////////////////////////////////////////////////////////// INLINE GeomVertexReader:: -GeomVertexReader() : +GeomVertexReader(Thread *current_thread) : _vertex_data(NULL), - _current_thread(Thread::get_current_thread()) + _current_thread(current_thread) { initialize(); } @@ -40,9 +40,10 @@ GeomVertexReader() : // the indicated data object. //////////////////////////////////////////////////////////////////// INLINE GeomVertexReader:: -GeomVertexReader(const GeomVertexData *vertex_data) : +GeomVertexReader(const GeomVertexData *vertex_data, + Thread *current_thread) : _vertex_data(vertex_data), - _current_thread(Thread::get_current_thread()) + _current_thread(current_thread) { initialize(); } @@ -55,9 +56,10 @@ GeomVertexReader(const GeomVertexData *vertex_data) : // reader specifically to process the named data type. //////////////////////////////////////////////////////////////////// INLINE GeomVertexReader:: -GeomVertexReader(const GeomVertexData *vertex_data, const string &name) : +GeomVertexReader(const GeomVertexData *vertex_data, const string &name, + Thread *current_thread) : _vertex_data(vertex_data), - _current_thread(Thread::get_current_thread()) + _current_thread(current_thread) { initialize(); set_column(name); @@ -72,9 +74,10 @@ GeomVertexReader(const GeomVertexData *vertex_data, const string &name) : //////////////////////////////////////////////////////////////////// INLINE GeomVertexReader:: GeomVertexReader(const GeomVertexData *vertex_data, - const InternalName *name) : + const InternalName *name, + Thread *current_thread) : _vertex_data(vertex_data), - _current_thread(Thread::get_current_thread()) + _current_thread(current_thread) { initialize(); set_column(name); @@ -87,9 +90,10 @@ GeomVertexReader(const GeomVertexData *vertex_data, // the indicated array only. //////////////////////////////////////////////////////////////////// INLINE GeomVertexReader:: -GeomVertexReader(const GeomVertexArrayData *array_data) : +GeomVertexReader(const GeomVertexArrayData *array_data, + Thread *current_thread) : _array_data(array_data), - _current_thread(Thread::get_current_thread()) + _current_thread(current_thread) { initialize(); } @@ -101,9 +105,10 @@ GeomVertexReader(const GeomVertexArrayData *array_data) : // the indicated array only. //////////////////////////////////////////////////////////////////// INLINE GeomVertexReader:: -GeomVertexReader(const GeomVertexArrayData *array_data, int column) : +GeomVertexReader(const GeomVertexArrayData *array_data, int column, + Thread *current_thread) : _array_data(array_data), - _current_thread(Thread::get_current_thread()) + _current_thread(current_thread) { initialize(); set_column(column); diff --git a/panda/src/gobj/geomVertexReader.h b/panda/src/gobj/geomVertexReader.h index 7762b4214b..a948809f22 100644 --- a/panda/src/gobj/geomVertexReader.h +++ b/panda/src/gobj/geomVertexReader.h @@ -59,15 +59,20 @@ //////////////////////////////////////////////////////////////////// class EXPCL_PANDA GeomVertexReader : public GeomEnums { PUBLISHED: - INLINE GeomVertexReader(); - INLINE GeomVertexReader(const GeomVertexData *vertex_data); + INLINE GeomVertexReader(Thread *current_thread = Thread::get_current_thread()); INLINE GeomVertexReader(const GeomVertexData *vertex_data, - const string &name); + Thread *current_thread = Thread::get_current_thread()); INLINE GeomVertexReader(const GeomVertexData *vertex_data, - const InternalName *name); - INLINE GeomVertexReader(const GeomVertexArrayData *array_data); + const string &name, + Thread *current_thread = Thread::get_current_thread()); + INLINE GeomVertexReader(const GeomVertexData *vertex_data, + const InternalName *name, + Thread *current_thread = Thread::get_current_thread()); + INLINE GeomVertexReader(const GeomVertexArrayData *array_data, + Thread *current_thread = Thread::get_current_thread()); INLINE GeomVertexReader(const GeomVertexArrayData *array_data, - int column); + int column, + Thread *current_thread = Thread::get_current_thread()); public: INLINE GeomVertexReader(const GeomVertexDataPipelineReader *data_reader, diff --git a/panda/src/gobj/geomVertexWriter.I b/panda/src/gobj/geomVertexWriter.I index caf9c1c4a2..b9db532486 100644 --- a/panda/src/gobj/geomVertexWriter.I +++ b/panda/src/gobj/geomVertexWriter.I @@ -26,9 +26,9 @@ // it. //////////////////////////////////////////////////////////////////// INLINE GeomVertexWriter:: -GeomVertexWriter() : +GeomVertexWriter(Thread *current_thread) : _vertex_data(NULL), - _current_thread(Thread::get_current_thread()) + _current_thread(current_thread) { initialize(); } @@ -40,9 +40,9 @@ GeomVertexWriter() : // the indicated data object. //////////////////////////////////////////////////////////////////// INLINE GeomVertexWriter:: -GeomVertexWriter(GeomVertexData *vertex_data) : +GeomVertexWriter(GeomVertexData *vertex_data, Thread *current_thread) : _vertex_data(vertex_data), - _current_thread(Thread::get_current_thread()) + _current_thread(current_thread) { initialize(); } @@ -55,9 +55,10 @@ GeomVertexWriter(GeomVertexData *vertex_data) : // writer specifically to process the named data type. //////////////////////////////////////////////////////////////////// INLINE GeomVertexWriter:: -GeomVertexWriter(GeomVertexData *vertex_data, const string &name) : +GeomVertexWriter(GeomVertexData *vertex_data, const string &name, + Thread *current_thread) : _vertex_data(vertex_data), - _current_thread(Thread::get_current_thread()) + _current_thread(current_thread) { initialize(); set_column(name); @@ -71,9 +72,10 @@ GeomVertexWriter(GeomVertexData *vertex_data, const string &name) : // writer specifically to process the named data type. //////////////////////////////////////////////////////////////////// INLINE GeomVertexWriter:: -GeomVertexWriter(GeomVertexData *vertex_data, const InternalName *name) : +GeomVertexWriter(GeomVertexData *vertex_data, const InternalName *name, + Thread *current_thread) : _vertex_data(vertex_data), - _current_thread(Thread::get_current_thread()) + _current_thread(current_thread) { initialize(); set_column(name); @@ -86,9 +88,10 @@ GeomVertexWriter(GeomVertexData *vertex_data, const InternalName *name) : // the indicated array only. //////////////////////////////////////////////////////////////////// INLINE GeomVertexWriter:: -GeomVertexWriter(GeomVertexArrayData *array_data) : +GeomVertexWriter(GeomVertexArrayData *array_data, + Thread *current_thread) : _array_data(array_data), - _current_thread(Thread::get_current_thread()) + _current_thread(current_thread) { initialize(); } @@ -100,9 +103,10 @@ GeomVertexWriter(GeomVertexArrayData *array_data) : // the indicated array only. //////////////////////////////////////////////////////////////////// INLINE GeomVertexWriter:: -GeomVertexWriter(GeomVertexArrayData *array_data, int column) : +GeomVertexWriter(GeomVertexArrayData *array_data, int column, + Thread *current_thread) : _array_data(array_data), - _current_thread(Thread::get_current_thread()) + _current_thread(current_thread) { initialize(); set_column(column); diff --git a/panda/src/gobj/geomVertexWriter.h b/panda/src/gobj/geomVertexWriter.h index 35ee8b281d..1874290971 100644 --- a/panda/src/gobj/geomVertexWriter.h +++ b/panda/src/gobj/geomVertexWriter.h @@ -72,15 +72,20 @@ //////////////////////////////////////////////////////////////////// class EXPCL_PANDA GeomVertexWriter : public GeomEnums { PUBLISHED: - INLINE GeomVertexWriter(); - INLINE GeomVertexWriter(GeomVertexData *vertex_data); + INLINE GeomVertexWriter(Thread *current_thread = Thread::get_current_thread()); INLINE GeomVertexWriter(GeomVertexData *vertex_data, - const string &name); + Thread *current_thread = Thread::get_current_thread()); INLINE GeomVertexWriter(GeomVertexData *vertex_data, - const InternalName *name); - INLINE GeomVertexWriter(GeomVertexArrayData *array_data); + const string &name, + Thread *current_thread = Thread::get_current_thread()); + INLINE GeomVertexWriter(GeomVertexData *vertex_data, + const InternalName *name, + Thread *current_thread = Thread::get_current_thread()); + INLINE GeomVertexWriter(GeomVertexArrayData *array_data, + Thread *current_thread = Thread::get_current_thread()); INLINE GeomVertexWriter(GeomVertexArrayData *array_data, - int column); + int column, + Thread *current_thread = Thread::get_current_thread()); public: INLINE GeomVertexWriter(GeomVertexDataPipelineWriter *data_writer, diff --git a/panda/src/gobj/preparedGraphicsObjects.cxx b/panda/src/gobj/preparedGraphicsObjects.cxx index cafec2cd09..78ef10d968 100644 --- a/panda/src/gobj/preparedGraphicsObjects.cxx +++ b/panda/src/gobj/preparedGraphicsObjects.cxx @@ -834,8 +834,8 @@ prepare_index_buffer_now(GeomPrimitive *data, GraphicsStateGuardianBase *gsg) { // passed to prepare_texture are actually loaded. //////////////////////////////////////////////////////////////////// void PreparedGraphicsObjects:: -begin_frame(GraphicsStateGuardianBase *gsg) { - ReMutexHolder holder(_lock); +begin_frame(GraphicsStateGuardianBase *gsg, Thread *current_thread) { + ReMutexHolder holder(_lock, current_thread); // First, release all the textures, geoms, and buffers awaiting // release. @@ -890,9 +890,9 @@ begin_frame(GraphicsStateGuardianBase *gsg) { _released_index_buffers.clear(); // Reset the residency trackers. - _texture_residency.begin_frame(); - _vbuffer_residency.begin_frame(); - _ibuffer_residency.begin_frame(); + _texture_residency.begin_frame(current_thread); + _vbuffer_residency.begin_frame(current_thread); + _ibuffer_residency.begin_frame(current_thread); // Now prepare all the textures, geoms, and buffers awaiting // preparation. @@ -955,12 +955,12 @@ begin_frame(GraphicsStateGuardianBase *gsg) { // frame. //////////////////////////////////////////////////////////////////// void PreparedGraphicsObjects:: -end_frame() { - ReMutexHolder holder(_lock); +end_frame(Thread *current_thread) { + ReMutexHolder holder(_lock, current_thread); - _texture_residency.end_frame(); - _vbuffer_residency.end_frame(); - _ibuffer_residency.end_frame(); + _texture_residency.end_frame(current_thread); + _vbuffer_residency.end_frame(current_thread); + _ibuffer_residency.end_frame(current_thread); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/preparedGraphicsObjects.h b/panda/src/gobj/preparedGraphicsObjects.h index 89b3edd000..10f13986d1 100644 --- a/panda/src/gobj/preparedGraphicsObjects.h +++ b/panda/src/gobj/preparedGraphicsObjects.h @@ -106,8 +106,9 @@ public: prepare_index_buffer_now(GeomPrimitive *data, GraphicsStateGuardianBase *gsg); - void begin_frame(GraphicsStateGuardianBase *gsg); - void end_frame(); + void begin_frame(GraphicsStateGuardianBase *gsg, + Thread *current_thread); + void end_frame(Thread *current_thread); private: static string init_name(); diff --git a/panda/src/grutil/multitexReducer.cxx b/panda/src/grutil/multitexReducer.cxx index 93db90751f..8ead100d5d 100644 --- a/panda/src/grutil/multitexReducer.cxx +++ b/panda/src/grutil/multitexReducer.cxx @@ -883,6 +883,7 @@ void MultitexReducer:: transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name, const MultitexReducer::GeomList &geom_list, bool preserve_color) { + Thread *current_thread = Thread::get_current_thread(); GeomList::const_iterator gi; for (gi = geom_list.begin(); gi != geom_list.end(); ++gi) { const GeomInfo &geom_info = (*gi); @@ -893,7 +894,7 @@ transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name, PT(Geom) geom = orig_geom->make_copy(); // Ensure that any vertex animation has been applied. - geom->set_vertex_data(geom->get_vertex_data()->animate_vertices()); + geom->set_vertex_data(geom->get_vertex_data(current_thread)->animate_vertices(current_thread)); // Now get a modifiable pointer to the vertex data in the new // Geom. This will actually perform a deep copy of the vertex @@ -902,8 +903,8 @@ transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name, vdata->set_usage_hint(Geom::UH_stream); if (vdata->has_column(_target_stage->get_texcoord_name())) { - GeomVertexWriter vertex(vdata, InternalName::get_vertex()); - GeomVertexReader texcoord(vdata, _target_stage->get_texcoord_name()); + GeomVertexWriter vertex(vdata, InternalName::get_vertex(), current_thread); + GeomVertexReader texcoord(vdata, _target_stage->get_texcoord_name(), current_thread); while (!texcoord.is_at_end()) { const LVecBase2f &tc = texcoord.get_data2f(); @@ -923,8 +924,8 @@ transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name, column->get_numeric_type(), column->get_contents()); geom->set_vertex_data(vdata); - GeomVertexReader from(vdata, texcoord_name); - GeomVertexWriter to(vdata, InternalName::get_texcoord()); + GeomVertexReader from(vdata, texcoord_name, current_thread); + GeomVertexWriter to(vdata, InternalName::get_texcoord(), current_thread); while (!from.is_at_end()) { to.add_data2f(from.get_data2f()); } diff --git a/panda/src/parametrics/ropeNode.cxx b/panda/src/parametrics/ropeNode.cxx index a8622f31ea..b6a8c44224 100644 --- a/panda/src/parametrics/ropeNode.cxx +++ b/panda/src/parametrics/ropeNode.cxx @@ -233,9 +233,10 @@ write(ostream &out, int indent_level) const { //////////////////////////////////////////////////////////////////// void RopeNode:: reset_bound(const NodePath &rel_to) { - int pipeline_stage = Thread::get_current_pipeline_stage(); - do_recompute_bounds(rel_to, pipeline_stage); - mark_internal_bounds_stale(); + Thread *current_thread = Thread::get_current_thread(); + int pipeline_stage = current_thread->get_pipeline_stage(); + do_recompute_bounds(rel_to, pipeline_stage, current_thread); + mark_internal_bounds_stale(current_thread); } //////////////////////////////////////////////////////////////////// @@ -247,8 +248,9 @@ reset_bound(const NodePath &rel_to) { // thing. //////////////////////////////////////////////////////////////////// PT(BoundingVolume) RopeNode:: -compute_internal_bounds(int pipeline_stage) const { - return do_recompute_bounds(NodePath((PandaNode *)this), pipeline_stage); +compute_internal_bounds(int pipeline_stage, Thread *current_thread) const { + return do_recompute_bounds(NodePath((PandaNode *)this), pipeline_stage, + current_thread); } //////////////////////////////////////////////////////////////////// @@ -289,13 +291,14 @@ get_format(bool support_normals) const { // Description: Does the actual internal recompute. //////////////////////////////////////////////////////////////////// PT(BoundingVolume) RopeNode:: -do_recompute_bounds(const NodePath &rel_to, int pipeline_stage) const { +do_recompute_bounds(const NodePath &rel_to, int pipeline_stage, + Thread *current_thread) const { // TODO: fix the bounds so that it properly reflects the indicated // pipeline stage. At the moment, we cheat and get some of the // properties from the current pipeline stage, the lazy way. // First, get ourselves a fresh, empty bounding volume. - PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage); + PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage, current_thread); nassertr(bound != (BoundingVolume *)NULL, bound); NurbsCurveEvaluator *curve = get_curve(); diff --git a/panda/src/parametrics/ropeNode.h b/panda/src/parametrics/ropeNode.h index 8b9e6009c7..db38728124 100644 --- a/panda/src/parametrics/ropeNode.h +++ b/panda/src/parametrics/ropeNode.h @@ -142,13 +142,14 @@ PUBLISHED: void reset_bound(const NodePath &rel_to); protected: - virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const; + virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage, Thread *current_thread) const; private: CPT(GeomVertexFormat) get_format(bool support_normals) const; PT(BoundingVolume) do_recompute_bounds(const NodePath &rel_to, - int pipeline_stage) const; + int pipeline_stage, + Thread *current_thread) const; void render_thread(CullTraverser *trav, CullTraverserData &data, NurbsCurveResult *result) const; void render_tape(CullTraverser *trav, CullTraverserData &data, diff --git a/panda/src/parametrics/sheetNode.cxx b/panda/src/parametrics/sheetNode.cxx index 0f338132f1..4af75ae738 100644 --- a/panda/src/parametrics/sheetNode.cxx +++ b/panda/src/parametrics/sheetNode.cxx @@ -215,9 +215,10 @@ write(ostream &out, int indent_level) const { //////////////////////////////////////////////////////////////////// void SheetNode:: reset_bound(const NodePath &rel_to) { - int pipeline_stage = Thread::get_current_pipeline_stage(); - do_recompute_bounds(rel_to, pipeline_stage); - mark_internal_bounds_stale(); + Thread *current_thread = Thread::get_current_thread(); + int pipeline_stage = current_thread->get_pipeline_stage(); + do_recompute_bounds(rel_to, pipeline_stage, current_thread); + mark_internal_bounds_stale(current_thread); } //////////////////////////////////////////////////////////////////// @@ -229,8 +230,9 @@ reset_bound(const NodePath &rel_to) { // thing. //////////////////////////////////////////////////////////////////// PT(BoundingVolume) SheetNode:: -compute_internal_bounds(int pipeline_stage) const { - return do_recompute_bounds(NodePath((PandaNode *)this), pipeline_stage); +compute_internal_bounds(int pipeline_stage, Thread *current_thread) const { + return do_recompute_bounds(NodePath((PandaNode *)this), pipeline_stage, + current_thread); } //////////////////////////////////////////////////////////////////// @@ -239,13 +241,14 @@ compute_internal_bounds(int pipeline_stage) const { // Description: Does the actual internal recompute. //////////////////////////////////////////////////////////////////// PT(BoundingVolume) SheetNode:: -do_recompute_bounds(const NodePath &rel_to, int pipeline_stage) const { +do_recompute_bounds(const NodePath &rel_to, int pipeline_stage, + Thread *current_thread) const { // TODO: fix the bounds so that it properly reflects the indicated // pipeline stage. At the moment, we cheat and get some of the // properties from the current pipeline stage, the lazy way. // First, get ourselves a fresh, empty bounding volume. - PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage); + PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage, current_thread); nassertr(bound != (BoundingVolume *)NULL, bound); NurbsSurfaceEvaluator *surface = get_surface(); diff --git a/panda/src/parametrics/sheetNode.h b/panda/src/parametrics/sheetNode.h index c6606f6eca..7d50f79169 100644 --- a/panda/src/parametrics/sheetNode.h +++ b/panda/src/parametrics/sheetNode.h @@ -68,11 +68,12 @@ PUBLISHED: void reset_bound(const NodePath &rel_to); protected: - virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const; + virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage, Thread *current_thread) const; private: PT(BoundingVolume) do_recompute_bounds(const NodePath &rel_to, - int pipeline_stage) const; + int pipeline_stage, + Thread *current_thread) const; void render_sheet(CullTraverser *trav, CullTraverserData &data, NurbsSurfaceResult *result); diff --git a/panda/src/pgraph/cullBin.cxx b/panda/src/pgraph/cullBin.cxx index b49bcb5e26..d90b6130f9 100644 --- a/panda/src/pgraph/cullBin.cxx +++ b/panda/src/pgraph/cullBin.cxx @@ -51,16 +51,6 @@ make_next() const { return (CullBin *)NULL; } -//////////////////////////////////////////////////////////////////// -// Function: CullBin::add_object -// Access: Public, Virtual -// Description: Adds a geom, along with its associated state, to -// the bin for rendering. -//////////////////////////////////////////////////////////////////// -void CullBin:: -add_object(CullableObject *) { -} - //////////////////////////////////////////////////////////////////// // Function: CullBin::finish_cull // Access: Public, Virtual @@ -71,7 +61,7 @@ add_object(CullableObject *) { // draw. //////////////////////////////////////////////////////////////////// void CullBin:: -finish_cull(SceneSetup *) { +finish_cull(SceneSetup *, Thread *) { } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/cullBin.h b/panda/src/pgraph/cullBin.h index 8358eeee74..a4e36fc6ee 100644 --- a/panda/src/pgraph/cullBin.h +++ b/panda/src/pgraph/cullBin.h @@ -54,8 +54,8 @@ public: virtual PT(CullBin) make_next() const; - virtual void add_object(CullableObject *object)=0; - virtual void finish_cull(SceneSetup *scene_setup); + virtual void add_object(CullableObject *object, Thread *current_thread)=0; + virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread); virtual void draw(Thread *current_thread)=0; diff --git a/panda/src/pgraph/cullResult.cxx b/panda/src/pgraph/cullResult.cxx index 1a3dfedc93..e121c7604d 100644 --- a/panda/src/pgraph/cullResult.cxx +++ b/panda/src/pgraph/cullResult.cxx @@ -98,6 +98,8 @@ add_object(CullableObject *object, const CullTraverser *traverser) { static const Colorf flash_multisample_color(0.78f, 0.05f, 0.81f, 1.0f); static const Colorf flash_dual_color(0.92f, 0.01f, 0.01f, 1.0f); + Thread *current_thread = traverser->get_current_thread(); + // Check to see if there's a special transparency setting. const RenderState *state = object->_state; nassertv(state != (const RenderState *)NULL); @@ -172,7 +174,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) { #ifndef NDEBUG check_flash_bin(transparent_part->_state, bin); #endif - bin->add_object(transparent_part); + bin->add_object(transparent_part, current_thread); } // Now we can draw the opaque part, with decals. This will @@ -206,8 +208,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) { // Munge vertices as needed for the GSG's requirements, and the // object's current state. object->munge_geom(_gsg, _gsg->get_geom_munger(object->_state), traverser); - - bin->add_object(object); + bin->add_object(object, current_thread); } //////////////////////////////////////////////////////////////////// @@ -220,7 +221,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) { // draw. //////////////////////////////////////////////////////////////////// void CullResult:: -finish_cull(SceneSetup *scene_setup) { +finish_cull(SceneSetup *scene_setup, Thread *current_thread) { CullBinManager *bin_manager = CullBinManager::get_global_ptr(); for (size_t i = 0; i < _bins.size(); ++i) { @@ -232,7 +233,7 @@ finish_cull(SceneSetup *scene_setup) { } else { CullBin *bin = _bins[i]; if (bin != (CullBin *)NULL) { - bin->finish_cull(scene_setup); + bin->finish_cull(scene_setup, current_thread); } } } diff --git a/panda/src/pgraph/cullResult.h b/panda/src/pgraph/cullResult.h index aee49de7d2..81b97229c6 100644 --- a/panda/src/pgraph/cullResult.h +++ b/panda/src/pgraph/cullResult.h @@ -59,7 +59,7 @@ public: INLINE CullBin *get_bin(int bin_index); void add_object(CullableObject *object, const CullTraverser *traverser); - void finish_cull(SceneSetup *scene_setup); + void finish_cull(SceneSetup *scene_setup, Thread *current_thread); void draw(Thread *current_thread); public: diff --git a/panda/src/pgraph/cullTraverser.I b/panda/src/pgraph/cullTraverser.I index 6876bee29a..ac7f57c8d8 100644 --- a/panda/src/pgraph/cullTraverser.I +++ b/panda/src/pgraph/cullTraverser.I @@ -27,6 +27,17 @@ get_gsg() const { return _gsg; } +//////////////////////////////////////////////////////////////////// +// Function: CullTraverser::get_current_thread +// Access: Public +// Description: Returns the currently-executing thread object, as +// passed to the CullTraverser constructor. +//////////////////////////////////////////////////////////////////// +INLINE Thread *CullTraverser:: +get_current_thread() const { + return _current_thread; +} + //////////////////////////////////////////////////////////////////// // Function: CullTraverser::set_scene // Access: Public diff --git a/panda/src/pgraph/cullTraverser.cxx b/panda/src/pgraph/cullTraverser.cxx index 62897af494..0142d17eca 100644 --- a/panda/src/pgraph/cullTraverser.cxx +++ b/panda/src/pgraph/cullTraverser.cxx @@ -50,8 +50,9 @@ TypeHandle CullTraverser::_type_handle; // Description: //////////////////////////////////////////////////////////////////// CullTraverser:: -CullTraverser(GraphicsStateGuardianBase *gsg) : - _gsg(gsg) +CullTraverser(GraphicsStateGuardianBase *gsg, Thread *current_thread) : + _gsg(gsg), + _current_thread(current_thread) { _camera_mask = DrawMask::all_on(); _has_tag_state_key = false; @@ -151,7 +152,7 @@ traverse(CullTraverserData &data) { // optimization, we should tag nodes with these properties as // being "fancy", and skip this processing for non-fancy nodes. - if (data.is_in_view(_camera_mask)) { + if (data.is_in_view(_camera_mask, _current_thread)) { if (pgraph_cat.is_spam()) { pgraph_cat.spam() << "\n" << data._node_path @@ -378,12 +379,14 @@ make_tight_bounds_viz(PandaNode *node) { LPoint3f n, x; bool found_any = false; - node->calc_tight_bounds(n, x, found_any, TransformState::make_identity()); + node->calc_tight_bounds(n, x, found_any, TransformState::make_identity(), + _current_thread); if (found_any) { PT(GeomVertexData) vdata = new GeomVertexData ("bounds", GeomVertexFormat::get_v3(), Geom::UH_stream); - GeomVertexWriter vertex(vdata, InternalName::get_vertex()); + GeomVertexWriter vertex(vdata, InternalName::get_vertex(), + _current_thread); vertex.add_data3f(n[0], n[1], n[2]); vertex.add_data3f(n[0], n[1], x[2]); @@ -586,7 +589,7 @@ start_decal(const CullTraverserData &data) { //////////////////////////////////////////////////////////////////// CullableObject *CullTraverser:: r_get_decals(CullTraverserData &data, CullableObject *decals) { - if (data.is_in_view(_camera_mask)) { + if (data.is_in_view(_camera_mask, _current_thread)) { PandaNode *node = data.node(); const RenderEffects *node_effects = node->get_effects(); diff --git a/panda/src/pgraph/cullTraverser.h b/panda/src/pgraph/cullTraverser.h index cde8a4682d..019684b281 100644 --- a/panda/src/pgraph/cullTraverser.h +++ b/panda/src/pgraph/cullTraverser.h @@ -50,10 +50,11 @@ class NodePath; //////////////////////////////////////////////////////////////////// class EXPCL_PANDA CullTraverser : public TypedObject { public: - CullTraverser(GraphicsStateGuardianBase *gsg); + CullTraverser(GraphicsStateGuardianBase *gsg, Thread *current_thread); CullTraverser(const CullTraverser ©); INLINE GraphicsStateGuardianBase *get_gsg() const; + INLINE Thread *get_current_thread() const; INLINE void set_scene(SceneSetup *scene_setup); INLINE SceneSetup *get_scene() const; @@ -111,6 +112,7 @@ private: CullableObject *decals); GraphicsStateGuardianBase *_gsg; + Thread *_current_thread; PT(SceneSetup) _scene_setup; DrawMask _camera_mask; bool _has_tag_state_key; diff --git a/panda/src/pgraph/cullTraverserData.I b/panda/src/pgraph/cullTraverserData.I index b9dde02a56..97f8b6f2c7 100644 --- a/panda/src/pgraph/cullTraverserData.I +++ b/panda/src/pgraph/cullTraverserData.I @@ -128,13 +128,13 @@ get_net_transform(const CullTraverser *) const { // work for future nodes. //////////////////////////////////////////////////////////////////// INLINE bool CullTraverserData:: -is_in_view(const DrawMask &camera_mask) { - if (node()->get_transform()->is_invalid()) { +is_in_view(const DrawMask &camera_mask, Thread *current_thread) { + if (node()->get_transform(current_thread)->is_invalid()) { // If the transform is invalid, forget it. return false; } - if (!node()->compare_draw_mask(_draw_mask, camera_mask)) { + if (!node()->compare_draw_mask(_draw_mask, camera_mask, current_thread)) { // If there are no draw bits in common with the camera, the node // is out. return false; diff --git a/panda/src/pgraph/cullTraverserData.h b/panda/src/pgraph/cullTraverserData.h index f303c165d5..f372c8bfb5 100644 --- a/panda/src/pgraph/cullTraverserData.h +++ b/panda/src/pgraph/cullTraverserData.h @@ -63,7 +63,7 @@ public: CPT(TransformState) get_modelview_transform(const CullTraverser *trav) const; INLINE const TransformState *get_net_transform(const CullTraverser *trav) const; - INLINE bool is_in_view(const DrawMask &camera_mask); + INLINE bool is_in_view(const DrawMask &camera_mask, Thread *current_thread); INLINE bool is_this_node_hidden(const CullTraverser *trav) const; void apply_transform_and_state(CullTraverser *trav); diff --git a/panda/src/pgraph/cullableObject.cxx b/panda/src/pgraph/cullableObject.cxx index 09f027f488..c0673e8c25 100644 --- a/panda/src/pgraph/cullableObject.cxx +++ b/panda/src/pgraph/cullableObject.cxx @@ -50,11 +50,21 @@ void CullableObject:: munge_geom(GraphicsStateGuardianBase *gsg, GeomMunger *munger, const CullTraverser *traverser) { if (_geom != (Geom *)NULL) { + Thread *current_thread = traverser->get_current_thread(); _munger = munger; - _munged_data = _geom->get_vertex_data(); - nassertv(_geom->check_valid(_munged_data)); - int geom_rendering = _geom->get_geom_rendering(); + GeomPipelineReader geom_reader(_geom, current_thread); + _munged_data = geom_reader.get_vertex_data(); + +#ifndef NDEBUG + { + GeomVertexDataPipelineReader data_reader(_munged_data, current_thread); + data_reader.check_array_readers(); + nassertv(geom_reader.check_valid(&data_reader)); + } +#endif // NDEBUG + + int geom_rendering = geom_reader.get_geom_rendering(); geom_rendering = _state->get_geom_rendering(geom_rendering); geom_rendering = _modelview_transform->get_geom_rendering(geom_rendering); @@ -89,7 +99,7 @@ munge_geom(GraphicsStateGuardianBase *gsg, // the vertices in the CPU--and we have to do it before we call // munge_geom(), which might lose the tangent and binormal. CPT(GeomVertexData) animated_vertices = - _munged_data->animate_vertices(); + _munged_data->animate_vertices(current_thread); if (animated_vertices != _munged_data) { cpu_animated = true; _munged_data = animated_vertices; @@ -99,7 +109,7 @@ munge_geom(GraphicsStateGuardianBase *gsg, // Now invoke the munger to ensure the resulting geometry is in // a GSG-friendly form. - munger->munge_geom(_geom, _munged_data); + munger->munge_geom(_geom, _munged_data, current_thread); StateMunger *state_munger; DCAST_INTO_V(state_munger, munger); @@ -111,7 +121,7 @@ munge_geom(GraphicsStateGuardianBase *gsg, // animation in hardware--then we have to calculate that // animation now. CPT(GeomVertexData) animated_vertices = - _munged_data->animate_vertices(); + _munged_data->animate_vertices(current_thread); if (animated_vertices != _munged_data) { cpu_animated = true; _munged_data = animated_vertices; @@ -120,7 +130,8 @@ munge_geom(GraphicsStateGuardianBase *gsg, #ifndef NDEBUG if (show_vertex_animation) { - bool hardware_animated = (_munged_data->get_format()->get_animation().get_animation_type() == Geom::AT_hardware); + GeomVertexDataPipelineReader data_reader(_munged_data, current_thread); + bool hardware_animated = (data_reader.get_format()->get_animation().get_animation_type() == Geom::AT_hardware); if (cpu_animated || hardware_animated) { // These vertices were animated, so flash them red or blue. static const double flash_rate = 1.0; // 1 state change per second @@ -178,17 +189,25 @@ output(ostream &out) const { //////////////////////////////////////////////////////////////////// void CullableObject:: munge_points_to_quads(const CullTraverser *traverser) { - PStatTimer timer(_munge_points_pcollector); + Thread *current_thread = traverser->get_current_thread(); + PStatTimer timer(_munge_points_pcollector, current_thread); GraphicsStateGuardianBase *gsg = traverser->get_gsg(); - GeomVertexReader vertex(_munged_data, InternalName::get_vertex()); - GeomVertexReader normal(_munged_data, InternalName::get_normal()); - GeomVertexReader color(_munged_data, InternalName::get_color()); - GeomVertexReader texcoord(_munged_data, InternalName::get_texcoord()); - GeomVertexReader rotate(_munged_data, InternalName::get_rotate()); - GeomVertexReader size(_munged_data, InternalName::get_size()); - GeomVertexReader aspect_ratio(_munged_data, InternalName::get_aspect_ratio()); + GeomVertexReader vertex(_munged_data, InternalName::get_vertex(), + current_thread); + GeomVertexReader normal(_munged_data, InternalName::get_normal(), + current_thread); + GeomVertexReader color(_munged_data, InternalName::get_color(), + current_thread); + GeomVertexReader texcoord(_munged_data, InternalName::get_texcoord(), + current_thread); + GeomVertexReader rotate(_munged_data, InternalName::get_rotate(), + current_thread); + GeomVertexReader size(_munged_data, InternalName::get_size(), + current_thread); + GeomVertexReader aspect_ratio(_munged_data, InternalName::get_aspect_ratio(), + current_thread); bool has_normal = (normal.has_column()); bool has_color = (color.has_column()); @@ -301,9 +320,11 @@ munge_points_to_quads(const CullTraverser *traverser) { // CullFaceAttrib but will always render all of the vertices of the // polygons. This is certainly a bug, but in order to fix it we'd // have to do the face culling ourselves--not sure if it's worth it. - int num_primitives = _geom->get_num_primitives(); + + GeomPipelineReader geom_reader(_geom, current_thread); + int num_primitives = geom_reader.get_num_primitives(); for (int pi = 0; pi < num_primitives; ++pi) { - const GeomPrimitive *primitive = _geom->get_primitive(pi); + const GeomPrimitive *primitive = geom_reader.get_primitive(pi); if (primitive->get_num_vertices() != 0) { // We must first convert all of the points to eye space. int num_points = primitive->get_max_vertex() + 1; @@ -314,7 +335,7 @@ munge_points_to_quads(const CullTraverser *traverser) { unsigned int *vertices_end = vertices + num_vertices; if (primitive->is_indexed()) { - GeomVertexReader index(primitive->get_vertices(), 0); + GeomVertexReader index(primitive->get_vertices(), 0, current_thread); for (unsigned int *vi = vertices; vi != vertices_end; ++vi) { // Get the point in eye-space coordinates. unsigned int v = index.get_data1i(); @@ -475,7 +496,8 @@ munge_points_to_quads(const CullTraverser *traverser) { //////////////////////////////////////////////////////////////////// void CullableObject:: munge_texcoord_light_vector(const CullTraverser *traverser) { - PStatTimer timer(_munge_light_vector_pcollector); + Thread *current_thread = traverser->get_current_thread(); + PStatTimer timer(_munge_light_vector_pcollector, current_thread); if (_net_transform->is_singular()) { // If we're under a singular transform, never mind. @@ -547,11 +569,13 @@ munge_texcoord_light_vector(const CullTraverser *traverser) { _net_transform->invert_compose(light.get_net_transform()); const LMatrix4f &light_mat = light_transform->get_mat(); - GeomVertexWriter texcoord(new_data, texcoord_name); - GeomVertexReader vertex(new_data, InternalName::get_vertex()); - GeomVertexReader tangent(new_data, tangent_name); - GeomVertexReader binormal(new_data, binormal_name); - GeomVertexReader normal(new_data, InternalName::get_normal()); + GeomVertexWriter texcoord(new_data, texcoord_name, current_thread); + GeomVertexReader vertex(new_data, InternalName::get_vertex(), + current_thread); + GeomVertexReader tangent(new_data, tangent_name, current_thread); + GeomVertexReader binormal(new_data, binormal_name, current_thread); + GeomVertexReader normal(new_data, InternalName::get_normal(), + current_thread); while (!vertex.is_at_end()) { LPoint3f p = vertex.get_data3f(); diff --git a/panda/src/pgraph/geomNode.cxx b/panda/src/pgraph/geomNode.cxx index 868cb72384..702d0e5656 100644 --- a/panda/src/pgraph/geomNode.cxx +++ b/panda/src/pgraph/geomNode.cxx @@ -349,17 +349,21 @@ combine_with(PandaNode *other) { //////////////////////////////////////////////////////////////////// CPT(TransformState) GeomNode:: calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, - const TransformState *transform) const { + const TransformState *transform, Thread *current_thread) const { CPT(TransformState) next_transform = - PandaNode::calc_tight_bounds(min_point, max_point, found_any, transform); + PandaNode::calc_tight_bounds(min_point, max_point, found_any, transform, + current_thread); const LMatrix4f &mat = next_transform->get_mat(); - int num_geoms = get_num_geoms(); - for (int i = 0; i < num_geoms; i++) { - const Geom *geom = get_geom(i); + + CDReader cdata(_cycler, current_thread); + Geoms::const_iterator gi; + for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) { + const Geom *geom = (*gi)._geom; geom->calc_tight_bounds(min_point, max_point, found_any, - geom->get_vertex_data()->animate_vertices(), - !next_transform->is_identity(), mat); + geom->get_vertex_data(current_thread)->animate_vertices(current_thread), + !next_transform->is_identity(), mat, + current_thread); } return next_transform; @@ -661,16 +665,16 @@ is_geom_node() const { // something internally. //////////////////////////////////////////////////////////////////// PT(BoundingVolume) GeomNode:: -compute_internal_bounds(int pipeline_stage) const { +compute_internal_bounds(int pipeline_stage, Thread *current_thread) const { // First, get ourselves a fresh, empty bounding volume. - PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage); + PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage, current_thread); nassertr(bound != (BoundingVolume *)NULL, bound); // Now actually compute the bounding volume by putting it around all // of our geoms' bounding volumes. pvector child_volumes; - CDStageReader cdata(_cycler, pipeline_stage); + CDStageReader cdata(_cycler, pipeline_stage, current_thread); Geoms::const_iterator gi; for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) { const GeomEntry &entry = (*gi); diff --git a/panda/src/pgraph/geomNode.h b/panda/src/pgraph/geomNode.h index 04281ddcb3..e11bb9a91d 100644 --- a/panda/src/pgraph/geomNode.h +++ b/panda/src/pgraph/geomNode.h @@ -52,7 +52,8 @@ public: virtual CPT(TransformState) calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, - const TransformState *transform) const; + const TransformState *transform, + Thread *current_thread) const; virtual bool is_renderable() const; virtual CollideMask get_legal_collide_mask() const; @@ -84,7 +85,7 @@ public: virtual bool is_geom_node() const; protected: - virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const; + virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage, Thread *current_thread) const; public: // This must be declared public so that VC6 will allow the nested diff --git a/panda/src/pgraph/nodePath.I b/panda/src/pgraph/nodePath.I index e16408079a..0e272e7148 100644 --- a/panda/src/pgraph/nodePath.I +++ b/panda/src/pgraph/nodePath.I @@ -36,12 +36,12 @@ NodePath() : // with the indicated name. //////////////////////////////////////////////////////////////////// INLINE NodePath:: -NodePath(const string &top_node_name) : +NodePath(const string &top_node_name, Thread *current_thread) : _error_type(ET_ok) { PandaNode *top_node = new PandaNode(top_node_name); - int pipeline_stage = Thread::get_current_pipeline_stage(); - _head = top_node->get_generic_component(false, pipeline_stage); + int pipeline_stage = current_thread->get_pipeline_stage(); + _head = top_node->get_generic_component(false, pipeline_stage, current_thread); _backup_key = 0; } @@ -57,12 +57,12 @@ NodePath(const string &top_node_name) : // also NodePath::any_path(), below). //////////////////////////////////////////////////////////////////// INLINE NodePath:: -NodePath(PandaNode *node) : +NodePath(PandaNode *node, Thread *current_thread) : _error_type(ET_ok) { if (node != (PandaNode *)NULL) { - int pipeline_stage = Thread::get_current_pipeline_stage(); - _head = node->get_generic_component(false, pipeline_stage); + int pipeline_stage = current_thread->get_pipeline_stage(); + _head = node->get_generic_component(false, pipeline_stage, current_thread); } _backup_key = 0; } @@ -77,11 +77,12 @@ NodePath(PandaNode *node) : // the path is ambiguous. //////////////////////////////////////////////////////////////////// INLINE NodePath NodePath:: -any_path(PandaNode *node) { +any_path(PandaNode *node, Thread *current_thread) { NodePath result; if (node != (PandaNode *)NULL) { - int pipeline_stage = Thread::get_current_pipeline_stage(); - result._head = node->get_generic_component(true, pipeline_stage); + int pipeline_stage = current_thread->get_pipeline_stage(); + result._head = node->get_generic_component(true, pipeline_stage, + current_thread); } return result; } @@ -94,13 +95,15 @@ any_path(PandaNode *node) { // stashed or unstashed child of the parent. //////////////////////////////////////////////////////////////////// INLINE NodePath:: -NodePath(const NodePath &parent, PandaNode *child_node) : +NodePath(const NodePath &parent, PandaNode *child_node, + Thread *current_thread) : _error_type(ET_fail) { nassertv(!parent.is_empty()); nassertv(child_node != (PandaNode *)NULL); - int pipeline_stage = Thread::get_current_pipeline_stage(); - _head = PandaNode::get_component(parent._head, child_node, pipeline_stage); + int pipeline_stage = current_thread->get_pipeline_stage(); + _head = PandaNode::get_component(parent._head, child_node, pipeline_stage, + current_thread); nassertv(_head != (NodePathComponent *)NULL); if (_head != (NodePathComponent *)NULL) { @@ -229,9 +232,9 @@ is_empty() const { // node. //////////////////////////////////////////////////////////////////// INLINE bool NodePath:: -is_singleton() const { - int pipeline_stage = Thread::get_current_pipeline_stage(); - return (_head != (NodePathComponent *)NULL && _head->is_top_node(pipeline_stage)); +is_singleton(Thread *current_thread) const { + int pipeline_stage = current_thread->get_pipeline_stage(); + return (_head != (NodePathComponent *)NULL && _head->is_top_node(pipeline_stage, current_thread)); } //////////////////////////////////////////////////////////////////// @@ -252,12 +255,12 @@ get_error_type() const { // is empty. This requires iterating through the path. //////////////////////////////////////////////////////////////////// INLINE PandaNode *NodePath:: -get_top_node() const { +get_top_node(Thread *current_thread) const { if (is_empty()) { return (PandaNode *)NULL; } - return get_top().node(); + return get_top(current_thread).node(); } //////////////////////////////////////////////////////////////////// @@ -306,7 +309,7 @@ get_key() const { // same (e.g., both "render"). //////////////////////////////////////////////////////////////////// INLINE bool NodePath:: -is_same_graph(const NodePath &other) const { +is_same_graph(const NodePath &other, Thread *current_thread) const { // Actually, it's possible for the top nodes to be the same, but the // NodePaths still to be considered in different graphs. But even // in this case, get_top() will be different for each one. (They'll @@ -318,7 +321,7 @@ is_same_graph(const NodePath &other) const { // returns a different instance of render that appears to have the // same top node. But this is a very rare thing to do. int a_count, b_count; - return (find_common_ancestor(*this, other, a_count, b_count) != (NodePathComponent *)NULL); + return (find_common_ancestor(*this, other, a_count, b_count, current_thread) != (NodePathComponent *)NULL); } //////////////////////////////////////////////////////////////////// @@ -329,9 +332,9 @@ is_same_graph(const NodePath &other) const { // or false if it is not. //////////////////////////////////////////////////////////////////// INLINE bool NodePath:: -is_ancestor_of(const NodePath &other) const { +is_ancestor_of(const NodePath &other, Thread *current_thread) const { int a_count, b_count; - if (find_common_ancestor(*this, other, a_count, b_count) == (NodePathComponent *)NULL) { + if (find_common_ancestor(*this, other, a_count, b_count, current_thread) == (NodePathComponent *)NULL) { // Not related. return false; } @@ -350,9 +353,9 @@ is_ancestor_of(const NodePath &other) const { // unrelated, returns NodePath::not_found(). //////////////////////////////////////////////////////////////////// INLINE NodePath NodePath:: -get_common_ancestor(const NodePath &other) const { +get_common_ancestor(const NodePath &other, Thread *current_thread) const { int a_count, b_count; - NodePathComponent *common = find_common_ancestor(*this, other, a_count, b_count); + NodePathComponent *common = find_common_ancestor(*this, other, a_count, b_count, current_thread); if (common == (NodePathComponent *)NULL) { return NodePath::not_found(); } @@ -368,9 +371,9 @@ get_common_ancestor(const NodePath &other) const { // Description: Returns the number of children of the referenced node. //////////////////////////////////////////////////////////////////// INLINE int NodePath:: -get_num_children() const { +get_num_children(Thread *current_thread) const { nassertr_always(!is_empty(), 0); - return _head->get_node()->get_num_children(); + return _head->get_node()->get_num_children(current_thread); } //////////////////////////////////////////////////////////////////// @@ -380,12 +383,12 @@ get_num_children() const { // referenced node. //////////////////////////////////////////////////////////////////// INLINE NodePath NodePath:: -get_child(int n) const { - nassertr(n >= 0 && n < get_num_children(), NodePath()); +get_child(int n, Thread *current_thread) const { + nassertr(n >= 0 && n < get_num_children(current_thread), NodePath()); NodePath child; - int pipeline_stage = Thread::get_current_pipeline_stage(); - child._head = PandaNode::get_component(_head, _head->get_node()->get_child(n), - pipeline_stage); + int pipeline_stage = current_thread->get_pipeline_stage(); + child._head = PandaNode::get_component(_head, _head->get_node()->get_child(n, current_thread), + pipeline_stage, current_thread); return child; } @@ -396,8 +399,8 @@ get_child(int n) const { // i.e. the NodePath chain contains at least two nodes. //////////////////////////////////////////////////////////////////// INLINE bool NodePath:: -has_parent() const { - return !is_empty() && !is_singleton(); +has_parent(Thread *current_thread) const { + return !is_empty() && !is_singleton(current_thread); } //////////////////////////////////////////////////////////////////// @@ -409,15 +412,15 @@ has_parent() const { // the empty NodePath. //////////////////////////////////////////////////////////////////// INLINE NodePath NodePath:: -get_parent() const { - if (!has_parent()) { +get_parent(Thread *current_thread) const { + if (!has_parent(current_thread)) { return NodePath(); } - int pipeline_stage = Thread::get_current_pipeline_stage(); + int pipeline_stage = current_thread->get_pipeline_stage(); NodePath parent; - parent._head = _head->get_next(pipeline_stage); + parent._head = _head->get_next(pipeline_stage, current_thread); return parent; } @@ -429,10 +432,10 @@ get_parent() const { // references it. //////////////////////////////////////////////////////////////////// INLINE NodePath NodePath:: -attach_new_node(const string &name, int sort) const { - nassertr(verify_complete(), NodePath::fail()); +attach_new_node(const string &name, int sort, Thread *current_thread) const { + nassertr(verify_complete(current_thread), NodePath::fail()); - return attach_new_node(new PandaNode(name), sort); + return attach_new_node(new PandaNode(name), sort, current_thread); } //////////////////////////////////////////////////////////////////// @@ -492,9 +495,9 @@ reverse_ls(ostream &out, int indent_level) const { // Description: Changes the complete state object on this node. //////////////////////////////////////////////////////////////////// INLINE void NodePath:: -set_state(const RenderState *state) { +set_state(const RenderState *state, Thread *current_thread) { nassertv_always(!is_empty()); - node()->set_state(state); + node()->set_state(state, current_thread); } //////////////////////////////////////////////////////////////////// @@ -503,9 +506,9 @@ set_state(const RenderState *state) { // Description: Returns the net state on this node from the root. //////////////////////////////////////////////////////////////////// INLINE CPT(RenderState) NodePath:: -get_net_state() const { +get_net_state(Thread *current_thread) const { nassertr(_error_type == ET_ok, RenderState::make_empty()); - return r_get_net_state(_head); + return r_get_net_state(_head, current_thread); } //////////////////////////////////////////////////////////////////// @@ -657,8 +660,8 @@ clear_effects() { // Description: Sets the transform object on this node to identity. //////////////////////////////////////////////////////////////////// INLINE void NodePath:: -clear_transform() { - set_transform(TransformState::make_identity()); +clear_transform(Thread *current_thread) { + set_transform(TransformState::make_identity(), current_thread); } //////////////////////////////////////////////////////////////////// @@ -667,9 +670,9 @@ clear_transform() { // Description: Changes the complete transform object on this node. //////////////////////////////////////////////////////////////////// INLINE void NodePath:: -set_transform(const TransformState *transform) { +set_transform(const TransformState *transform, Thread *current_thread) { nassertv_always(!is_empty()); - node()->set_transform(transform); + node()->set_transform(transform, current_thread); } //////////////////////////////////////////////////////////////////// @@ -680,8 +683,8 @@ set_transform(const TransformState *transform) { // this node at the same position as the other node. //////////////////////////////////////////////////////////////////// INLINE void NodePath:: -clear_transform(const NodePath &other) { - set_transform(other, TransformState::make_identity()); +clear_transform(const NodePath &other, Thread *current_thread) { + set_transform(other, TransformState::make_identity(), current_thread); } //////////////////////////////////////////////////////////////////// @@ -690,9 +693,9 @@ clear_transform(const NodePath &other) { // Description: Returns the net transform on this node from the root. //////////////////////////////////////////////////////////////////// INLINE CPT(TransformState) NodePath:: -get_net_transform() const { +get_net_transform(Thread *current_thread) const { nassertr(_error_type == ET_ok, TransformState::make_identity()); - return r_get_net_transform(_head); + return r_get_net_transform(_head, current_thread); } //////////////////////////////////////////////////////////////////// @@ -704,9 +707,9 @@ get_net_transform() const { // calculations. //////////////////////////////////////////////////////////////////// INLINE void NodePath:: -set_prev_transform(const TransformState *transform) { +set_prev_transform(const TransformState *transform, Thread *current_thread) { nassertv_always(!is_empty()); - node()->set_prev_transform(transform); + node()->set_prev_transform(transform, current_thread); } //////////////////////////////////////////////////////////////////// @@ -716,9 +719,9 @@ set_prev_transform(const TransformState *transform) { // from the root. See set_prev_transform(). //////////////////////////////////////////////////////////////////// INLINE CPT(TransformState) NodePath:: -get_net_prev_transform() const { +get_net_prev_transform(Thread *current_thread) const { nassertr(_error_type == ET_ok, TransformState::make_identity()); - return r_get_net_prev_transform(_head); + return r_get_net_prev_transform(_head, current_thread); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index b15c43fc22..7e53c7de38 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/panda/src/pgraph/nodePath.cxx @@ -77,12 +77,12 @@ TypeHandle NodePath::_type_handle; // Description: Returns the number of nodes in the path. //////////////////////////////////////////////////////////////////// int NodePath:: -get_num_nodes() const { +get_num_nodes(Thread *current_thread) const { if (is_empty()) { return 0; } - int pipeline_stage = Thread::get_current_pipeline_stage(); - return _head->get_length(pipeline_stage); + int pipeline_stage = current_thread->get_pipeline_stage(); + return _head->get_length(pipeline_stage, current_thread); } //////////////////////////////////////////////////////////////////// @@ -99,17 +99,17 @@ get_num_nodes() const { // NodePath, and is the one most frequently referenced). //////////////////////////////////////////////////////////////////// PandaNode *NodePath:: -get_node(int index) const { +get_node(int index, Thread *current_thread) const { nassertr(index >= 0 && index < get_num_nodes(), NULL); - int pipeline_stage = Thread::get_current_pipeline_stage(); + int pipeline_stage = current_thread->get_pipeline_stage(); NodePathComponent *comp = _head; while (index > 0) { // If this assertion fails, the index was out of range; the // component's length must have been invalid. nassertr(comp != (NodePathComponent *)NULL, NULL); - comp = comp->get_next(pipeline_stage); + comp = comp->get_next(pipeline_stage, current_thread); index--; } @@ -126,16 +126,16 @@ get_node(int index) const { // of the path, or empty NodePath if this path is empty. //////////////////////////////////////////////////////////////////// NodePath NodePath:: -get_top() const { +get_top(Thread *current_thread) const { if (is_empty()) { return *this; } - int pipeline_stage = Thread::get_current_pipeline_stage(); + int pipeline_stage = current_thread->get_pipeline_stage(); NodePathComponent *comp = _head; - while (!comp->is_top_node(pipeline_stage)) { - comp = comp->get_next(pipeline_stage); + while (!comp->is_top_node(pipeline_stage, current_thread)) { + comp = comp->get_next(pipeline_stage, current_thread); nassertr(comp != (NodePathComponent *)NULL, NULL); } @@ -152,20 +152,20 @@ get_top() const { // node. //////////////////////////////////////////////////////////////////// NodePathCollection NodePath:: -get_children() const { +get_children(Thread *current_thread) const { NodePathCollection result; nassertr_always(!is_empty(), result); PandaNode *bottom_node = node(); - int pipeline_stage = Thread::get_current_pipeline_stage(); + int pipeline_stage = current_thread->get_pipeline_stage(); PandaNode::Children cr = bottom_node->get_children(); int num_children = cr.get_num_children(); for (int i = 0; i < num_children; i++) { NodePath child; child._head = PandaNode::get_component(_head, cr.get_child(i), - pipeline_stage); + pipeline_stage, current_thread); result.add_path(child); } @@ -181,19 +181,19 @@ get_children() const { // the list returned by get_children(). //////////////////////////////////////////////////////////////////// NodePathCollection NodePath:: -get_stashed_children() const { +get_stashed_children(Thread *current_thread) const { NodePathCollection result; nassertr_always(!is_empty(), result); PandaNode *bottom_node = node(); - int pipeline_stage = Thread::get_current_pipeline_stage(); + int pipeline_stage = current_thread->get_pipeline_stage(); int num_stashed = bottom_node->get_num_stashed(); for (int i = 0; i < num_stashed; i++) { NodePath stashed; stashed._head = PandaNode::get_component(_head, bottom_node->get_stashed(i), - pipeline_stage); + pipeline_stage, current_thread); result.add_path(stashed); } @@ -210,14 +210,14 @@ get_stashed_children() const { // list of children. //////////////////////////////////////////////////////////////////// int NodePath:: -get_sort() const { +get_sort(Thread *current_thread) const { if (!has_parent()) { return 0; } - int pipeline_stage = Thread::get_current_pipeline_stage(); + int pipeline_stage = current_thread->get_pipeline_stage(); - PandaNode *parent = _head->get_next(pipeline_stage)->get_node(); + PandaNode *parent = _head->get_next(pipeline_stage, current_thread)->get_node(); PandaNode *child = node(); nassertr(parent != (PandaNode *)NULL && child != (PandaNode *)NULL, 0); int child_index = parent->find_child(child); @@ -328,7 +328,7 @@ find_all_paths_to(PandaNode *node) const { // same thing as detach_node(). //////////////////////////////////////////////////////////////////// void NodePath:: -reparent_to(const NodePath &other, int sort) { +reparent_to(const NodePath &other, int sort, Thread *current_thread) { nassertv(verify_complete()); nassertv(other.verify_complete()); nassertv_always(!is_empty()); @@ -337,9 +337,9 @@ reparent_to(const NodePath &other, int sort) { // Reparenting implicitly resets the delta vector. node()->reset_prev_transform(); - int pipeline_stage = Thread::get_current_pipeline_stage(); + int pipeline_stage = current_thread->get_pipeline_stage(); bool reparented = PandaNode::reparent(other._head, _head, sort, false, - pipeline_stage); + pipeline_stage, current_thread); nassertv(reparented); } @@ -353,21 +353,21 @@ reparent_to(const NodePath &other, int sort) { // different coordinate system. //////////////////////////////////////////////////////////////////// void NodePath:: -wrt_reparent_to(const NodePath &other, int sort) { - nassertv(verify_complete()); - nassertv(other.verify_complete()); +wrt_reparent_to(const NodePath &other, int sort, Thread *current_thread) { + nassertv(verify_complete(current_thread)); + nassertv(other.verify_complete(current_thread)); nassertv_always(!is_empty()); nassertv(other._error_type == ET_ok); - if (get_transform() == get_prev_transform()) { - set_transform(get_transform(other)); - node()->reset_prev_transform(); + if (get_transform(current_thread) == get_prev_transform(current_thread)) { + set_transform(get_transform(other, current_thread), current_thread); + node()->reset_prev_transform(current_thread); } else { - set_transform(get_transform(other)); - set_prev_transform(get_prev_transform(other)); + set_transform(get_transform(other, current_thread), current_thread); + set_prev_transform(get_prev_transform(other, current_thread), current_thread); } - reparent_to(other, sort); + reparent_to(other, sort, current_thread); } //////////////////////////////////////////////////////////////////// @@ -395,7 +395,7 @@ wrt_reparent_to(const NodePath &other, int sort) { // return a different get_id() value. //////////////////////////////////////////////////////////////////// NodePath NodePath:: -instance_to(const NodePath &other, int sort) const { +instance_to(const NodePath &other, int sort, Thread *current_thread) const { nassertr(verify_complete(), NodePath::fail()); nassertr(other.verify_complete(), NodePath::fail()); nassertr_always(!is_empty(), NodePath::fail()); @@ -405,12 +405,14 @@ instance_to(const NodePath &other, int sort) const { // First, we'll attach to NULL, to guarantee we get a brand new // instance. - int pipeline_stage = Thread::get_current_pipeline_stage(); - new_instance._head = PandaNode::attach(NULL, node(), sort, pipeline_stage); + int pipeline_stage = current_thread->get_pipeline_stage(); + new_instance._head = PandaNode::attach(NULL, node(), sort, pipeline_stage, + current_thread); // Now, we'll reparent the new instance to the target node. bool reparented = PandaNode::reparent(other._head, new_instance._head, - sort, false, pipeline_stage); + sort, false, pipeline_stage, + current_thread); nassertr(reparented, new_instance); // instance_to() doesn't reset the velocity delta, unlike most of @@ -431,11 +433,12 @@ instance_to(const NodePath &other, int sort) const { // this instance. //////////////////////////////////////////////////////////////////// NodePath NodePath:: -instance_under_node(const NodePath &other, const string &name, int sort) const { - NodePath new_node = other.attach_new_node(name, sort); - NodePath instance = instance_to(new_node); +instance_under_node(const NodePath &other, const string &name, int sort, + Thread *current_thread) const { + NodePath new_node = other.attach_new_node(name, sort, current_thread); + NodePath instance = instance_to(new_node, 0, current_thread); if (instance.is_empty()) { - new_node.remove_node(); + new_node.remove_node(current_thread); return instance; } return new_node; @@ -451,19 +454,19 @@ instance_under_node(const NodePath &other, const string &name, int sort) const { // returned. //////////////////////////////////////////////////////////////////// NodePath NodePath:: -copy_to(const NodePath &other, int sort) const { - nassertr(verify_complete(), fail()); - nassertr(other.verify_complete(), fail()); +copy_to(const NodePath &other, int sort, Thread *current_thread) const { + nassertr(verify_complete(current_thread), fail()); + nassertr(other.verify_complete(current_thread), fail()); nassertr_always(!is_empty(), fail()); nassertr(other._error_type == ET_ok, fail()); PandaNode *source_node = node(); - PT(PandaNode) copy_node = source_node->copy_subgraph(); + PT(PandaNode) copy_node = source_node->copy_subgraph(current_thread); nassertr(copy_node != (PandaNode *)NULL, fail()); - copy_node->reset_prev_transform(); + copy_node->reset_prev_transform(current_thread); - return other.attach_new_node(copy_node, sort); + return other.attach_new_node(copy_node, sort, current_thread); } //////////////////////////////////////////////////////////////////// @@ -483,14 +486,15 @@ copy_to(const NodePath &other, int sort) const { // returned. //////////////////////////////////////////////////////////////////// NodePath NodePath:: -attach_new_node(PandaNode *node, int sort) const { - nassertr(verify_complete(), NodePath::fail()); +attach_new_node(PandaNode *node, int sort, Thread *current_thread) const { + nassertr(verify_complete(current_thread), NodePath::fail()); nassertr(_error_type == ET_ok, NodePath::fail()); nassertr(node != (PandaNode *)NULL, NodePath::fail()); NodePath new_path(*this); - int pipeline_stage = Thread::get_current_pipeline_stage(); - new_path._head = PandaNode::attach(_head, node, sort, pipeline_stage); + int pipeline_stage = current_thread->get_pipeline_stage(); + new_path._head = PandaNode::attach(_head, node, sort, pipeline_stage, + current_thread); return new_path; } @@ -516,17 +520,17 @@ attach_new_node(PandaNode *node, int sort) const { // as the NodePath exists. //////////////////////////////////////////////////////////////////// void NodePath:: -remove_node() { +remove_node(Thread *current_thread) { nassertv(_error_type != ET_not_found); // If we have no parents, remove_node() is just a do-nothing // operation; if we have no nodes, maybe we were already removed. // In either case, quietly do nothing except to ensure the // NodePath is clear. - if (!is_empty() && !is_singleton()) { - node()->reset_prev_transform(); - int pipeline_stage = Thread::get_current_pipeline_stage(); - PandaNode::detach(_head, pipeline_stage); + if (!is_empty() && !is_singleton(current_thread)) { + node()->reset_prev_transform(current_thread); + int pipeline_stage = current_thread->get_pipeline_stage(); + PandaNode::detach(_head, pipeline_stage, current_thread); } if (is_empty() || _head->has_key()) { @@ -563,12 +567,12 @@ remove_node() { // as the NodePath exists. //////////////////////////////////////////////////////////////////// void NodePath:: -detach_node() { +detach_node(Thread *current_thread) { nassertv(_error_type != ET_not_found); if (!is_empty() && !is_singleton()) { node()->reset_prev_transform(); - int pipeline_stage = Thread::get_current_pipeline_stage(); - PandaNode::detach(_head, pipeline_stage); + int pipeline_stage = current_thread->get_pipeline_stage(); + PandaNode::detach(_head, pipeline_stage, current_thread); } } @@ -607,11 +611,11 @@ output(ostream &out) const { // Description: Returns the complete state object set on this node. //////////////////////////////////////////////////////////////////// const RenderState *NodePath:: -get_state() const { +get_state(Thread *current_thread) const { // This method is declared non-inline to avoid a compiler bug in // gcc-3.4 and gcc-4.0. nassertr_always(!is_empty(), RenderState::make_empty()); - return node()->get_state(); + return node()->get_state(current_thread); } //////////////////////////////////////////////////////////////////// @@ -622,21 +626,21 @@ get_state() const { // render state of the other node. //////////////////////////////////////////////////////////////////// CPT(RenderState) NodePath:: -get_state(const NodePath &other) const { +get_state(const NodePath &other, Thread *current_thread) const { nassertr(_error_type == ET_ok && other._error_type == ET_ok, RenderState::make_empty()); if (other.is_empty()) { - return get_net_state(); + return get_net_state(current_thread); } if (is_empty()) { - return other.get_net_state()->invert_compose(RenderState::make_empty()); + return other.get_net_state(current_thread)->invert_compose(RenderState::make_empty()); } - nassertr(verify_complete(), RenderState::make_empty()); - nassertr(other.verify_complete(), RenderState::make_empty()); + nassertr(verify_complete(current_thread), RenderState::make_empty()); + nassertr(other.verify_complete(current_thread), RenderState::make_empty()); int a_count, b_count; - if (find_common_ancestor(*this, other, a_count, b_count) == (NodePathComponent *)NULL) { + if (find_common_ancestor(*this, other, a_count, b_count, current_thread) == (NodePathComponent *)NULL) { if (allow_unrelated_wrt) { pgraph_cat.debug() << *this << " is not related to " << other << "\n"; @@ -647,8 +651,8 @@ get_state(const NodePath &other) const { } } - CPT(RenderState) a_state = r_get_partial_state(_head, a_count); - CPT(RenderState) b_state = r_get_partial_state(other._head, b_count); + CPT(RenderState) a_state = r_get_partial_state(_head, a_count, current_thread); + CPT(RenderState) b_state = r_get_partial_state(other._head, b_count, current_thread); return b_state->invert_compose(a_state); } @@ -661,20 +665,21 @@ get_state(const NodePath &other) const { // other node. //////////////////////////////////////////////////////////////////// void NodePath:: -set_state(const NodePath &other, const RenderState *state) { +set_state(const NodePath &other, const RenderState *state, + Thread *current_thread) { nassertv(_error_type == ET_ok && other._error_type == ET_ok); nassertv_always(!is_empty()); // First, we perform a wrt to the parent, to get the conversion. CPT(RenderState) rel_state; if (has_parent()) { - rel_state = other.get_state(get_parent()); + rel_state = other.get_state(get_parent(current_thread), current_thread); } else { - rel_state = other.get_state(NodePath()); + rel_state = other.get_state(NodePath(), current_thread); } CPT(RenderState) new_state = rel_state->compose(state); - set_state(new_state); + set_state(new_state, current_thread); } //////////////////////////////////////////////////////////////////// @@ -683,11 +688,11 @@ set_state(const NodePath &other, const RenderState *state) { // Description: Returns the complete transform object set on this node. //////////////////////////////////////////////////////////////////// const TransformState *NodePath:: -get_transform() const { +get_transform(Thread *current_thread) const { // This method is declared non-inline to avoid a compiler bug in // gcc-3.4 and gcc-4.0. nassertr_always(!is_empty(), TransformState::make_identity()); - return node()->get_transform(); + return node()->get_transform(current_thread); } //////////////////////////////////////////////////////////////////// @@ -698,21 +703,21 @@ get_transform() const { // as seen from the other node. //////////////////////////////////////////////////////////////////// CPT(TransformState) NodePath:: -get_transform(const NodePath &other) const { +get_transform(const NodePath &other, Thread *current_thread) const { nassertr(_error_type == ET_ok && other._error_type == ET_ok, TransformState::make_identity()); if (other.is_empty()) { - return get_net_transform(); + return get_net_transform(current_thread); } if (is_empty()) { - return other.get_net_transform()->invert_compose(TransformState::make_identity()); + return other.get_net_transform(current_thread)->invert_compose(TransformState::make_identity()); } - nassertr(verify_complete(), TransformState::make_identity()); - nassertr(other.verify_complete(), TransformState::make_identity()); + nassertr(verify_complete(current_thread), TransformState::make_identity()); + nassertr(other.verify_complete(current_thread), TransformState::make_identity()); int a_count, b_count; - if (find_common_ancestor(*this, other, a_count, b_count) == (NodePathComponent *)NULL) { + if (find_common_ancestor(*this, other, a_count, b_count, current_thread) == (NodePathComponent *)NULL) { if (allow_unrelated_wrt) { if (pgraph_cat.is_debug()) { pgraph_cat.debug() @@ -727,16 +732,16 @@ get_transform(const NodePath &other) const { CPT(TransformState) a_transform, b_transform; - a_transform = r_get_partial_transform(_head, a_count); + a_transform = r_get_partial_transform(_head, a_count, current_thread); if (a_transform != (TransformState *)NULL) { - b_transform = r_get_partial_transform(other._head, b_count); + b_transform = r_get_partial_transform(other._head, b_count, current_thread); } if (b_transform == (TransformState *)NULL) { // If either path involved a node with a net_transform // RenderEffect applied, we have to go all the way up to the root // to get the right answer. - a_transform = r_get_net_transform(_head); - b_transform = r_get_net_transform(other._head); + 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); } @@ -750,20 +755,21 @@ get_transform(const NodePath &other) const { // other node. //////////////////////////////////////////////////////////////////// void NodePath:: -set_transform(const NodePath &other, const TransformState *transform) { +set_transform(const NodePath &other, const TransformState *transform, + Thread *current_thread) { nassertv(_error_type == ET_ok && other._error_type == ET_ok); nassertv_always(!is_empty()); // First, we perform a wrt to the parent, to get the conversion. CPT(TransformState) rel_trans; if (has_parent()) { - rel_trans = other.get_transform(get_parent()); + rel_trans = other.get_transform(get_parent(current_thread), current_thread); } else { - rel_trans = other.get_transform(NodePath()); + rel_trans = other.get_transform(NodePath(), current_thread); } CPT(TransformState) new_trans = rel_trans->compose(transform); - set_transform(new_trans); + set_transform(new_trans, current_thread); } //////////////////////////////////////////////////////////////////// @@ -774,11 +780,11 @@ set_transform(const NodePath &other, const TransformState *transform) { // set_prev_transform(). //////////////////////////////////////////////////////////////////// const TransformState *NodePath:: -get_prev_transform() const { +get_prev_transform(Thread *current_thread) const { // This method is declared non-inline to avoid a compiler bug in // gcc-3.4 and gcc-4.0. nassertr_always(!is_empty(), TransformState::make_identity()); - return node()->get_prev_transform(); + return node()->get_prev_transform(current_thread); } //////////////////////////////////////////////////////////////////// @@ -790,21 +796,21 @@ get_prev_transform() const { // in the previous frame. //////////////////////////////////////////////////////////////////// CPT(TransformState) NodePath:: -get_prev_transform(const NodePath &other) const { +get_prev_transform(const NodePath &other, Thread *current_thread) const { nassertr(_error_type == ET_ok && other._error_type == ET_ok, TransformState::make_identity()); if (other.is_empty()) { - return get_net_prev_transform(); + return get_net_prev_transform(current_thread); } if (is_empty()) { - return other.get_net_prev_transform()->invert_compose(TransformState::make_identity()); + return other.get_net_prev_transform(current_thread)->invert_compose(TransformState::make_identity()); } - nassertr(verify_complete(), TransformState::make_identity()); - nassertr(other.verify_complete(), TransformState::make_identity()); + nassertr(verify_complete(current_thread), TransformState::make_identity()); + nassertr(other.verify_complete(current_thread), TransformState::make_identity()); int a_count, b_count; - if (find_common_ancestor(*this, other, a_count, b_count) == (NodePathComponent *)NULL) { + if (find_common_ancestor(*this, other, a_count, b_count, current_thread) == (NodePathComponent *)NULL) { if (allow_unrelated_wrt) { pgraph_cat.debug() << *this << " is not related to " << other << "\n"; @@ -815,8 +821,8 @@ get_prev_transform(const NodePath &other) const { } } - CPT(TransformState) a_prev_transform = r_get_partial_prev_transform(_head, a_count); - CPT(TransformState) b_prev_transform = r_get_partial_prev_transform(other._head, b_count); + CPT(TransformState) a_prev_transform = r_get_partial_prev_transform(_head, a_count, current_thread); + CPT(TransformState) b_prev_transform = r_get_partial_prev_transform(other._head, b_count, current_thread); return b_prev_transform->invert_compose(a_prev_transform); } @@ -829,20 +835,21 @@ get_prev_transform(const NodePath &other) const { // when seen from the other node. //////////////////////////////////////////////////////////////////// void NodePath:: -set_prev_transform(const NodePath &other, const TransformState *transform) { +set_prev_transform(const NodePath &other, const TransformState *transform, + Thread *current_thread) { nassertv(_error_type == ET_ok && other._error_type == ET_ok); nassertv_always(!is_empty()); // First, we perform a wrt to the parent, to get the conversion. CPT(TransformState) rel_trans; - if (has_parent()) { - rel_trans = other.get_prev_transform(get_parent()); + if (has_parent(current_thread)) { + rel_trans = other.get_prev_transform(get_parent(current_thread), current_thread); } else { - rel_trans = other.get_prev_transform(NodePath()); + rel_trans = other.get_prev_transform(NodePath(), current_thread); } CPT(TransformState) new_trans = rel_trans->compose(transform); - set_prev_transform(new_trans); + set_prev_transform(new_trans, current_thread); } //////////////////////////////////////////////////////////////////// @@ -5146,13 +5153,13 @@ get_antialias() const { // is hidden (and the node should be visible). //////////////////////////////////////////////////////////////////// NodePath NodePath:: -get_hidden_ancestor(DrawMask camera_mask) const { - int pipeline_stage = Thread::get_current_pipeline_stage(); +get_hidden_ancestor(DrawMask camera_mask, Thread *current_thread) const { + int pipeline_stage = current_thread->get_pipeline_stage(); NodePathComponent *comp; for (comp = _head; comp != (NodePathComponent *)NULL; - comp = comp->get_next(pipeline_stage)) { + comp = comp->get_next(pipeline_stage, current_thread)) { PandaNode *node = comp->get_node(); if (node->is_overall_hidden() || ((node->get_draw_show_mask() | ~node->get_draw_control_mask()) & camera_mask).is_zero()) { @@ -5181,13 +5188,14 @@ get_hidden_ancestor(DrawMask camera_mask) const { // retrieve it). //////////////////////////////////////////////////////////////////// void NodePath:: -stash(int sort) { +stash(int sort, Thread *current_thread) { nassertv_always(!is_singleton() && !is_empty()); nassertv(verify_complete()); - int pipeline_stage = Thread::get_current_pipeline_stage(); - bool reparented = PandaNode::reparent(_head->get_next(pipeline_stage), - _head, sort, true, pipeline_stage); + int pipeline_stage = current_thread->get_pipeline_stage(); + bool reparented = PandaNode::reparent(_head->get_next(pipeline_stage, current_thread), + _head, sort, true, pipeline_stage, + current_thread); nassertv(reparented); } @@ -5200,13 +5208,14 @@ stash(int sort) { // scene graph. //////////////////////////////////////////////////////////////////// void NodePath:: -unstash(int sort) { +unstash(int sort, Thread *current_thread) { nassertv_always(!is_singleton() && !is_empty()); nassertv(verify_complete()); - int pipeline_stage = Thread::get_current_pipeline_stage(); - bool reparented = PandaNode::reparent(_head->get_next(pipeline_stage), - _head, sort, false, pipeline_stage); + int pipeline_stage = current_thread->get_pipeline_stage(); + bool reparented = PandaNode::reparent(_head->get_next(pipeline_stage, current_thread), + _head, sort, false, pipeline_stage, + current_thread); nassertv(reparented); } @@ -5216,10 +5225,10 @@ unstash(int sort) { // Description: Unstashes this node and all stashed child nodes. //////////////////////////////////////////////////////////////////// void NodePath:: -unstash_all() { +unstash_all(Thread *current_thread) { NodePathCollection stashed_descendents = find_all_matches("**/@@*"); stashed_descendents.unstash(); - unstash(); + unstash(0, current_thread); } //////////////////////////////////////////////////////////////////// @@ -5231,11 +5240,11 @@ unstash_all() { // be visible). //////////////////////////////////////////////////////////////////// NodePath NodePath:: -get_stashed_ancestor() const { +get_stashed_ancestor(Thread *current_thread) const { NodePathComponent *comp = _head; if (comp != (NodePathComponent *)NULL) { - int pipeline_stage = Thread::get_current_pipeline_stage(); - NodePathComponent *next = comp->get_next(pipeline_stage); + int pipeline_stage = current_thread->get_pipeline_stage(); + NodePathComponent *next = comp->get_next(pipeline_stage, current_thread); while (next != (NodePathComponent *)NULL) { PandaNode *node = comp->get_node(); @@ -5248,7 +5257,7 @@ get_stashed_ancestor() const { } comp = next; - next = next->get_next(pipeline_stage); + next = next->get_next(pipeline_stage, current_thread); } } @@ -5262,7 +5271,7 @@ get_stashed_ancestor() const { // NodePath are connected, or false otherwise. //////////////////////////////////////////////////////////////////// bool NodePath:: -verify_complete() const { +verify_complete(Thread *current_thread) const { if (is_empty()) { return true; } @@ -5270,13 +5279,13 @@ verify_complete() const { const NodePathComponent *comp = _head; nassertr(comp != (const NodePathComponent *)NULL, false); - int pipeline_stage = Thread::get_current_pipeline_stage(); + int pipeline_stage = current_thread->get_pipeline_stage(); PandaNode *node = comp->get_node(); nassertr(node != (const PandaNode *)NULL, false); - int length = comp->get_length(pipeline_stage); + int length = comp->get_length(pipeline_stage, current_thread); - comp = comp->get_next(pipeline_stage); + comp = comp->get_next(pipeline_stage, current_thread); length--; while (comp != (const NodePathComponent *)NULL) { PandaNode *next_node = comp->get_node(); @@ -5289,16 +5298,16 @@ verify_complete() const { return false; } - if (comp->get_length(pipeline_stage) != length) { + if (comp->get_length(pipeline_stage, current_thread) != length) { pgraph_cat.warning() << *this << " is incomplete; length at " << *next_node - << " indicates " << comp->get_length(pipeline_stage) + << " indicates " << comp->get_length(pipeline_stage, current_thread) << " while length at " << *node << " indicates " << length << "\n"; return false; } node = next_node; - comp = comp->get_next(pipeline_stage); + comp = comp->get_next(pipeline_stage, current_thread); length--; } @@ -5434,14 +5443,16 @@ write_bounds(ostream &out) const { // bounding volume, or false if none are. //////////////////////////////////////////////////////////////////// bool NodePath:: -calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point) { +calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, + Thread *current_thread) { min_point.set(0.0f, 0.0f, 0.0f); max_point.set(0.0f, 0.0f, 0.0f); nassertr_always(!is_empty(), false); bool found_any = false; node()->calc_tight_bounds(min_point, max_point, found_any, - TransformState::make_identity()); + TransformState::make_identity(), + current_thread); return found_any; } @@ -5641,24 +5652,24 @@ write_bam_file(const string &filename) const { //////////////////////////////////////////////////////////////////// NodePathComponent *NodePath:: find_common_ancestor(const NodePath &a, const NodePath &b, - int &a_count, int &b_count) { + int &a_count, int &b_count, Thread *current_thread) { nassertr(!a.is_empty() && !b.is_empty(), NULL); NodePathComponent *ac = a._head; NodePathComponent *bc = b._head; a_count = 0; b_count = 0; - int pipeline_stage = Thread::get_current_pipeline_stage(); + int pipeline_stage = current_thread->get_pipeline_stage(); // Shorten up the longer one until they are the same length. - while (ac->get_length(pipeline_stage) > bc->get_length(pipeline_stage)) { + while (ac->get_length(pipeline_stage, current_thread) > bc->get_length(pipeline_stage, current_thread)) { nassertr(ac != (NodePathComponent *)NULL, NULL); - ac = ac->get_next(pipeline_stage); + ac = ac->get_next(pipeline_stage, current_thread); a_count++; } - while (bc->get_length(pipeline_stage) > ac->get_length(pipeline_stage)) { + while (bc->get_length(pipeline_stage, current_thread) > ac->get_length(pipeline_stage, current_thread)) { nassertr(bc != (NodePathComponent *)NULL, NULL); - bc = bc->get_next(pipeline_stage); + bc = bc->get_next(pipeline_stage, current_thread); b_count++; } @@ -5667,9 +5678,9 @@ find_common_ancestor(const NodePath &a, const NodePath &b, // These shouldn't go to NULL unless they both go there together. nassertr(ac != (NodePathComponent *)NULL, NULL); nassertr(bc != (NodePathComponent *)NULL, NULL); - ac = ac->get_next(pipeline_stage); + ac = ac->get_next(pipeline_stage, current_thread); a_count++; - bc = bc->get_next(pipeline_stage); + bc = bc->get_next(pipeline_stage, current_thread); b_count++; } @@ -5683,13 +5694,13 @@ find_common_ancestor(const NodePath &a, const NodePath &b, // indicated component node from the root of the graph. //////////////////////////////////////////////////////////////////// CPT(RenderState) NodePath:: -r_get_net_state(NodePathComponent *comp) const { +r_get_net_state(NodePathComponent *comp, Thread *current_thread) const { if (comp == (NodePathComponent *)NULL) { return RenderState::make_empty(); } else { CPT(RenderState) state = comp->get_node()->get_state(); - int pipeline_stage = Thread::get_current_pipeline_stage(); - return r_get_net_state(comp->get_next(pipeline_stage))->compose(state); + int pipeline_stage = current_thread->get_pipeline_stage(); + return r_get_net_state(comp->get_next(pipeline_stage, current_thread), current_thread)->compose(state); } } @@ -5702,13 +5713,14 @@ r_get_net_state(NodePathComponent *comp) const { // net transform from the root of the graph. //////////////////////////////////////////////////////////////////// CPT(RenderState) NodePath:: -r_get_partial_state(NodePathComponent *comp, int n) const { +r_get_partial_state(NodePathComponent *comp, int n, + Thread *current_thread) const { if (n == 0 || comp == (NodePathComponent *)NULL) { return RenderState::make_empty(); } else { CPT(RenderState) state = comp->get_node()->get_state(); - int pipeline_stage = Thread::get_current_pipeline_stage(); - return r_get_partial_state(comp->get_next(pipeline_stage), n - 1)->compose(state); + int pipeline_stage = current_thread->get_pipeline_stage(); + return r_get_partial_state(comp->get_next(pipeline_stage, current_thread), n - 1, current_thread)->compose(state); } } @@ -5719,12 +5731,12 @@ r_get_partial_state(NodePathComponent *comp, int n) const { // indicated component node from the root of the graph. //////////////////////////////////////////////////////////////////// CPT(TransformState) NodePath:: -r_get_net_transform(NodePathComponent *comp) const { +r_get_net_transform(NodePathComponent *comp, Thread *current_thread) const { if (comp == (NodePathComponent *)NULL) { return TransformState::make_identity(); } else { - int pipeline_stage = Thread::get_current_pipeline_stage(); - CPT(TransformState) net_transform = r_get_net_transform(comp->get_next(pipeline_stage)); + int pipeline_stage = current_thread->get_pipeline_stage(); + CPT(TransformState) net_transform = r_get_net_transform(comp->get_next(pipeline_stage, current_thread), current_thread); CPT(TransformState) transform = comp->get_node()->get_transform(); CPT(RenderEffects) effects = comp->get_node()->get_effects(); @@ -5749,7 +5761,8 @@ r_get_net_transform(NodePathComponent *comp) const { // transform cannot be easily determined. //////////////////////////////////////////////////////////////////// CPT(TransformState) NodePath:: -r_get_partial_transform(NodePathComponent *comp, int n) const { +r_get_partial_transform(NodePathComponent *comp, int n, + Thread *current_thread) const { if (n == 0 || comp == (NodePathComponent *)NULL) { return TransformState::make_identity(); } else { @@ -5757,8 +5770,8 @@ r_get_partial_transform(NodePathComponent *comp, int n) const { return NULL; } CPT(TransformState) transform = comp->get_node()->get_transform(); - int pipeline_stage = Thread::get_current_pipeline_stage(); - CPT(TransformState) partial = r_get_partial_transform(comp->get_next(pipeline_stage), n - 1); + int pipeline_stage = current_thread->get_pipeline_stage(); + CPT(TransformState) partial = r_get_partial_transform(comp->get_next(pipeline_stage, current_thread), n - 1, current_thread); if (partial == (const TransformState *)NULL) { return NULL; } @@ -5774,13 +5787,13 @@ r_get_partial_transform(NodePathComponent *comp, int n) const { // graph. //////////////////////////////////////////////////////////////////// CPT(TransformState) NodePath:: -r_get_net_prev_transform(NodePathComponent *comp) const { +r_get_net_prev_transform(NodePathComponent *comp, Thread *current_thread) const { if (comp == (NodePathComponent *)NULL) { return TransformState::make_identity(); } else { CPT(TransformState) transform = comp->get_node()->get_prev_transform(); - int pipeline_stage = Thread::get_current_pipeline_stage(); - return r_get_net_prev_transform(comp->get_next(pipeline_stage))->compose(transform); + int pipeline_stage = current_thread->get_pipeline_stage(); + return r_get_net_prev_transform(comp->get_next(pipeline_stage, current_thread), current_thread)->compose(transform); } } @@ -5794,13 +5807,13 @@ r_get_net_prev_transform(NodePathComponent *comp) const { // the graph. //////////////////////////////////////////////////////////////////// CPT(TransformState) NodePath:: -r_get_partial_prev_transform(NodePathComponent *comp, int n) const { +r_get_partial_prev_transform(NodePathComponent *comp, int n, Thread *current_thread) const { if (n == 0 || comp == (NodePathComponent *)NULL) { return TransformState::make_identity(); } else { CPT(TransformState) transform = comp->get_node()->get_prev_transform(); - int pipeline_stage = Thread::get_current_pipeline_stage(); - return r_get_partial_prev_transform(comp->get_next(pipeline_stage), n - 1)->compose(transform); + int pipeline_stage = current_thread->get_pipeline_stage(); + return r_get_partial_prev_transform(comp->get_next(pipeline_stage, current_thread), n - 1, current_thread)->compose(transform); } } diff --git a/panda/src/pgraph/nodePath.h b/panda/src/pgraph/nodePath.h index 734310730e..60aa2b21ee 100644 --- a/panda/src/pgraph/nodePath.h +++ b/panda/src/pgraph/nodePath.h @@ -163,10 +163,11 @@ PUBLISHED: }; INLINE NodePath(); - INLINE NodePath(const string &top_node_name); - INLINE NodePath(PandaNode *node); - INLINE static NodePath any_path(PandaNode *node); - INLINE NodePath(const NodePath &parent, PandaNode *child_node); + INLINE NodePath(const string &top_node_name, Thread *current_thread = Thread::get_current_thread()); + INLINE NodePath(PandaNode *node, Thread *current_thread = Thread::get_current_thread()); + INLINE static NodePath any_path(PandaNode *node, Thread *current_thread = Thread::get_current_thread()); + INLINE NodePath(const NodePath &parent, PandaNode *child_node, + Thread *current_thread = Thread::get_current_thread()); INLINE NodePath(const NodePath ©); INLINE void operator = (const NodePath ©); @@ -180,34 +181,34 @@ PUBLISHED: // Methods to query a NodePath's contents. INLINE bool is_empty() const; - INLINE bool is_singleton() const; - int get_num_nodes() const; - PandaNode *get_node(int index) const; + INLINE bool is_singleton(Thread *current_thread = Thread::get_current_thread()) const; + int get_num_nodes(Thread *current_thread = Thread::get_current_thread()) const; + PandaNode *get_node(int index, Thread *current_thread = Thread::get_current_thread()) const; INLINE ErrorType get_error_type() const; - PandaNode *get_top_node() const; - NodePath get_top() const; + INLINE PandaNode *get_top_node(Thread *current_thread = Thread::get_current_thread()) const; + NodePath get_top(Thread *current_thread = Thread::get_current_thread()) const; INLINE PandaNode *node() const; INLINE int get_key() const; - INLINE bool is_same_graph(const NodePath &other) const; - INLINE bool is_ancestor_of(const NodePath &other) const; - INLINE NodePath get_common_ancestor(const NodePath &other) const; + INLINE bool is_same_graph(const NodePath &other, Thread *current_thread = Thread::get_current_thread()) const; + INLINE bool is_ancestor_of(const NodePath &other, Thread *current_thread = Thread::get_current_thread()) const; + INLINE NodePath get_common_ancestor(const NodePath &other, Thread *current_thread = Thread::get_current_thread()) const; // Methods that return collections of NodePaths derived from or // related to this one. - NodePathCollection get_children() const; - INLINE int get_num_children() const; - INLINE NodePath get_child(int n) const; - NodePathCollection get_stashed_children() const; + NodePathCollection get_children(Thread *current_thread = Thread::get_current_thread()) const; + INLINE int get_num_children(Thread *current_thread = Thread::get_current_thread()) const; + INLINE NodePath get_child(int n, Thread *current_thread = Thread::get_current_thread()) const; + NodePathCollection get_stashed_children(Thread *current_thread = Thread::get_current_thread()) const; - INLINE bool has_parent() const; - INLINE NodePath get_parent() const; - int get_sort() const; + INLINE bool has_parent(Thread *current_thread = Thread::get_current_thread()) const; + INLINE NodePath get_parent(Thread *current_thread = Thread::get_current_thread()) const; + int get_sort(Thread *current_thread = Thread::get_current_thread()) const; NodePath find(const string &path) const; NodePath find_path_to(PandaNode *node) const; @@ -219,16 +220,23 @@ PUBLISHED: // ordering between sibling nodes, useful when dealing with LOD's // and similar switch nodes. If the sort value is the same, nodes // will be arranged in the order they were added. - void reparent_to(const NodePath &other, int sort = 0); - void wrt_reparent_to(const NodePath &other, int sort = 0); - NodePath instance_to(const NodePath &other, int sort = 0) const; + void reparent_to(const NodePath &other, int sort = 0, + Thread *current_thread = Thread::get_current_thread()); + void wrt_reparent_to(const NodePath &other, int sort = 0, + Thread *current_thread = Thread::get_current_thread()); + NodePath instance_to(const NodePath &other, int sort = 0, + Thread *current_thread = Thread::get_current_thread()) const; NodePath instance_under_node(const NodePath &other, const string &name, - int sort = 0) const; - NodePath copy_to(const NodePath &other, int sort = 0) const; - NodePath attach_new_node(PandaNode *node, int sort = 0) const; - INLINE NodePath attach_new_node(const string &name, int sort = 0) const; - void remove_node(); - void detach_node(); + int sort = 0, + Thread *current_thread = Thread::get_current_thread()) const; + NodePath copy_to(const NodePath &other, int sort = 0, + Thread *current_thread = Thread::get_current_thread()) const; + NodePath attach_new_node(PandaNode *node, int sort = 0, + Thread *current_thread = Thread::get_current_thread()) const; + INLINE NodePath attach_new_node(const string &name, int sort = 0, + Thread *current_thread = Thread::get_current_thread()) const; + void remove_node(Thread *current_thread = Thread::get_current_thread()); + void detach_node(Thread *current_thread = Thread::get_current_thread()); // Handy ways to look at what's there, and other miscellaneous // operations. @@ -242,11 +250,11 @@ PUBLISHED: // Aggregate transform and state information. - const RenderState *get_state() const; - INLINE void set_state(const RenderState *state); - CPT(RenderState) get_state(const NodePath &other) const; - void set_state(const NodePath &other, const RenderState *state); - INLINE CPT(RenderState) get_net_state() const; + const RenderState *get_state(Thread *current_thread = Thread::get_current_thread()) const; + INLINE void set_state(const RenderState *state, Thread *current_thread = Thread::get_current_thread()); + CPT(RenderState) get_state(const NodePath &other, Thread *current_thread = Thread::get_current_thread()) const; + void set_state(const NodePath &other, const RenderState *state, Thread *current_thread = Thread::get_current_thread()); + INLINE CPT(RenderState) get_net_state(Thread *current_thread = Thread::get_current_thread()) const; INLINE void set_attrib(const RenderAttrib *attrib, int priority = 0); INLINE const RenderAttrib *get_attrib(TypeHandle type) const; @@ -262,19 +270,19 @@ PUBLISHED: INLINE const RenderEffects *get_effects() const; INLINE void clear_effects(); - const TransformState *get_transform() const; - INLINE void clear_transform(); - INLINE void set_transform(const TransformState *transform); - CPT(TransformState) get_transform(const NodePath &other) const; - INLINE void clear_transform(const NodePath &other); - void set_transform(const NodePath &other, const TransformState *transform); - INLINE CPT(TransformState) get_net_transform() const; + const TransformState *get_transform(Thread *current_thread = Thread::get_current_thread()) const; + INLINE void clear_transform(Thread *current_thread = Thread::get_current_thread()); + INLINE void set_transform(const TransformState *transform, Thread *current_thread = Thread::get_current_thread()); + CPT(TransformState) get_transform(const NodePath &other, Thread *current_thread = Thread::get_current_thread()) const; + INLINE void clear_transform(const NodePath &other, Thread *current_thread = Thread::get_current_thread()); + void set_transform(const NodePath &other, const TransformState *transform, Thread *current_thread = Thread::get_current_thread()); + INLINE CPT(TransformState) get_net_transform(Thread *current_thread = Thread::get_current_thread()) const; - const TransformState *get_prev_transform() const; - INLINE void set_prev_transform(const TransformState *transform); - CPT(TransformState) get_prev_transform(const NodePath &other) const; - void set_prev_transform(const NodePath &other, const TransformState *transform); - INLINE CPT(TransformState) get_net_prev_transform() const; + const TransformState *get_prev_transform(Thread *current_thread = Thread::get_current_thread()) const; + INLINE void set_prev_transform(const TransformState *transform, Thread *current_thread = Thread::get_current_thread()); + CPT(TransformState) get_prev_transform(const NodePath &other, Thread *current_thread = Thread::get_current_thread()) const; + void set_prev_transform(const NodePath &other, const TransformState *transform, Thread *current_thread = Thread::get_current_thread()); + INLINE CPT(TransformState) get_net_prev_transform(Thread *current_thread = Thread::get_current_thread()) const; // Methods that get and set the matrix transform: pos, hpr, scale, @@ -743,13 +751,14 @@ PUBLISHED: INLINE void hide(); INLINE void hide(DrawMask camera_mask); INLINE bool is_hidden(DrawMask camera_mask = PandaNode::get_overall_bit()) const; - NodePath get_hidden_ancestor(DrawMask camera_mask = PandaNode::get_overall_bit()) const; + NodePath get_hidden_ancestor(DrawMask camera_mask = PandaNode::get_overall_bit(), + Thread *current_thread = Thread::get_current_thread()) const; - void stash(int sort = 0); - void unstash(int sort = 0); - void unstash_all(); + void stash(int sort = 0, Thread *current_thread = Thread::get_current_thread()); + void unstash(int sort = 0, Thread *current_thread = Thread::get_current_thread()); + void unstash_all(Thread *current_thread = Thread::get_current_thread()); INLINE bool is_stashed() const; - NodePath get_stashed_ancestor() const; + NodePath get_stashed_ancestor(Thread *current_thread = Thread::get_current_thread()) const; INLINE CollideMask get_collide_mask() const; INLINE void set_collide_mask(CollideMask new_mask, CollideMask bits_to_change = CollideMask::all_on(), @@ -762,7 +771,7 @@ PUBLISHED: INLINE int compare_to(const NodePath &other) const; // Miscellaneous - bool verify_complete() const; + bool verify_complete(Thread *current_thread = Thread::get_current_thread()) const; void prepare_scene(GraphicsStateGuardianBase *gsg); @@ -772,7 +781,8 @@ PUBLISHED: PT(BoundingVolume) get_bounds() const; void force_recompute_bounds(); void write_bounds(ostream &out) const; - bool calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point); + bool calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, + Thread *current_thread = Thread::get_current_thread()); void analyze() const; @@ -808,14 +818,21 @@ PUBLISHED: private: static NodePathComponent * find_common_ancestor(const NodePath &a, const NodePath &b, - int &a_count, int &b_count); + int &a_count, int &b_count, + Thread *current_thread); - CPT(RenderState) r_get_net_state(NodePathComponent *comp) const; - CPT(RenderState) r_get_partial_state(NodePathComponent *comp, int n) const; - CPT(TransformState) r_get_net_transform(NodePathComponent *comp) const; - CPT(TransformState) r_get_partial_transform(NodePathComponent *comp, int n) const; - CPT(TransformState) r_get_net_prev_transform(NodePathComponent *comp) const; - CPT(TransformState) r_get_partial_prev_transform(NodePathComponent *comp, int n) const; + CPT(RenderState) r_get_net_state(NodePathComponent *comp, + Thread *current_thread) const; + CPT(RenderState) r_get_partial_state(NodePathComponent *comp, int n, + Thread *current_thread) const; + CPT(TransformState) r_get_net_transform(NodePathComponent *comp, + Thread *current_thread) const; + CPT(TransformState) r_get_partial_transform(NodePathComponent *comp, int n, + Thread *current_thread) const; + CPT(TransformState) r_get_net_prev_transform(NodePathComponent *comp, + Thread *current_thread) const; + CPT(TransformState) r_get_partial_prev_transform(NodePathComponent *comp, + int n, Thread *current_thread) const; void find_matches(NodePathCollection &result, const string &approx_path_str, diff --git a/panda/src/pgraph/nodePathComponent.cxx b/panda/src/pgraph/nodePathComponent.cxx index 0d77c0e114..b44b535b89 100644 --- a/panda/src/pgraph/nodePathComponent.cxx +++ b/panda/src/pgraph/nodePathComponent.cxx @@ -45,7 +45,7 @@ make_copy() const { //////////////////////////////////////////////////////////////////// NodePathComponent:: NodePathComponent(PandaNode *node, NodePathComponent *next, - int pipeline_stage) : + int pipeline_stage, Thread *current_thread) : _node(node), _key(0) { @@ -56,11 +56,11 @@ NodePathComponent(PandaNode *node, NodePathComponent *next, for (int pipeline_stage_i = pipeline_stage; pipeline_stage_i >= 0; --pipeline_stage_i) { - CDStageWriter cdata(_cycler, pipeline_stage_i); + CDStageWriter cdata(_cycler, pipeline_stage_i, current_thread); cdata->_next = next; if (next != (NodePathComponent *)NULL) { - cdata->_length = next->get_length(pipeline_stage_i) + 1; + cdata->_length = next->get_length(pipeline_stage_i, current_thread) + 1; } } } @@ -94,8 +94,8 @@ get_key() const { // node in the path. //////////////////////////////////////////////////////////////////// bool NodePathComponent:: -is_top_node(int pipeline_stage) const { - CDStageReader cdata(_cycler, pipeline_stage); +is_top_node(int pipeline_stage, Thread *current_thread) const { + CDStageReader cdata(_cycler, pipeline_stage, current_thread); return (cdata->_next == (NodePathComponent *)NULL); } @@ -105,8 +105,8 @@ is_top_node(int pipeline_stage) const { // Description: Returns the length of the path to this node. //////////////////////////////////////////////////////////////////// int NodePathComponent:: -get_length(int pipeline_stage) const { - CDStageReader cdata(_cycler, pipeline_stage); +get_length(int pipeline_stage, Thread *current_thread) const { + CDStageReader cdata(_cycler, pipeline_stage, current_thread); return cdata->_length; } @@ -116,8 +116,8 @@ get_length(int pipeline_stage) const { // Description: Returns the next component in the path. //////////////////////////////////////////////////////////////////// NodePathComponent *NodePathComponent:: -get_next(int pipeline_stage) const { - CDStageReader cdata(_cycler, pipeline_stage); +get_next(int pipeline_stage, Thread *current_thread) const { + CDStageReader cdata(_cycler, pipeline_stage, current_thread); NodePathComponent *next = cdata->_next; return next; @@ -132,12 +132,12 @@ get_next(int pipeline_stage) const { // component has been changed; otherwise, returns false. //////////////////////////////////////////////////////////////////// bool NodePathComponent:: -fix_length(int pipeline_stage) { - CDStageReader cdata(_cycler, pipeline_stage); +fix_length(int pipeline_stage, Thread *current_thread) { + CDStageReader cdata(_cycler, pipeline_stage, current_thread); int length_should_be = 1; if (cdata->_next != (NodePathComponent *)NULL) { - length_should_be = cdata->_next->get_length(pipeline_stage) + 1; + length_should_be = cdata->_next->get_length(pipeline_stage, current_thread) + 1; } if (cdata->_length == length_should_be) { @@ -159,10 +159,11 @@ fix_length(int pipeline_stage) { //////////////////////////////////////////////////////////////////// void NodePathComponent:: output(ostream &out) const { - int pipeline_stage = Thread::get_current_pipeline_stage(); + Thread *current_thread = Thread::get_current_thread(); + int pipeline_stage = current_thread->get_pipeline_stage(); PandaNode *node = get_node(); - NodePathComponent *next = get_next(pipeline_stage); + NodePathComponent *next = get_next(pipeline_stage, current_thread); if (next != (NodePathComponent *)NULL) { // This is not the head of the list; keep going up. next->output(out); @@ -194,9 +195,9 @@ output(ostream &out) const { // Description: Sets the next pointer in the path. //////////////////////////////////////////////////////////////////// void NodePathComponent:: -set_next(NodePathComponent *next, int pipeline_stage) { +set_next(NodePathComponent *next, int pipeline_stage, Thread *current_thread) { nassertv(next != (NodePathComponent *)NULL); - CDStageWriter cdata(_cycler, pipeline_stage); + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); cdata->_next = next; } @@ -207,7 +208,7 @@ set_next(NodePathComponent *next, int pipeline_stage) { // path and makes this component a top node. //////////////////////////////////////////////////////////////////// void NodePathComponent:: -set_top_node(int pipeline_stage) { - CDStageWriter cdata(_cycler, pipeline_stage); +set_top_node(int pipeline_stage, Thread *current_thread) { + CDStageWriter cdata(_cycler, pipeline_stage, current_thread); cdata->_next = (NodePathComponent *)NULL; } diff --git a/panda/src/pgraph/nodePathComponent.h b/panda/src/pgraph/nodePathComponent.h index 718a80070c..73a5a52706 100644 --- a/panda/src/pgraph/nodePathComponent.h +++ b/panda/src/pgraph/nodePathComponent.h @@ -51,7 +51,7 @@ class EXPCL_PANDA NodePathComponent : public ReferenceCount { private: NodePathComponent(PandaNode *node, NodePathComponent *next, - int pipeline_stage); + int pipeline_stage, Thread *current_thread); INLINE NodePathComponent(const NodePathComponent ©); INLINE void operator = (const NodePathComponent ©); @@ -62,18 +62,18 @@ public: INLINE PandaNode *get_node() const; INLINE bool has_key() const; int get_key() const; - bool is_top_node(int pipeline_stage) const; + bool is_top_node(int pipeline_stage, Thread *current_thread) const; - NodePathComponent *get_next(int pipeline_stage) const; - int get_length(int pipeline_stage) const; + NodePathComponent *get_next(int pipeline_stage, Thread *current_thread) const; + int get_length(int pipeline_stage, Thread *current_thread) const; - bool fix_length(int pipeline_stage); + bool fix_length(int pipeline_stage, Thread *current_thread); void output(ostream &out) const; private: - void set_next(NodePathComponent *next, int pipeline_stage); - void set_top_node(int pipeline_stage); + void set_next(NodePathComponent *next, int pipeline_stage, Thread *current_thread); + void set_top_node(int pipeline_stage, Thread *current_thread); // We don't have to cycle the _node and _key elements, since these // are permanent properties of this object. (Well, the _key is diff --git a/panda/src/pgraph/pandaNode.I b/panda/src/pgraph/pandaNode.I index f347daacd5..ef12eb5a96 100644 --- a/panda/src/pgraph/pandaNode.I +++ b/panda/src/pgraph/pandaNode.I @@ -40,15 +40,15 @@ compose_draw_mask(DrawMask &running_draw_mask) const { // be visible to the indicated camera_mask. //////////////////////////////////////////////////////////////////// INLINE bool PandaNode:: -compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask) const { +compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask, + Thread *current_thread) const { DrawMask net_draw_control_mask, net_draw_show_mask; - int pipeline_stage = Thread::get_current_pipeline_stage(); - CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage); + int pipeline_stage = current_thread->get_pipeline_stage(); + CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage, current_thread); if (cdata->_last_update != cdata->_next_update) { // The cache is stale; it needs to be rebuilt. - CDBoundsStageWriter cdataw = - ((PandaNode *)this)->update_bounds(pipeline_stage, cdata); + CDBoundsStageWriter cdataw = ((PandaNode *)this)->update_bounds(pipeline_stage, cdata); net_draw_control_mask = cdataw->_net_draw_control_mask; net_draw_show_mask = cdataw->_net_draw_show_mask; } else { @@ -84,8 +84,8 @@ compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask) const { // which the node was instanced to them. //////////////////////////////////////////////////////////////////// INLINE int PandaNode:: -get_num_parents() const { - CDLinksReader cdata(_cycler_links); +get_num_parents(Thread *current_thread) const { + CDLinksReader cdata(_cycler_links, current_thread); return cdata->get_up()->size(); } @@ -98,8 +98,8 @@ get_num_parents() const { // parents; get_parents() is preferable in this case. //////////////////////////////////////////////////////////////////// INLINE PandaNode *PandaNode:: -get_parent(int n) const { - CDLinksReader cdata(_cycler_links); +get_parent(int n, Thread *current_thread) const { + CDLinksReader cdata(_cycler_links, current_thread); const Up &up = *cdata->get_up(); nassertr(n >= 0 && n < (int)up.size(), NULL); return up[n].get_parent(); @@ -112,8 +112,8 @@ get_parent(int n) const { // is a parent, or -1 if it is not. //////////////////////////////////////////////////////////////////// INLINE int PandaNode:: -find_parent(PandaNode *node) const { - CDLinksReader cdata(_cycler_links); +find_parent(PandaNode *node, Thread *current_thread) const { + CDLinksReader cdata(_cycler_links, current_thread); return do_find_parent(node, cdata); } @@ -126,8 +126,8 @@ find_parent(PandaNode *node) const { // and also on the order in which the nodes were added. //////////////////////////////////////////////////////////////////// INLINE int PandaNode:: -get_num_children() const { - CDLinksReader cdata(_cycler_links); +get_num_children(Thread *current_thread) const { + CDLinksReader cdata(_cycler_links, current_thread); return cdata->get_down()->size(); } @@ -140,8 +140,8 @@ get_num_children() const { // children; get_children() is preferable in this case. //////////////////////////////////////////////////////////////////// INLINE PandaNode *PandaNode:: -get_child(int n) const { - CDLinksReader cdata(_cycler_links); +get_child(int n, Thread *current_thread) const { + CDLinksReader cdata(_cycler_links, current_thread); const Down &down = *cdata->get_down(); nassertr(n >= 0 && n < (int)down.size(), NULL); return down[n].get_child(); @@ -155,8 +155,8 @@ get_child(int n) const { // add_child()). See get_num_children(). //////////////////////////////////////////////////////////////////// INLINE int PandaNode:: -get_child_sort(int n) const { - CDLinksReader cdata(_cycler_links); +get_child_sort(int n, Thread *current_thread) const { + CDLinksReader cdata(_cycler_links, current_thread); const Down &down = *cdata->get_down(); nassertr(n >= 0 && n < (int)down.size(), -1); return down[n].get_sort(); @@ -169,8 +169,8 @@ get_child_sort(int n) const { // is a child, or -1 if it is not. //////////////////////////////////////////////////////////////////// INLINE int PandaNode:: -find_child(PandaNode *node) const { - CDLinksReader cdata(_cycler_links); +find_child(PandaNode *node, Thread *current_thread) const { + CDLinksReader cdata(_cycler_links, current_thread); return do_find_child(node, cdata); } @@ -191,12 +191,12 @@ find_child(PandaNode *node) const { // previously stashed). //////////////////////////////////////////////////////////////////// INLINE bool PandaNode:: -stash_child(PandaNode *child_node) { - int child_index = find_child(child_node); +stash_child(PandaNode *child_node, Thread *current_thread) { + int child_index = find_child(child_node, current_thread); if (child_index < 0) { return false; } - stash_child(child_index); + stash_child(child_index, current_thread); return true; } @@ -217,12 +217,12 @@ stash_child(PandaNode *child_node) { // previously stashed). //////////////////////////////////////////////////////////////////// INLINE bool PandaNode:: -unstash_child(PandaNode *child_node) { - int stashed_index = find_stashed(child_node); +unstash_child(PandaNode *child_node, Thread *current_thread) { + int stashed_index = find_stashed(child_node, current_thread); if (stashed_index < 0) { return false; } - unstash_child(stashed_index); + unstash_child(stashed_index, current_thread); return true; } @@ -234,8 +234,8 @@ unstash_child(PandaNode *child_node) { // moved to the special stashed list via stash_child(). //////////////////////////////////////////////////////////////////// INLINE int PandaNode:: -get_num_stashed() const { - CDLinksReader cdata(_cycler_links); +get_num_stashed(Thread *current_thread) const { + CDLinksReader cdata(_cycler_links, current_thread); return cdata->get_stashed()->size(); } @@ -249,8 +249,8 @@ get_num_stashed() const { // case. //////////////////////////////////////////////////////////////////// INLINE PandaNode *PandaNode:: -get_stashed(int n) const { - CDLinksReader cdata(_cycler_links); +get_stashed(int n, Thread *current_thread) const { + CDLinksReader cdata(_cycler_links, current_thread); const Down &stashed = *cdata->get_stashed(); nassertr(n >= 0 && n < (int)stashed.size(), NULL); return stashed[n].get_child(); @@ -264,8 +264,8 @@ get_stashed(int n) const { // add_child()). See get_num_stashed(). //////////////////////////////////////////////////////////////////// INLINE int PandaNode:: -get_stashed_sort(int n) const { - CDLinksReader cdata(_cycler_links); +get_stashed_sort(int n, Thread *current_thread) const { + CDLinksReader cdata(_cycler_links, current_thread); const Down &stashed = *cdata->get_stashed(); nassertr(n >= 0 && n < (int)stashed.size(), -1); return stashed[n].get_sort(); @@ -278,8 +278,8 @@ get_stashed_sort(int n) const { // it is a stashed child, or -1 if it is not. //////////////////////////////////////////////////////////////////// INLINE int PandaNode:: -find_stashed(PandaNode *node) const { - CDLinksReader cdata(_cycler_links); +find_stashed(PandaNode *node, Thread *current_thread) const { + CDLinksReader cdata(_cycler_links, current_thread); return do_find_stashed(node, cdata); } @@ -356,8 +356,8 @@ has_effect(TypeHandle type) const { // that might be inherited from above. //////////////////////////////////////////////////////////////////// INLINE const RenderState *PandaNode:: -get_state() const { - CDLightReader cdata(_cycler_light); +get_state(Thread *current_thread) const { + CDLightReader cdata(_cycler_light, current_thread); return cdata->_state; } @@ -370,8 +370,8 @@ get_state() const { // this level. //////////////////////////////////////////////////////////////////// INLINE void PandaNode:: -clear_state() { - set_state(RenderState::make_empty()); +clear_state(Thread *current_thread) { + set_state(RenderState::make_empty(), current_thread); } //////////////////////////////////////////////////////////////////// @@ -405,8 +405,8 @@ clear_effects() { // node. //////////////////////////////////////////////////////////////////// INLINE const TransformState *PandaNode:: -get_transform() const { - CDLightReader cdata(_cycler_light); +get_transform(Thread *current_thread) const { + CDLightReader cdata(_cycler_light, current_thread); return cdata->_transform; } @@ -417,8 +417,8 @@ get_transform() const { // transform. //////////////////////////////////////////////////////////////////// INLINE void PandaNode:: -clear_transform() { - set_transform(TransformState::make_identity()); +clear_transform(Thread *current_thread) { + set_transform(TransformState::make_identity(), current_thread); } //////////////////////////////////////////////////////////////////// @@ -429,8 +429,8 @@ clear_transform() { // set_prev_transform(). //////////////////////////////////////////////////////////////////// const TransformState *PandaNode:: -get_prev_transform() const { - CDLightReader cdata(_cycler_light); +get_prev_transform(Thread *current_thread) const { + CDLightReader cdata(_cycler_light, current_thread); return cdata->_prev_transform; } @@ -620,8 +620,9 @@ clear_bounds() { //////////////////////////////////////////////////////////////////// INLINE CPT(BoundingVolume) PandaNode:: get_internal_bounds() const { - int pipeline_stage = Thread::get_current_pipeline_stage(); - return get_internal_bounds(pipeline_stage); + Thread *current_thread = Thread::get_current_thread(); + return get_internal_bounds(current_thread->get_pipeline_stage(), + current_thread); } //////////////////////////////////////////////////////////////////// @@ -670,8 +671,8 @@ is_final() const { // never been set. //////////////////////////////////////////////////////////////////// INLINE CPT(BoundingVolume) PandaNode:: -get_user_bounds(int pipeline_stage) const { - CDHeavyStageReader cdata(_cycler_heavy, pipeline_stage); +get_user_bounds(int pipeline_stage, Thread *current_thread) const { + CDHeavyStageReader cdata(_cycler_heavy, pipeline_stage, current_thread); return cdata->_user_bounds; } @@ -685,16 +686,16 @@ get_user_bounds(int pipeline_stage) const { // recomputed. //////////////////////////////////////////////////////////////////// INLINE void PandaNode:: -mark_bounds_stale(int pipeline_stage) const { +mark_bounds_stale(int pipeline_stage, Thread *current_thread) const { // It's important that we don't hold the lock during the call to // force_bounds_stale(). bool is_stale_bounds; { - CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage); + CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage, current_thread); is_stale_bounds = (cdata->_last_update != cdata->_next_update); } if (!is_stale_bounds) { - ((PandaNode *)this)->force_bounds_stale(pipeline_stage); + ((PandaNode *)this)->force_bounds_stale(pipeline_stage, current_thread); } } @@ -708,12 +709,12 @@ mark_bounds_stale(int pipeline_stage) const { // bounding volume is next requested. //////////////////////////////////////////////////////////////////// INLINE void PandaNode:: -mark_internal_bounds_stale(int pipeline_stage) { +mark_internal_bounds_stale(int pipeline_stage, Thread *current_thread) { { - CDHeavyWriter cdata(_cycler_heavy); + CDHeavyStageWriter cdata(_cycler_heavy, pipeline_stage, current_thread); cdata->_internal_bounds_stale = true; } - mark_bounds_stale(pipeline_stage); + mark_bounds_stale(pipeline_stage, current_thread); } //////////////////////////////////////////////////////////////////// @@ -1048,7 +1049,16 @@ modify_up() { // Description: //////////////////////////////////////////////////////////////////// INLINE PandaNode::Children:: -Children(const PandaNode::CDLinksReader &cdata) : +Children() { +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNode::Children::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PandaNode::Children:: +Children(const PandaNode::CDataLinks *cdata) : _down(cdata->get_down()) { } @@ -1081,6 +1091,7 @@ operator = (const PandaNode::Children ©) { //////////////////////////////////////////////////////////////////// INLINE int PandaNode::Children:: get_num_children() const { + nassertr(_down != (Down *)NULL, 0); return _down->size(); } @@ -1091,17 +1102,41 @@ get_num_children() const { //////////////////////////////////////////////////////////////////// INLINE PandaNode *PandaNode::Children:: get_child(int n) const { + nassertr(_down != (Down *)NULL, NULL); nassertr(n >= 0 && n < (int)_down->size(), NULL); return (*_down)[n].get_child(); } +//////////////////////////////////////////////////////////////////// +// Function: PandaNode::Children::get_child_sort +// Access: Public +// Description: Returns the sort index of the nth child node of this +// node (that is, the number that was passed to +// add_child()). See get_num_children(). +//////////////////////////////////////////////////////////////////// +INLINE int PandaNode::Children:: +get_child_sort(int n) const { + nassertr(_down != (Down *)NULL, -1); + nassertr(n >= 0 && n < (int)_down->size(), -1); + return (*_down)[n].get_sort(); +} + //////////////////////////////////////////////////////////////////// // Function: PandaNode::Stashed::Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// INLINE PandaNode::Stashed:: -Stashed(const PandaNode::CDLinksReader &cdata) : +Stashed() { +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNode::Stashed::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PandaNode::Stashed:: +Stashed(const PandaNode::CDataLinks *cdata) : _stashed(cdata->get_stashed()) { } @@ -1134,6 +1169,7 @@ operator = (const PandaNode::Stashed ©) { //////////////////////////////////////////////////////////////////// INLINE int PandaNode::Stashed:: get_num_stashed() const { + nassertr(_stashed != (Down *)NULL, 0); return _stashed->size(); } @@ -1144,17 +1180,41 @@ get_num_stashed() const { //////////////////////////////////////////////////////////////////// INLINE PandaNode *PandaNode::Stashed:: get_stashed(int n) const { + nassertr(_stashed != (Down *)NULL, NULL); nassertr(n >= 0 && n < (int)_stashed->size(), NULL); return (*_stashed)[n].get_child(); } +//////////////////////////////////////////////////////////////////// +// Function: PandaNode::Stashed::get_stashed_sort +// Access: Public +// Description: Returns the sort index of the nth child node of this +// node (that is, the number that was passed to +// add_child()). See get_num_stashed(). +//////////////////////////////////////////////////////////////////// +INLINE int PandaNode::Stashed:: +get_stashed_sort(int n) const { + nassertr(_stashed != (Down *)NULL, -1); + nassertr(n >= 0 && n < (int)_stashed->size(), -1); + return (*_stashed)[n].get_sort(); +} + //////////////////////////////////////////////////////////////////// // Function: PandaNode::Parents::Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// INLINE PandaNode::Parents:: -Parents(const PandaNode::CDLinksReader &cdata) : +Parents() { +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNode::Parents::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PandaNode::Parents:: +Parents(const PandaNode::CDataLinks *cdata) : _up(cdata->get_up()) { } @@ -1187,6 +1247,7 @@ operator = (const PandaNode::Parents ©) { //////////////////////////////////////////////////////////////////// INLINE int PandaNode::Parents:: get_num_parents() const { + nassertr(_up != (Up *)NULL, 0); return _up->size(); } @@ -1197,6 +1258,7 @@ get_num_parents() const { //////////////////////////////////////////////////////////////////// INLINE PandaNode *PandaNode::Parents:: get_parent(int n) const { + nassertr(_up != (Up *)NULL, NULL); nassertr(n >= 0 && n < (int)_up->size(), NULL); return (*_up)[n].get_parent(); } diff --git a/panda/src/pgraph/pandaNode.cxx b/panda/src/pgraph/pandaNode.cxx index 6dec8eea26..5617208326 100644 --- a/panda/src/pgraph/pandaNode.cxx +++ b/panda/src/pgraph/pandaNode.cxx @@ -389,14 +389,15 @@ combine_with(PandaNode *other) { //////////////////////////////////////////////////////////////////// CPT(TransformState) PandaNode:: calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, - const TransformState *transform) const { + const TransformState *transform, Thread *current_thread) const { CPT(TransformState) next_transform = transform->compose(get_transform()); Children cr = get_children(); int num_children = cr.get_num_children(); for (int i = 0; i < num_children; i++) { cr.get_child(i)->calc_tight_bounds(min_point, max_point, - found_any, next_transform); + found_any, next_transform, + current_thread); } return next_transform; @@ -551,9 +552,9 @@ is_renderable() const { // will impede normal use of the PandaNode. //////////////////////////////////////////////////////////////////// PT(PandaNode) PandaNode:: -copy_subgraph() const { +copy_subgraph(Thread *current_thread) const { InstanceMap inst_map; - return r_copy_subgraph(inst_map); + return r_copy_subgraph(inst_map, current_thread); } //////////////////////////////////////////////////////////////////// @@ -568,7 +569,7 @@ copy_subgraph() const { // the previous instance is first removed. //////////////////////////////////////////////////////////////////// void PandaNode:: -add_child(PandaNode *child_node, int sort) { +add_child(PandaNode *child_node, int sort, Thread *current_thread) { nassertv(child_node != (PandaNode *)NULL); // Ensure the child_node is not deleted while we do this. PT(PandaNode) keep_child = child_node; @@ -576,7 +577,6 @@ add_child(PandaNode *child_node, int sort) { // Apply this operation to the current stage as well as to all // upstream stages. - Thread *current_thread = Thread::get_current_thread(); OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_links, current_thread) { CDLinksStageWriter cdata(_cycler_links, pipeline_stage, current_thread); CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage, current_thread); @@ -587,7 +587,7 @@ add_child(PandaNode *child_node, int sort) { CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_links); OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links, current_thread) { - new_connection(this, child_node, pipeline_stage); + new_connection(this, child_node, pipeline_stage, current_thread); } CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links); @@ -602,24 +602,25 @@ add_child(PandaNode *child_node, int sort) { // Description: Removes the nth child from the node. //////////////////////////////////////////////////////////////////// void PandaNode:: -remove_child(int child_index) { - int pipeline_stage = Thread::get_current_pipeline_stage(); +remove_child(int child_index, Thread *current_thread) { + int pipeline_stage = current_thread->get_pipeline_stage(); nassertv(pipeline_stage == 0); - CDLinksStageWriter cdata(_cycler_links, pipeline_stage); + CDLinksStageWriter cdata(_cycler_links, pipeline_stage, current_thread); Down &down = *cdata->modify_down(); nassertv(child_index >= 0 && child_index < (int)down.size()); PT(PandaNode) child_node = down[child_index].get_child(); - CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage); + CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage, + current_thread); Up &up = *cdata_child->modify_up(); down.erase(down.begin() + child_index); int num_erased = up.erase(UpConnection(this)); nassertv(num_erased == 1); - sever_connection(this, child_node, pipeline_stage); - force_bounds_stale(pipeline_stage); + sever_connection(this, child_node, pipeline_stage, current_thread); + force_bounds_stale(pipeline_stage, current_thread); children_changed(); child_node->parents_changed(); @@ -634,7 +635,7 @@ remove_child(int child_index) { // successfully remove the child if it had been stashed. //////////////////////////////////////////////////////////////////// bool PandaNode:: -remove_child(PandaNode *child_node) { +remove_child(PandaNode *child_node, Thread *current_thread) { nassertr(child_node != (PandaNode *)NULL, false); // Make sure the child node is not destructed during the execution @@ -644,13 +645,12 @@ remove_child(PandaNode *child_node) { // We have to do this for each upstream pipeline stage. bool any_removed = false; - Thread *current_thread = Thread::get_current_thread(); OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links, current_thread) { - if (stage_remove_child(child_node, pipeline_stage)) { + if (stage_remove_child(child_node, pipeline_stage, current_thread)) { any_removed = true; - sever_connection(this, child_node, pipeline_stage); - force_bounds_stale(pipeline_stage); + sever_connection(this, child_node, pipeline_stage, current_thread); + force_bounds_stale(pipeline_stage, current_thread); } } CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links); @@ -673,7 +673,8 @@ remove_child(PandaNode *child_node) { // false if the node is not a child. //////////////////////////////////////////////////////////////////// bool PandaNode:: -replace_child(PandaNode *orig_child, PandaNode *new_child) { +replace_child(PandaNode *orig_child, PandaNode *new_child, + Thread *current_thread) { nassertr(orig_child != (PandaNode *)NULL, false); nassertr(new_child != (PandaNode *)NULL, false); @@ -689,9 +690,8 @@ replace_child(PandaNode *orig_child, PandaNode *new_child) { // We have to do this for each upstream pipeline stage. bool any_replaced = false; - Thread *current_thread = Thread::get_current_thread(); OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_links, current_thread) { - if (stage_replace_child(orig_child, new_child, pipeline_stage)) { + if (stage_replace_child(orig_child, new_child, pipeline_stage, current_thread)) { any_replaced = true; } } @@ -722,8 +722,8 @@ replace_child(PandaNode *orig_child, PandaNode *new_child) { // (i.e. from App). //////////////////////////////////////////////////////////////////// void PandaNode:: -stash_child(int child_index) { - int pipeline_stage = Thread::get_current_pipeline_stage(); +stash_child(int child_index, Thread *current_thread) { + int pipeline_stage = current_thread->get_pipeline_stage(); nassertv(pipeline_stage == 0); nassertv(child_index >= 0 && child_index < get_num_children()); @@ -736,15 +736,15 @@ stash_child(int child_index) { remove_child(child_index); { - CDLinksStageWriter cdata(_cycler_links, pipeline_stage); - CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage); + CDLinksStageWriter cdata(_cycler_links, pipeline_stage, current_thread); + CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage, current_thread); cdata->modify_stashed()->insert(DownConnection(child_node, sort)); cdata_child->modify_up()->insert(UpConnection(this)); } - new_connection(this, child_node, pipeline_stage); - force_bounds_stale(pipeline_stage); + new_connection(this, child_node, pipeline_stage, current_thread); + force_bounds_stale(pipeline_stage, current_thread); children_changed(); child_node->parents_changed(); @@ -765,8 +765,9 @@ stash_child(int child_index) { // (i.e. from App). //////////////////////////////////////////////////////////////////// void PandaNode:: -unstash_child(int stashed_index) { - nassertv(Thread::get_current_pipeline_stage() == 0); +unstash_child(int stashed_index, Thread *current_thread) { + int pipeline_stage = current_thread->get_pipeline_stage(); + nassertv(pipeline_stage == 0); nassertv(stashed_index >= 0 && stashed_index < get_num_stashed()); // Save a reference count for ourselves. I don't think this should @@ -788,8 +789,7 @@ unstash_child(int stashed_index) { cdata_child->modify_up()->insert(UpConnection(this)); } - int pipeline_stage = Thread::get_current_pipeline_stage(); - new_connection(this, child_node, pipeline_stage); + new_connection(this, child_node, pipeline_stage, current_thread); force_bounds_stale(); children_changed(); @@ -811,8 +811,9 @@ unstash_child(int stashed_index) { // (i.e. from App). //////////////////////////////////////////////////////////////////// void PandaNode:: -add_stashed(PandaNode *child_node, int sort) { - nassertv(Thread::get_current_pipeline_stage() == 0); +add_stashed(PandaNode *child_node, int sort, Thread *current_thread) { + int pipeline_stage = current_thread->get_pipeline_stage(); + nassertv(pipeline_stage == 0); // Ensure the child_node is not deleted while we do this. PT(PandaNode) keep_child = child_node; @@ -826,8 +827,7 @@ add_stashed(PandaNode *child_node, int sort) { cdata_child->modify_up()->insert(UpConnection(this)); } - int pipeline_stage = Thread::get_current_pipeline_stage(); - new_connection(this, child_node, pipeline_stage); + new_connection(this, child_node, pipeline_stage, current_thread); // Call callback hooks. children_changed(); @@ -840,23 +840,23 @@ add_stashed(PandaNode *child_node, int sort) { // Description: Removes the nth stashed child from the node. //////////////////////////////////////////////////////////////////// void PandaNode:: -remove_stashed(int child_index) { - int pipeline_stage = Thread::get_current_pipeline_stage(); +remove_stashed(int child_index, Thread *current_thread) { + int pipeline_stage = current_thread->get_pipeline_stage(); nassertv(pipeline_stage == 0); - CDLinksStageWriter cdata(_cycler_links, pipeline_stage); + CDLinksStageWriter cdata(_cycler_links, pipeline_stage, current_thread); Down &stashed = *cdata->modify_stashed(); nassertv(child_index >= 0 && child_index < (int)stashed.size()); PT(PandaNode) child_node = stashed[child_index].get_child(); - CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage); + CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage, current_thread); stashed.erase(stashed.begin() + child_index); int num_erased = cdata_child->modify_up()->erase(UpConnection(this)); nassertv(num_erased == 1); - sever_connection(this, child_node, pipeline_stage); - force_bounds_stale(pipeline_stage); + sever_connection(this, child_node, pipeline_stage, current_thread); + force_bounds_stale(pipeline_stage, current_thread); children_changed(); child_node->parents_changed(); @@ -872,9 +872,8 @@ remove_stashed(int child_index) { // (i.e. from App). //////////////////////////////////////////////////////////////////// void PandaNode:: -remove_all_children() { +remove_all_children(Thread *current_thread) { // We have to do this for each upstream pipeline stage. - Thread *current_thread = Thread::get_current_thread(); OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_links, current_thread) { CDLinksStageWriter cdata(_cycler_links, pipeline_stage, current_thread); Down &down = *cdata->modify_down(); @@ -885,7 +884,7 @@ remove_all_children() { current_thread); cdata_child->modify_up()->erase(UpConnection(this)); - sever_connection(this, child_node, pipeline_stage); + sever_connection(this, child_node, pipeline_stage, current_thread); child_node->parents_changed(); } down.clear(); @@ -897,7 +896,7 @@ remove_all_children() { current_thread); cdata_child->modify_up()->erase(UpConnection(this)); - sever_connection(this, child_node, pipeline_stage); + sever_connection(this, child_node, pipeline_stage, current_thread); child_node->parents_changed(); } stashed.clear(); @@ -915,7 +914,7 @@ remove_all_children() { // node. //////////////////////////////////////////////////////////////////// void PandaNode:: -steal_children(PandaNode *other) { +steal_children(PandaNode *other, Thread *current_thread) { if (other == this) { // Trivial. return; @@ -934,16 +933,16 @@ steal_children(PandaNode *other) { for (i = 0; i < num_children; i++) { PandaNode *child_node = other->get_child(i); int sort = other->get_child_sort(i); - add_child(child_node, sort); + add_child(child_node, sort, current_thread); } int num_stashed = other->get_num_stashed(); for (i = 0; i < num_stashed; i++) { PandaNode *child_node = other->get_stashed(i); int sort = other->get_stashed_sort(i); - add_stashed(child_node, sort); + add_stashed(child_node, sort, current_thread); } - other->remove_all_children(); + other->remove_all_children(current_thread); } //////////////////////////////////////////////////////////////////// @@ -953,23 +952,25 @@ steal_children(PandaNode *other) { // other node, copying them to this node. //////////////////////////////////////////////////////////////////// void PandaNode:: -copy_children(PandaNode *other) { +copy_children(PandaNode *other, Thread *current_thread) { if (other == this) { // Trivial. return; } - int num_children = other->get_num_children(); + Children children = other->get_children(current_thread); + Stashed stashed = other->get_stashed(current_thread); + int num_children = children.get_num_children(); int i; for (i = 0; i < num_children; i++) { - PandaNode *child_node = other->get_child(i); - int sort = other->get_child_sort(i); - add_child(child_node, sort); + PandaNode *child_node = children.get_child(i); + int sort = children.get_child_sort(i); + add_child(child_node, sort, current_thread); } - int num_stashed = other->get_num_stashed(); + int num_stashed = stashed.get_num_stashed(); for (i = 0; i < num_stashed; i++) { - PandaNode *child_node = other->get_stashed(i); - int sort = other->get_stashed_sort(i); - add_stashed(child_node, sort); + PandaNode *child_node = stashed.get_stashed(i); + int sort = stashed.get_stashed_sort(i); + add_stashed(child_node, sort, current_thread); } } @@ -1083,11 +1084,10 @@ clear_effect(TypeHandle type) { // set on this node via repeated calls to set_attrib(). //////////////////////////////////////////////////////////////////// void PandaNode:: -set_state(const RenderState *state) { +set_state(const RenderState *state, Thread *current_thread) { // Apply this operation to the current stage as well as to all // upstream stages. bool any_changed = false; - Thread *current_thread = Thread::get_current_thread(); OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light, current_thread) { CDLightStageWriter cdata(_cycler_light, pipeline_stage, current_thread); if (cdata->_state != state) { @@ -1132,11 +1132,10 @@ set_effects(const RenderEffects *effects) { // this point in the scene graph and below. //////////////////////////////////////////////////////////////////// void PandaNode:: -set_transform(const TransformState *transform) { +set_transform(const TransformState *transform, Thread *current_thread) { // Apply this operation to the current stage as well as to all // upstream stages. bool any_changed = false; - Thread *current_thread = Thread::get_current_thread(); OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light, current_thread) { CDLightStageWriter cdata(_cycler_light, pipeline_stage, current_thread); if (cdata->_transform != transform) { @@ -1161,10 +1160,9 @@ set_transform(const TransformState *transform) { // calculations. //////////////////////////////////////////////////////////////////// void PandaNode:: -set_prev_transform(const TransformState *transform) { +set_prev_transform(const TransformState *transform, Thread *current_thread) { // Apply this operation to the current stage as well as to all // upstream stages. - Thread *current_thread = Thread::get_current_thread(); OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light, current_thread) { CDLightStageWriter cdata(_cycler_light, pipeline_stage, current_thread); cdata->_prev_transform = transform; @@ -1188,11 +1186,9 @@ set_prev_transform(const TransformState *transform) { // to identity. //////////////////////////////////////////////////////////////////// void PandaNode:: -reset_prev_transform() { +reset_prev_transform(Thread *current_thread) { // Apply this operation to the current stage as well as to all // upstream stages. - Thread *current_thread = Thread::get_current_thread(); - clear_dirty_prev_transform(); OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler_light, current_thread) { @@ -1212,11 +1208,10 @@ reset_prev_transform() { // be the same as _transform. //////////////////////////////////////////////////////////////////// void PandaNode:: -reset_all_prev_transform() { - Thread *current_thread = Thread::get_current_thread(); +reset_all_prev_transform(Thread *current_thread) { nassertv(current_thread->get_pipeline_stage() == 0); - PStatTimer timer(_reset_prev_pcollector); + PStatTimer timer(_reset_prev_pcollector, current_thread); MutexHolder holder(_dirty_prev_transforms._lock); LinkedListNode *list_node = _dirty_prev_transforms._next; @@ -1298,7 +1293,9 @@ clear_tag(const string &key) { //////////////////////////////////////////////////////////////////// void PandaNode:: set_python_tag(const string &key, PyObject *value) { - nassertv(Thread::get_current_pipeline_stage() == 0); + Thread *current_thread = Thread::get_current_thread(); + int pipeline_stage = current_thread->get_pipeline_stage(); + nassertv(pipeline_stage == 0); CDHeavyWriter cdata(_cycler_heavy); Py_XINCREF(value); @@ -1369,9 +1366,11 @@ has_python_tag(const string &key) const { //////////////////////////////////////////////////////////////////// void PandaNode:: clear_python_tag(const string &key) { - nassertv(Thread::get_current_pipeline_stage() == 0); + Thread *current_thread = Thread::get_current_thread(); + int pipeline_stage = current_thread->get_pipeline_stage(); + nassertv(pipeline_stage == 0); - CDHeavyWriter cdata(_cycler_heavy); + CDHeavyWriter cdata(_cycler_heavy, current_thread); PythonTagData::iterator ti; ti = cdata->_python_tag_data.find(key); if (ti != cdata->_python_tag_data.end()) { @@ -1561,8 +1560,9 @@ adjust_draw_mask(DrawMask show_mask, DrawMask hide_mask, DrawMask clear_mask) { //////////////////////////////////////////////////////////////////// DrawMask PandaNode:: get_net_draw_control_mask() const { - int pipeline_stage = Thread::get_current_pipeline_stage(); - CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage); + Thread *current_thread = Thread::get_current_thread(); + int pipeline_stage = current_thread->get_pipeline_stage(); + CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage, current_thread); if (cdata->_last_update != cdata->_next_update) { // The cache is stale; it needs to be rebuilt. CDBoundsStageWriter cdataw = @@ -1590,8 +1590,9 @@ get_net_draw_control_mask() const { //////////////////////////////////////////////////////////////////// DrawMask PandaNode:: get_net_draw_show_mask() const { - int pipeline_stage = Thread::get_current_pipeline_stage(); - CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage); + Thread *current_thread = Thread::get_current_thread(); + int pipeline_stage = current_thread->get_pipeline_stage(); + CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage, current_thread); if (cdata->_last_update != cdata->_next_update) { // The cache is stale; it needs to be rebuilt. CDBoundsStageWriter cdataw = @@ -1662,8 +1663,9 @@ get_legal_collide_mask() const { //////////////////////////////////////////////////////////////////// CollideMask PandaNode:: get_net_collide_mask() const { - int pipeline_stage = Thread::get_current_pipeline_stage(); - CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage); + Thread *current_thread = Thread::get_current_thread(); + int pipeline_stage = current_thread->get_pipeline_stage(); + CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage, current_thread); if (cdata->_last_update != cdata->_next_update) { // The cache is stale; it needs to be rebuilt. CDBoundsStageWriter cdataw = @@ -1682,8 +1684,9 @@ get_net_collide_mask() const { //////////////////////////////////////////////////////////////////// CPT(RenderAttrib) PandaNode:: get_off_clip_planes() const { - int pipeline_stage = Thread::get_current_pipeline_stage(); - CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage); + Thread *current_thread = Thread::get_current_thread(); + int pipeline_stage = current_thread->get_pipeline_stage(); + CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage, current_thread); if (cdata->_last_update != cdata->_next_update) { // The cache is stale; it needs to be rebuilt. CDBoundsStageWriter cdataw = @@ -1803,8 +1806,9 @@ set_bound(const BoundingVolume *volume) { //////////////////////////////////////////////////////////////////// CPT(BoundingVolume) PandaNode:: get_bounds() const { - int pipeline_stage = Thread::get_current_pipeline_stage(); - CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage); + Thread *current_thread = Thread::get_current_thread(); + int pipeline_stage = current_thread->get_pipeline_stage(); + CDBoundsStageReader cdata(_cycler_bounds, pipeline_stage, current_thread); if (cdata->_last_update != cdata->_next_update) { // The cache is stale; it needs to be rebuilt. CPT(BoundingVolume) result; @@ -1837,10 +1841,9 @@ get_bounds() const { // when appropriate. //////////////////////////////////////////////////////////////////// void PandaNode:: -mark_bounds_stale() const { - Thread *current_thread = Thread::get_current_thread(); +mark_bounds_stale(Thread *current_thread) const { OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links, current_thread) { - mark_bounds_stale(pipeline_stage); + mark_bounds_stale(pipeline_stage, current_thread); } CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links); } @@ -1896,14 +1899,14 @@ as_light() { // including children. //////////////////////////////////////////////////////////////////// CPT(BoundingVolume) PandaNode:: -get_internal_bounds(int pipeline_stage) const { - CDHeavyStageReader cdata(_cycler_heavy, pipeline_stage); +get_internal_bounds(int pipeline_stage, Thread *current_thread) const { + CDHeavyStageReader cdata(_cycler_heavy, pipeline_stage, current_thread); if (cdata->_internal_bounds_stale) { CDHeavyStageWriter cdataw(((PandaNode *)this)->_cycler_heavy, pipeline_stage, cdata); if (cdataw->_user_bounds != (BoundingVolume *)NULL) { cdataw->_internal_bounds = cdataw->_user_bounds; } else { - cdataw->_internal_bounds = compute_internal_bounds(pipeline_stage); + cdataw->_internal_bounds = compute_internal_bounds(pipeline_stage, current_thread); } cdataw->_internal_bounds_stale = false; return cdataw->_internal_bounds; @@ -1929,7 +1932,7 @@ set_internal_bounds(const BoundingVolume *volume) { cdataw->_internal_bounds_stale = false; } CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler_heavy); - mark_bounds_stale(); + mark_bounds_stale(current_thread); } //////////////////////////////////////////////////////////////////// @@ -1944,10 +1947,9 @@ set_internal_bounds(const BoundingVolume *volume) { // stage. //////////////////////////////////////////////////////////////////// void PandaNode:: -force_bounds_stale() { - Thread *current_thread = Thread::get_current_thread(); +force_bounds_stale(Thread *current_thread) { OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links, current_thread) { - force_bounds_stale(pipeline_stage); + force_bounds_stale(pipeline_stage, current_thread); } CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links); } @@ -1960,9 +1962,9 @@ force_bounds_stale() { // was already considered stale. //////////////////////////////////////////////////////////////////// void PandaNode:: -force_bounds_stale(int pipeline_stage) { +force_bounds_stale(int pipeline_stage, Thread *current_thread) { { - CDBoundsStageWriter cdata(_cycler_bounds, pipeline_stage); + CDBoundsStageWriter cdata(_cycler_bounds, pipeline_stage, current_thread); ++cdata->_next_update; // It is important that we allow this lock to be dropped before we @@ -1973,11 +1975,15 @@ force_bounds_stale(int pipeline_stage) { // It is similarly important that we use get_parents() here to copy // the parents list, instead of keeping the lock open while we walk // through the parents list directly on the node. - Parents parents = get_parents(); + Parents parents; + { + CDLinksStageReader cdata(_cycler_links, pipeline_stage, current_thread); + parents = Parents(cdata); + } int num_parents = parents.get_num_parents(); for (int i = 0; i < num_parents; ++i) { PandaNode *parent = parents.get_parent(i); - parent->mark_bounds_stale(pipeline_stage); + parent->mark_bounds_stale(pipeline_stage, current_thread); } } @@ -1994,10 +2000,9 @@ force_bounds_stale(int pipeline_stage) { // stage. //////////////////////////////////////////////////////////////////// void PandaNode:: -mark_internal_bounds_stale() { - Thread *current_thread = Thread::get_current_thread(); +mark_internal_bounds_stale(Thread *current_thread) { OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links, current_thread) { - mark_internal_bounds_stale(pipeline_stage); + mark_internal_bounds_stale(pipeline_stage, current_thread); } CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(_cycler_links); } @@ -2011,7 +2016,7 @@ mark_internal_bounds_stale() { // something internally. //////////////////////////////////////////////////////////////////// PT(BoundingVolume) PandaNode:: -compute_internal_bounds(int pipeline_stage) const { +compute_internal_bounds(int pipeline_stage, Thread *current_thread) const { return new BoundingSphere; } @@ -2088,7 +2093,7 @@ draw_mask_changed() { // access this map. //////////////////////////////////////////////////////////////////// PT(PandaNode) PandaNode:: -r_copy_subgraph(PandaNode::InstanceMap &inst_map) const { +r_copy_subgraph(PandaNode::InstanceMap &inst_map, Thread *current_thread) const { PT(PandaNode) copy = make_copy(); nassertr(copy != (PandaNode *)NULL, NULL); if (copy->get_type() != get_type()) { @@ -2096,7 +2101,7 @@ r_copy_subgraph(PandaNode::InstanceMap &inst_map) const { << "Don't know how to copy nodes of type " << get_type() << "\n"; } - copy->r_copy_children(this, inst_map); + copy->r_copy_children(this, inst_map, current_thread); return copy; } @@ -2116,8 +2121,9 @@ r_copy_subgraph(PandaNode::InstanceMap &inst_map) const { // override this function. //////////////////////////////////////////////////////////////////// void PandaNode:: -r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map) { - CDLinksReader from_cdata(from->_cycler_links); +r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map, + Thread *current_thread) { + CDLinksReader from_cdata(from->_cycler_links, current_thread); const Down &from_down = *from_cdata->get_down(); Down::const_iterator di; for (di = from_down.begin(); di != from_down.end(); ++di) { @@ -2134,11 +2140,11 @@ r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map) { if (ci != inst_map.end()) { dest_child = (*ci).second; } else { - dest_child = source_child->r_copy_subgraph(inst_map); + dest_child = source_child->r_copy_subgraph(inst_map, current_thread); inst_map[source_child] = dest_child; } - add_child(dest_child, sort); + add_child(dest_child, sort, current_thread); } } @@ -2194,12 +2200,14 @@ do_find_stashed(PandaNode *node, const CDataLinks *cdata) const { // particular pipeline stage. //////////////////////////////////////////////////////////////////// bool PandaNode:: -stage_remove_child(PandaNode *child_node, int pipeline_stage) { - CDLinksStageWriter cdata(_cycler_links, pipeline_stage); +stage_remove_child(PandaNode *child_node, int pipeline_stage, + Thread *current_thread) { + CDLinksStageWriter cdata(_cycler_links, pipeline_stage, current_thread); // First, look for the parent in the child's up list, to ensure the // child is known. - CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage); + CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage, + current_thread); int parent_index = child_node->do_find_parent(this, cdata_child); if (parent_index < 0) { // Nope, no relation. @@ -2241,11 +2249,11 @@ stage_remove_child(PandaNode *child_node, int pipeline_stage) { //////////////////////////////////////////////////////////////////// bool PandaNode:: stage_replace_child(PandaNode *orig_child, PandaNode *new_child, - int pipeline_stage) { + int pipeline_stage, Thread *current_thread) { { - CDLinksStageWriter cdata(_cycler_links, pipeline_stage); - CDLinksStageWriter cdata_orig_child(orig_child->_cycler_links, pipeline_stage); - CDLinksStageWriter cdata_new_child(new_child->_cycler_links, pipeline_stage); + CDLinksStageWriter cdata(_cycler_links, pipeline_stage, current_thread); + CDLinksStageWriter cdata_orig_child(orig_child->_cycler_links, pipeline_stage, current_thread); + CDLinksStageWriter cdata_new_child(new_child->_cycler_links, pipeline_stage, current_thread); // First, look for the parent in the child's up list, to ensure the // child is known. @@ -2293,10 +2301,10 @@ stage_replace_child(PandaNode *orig_child, PandaNode *new_child, nassertr(num_erased == 1, false); } - sever_connection(this, orig_child, pipeline_stage); - new_connection(this, new_child, pipeline_stage); + sever_connection(this, orig_child, pipeline_stage, current_thread); + new_connection(this, new_child, pipeline_stage, current_thread); - force_bounds_stale(pipeline_stage); + force_bounds_stale(pipeline_stage, current_thread); orig_child->parents_changed(); new_child->parents_changed(); @@ -2316,13 +2324,13 @@ stage_replace_child(PandaNode *orig_child, PandaNode *new_child, //////////////////////////////////////////////////////////////////// PT(NodePathComponent) PandaNode:: attach(NodePathComponent *parent, PandaNode *child_node, int sort, - int pipeline_stage) { + int pipeline_stage, Thread *current_thread) { if (parent == (NodePathComponent *)NULL) { // Attaching to NULL means to create a new "instance" with no // attachments, and no questions asked. PT(NodePathComponent) child = new NodePathComponent(child_node, (NodePathComponent *)NULL, - pipeline_stage); + pipeline_stage, current_thread); MutexHolder holder(child_node->_paths_lock); child_node->_paths.insert(child); return child; @@ -2330,15 +2338,15 @@ attach(NodePathComponent *parent, PandaNode *child_node, int sort, // See if the child was already attached to the parent. If it was, // we'll use that same NodePathComponent. - PT(NodePathComponent) child = get_component(parent, child_node, pipeline_stage); + PT(NodePathComponent) child = get_component(parent, child_node, pipeline_stage, current_thread); if (child == (NodePathComponent *)NULL) { // The child was not already attached to the parent, so get a new // component. - child = get_top_component(child_node, true, pipeline_stage); + child = get_top_component(child_node, true, pipeline_stage, current_thread); } - reparent(parent, child, sort, false, pipeline_stage); + reparent(parent, child, sort, false, pipeline_stage, current_thread); return child; } @@ -2352,13 +2360,13 @@ attach(NodePathComponent *parent, PandaNode *child_node, int sort, // pipeline 0, from the specified pipeline stage. //////////////////////////////////////////////////////////////////// void PandaNode:: -detach(NodePathComponent *child, int pipeline_stage) { +detach(NodePathComponent *child, int pipeline_stage, Thread *current_thread) { nassertv(child != (NodePathComponent *)NULL); for (int pipeline_stage_i = pipeline_stage; pipeline_stage_i >= 0; --pipeline_stage_i) { - detach_one_stage(child, pipeline_stage_i); + detach_one_stage(child, pipeline_stage_i, current_thread); } child->get_node()->parents_changed(); @@ -2374,17 +2382,18 @@ detach(NodePathComponent *child, int pipeline_stage) { // stage only. //////////////////////////////////////////////////////////////////// void PandaNode:: -detach_one_stage(NodePathComponent *child, int pipeline_stage) { +detach_one_stage(NodePathComponent *child, int pipeline_stage, + Thread *current_thread) { nassertv(child != (NodePathComponent *)NULL); - if (child->is_top_node(pipeline_stage)) { + if (child->is_top_node(pipeline_stage, current_thread)) { return; } PT(PandaNode) child_node = child->get_node(); - PT(PandaNode) parent_node = child->get_next(pipeline_stage)->get_node(); + PT(PandaNode) parent_node = child->get_next(pipeline_stage, current_thread)->get_node(); - CDLinksStageWriter cdata_parent(parent_node->_cycler_links, pipeline_stage); - CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage); + CDLinksStageWriter cdata_parent(parent_node->_cycler_links, pipeline_stage, current_thread); + CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage, current_thread); int parent_index = child_node->do_find_parent(parent_node, cdata_child); if (parent_index >= 0) { // Now look for the child and break the actual connection. @@ -2417,9 +2426,9 @@ detach_one_stage(NodePathComponent *child, int pipeline_stage) { } // Finally, break the NodePathComponent connection. - sever_connection(parent_node, child_node, pipeline_stage); + sever_connection(parent_node, child_node, pipeline_stage, current_thread); - parent_node->force_bounds_stale(pipeline_stage); + parent_node->force_bounds_stale(pipeline_stage, current_thread); parent_node->children_changed(); } @@ -2437,14 +2446,14 @@ detach_one_stage(NodePathComponent *child, int pipeline_stage) { //////////////////////////////////////////////////////////////////// bool PandaNode:: reparent(NodePathComponent *new_parent, NodePathComponent *child, int sort, - bool as_stashed, int pipeline_stage) { + bool as_stashed, int pipeline_stage, Thread *current_thread) { bool any_ok = false; for (int pipeline_stage_i = pipeline_stage; pipeline_stage_i >= 0; --pipeline_stage_i) { if (reparent_one_stage(new_parent, child, sort, as_stashed, - pipeline_stage_i)) { + pipeline_stage_i, current_thread)) { any_ok = true; } } @@ -2472,15 +2481,16 @@ reparent(NodePathComponent *new_parent, NodePathComponent *child, int sort, //////////////////////////////////////////////////////////////////// bool PandaNode:: reparent_one_stage(NodePathComponent *new_parent, NodePathComponent *child, - int sort, bool as_stashed, int pipeline_stage) { + int sort, bool as_stashed, int pipeline_stage, + Thread *current_thread) { nassertr(child != (NodePathComponent *)NULL, false); // Keep a reference count to the new parent, since detaching the // child might lose the count. PT(NodePathComponent) keep_parent = new_parent; - if (!child->is_top_node(pipeline_stage)) { - detach(child, pipeline_stage); + if (!child->is_top_node(pipeline_stage, current_thread)) { + detach(child, pipeline_stage, current_thread); } if (new_parent != (NodePathComponent *)NULL) { @@ -2488,7 +2498,7 @@ reparent_one_stage(NodePathComponent *new_parent, NodePathComponent *child, PandaNode *parent_node = new_parent->get_node(); { - CDLinksStageReader cdata_child(child_node->_cycler_links, pipeline_stage); + CDLinksStageReader cdata_child(child_node->_cycler_links, pipeline_stage, current_thread); int parent_index = child_node->do_find_parent(parent_node, cdata_child); if (parent_index >= 0) { @@ -2498,12 +2508,12 @@ reparent_one_stage(NodePathComponent *new_parent, NodePathComponent *child, } // Redirect the connection to the indicated new parent. - child->set_next(new_parent, pipeline_stage); + child->set_next(new_parent, pipeline_stage, current_thread); // Now reattach the child node at the indicated sort position. { - CDLinksStageWriter cdata_parent(parent_node->_cycler_links, pipeline_stage); - CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage); + CDLinksStageWriter cdata_parent(parent_node->_cycler_links, pipeline_stage, current_thread); + CDLinksStageWriter cdata_child(child_node->_cycler_links, pipeline_stage, current_thread); if (as_stashed) { cdata_parent->modify_stashed()->insert(DownConnection(child_node, sort)); @@ -2521,8 +2531,8 @@ reparent_one_stage(NodePathComponent *new_parent, NodePathComponent *child, #endif // NDEBUG } - child_node->fix_path_lengths(pipeline_stage); - parent_node->force_bounds_stale(pipeline_stage); + child_node->fix_path_lengths(pipeline_stage, current_thread); + parent_node->force_bounds_stale(pipeline_stage, current_thread); } return true; @@ -2537,7 +2547,7 @@ reparent_one_stage(NodePathComponent *new_parent, NodePathComponent *child, //////////////////////////////////////////////////////////////////// PT(NodePathComponent) PandaNode:: get_component(NodePathComponent *parent, PandaNode *child_node, - int pipeline_stage) { + int pipeline_stage, Thread *current_thread) { nassertr(parent != (NodePathComponent *)NULL, (NodePathComponent *)NULL); PandaNode *parent_node = parent->get_node(); @@ -2548,7 +2558,7 @@ get_component(NodePathComponent *parent, PandaNode *child_node, // referencing the indicated parent component. Paths::const_iterator pi; for (pi = child_node->_paths.begin(); pi != child_node->_paths.end(); ++pi) { - if ((*pi)->get_next(pipeline_stage) == parent) { + if ((*pi)->get_next(pipeline_stage, current_thread) == parent) { // If we already have such a component, just return it. return (*pi); } @@ -2556,13 +2566,13 @@ get_component(NodePathComponent *parent, PandaNode *child_node, // We don't already have a NodePathComponent referring to this // parent-child relationship. Are they actually related? - CDLinksStageReader cdata_child(child_node->_cycler_links, pipeline_stage); + CDLinksStageReader cdata_child(child_node->_cycler_links, pipeline_stage, current_thread); int parent_index = child_node->do_find_parent(parent_node, cdata_child); if (parent_index >= 0) { // They are. Create and return a new one. PT(NodePathComponent) child = - new NodePathComponent(child_node, parent, pipeline_stage); + new NodePathComponent(child_node, parent, pipeline_stage, current_thread); child_node->_paths.insert(child); return child; } else { @@ -2586,14 +2596,15 @@ get_component(NodePathComponent *parent, PandaNode *child_node, // there is not already a top component available. //////////////////////////////////////////////////////////////////// PT(NodePathComponent) PandaNode:: -get_top_component(PandaNode *child_node, bool force, int pipeline_stage) { +get_top_component(PandaNode *child_node, bool force, int pipeline_stage, + Thread *current_thread) { MutexHolder holder(child_node->_paths_lock); // Walk through the list of NodePathComponents we already have on // the child, looking for one that already exists as a top node. Paths::const_iterator pi; for (pi = child_node->_paths.begin(); pi != child_node->_paths.end(); ++pi) { - if ((*pi)->is_top_node(pipeline_stage)) { + if ((*pi)->is_top_node(pipeline_stage, current_thread)) { // If we already have such a component, just return it. return (*pi); } @@ -2609,7 +2620,7 @@ get_top_component(PandaNode *child_node, bool force, int pipeline_stage) { // return a new one. PT(NodePathComponent) child = new NodePathComponent(child_node, (NodePathComponent *)NULL, - pipeline_stage); + pipeline_stage, current_thread); child_node->_paths.insert(child); return child; @@ -2627,11 +2638,12 @@ get_top_component(PandaNode *child_node, bool force, int pipeline_stage) { // path will be chosen arbitrarily. //////////////////////////////////////////////////////////////////// PT(NodePathComponent) PandaNode:: -get_generic_component(bool accept_ambiguity, int pipeline_stage) { +get_generic_component(bool accept_ambiguity, int pipeline_stage, + Thread *current_thread) { bool ambiguity_detected = false; PT(NodePathComponent) result = r_get_generic_component(accept_ambiguity, ambiguity_detected, - pipeline_stage); + pipeline_stage, current_thread); if (!accept_ambiguity && ambiguity_detected) { pgraph_cat.warning() @@ -2652,24 +2664,24 @@ get_generic_component(bool accept_ambiguity, int pipeline_stage) { //////////////////////////////////////////////////////////////////// PT(NodePathComponent) PandaNode:: r_get_generic_component(bool accept_ambiguity, bool &ambiguity_detected, - int pipeline_stage) { + int pipeline_stage, Thread *current_thread) { PT(PandaNode) parent_node; { - CDLinksStageReader cdata(_cycler_links, pipeline_stage); + CDLinksStageReader cdata(_cycler_links, pipeline_stage, current_thread); int num_parents = cdata->get_up()->size(); if (num_parents == 0) { // No parents; no ambiguity. This is the root. - return get_top_component(this, true, pipeline_stage); + return get_top_component(this, true, pipeline_stage, current_thread); } PT(NodePathComponent) result; if (num_parents == 1) { // Only one parent; no ambiguity. PT(NodePathComponent) parent = - get_parent(0)->r_get_generic_component(accept_ambiguity, ambiguity_detected, pipeline_stage); - return get_component(parent, this, pipeline_stage); + get_parent(0)->r_get_generic_component(accept_ambiguity, ambiguity_detected, pipeline_stage, current_thread); + return get_component(parent, this, pipeline_stage, current_thread); } // Oops, multiple parents; the NodePath is ambiguous. @@ -2685,8 +2697,8 @@ r_get_generic_component(bool accept_ambiguity, bool &ambiguity_detected, // Now that the lock is released, it's safe to recurse. PT(NodePathComponent) parent = - parent_node->r_get_generic_component(accept_ambiguity, ambiguity_detected, pipeline_stage); - return get_component(parent, this, pipeline_stage); + parent_node->r_get_generic_component(accept_ambiguity, ambiguity_detected, pipeline_stage, current_thread); + return get_component(parent, this, pipeline_stage, current_thread); } //////////////////////////////////////////////////////////////////// @@ -2723,19 +2735,19 @@ delete_component(NodePathComponent *component) { //////////////////////////////////////////////////////////////////// void PandaNode:: sever_connection(PandaNode *parent_node, PandaNode *child_node, - int pipeline_stage) { + int pipeline_stage, Thread *current_thread) { { MutexHolder holder(child_node->_paths_lock); Paths::iterator pi; for (pi = child_node->_paths.begin(); pi != child_node->_paths.end(); ++pi) { - if (!(*pi)->is_top_node(pipeline_stage) && - (*pi)->get_next(pipeline_stage)->get_node() == parent_node) { + if (!(*pi)->is_top_node(pipeline_stage, current_thread) && + (*pi)->get_next(pipeline_stage, current_thread)->get_node() == parent_node) { // Sever the component here. - (*pi)->set_top_node(pipeline_stage); + (*pi)->set_top_node(pipeline_stage, current_thread); } } } - child_node->fix_path_lengths(pipeline_stage); + child_node->fix_path_lengths(pipeline_stage, current_thread); } //////////////////////////////////////////////////////////////////// @@ -2756,17 +2768,17 @@ sever_connection(PandaNode *parent_node, PandaNode *child_node, //////////////////////////////////////////////////////////////////// void PandaNode:: new_connection(PandaNode *parent_node, PandaNode *child_node, - int pipeline_stage) { + int pipeline_stage, Thread *current_thread) { { MutexHolder holder(child_node->_paths_lock); Paths::iterator pi; for (pi = child_node->_paths.begin(); pi != child_node->_paths.end(); ++pi) { - if ((*pi)->is_top_node(pipeline_stage)) { - (*pi)->set_next(parent_node->get_generic_component(false, pipeline_stage), pipeline_stage); + if ((*pi)->is_top_node(pipeline_stage, current_thread)) { + (*pi)->set_next(parent_node->get_generic_component(false, pipeline_stage, current_thread), pipeline_stage, current_thread); } } } - child_node->fix_path_lengths(pipeline_stage); + child_node->fix_path_lengths(pipeline_stage, current_thread); } //////////////////////////////////////////////////////////////////// @@ -2782,14 +2794,14 @@ new_connection(PandaNode *parent_node, PandaNode *child_node, // stage only. //////////////////////////////////////////////////////////////////// void PandaNode:: -fix_path_lengths(int pipeline_stage) { +fix_path_lengths(int pipeline_stage, Thread *current_thread) { MutexHolder holder(_paths_lock); bool any_wrong = false; Paths::const_iterator pi; for (pi = _paths.begin(); pi != _paths.end(); ++pi) { - if ((*pi)->fix_length(pipeline_stage)) { + if ((*pi)->fix_length(pipeline_stage, current_thread)) { any_wrong = true; } } @@ -2798,19 +2810,24 @@ fix_path_lengths(int pipeline_stage) { // children, since any one of those paths might be shared by any of // our child nodes. Don't hold any locks while we recurse. if (any_wrong) { - Children children = get_children(); - Stashed stashed = get_stashed(); + Children children; + Stashed stashed; + { + CDLinksStageReader cdata(_cycler_links, pipeline_stage, current_thread); + children = Children(cdata); + stashed = Stashed(cdata); + } int num_children = children.get_num_children(); int i; for (i = 0; i < num_children; ++i) { PandaNode *child_node = children.get_child(i); - child_node->fix_path_lengths(pipeline_stage); + child_node->fix_path_lengths(pipeline_stage, current_thread); } int num_stashed = stashed.get_num_stashed(); for (i = 0; i < num_stashed; ++i) { PandaNode *child_node = stashed.get_stashed(i); - child_node->fix_path_lengths(pipeline_stage); + child_node->fix_path_lengths(pipeline_stage, current_thread); } } } @@ -2858,6 +2875,8 @@ update_bounds(int pipeline_stage, PandaNode::CDBoundsStageReader &cdata) { drawmask_cat.debug(false) << *this << "::update_bounds() {\n"; } + Thread *current_thread = cdata.get_current_thread(); + do { // Grab the last_update counter, then release the lock. UpdateSeq last_update = cdata->_last_update; @@ -2872,7 +2891,7 @@ update_bounds(int pipeline_stage, PandaNode::CDBoundsStageReader &cdata) { DrawMask draw_control_mask, draw_show_mask; bool renderable = is_renderable(); { - CDHeavyStageReader cdata(_cycler_heavy, pipeline_stage); + CDHeavyStageReader cdata(_cycler_heavy, pipeline_stage, current_thread); net_collide_mask = cdata->_into_collide_mask; draw_control_mask = net_draw_control_mask = cdata->_draw_control_mask; draw_show_mask = net_draw_show_mask = cdata->_draw_show_mask; @@ -2897,7 +2916,7 @@ update_bounds(int pipeline_stage, PandaNode::CDBoundsStageReader &cdata) { } CPT(RenderAttrib) off_clip_planes; { - CDLightStageReader cdata(_cycler_light, pipeline_stage); + CDLightStageReader cdata(_cycler_light, pipeline_stage, current_thread); off_clip_planes = cdata->_state->get_clip_plane(); } if (off_clip_planes == (RenderAttrib *)NULL) { @@ -2912,7 +2931,8 @@ update_bounds(int pipeline_stage, PandaNode::CDBoundsStageReader &cdata) { pvector child_volumes_ref; pvector child_volumes; - CPT(BoundingVolume) internal_bounds = get_internal_bounds(pipeline_stage); + CPT(BoundingVolume) internal_bounds = + get_internal_bounds(pipeline_stage, current_thread); child_volumes_ref.push_back(internal_bounds); child_volumes.push_back(internal_bounds); @@ -2925,7 +2945,7 @@ update_bounds(int pipeline_stage, PandaNode::CDBoundsStageReader &cdata) { const ClipPlaneAttrib *orig_cp = DCAST(ClipPlaneAttrib, off_clip_planes); - CDBoundsStageReader child_cdata(child->_cycler_bounds, pipeline_stage); + CDBoundsStageReader child_cdata(child->_cycler_bounds, pipeline_stage, current_thread); if (child_cdata->_last_update != child_cdata->_next_update) { // Child needs update. CDBoundsStageWriter child_cdataw = child->update_bounds(pipeline_stage, child_cdata); @@ -3008,7 +3028,7 @@ update_bounds(int pipeline_stage, PandaNode::CDBoundsStageReader &cdata) { { // Now grab the write lock on this node. - CDBoundsStageWriter cdataw(_cycler_bounds, pipeline_stage); + CDBoundsStageWriter cdataw(_cycler_bounds, pipeline_stage, current_thread); if (last_update == cdataw->_last_update && next_update == cdataw->_next_update) { // Great, no one has monkeyed with these while we were computing @@ -3069,7 +3089,7 @@ update_bounds(int pipeline_stage, PandaNode::CDBoundsStageReader &cdata) { // We need to go around again. Release the write lock, and grab // the read lock back. - cdata = CDBoundsStageReader(_cycler_bounds, pipeline_stage); + cdata = CDBoundsStageReader(_cycler_bounds, pipeline_stage, current_thread); if (cdata->_last_update == cdata->_next_update) { // Someone else has computed the cache for us while we were diff --git a/panda/src/pgraph/pandaNode.h b/panda/src/pgraph/pandaNode.h index 57f6f4d2ba..6d5c15b190 100644 --- a/panda/src/pgraph/pandaNode.h +++ b/panda/src/pgraph/pandaNode.h @@ -98,7 +98,8 @@ public: virtual CPT(TransformState) calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, - const TransformState *transform) const; + const TransformState *transform, + Thread *current_thread) const; virtual bool has_cull_callback() const; virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data); @@ -111,41 +112,48 @@ public: INLINE void compose_draw_mask(DrawMask &running_draw_mask) const; INLINE bool compare_draw_mask(DrawMask running_draw_mask, - DrawMask camera_mask) const; + DrawMask camera_mask, + Thread *current_thread) const; PUBLISHED: - PT(PandaNode) copy_subgraph() const; + PT(PandaNode) copy_subgraph(Thread *current_thread = Thread::get_current_thread()) const; - INLINE int get_num_parents() const; - INLINE PandaNode *get_parent(int n) const; - INLINE int find_parent(PandaNode *node) const; + INLINE int get_num_parents(Thread *current_thread = Thread::get_current_thread()) const; + INLINE PandaNode *get_parent(int n, Thread *current_thread = Thread::get_current_thread()) const; + INLINE int find_parent(PandaNode *node, Thread *current_thread = Thread::get_current_thread()) const; - INLINE int get_num_children() const; - INLINE PandaNode *get_child(int n) const; - INLINE int get_child_sort(int n) const; - INLINE int find_child(PandaNode *node) const; + INLINE int get_num_children(Thread *current_thread = Thread::get_current_thread()) const; + INLINE PandaNode *get_child(int n, Thread *current_thread = Thread::get_current_thread()) const; + INLINE int get_child_sort(int n, Thread *current_thread = Thread::get_current_thread()) const; + INLINE int find_child(PandaNode *node, Thread *current_thread = Thread::get_current_thread()) const; - void add_child(PandaNode *child_node, int sort = 0); - void remove_child(int child_index); - bool remove_child(PandaNode *child_node); - bool replace_child(PandaNode *orig_child, PandaNode *new_child); + void add_child(PandaNode *child_node, int sort = 0, + Thread *current_thread = Thread::get_current_thread()); + void remove_child(int child_index, Thread *current_thread = Thread::get_current_thread()); + bool remove_child(PandaNode *child_node, Thread *current_thread = Thread::get_current_thread()); + bool replace_child(PandaNode *orig_child, PandaNode *new_child, + Thread *current_thread = Thread::get_current_thread()); - INLINE bool stash_child(PandaNode *child_node); - void stash_child(int child_index); - INLINE bool unstash_child(PandaNode *child_node); - void unstash_child(int stashed_index); + INLINE bool stash_child(PandaNode *child_node, + Thread *current_thread = Thread::get_current_thread()); + void stash_child(int child_index, + Thread *current_thread = Thread::get_current_thread()); + INLINE bool unstash_child(PandaNode *child_node, + Thread *current_thread = Thread::get_current_thread()); + void unstash_child(int stashed_index, + Thread *current_thread = Thread::get_current_thread()); - INLINE int get_num_stashed() const; - INLINE PandaNode *get_stashed(int n) const; - INLINE int get_stashed_sort(int n) const; - INLINE int find_stashed(PandaNode *node) const; + INLINE int get_num_stashed(Thread *current_thread = Thread::get_current_thread()) const; + INLINE PandaNode *get_stashed(int n, Thread *current_thread = Thread::get_current_thread()) const; + INLINE int get_stashed_sort(int n, Thread *current_thread = Thread::get_current_thread()) const; + INLINE int find_stashed(PandaNode *node, Thread *current_thread = Thread::get_current_thread()) const; - void add_stashed(PandaNode *child_node, int sort = 0); - void remove_stashed(int child_index); + void add_stashed(PandaNode *child_node, int sort = 0, Thread *current_thread = Thread::get_current_thread()); + void remove_stashed(int child_index, Thread *current_thread = Thread::get_current_thread()); - void remove_all_children(); - void steal_children(PandaNode *other); - void copy_children(PandaNode *other); + void remove_all_children(Thread *current_thread = Thread::get_current_thread()); + void steal_children(PandaNode *other, Thread *current_thread = Thread::get_current_thread()); + void copy_children(PandaNode *other, Thread *current_thread = Thread::get_current_thread()); void set_attrib(const RenderAttrib *attrib, int override = 0); INLINE const RenderAttrib *get_attrib(TypeHandle type) const; @@ -157,23 +165,23 @@ PUBLISHED: INLINE bool has_effect(TypeHandle type) const; void clear_effect(TypeHandle type); - void set_state(const RenderState *state); - INLINE const RenderState *get_state() const; - INLINE void clear_state(); + void set_state(const RenderState *state, Thread *current_thread = Thread::get_current_thread()); + INLINE const RenderState *get_state(Thread *current_thread = Thread::get_current_thread()) const; + INLINE void clear_state(Thread *current_thread = Thread::get_current_thread()); void set_effects(const RenderEffects *effects); INLINE const RenderEffects *get_effects() const; INLINE void clear_effects(); - void set_transform(const TransformState *transform); - INLINE const TransformState *get_transform() const; - INLINE void clear_transform(); + void set_transform(const TransformState *transform, Thread *current_thread = Thread::get_current_thread()); + INLINE const TransformState *get_transform(Thread *current_thread = Thread::get_current_thread()) const; + INLINE void clear_transform(Thread *current_thread = Thread::get_current_thread()); - void set_prev_transform(const TransformState *transform); - INLINE const TransformState *get_prev_transform() const; - void reset_prev_transform(); + void set_prev_transform(const TransformState *transform, Thread *current_thread = Thread::get_current_thread()); + INLINE const TransformState *get_prev_transform(Thread *current_thread = Thread::get_current_thread()) const; + void reset_prev_transform(Thread *current_thread = Thread::get_current_thread()); INLINE bool has_dirty_prev_transform() const; - static void reset_all_prev_transform(); + static void reset_all_prev_transform(Thread *current_thread = Thread::get_current_thread()); void set_tag(const string &key, const string &value); INLINE string get_tag(const string &key) const; @@ -233,7 +241,7 @@ PUBLISHED: CPT(BoundingVolume) get_bounds() const; INLINE CPT(BoundingVolume) get_internal_bounds() const; - void mark_bounds_stale() const; + void mark_bounds_stale(Thread *current_thread = Thread::get_current_thread()) const; INLINE void set_final(bool flag); INLINE bool is_final() const; @@ -243,17 +251,17 @@ PUBLISHED: virtual Light *as_light(); protected: - INLINE CPT(BoundingVolume) get_user_bounds(int pipeline_stage) const; - CPT(BoundingVolume) get_internal_bounds(int pipeline_stage) const; + INLINE CPT(BoundingVolume) get_user_bounds(int pipeline_stage, Thread *current_thread) const; + CPT(BoundingVolume) get_internal_bounds(int pipeline_stage, Thread *current_thread) const; void set_internal_bounds(const BoundingVolume *volume); - INLINE void mark_bounds_stale(int pipeline_stage) const; - void force_bounds_stale(); - void force_bounds_stale(int pipeline_stage); - void mark_internal_bounds_stale(); - INLINE void mark_internal_bounds_stale(int pipeline_stage); + INLINE void mark_bounds_stale(int pipeline_stage, Thread *current_thread) const; + void force_bounds_stale(Thread *current_thread = Thread::get_current_thread()); + void force_bounds_stale(int pipeline_stage, Thread *current_thread); + void mark_internal_bounds_stale(Thread *current_thread = Thread::get_current_thread()); + INLINE void mark_internal_bounds_stale(int pipeline_stage, Thread *current_thread); - virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const; + virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage, Thread *current_thread) const; virtual void parents_changed(); virtual void children_changed(); virtual void transform_changed(); @@ -261,8 +269,10 @@ protected: virtual void draw_mask_changed(); typedef pmap InstanceMap; - virtual PT(PandaNode) r_copy_subgraph(InstanceMap &inst_map) const; - virtual void r_copy_children(const PandaNode *from, InstanceMap &inst_map); + virtual PT(PandaNode) r_copy_subgraph(InstanceMap &inst_map, + Thread *current_thread) const; + virtual void r_copy_children(const PandaNode *from, InstanceMap &inst_map, + Thread *current_thread); private: class CDataLight; @@ -273,39 +283,40 @@ private: INLINE int do_find_parent(PandaNode *node, const CDataLinks *cdata) const; int do_find_child(PandaNode *node, const CDataLinks *cdata) const; int do_find_stashed(PandaNode *node, const CDataLinks *cdata) const; - bool stage_remove_child(PandaNode *child_node, int pipeline_stage); + bool stage_remove_child(PandaNode *child_node, int pipeline_stage, + Thread *current_thread); bool stage_replace_child(PandaNode *orig_child, PandaNode *new_child, - int pipeline_stage); + int pipeline_stage, Thread *current_thread); // parent-child manipulation for NodePath support. Don't try to // call these directly. static PT(NodePathComponent) attach(NodePathComponent *parent, PandaNode *child, int sort, - int pipeline_stage); - static void detach(NodePathComponent *child, int pipeline_stage); - static void detach_one_stage(NodePathComponent *child, int pipeline_stage); + int pipeline_stage, Thread *current_thread); + static void detach(NodePathComponent *child, int pipeline_stage, Thread *current_thread); + static void detach_one_stage(NodePathComponent *child, int pipeline_stage, Thread *current_thread); static bool reparent(NodePathComponent *new_parent, NodePathComponent *child, int sort, bool as_stashed, - int pipeline_stage); + int pipeline_stage, Thread *current_thread); static bool reparent_one_stage(NodePathComponent *new_parent, NodePathComponent *child, int sort, - bool as_stashed, int pipeline_stage); + bool as_stashed, int pipeline_stage, Thread *current_thread); static PT(NodePathComponent) get_component(NodePathComponent *parent, PandaNode *child, - int pipeline_stage); + int pipeline_stage, Thread *current_thread); static PT(NodePathComponent) get_top_component(PandaNode *child, bool force, - int pipeline_stage); + int pipeline_stage, Thread *current_thread); PT(NodePathComponent) get_generic_component(bool accept_ambiguity, - int pipeline_stage); + int pipeline_stage, Thread *current_thread); PT(NodePathComponent) r_get_generic_component(bool accept_ambiguity, bool &ambiguity_detected, - int pipeline_stage); + int pipeline_stage, Thread *current_thread); void delete_component(NodePathComponent *component); static void sever_connection(PandaNode *parent_node, PandaNode *child_node, - int pipeline_stage); + int pipeline_stage, Thread *current_thread); static void new_connection(PandaNode *parent_node, PandaNode *child_node, - int pipeline_stage); - void fix_path_lengths(int pipeline_stage); + int pipeline_stage, Thread *current_thread); + void fix_path_lengths(int pipeline_stage, Thread *current_thread); void r_list_descendants(ostream &out, int indent_level) const; INLINE void set_dirty_prev_transform(); @@ -561,8 +572,8 @@ private: typedef CycleDataStageReader CDLinksStageReader; typedef CycleDataStageWriter CDLinksStageWriter; - CDBoundsStageWriter update_bounds(int pipeline_stage, - CDBoundsStageReader &cdata); + CDBoundsStageWriter update_bounds(int pipeline_stage, + CDBoundsStageReader &cdata); static DrawMask _overall_bit; @@ -578,12 +589,14 @@ public: // pass. class EXPCL_PANDA Children { public: - INLINE Children(const CDLinksReader &cdata); + INLINE Children(); + INLINE Children(const CDataLinks *cdata); INLINE Children(const Children ©); INLINE void operator = (const Children ©); INLINE int get_num_children() const; INLINE PandaNode *get_child(int n) const; + INLINE int get_child_sort(int n) const; private: CPT(Down) _down; @@ -592,12 +605,14 @@ public: // Similarly for stashed children. class EXPCL_PANDA Stashed { public: - INLINE Stashed(const CDLinksReader &cdata); + INLINE Stashed(); + INLINE Stashed(const CDataLinks *cdata); INLINE Stashed(const Stashed ©); INLINE void operator = (const Stashed ©); INLINE int get_num_stashed() const; INLINE PandaNode *get_stashed(int n) const; + INLINE int get_stashed_sort(int n) const; private: CPT(Down) _stashed; @@ -606,7 +621,8 @@ public: // This class is returned from get_parents(). class EXPCL_PANDA Parents { public: - INLINE Parents(const CDLinksReader &cdata); + INLINE Parents(); + INLINE Parents(const CDataLinks *cdata); INLINE Parents(const Parents ©); INLINE void operator = (const Parents ©); diff --git a/panda/src/pgraph/planeNode.cxx b/panda/src/pgraph/planeNode.cxx index ac90160e39..e5a81e5361 100644 --- a/panda/src/pgraph/planeNode.cxx +++ b/panda/src/pgraph/planeNode.cxx @@ -209,8 +209,8 @@ is_renderable() const { // something internally. //////////////////////////////////////////////////////////////////// PT(BoundingVolume) PlaneNode:: -compute_internal_bounds(int pipeline_stage) const { - CDStageReader cdata(_cycler, pipeline_stage); +compute_internal_bounds(int pipeline_stage, Thread *current_thread) const { + CDStageReader cdata(_cycler, pipeline_stage, current_thread); return new BoundingPlane(cdata->_plane); } diff --git a/panda/src/pgraph/planeNode.h b/panda/src/pgraph/planeNode.h index b6661d83cf..0cdee825e1 100644 --- a/panda/src/pgraph/planeNode.h +++ b/panda/src/pgraph/planeNode.h @@ -69,7 +69,7 @@ public: INLINE static UpdateSeq get_sort_seq(); protected: - virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const; + virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage, Thread *current_thread) const; PT(Geom) get_viz(CullTraverser *trav, CullTraverserData &data); private: diff --git a/panda/src/pgraph/portalNode.cxx b/panda/src/pgraph/portalNode.cxx index 4a6141975f..1bffe6ef56 100755 --- a/panda/src/pgraph/portalNode.cxx +++ b/panda/src/pgraph/portalNode.cxx @@ -389,9 +389,9 @@ draw() const { // thing. //////////////////////////////////////////////////////////////////// PT(BoundingVolume) PortalNode:: -compute_internal_bounds(int pipeline_stage) const { +compute_internal_bounds(int pipeline_stage, Thread *current_thread) const { // First, get ourselves a fresh, empty bounding volume. - PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage); + PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage, current_thread); nassertr(bound != (BoundingVolume *)NULL, bound); GeometricBoundingVolume *gbv = DCAST(GeometricBoundingVolume, bound); diff --git a/panda/src/pgraph/portalNode.h b/panda/src/pgraph/portalNode.h index 26e5be5799..e94b6aaf85 100755 --- a/panda/src/pgraph/portalNode.h +++ b/panda/src/pgraph/portalNode.h @@ -98,7 +98,7 @@ PUBLISHED: // void draw () const; protected: - virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const; + virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage, Thread *current_thread) const; private: CPT(RenderState) get_last_pos_state(); diff --git a/panda/src/pgraph/workingNodePath.cxx b/panda/src/pgraph/workingNodePath.cxx index 618cafc6dc..42ed7366af 100644 --- a/panda/src/pgraph/workingNodePath.cxx +++ b/panda/src/pgraph/workingNodePath.cxx @@ -50,8 +50,9 @@ is_valid() const { int WorkingNodePath:: get_num_nodes() const { if (_next == (WorkingNodePath *)NULL) { - int pipeline_stage = Thread::get_current_pipeline_stage(); - return _start->get_length(pipeline_stage); + Thread *current_thread = Thread::get_current_thread(); + int pipeline_stage = current_thread->get_pipeline_stage(); + return _start->get_length(pipeline_stage, current_thread); } return _next->get_num_nodes() + 1; @@ -111,15 +112,16 @@ r_get_node_path() const { PT(NodePathComponent) comp = _next->r_get_node_path(); nassertr(comp != (NodePathComponent *)NULL, NULL); - int pipeline_stage = Thread::get_current_pipeline_stage(); - PT(NodePathComponent) result = PandaNode::get_component(comp, _node, - pipeline_stage); + Thread *current_thread = Thread::get_current_thread(); + int pipeline_stage = current_thread->get_pipeline_stage(); + PT(NodePathComponent) result = + PandaNode::get_component(comp, _node, pipeline_stage, current_thread); if (result == (NodePathComponent *)NULL) { // This means we found a disconnected chain in the // WorkingNodePath's ancestry: the node above this node isn't // connected. In this case, don't attempt to go higher; just // truncate the NodePath at the bottom of the disconnect. - return PandaNode::get_top_component(_node, true, pipeline_stage); + return PandaNode::get_top_component(_node, true, pipeline_stage, current_thread); } return result; diff --git a/panda/src/pgui/pgItem.cxx b/panda/src/pgui/pgItem.cxx index 42386c4c25..27ad5dbcfd 100644 --- a/panda/src/pgui/pgItem.cxx +++ b/panda/src/pgui/pgItem.cxx @@ -277,9 +277,9 @@ is_renderable() const { // thing. //////////////////////////////////////////////////////////////////// PT(BoundingVolume) PGItem:: -compute_internal_bounds(int pipeline_stage) const { +compute_internal_bounds(int pipeline_stage, Thread *current_thread) const { // First, get ourselves a fresh, empty bounding volume. - PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage); + PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage, current_thread); nassertr(bound != (BoundingVolume *)NULL, bound); // Now actually compute the bounding volume by putting it around all diff --git a/panda/src/pgui/pgItem.h b/panda/src/pgui/pgItem.h index 0507399ee3..cc34b6a38d 100644 --- a/panda/src/pgui/pgItem.h +++ b/panda/src/pgui/pgItem.h @@ -69,7 +69,7 @@ protected: virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data); virtual bool is_renderable() const; - virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const; + virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage, Thread *current_thread) const; public: virtual void xform(const LMatrix4f &mat); diff --git a/panda/src/pgui/pgVirtualFrame.cxx b/panda/src/pgui/pgVirtualFrame.cxx index 6ea8914fab..0ba2d76530 100644 --- a/panda/src/pgui/pgVirtualFrame.cxx +++ b/panda/src/pgui/pgVirtualFrame.cxx @@ -96,8 +96,9 @@ make_copy() const { // override this function. //////////////////////////////////////////////////////////////////// void PGVirtualFrame:: -r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map) { - PandaNode::r_copy_children(from, inst_map); +r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map, + Thread *current_thread) { + PandaNode::r_copy_children(from, inst_map, current_thread); // Reassign the canvas_node to point to the new copy, if it's there. const PGVirtualFrame *from_frame = DCAST(PGVirtualFrame, from); diff --git a/panda/src/pgui/pgVirtualFrame.h b/panda/src/pgui/pgVirtualFrame.h index fc2c860067..d3c2a433f7 100644 --- a/panda/src/pgui/pgVirtualFrame.h +++ b/panda/src/pgui/pgVirtualFrame.h @@ -59,7 +59,8 @@ PUBLISHED: protected: PGVirtualFrame(const PGVirtualFrame ©); virtual PandaNode *make_copy() const; - virtual void r_copy_children(const PandaNode *from, InstanceMap &inst_map); + virtual void r_copy_children(const PandaNode *from, InstanceMap &inst_map, + Thread *current_thread); PUBLISHED: void setup(float width, float height); diff --git a/panda/src/pstatclient/pStatClient.I b/panda/src/pstatclient/pStatClient.I index 33f580b44d..7b1cd7dc80 100644 --- a/panda/src/pstatclient/pStatClient.I +++ b/panda/src/pstatclient/pStatClient.I @@ -146,17 +146,17 @@ get_thread_object(int index) const { } //////////////////////////////////////////////////////////////////// -// Function: PStatClient::get_clock +// Function: PStatClient::get_real_time // Access: Published -// Description: Returns a reference to the PStatClient's clock -// object. It keeps its own clock, instead of using the -// global clock object, so the stats won't get mucked up -// if you put the global clock in non-real-time mode or -// something. +// Description: Returns the time according to to the PStatClient's +// clock object. It keeps its own clock, instead of +// using the global clock object, so the stats won't get +// mucked up if you put the global clock in +// non-real-time mode or something. //////////////////////////////////////////////////////////////////// -INLINE const ClockObject &PStatClient:: -get_clock() const { - return get_impl()->get_clock(); +INLINE double PStatClient:: +get_real_time() const { + return get_impl()->get_real_time(); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pstatclient/pStatClient.cxx b/panda/src/pstatclient/pStatClient.cxx index abed78c749..d74e845e57 100644 --- a/panda/src/pstatclient/pStatClient.cxx +++ b/panda/src/pstatclient/pStatClient.cxx @@ -58,8 +58,8 @@ PerThreadData() { //////////////////////////////////////////////////////////////////// PStatClient:: PStatClient() : - _impl(NULL), - _lock("PStatClient") + _lock("PStatClient"), + _impl(NULL) { _collectors = NULL; _collectors_size = 0; @@ -164,6 +164,7 @@ get_main_thread() const { return PStatThread((PStatClient *)this, 0); } + //////////////////////////////////////////////////////////////////// // Function: PStatClient::get_current_thread // Access: Published @@ -173,15 +174,12 @@ get_main_thread() const { //////////////////////////////////////////////////////////////////// PStatThread PStatClient:: get_current_thread() const { - Thread *thread = Thread::get_current_thread(); - int thread_index = thread->get_pstats_index(); - if (thread_index != -1) { - return PStatThread((PStatClient *)this, thread_index); + if (!client_is_connected()) { + // No need to make the relatively expensive call to + // Thread::get_current_thread() if we're not even connected. + return get_main_thread(); } - - // This is the first time we have encountered this current Thread. - // Make a new PStatThread object for it. - return ((PStatClient *)this)->make_thread(thread); + return PStatThread(Thread::get_current_thread(), (PStatClient *)this); } //////////////////////////////////////////////////////////////////// @@ -499,7 +497,7 @@ do_make_thread(Thread *thread) { for (int ci = 0; ci < _num_collectors; ++ci) { Collector *collector = collectors[ci]; collector->_per_thread.push_back(PerThreadData()); - nassertr(collector->_per_thread.size() == _num_threads, PStatThread()); + nassertr((int)collector->_per_thread.size() == _num_threads, PStatThread()); } return PStatThread(this, new_index); @@ -578,8 +576,7 @@ start(int collector_index, int thread_index) { if (collector->_per_thread[thread_index]._nested_count == 0) { // This collector wasn't already started in this thread; record // a new data point. - thread->_frame_data.add_start(collector_index, - get_clock().get_real_time()); + thread->_frame_data.add_start(collector_index, get_real_time()); } collector->_per_thread[thread_index]._nested_count++; } @@ -647,8 +644,7 @@ stop(int collector_index, int thread_index) { if (collector->_per_thread[thread_index]._nested_count == 0) { // This collector has now been completely stopped; record a new // data point. - thread->_frame_data.add_stop(collector_index, - get_clock().get_real_time()); + thread->_frame_data.add_stop(collector_index, get_real_time()); } } } @@ -904,8 +900,8 @@ InternalThread(Thread *thread) : _name(thread->get_name()), _sync_name(thread->get_sync_name()), _is_active(false), - _next_packet(0.0), _frame_number(0), + _next_packet(0.0), _thread_lock(string("PStatClient::InternalThread ") + thread->get_name()) { } diff --git a/panda/src/pstatclient/pStatClient.h b/panda/src/pstatclient/pStatClient.h index 46eeebe29b..91549f9115 100644 --- a/panda/src/pstatclient/pStatClient.h +++ b/panda/src/pstatclient/pStatClient.h @@ -83,7 +83,7 @@ PUBLISHED: PStatThread get_main_thread() const; PStatThread get_current_thread() const; - INLINE const ClockObject &get_clock() const; + INLINE double get_real_time() const; INLINE static bool connect(const string &hostname = string(), int port = -1); INLINE static void disconnect(); diff --git a/panda/src/pstatclient/pStatClientImpl.I b/panda/src/pstatclient/pStatClientImpl.I index 4fe0905780..9419d915c4 100644 --- a/panda/src/pstatclient/pStatClientImpl.I +++ b/panda/src/pstatclient/pStatClientImpl.I @@ -72,17 +72,17 @@ get_max_rate() const { } //////////////////////////////////////////////////////////////////// -// Function: PStatClientImpl::get_clock +// Function: PStatClientImpl::get_real_time // Access: Public -// Description: Returns a reference to the PStatClientImpl's clock -// object. It keeps its own clock, instead of using the -// global clock object, so the stats won't get mucked up -// if you put the global clock in non-real-time mode or -// something. +// Description: Returns the time according to the PStatClientImpl's +// clock object. It keeps its own clock, instead of +// using the global clock object, so the stats won't get +// mucked up if you put the global clock in +// non-real-time mode or something. //////////////////////////////////////////////////////////////////// -INLINE const ClockObject &PStatClientImpl:: -get_clock() const { - return _clock; +INLINE double PStatClientImpl:: +get_real_time() const { + return _clock->get_short_time() + _delta; } //////////////////////////////////////////////////////////////////// @@ -92,7 +92,7 @@ get_clock() const { //////////////////////////////////////////////////////////////////// INLINE void PStatClientImpl:: client_main_tick() { - _clock.tick(); + _last_frame = _clock->get_short_time(); } //////////////////////////////////////////////////////////////////// @@ -115,7 +115,6 @@ client_resume_after_pause() { // Simply reset the clock to the beginning of the last frame. This // may lose a frame, but on the other hand we won't skip a whole // slew of frames either. - - double frame_time = _clock.get_frame_time(); - _clock.set_real_time(frame_time); + double delta = _clock->get_short_time() - _last_frame; + _delta -= delta; } diff --git a/panda/src/pstatclient/pStatClientImpl.cxx b/panda/src/pstatclient/pStatClientImpl.cxx index 376207ec3b..b8aedcc80f 100644 --- a/panda/src/pstatclient/pStatClientImpl.cxx +++ b/panda/src/pstatclient/pStatClientImpl.cxx @@ -43,6 +43,8 @@ //////////////////////////////////////////////////////////////////// PStatClientImpl:: PStatClientImpl(PStatClient *client) : + _clock(TrueClock::get_global_ptr()), + _delta(0.0), _client(client), _reader(this, 0), _writer(this, pstats_threaded_write ? 1 : 0) @@ -54,9 +56,6 @@ PStatClientImpl(PStatClient *client) : _collectors_reported = 0; _threads_reported = 0; - // Make sure our clock is in "normal" mode. - _clock.set_mode(ClockObject::M_normal); - _client_name = pstats_name; _max_rate = pstats_max_rate; @@ -185,7 +184,7 @@ new_frame(int thread_index) { return; } - float frame_start = _clock.get_real_time(); + float frame_start = get_real_time(); if (!pthread->_frame_data.is_empty()) { // Collector 0 is the whole frame. @@ -213,7 +212,7 @@ new_frame(int thread_index) { // Also record the time for the PStats operation itself. int pstats_index = PStatClient::_pstats_pcollector.get_index(); _client->start(pstats_index, thread_index, frame_start); - _client->stop(pstats_index, thread_index, _clock.get_real_time()); + _client->stop(pstats_index, thread_index, get_real_time()); } //////////////////////////////////////////////////////////////////// @@ -232,7 +231,7 @@ transmit_frame_data(int thread_index) { // server. Check that enough time has elapsed for us to send a // new packet. If not, we'll drop this packet on the floor and // send a new one next time around. - float now = _clock.get_real_time(); + float now = get_real_time(); if (now >= thread->_next_packet) { // We don't want to send more than _max_rate UDP-size packets // per second, per thread. diff --git a/panda/src/pstatclient/pStatClientImpl.h b/panda/src/pstatclient/pStatClientImpl.h index 5fcde07cdc..3af65cc001 100644 --- a/panda/src/pstatclient/pStatClientImpl.h +++ b/panda/src/pstatclient/pStatClientImpl.h @@ -30,7 +30,7 @@ #include "connectionWriter.h" #include "netAddress.h" -#include "clockObject.h" +#include "trueClock.h" #include "pmap.h" class PStatClient; @@ -66,7 +66,7 @@ public: INLINE void set_max_rate(float rate); INLINE float get_max_rate() const; - INLINE const ClockObject &get_clock() const; + INLINE double get_real_time() const; INLINE void client_main_tick(); bool client_connect(string hostname, int port); @@ -82,8 +82,9 @@ private: void transmit_control_data(); - // Stats collecting stuff - ClockObject _clock; + TrueClock *_clock; + double _delta; + double _last_frame; // Networking stuff string get_hostname(); diff --git a/panda/src/pstatclient/pStatCollector.h b/panda/src/pstatclient/pStatCollector.h index a073525473..6690d953e7 100644 --- a/panda/src/pstatclient/pStatCollector.h +++ b/panda/src/pstatclient/pStatCollector.h @@ -24,6 +24,8 @@ #include "pStatThread.h" #include "pStatClient.h" +class Thread; + //////////////////////////////////////////////////////////////////// // Class : PStatCollector // Description : A lightweight class that represents a single element diff --git a/panda/src/pstatclient/pStatThread.I b/panda/src/pstatclient/pStatThread.I index b89ed2907e..d8d66eaf69 100644 --- a/panda/src/pstatclient/pStatThread.I +++ b/panda/src/pstatclient/pStatThread.I @@ -55,8 +55,15 @@ PStatThread(Thread *thread, PStatClient *client) { if (client == (PStatClient *)NULL) { client = PStatClient::get_global_pstats(); } - PStatThread pthread(client->make_thread(thread)); - (*this) = pthread; + + int thread_index = thread->get_pstats_index(); + if (thread_index != -1) { + (*this) = PStatThread(client, thread_index); + } + + // This is the first time we have encountered this current Thread. + // Make a new PStatThread object for it. + (*this) = client->make_thread(thread); #else _client = (PStatClient *)NULL; _index = 0; diff --git a/panda/src/pstatclient/pStatTimer.I b/panda/src/pstatclient/pStatTimer.I index b6c7891985..f67fbdb479 100644 --- a/panda/src/pstatclient/pStatTimer.I +++ b/panda/src/pstatclient/pStatTimer.I @@ -26,9 +26,23 @@ //////////////////////////////////////////////////////////////////// INLINE PStatTimer:: PStatTimer(PStatCollector &collector) : - _collector(collector) + _collector(collector), + _thread(PStatClient::get_global_pstats()->get_current_thread()) { - _collector.start(); + _collector.start(_thread); +} + +//////////////////////////////////////////////////////////////////// +// Function: PStatTimer::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PStatTimer:: +PStatTimer(PStatCollector &collector, Thread *current_thread) : + _collector(collector), + _thread(current_thread) +{ + _collector.start(_thread); } //////////////////////////////////////////////////////////////////// @@ -38,7 +52,7 @@ PStatTimer(PStatCollector &collector) : //////////////////////////////////////////////////////////////////// INLINE PStatTimer:: ~PStatTimer() { - _collector.stop(); + _collector.stop(_thread); } #endif diff --git a/panda/src/pstatclient/pStatTimer.h b/panda/src/pstatclient/pStatTimer.h index ed2daab2d9..79b783be5b 100644 --- a/panda/src/pstatclient/pStatTimer.h +++ b/panda/src/pstatclient/pStatTimer.h @@ -23,6 +23,8 @@ #include "pStatCollector.h" +class Thread; + //////////////////////////////////////////////////////////////////// // Class : PStatTimer // Description : A lightweight class that can be used to automatically @@ -37,11 +39,12 @@ class EXPCL_PANDA PStatTimer { public: #ifdef DO_PSTATS INLINE PStatTimer(PStatCollector &collector); + INLINE PStatTimer(PStatCollector &collector, Thread *current_thread); INLINE ~PStatTimer(); private: PStatCollector &_collector; - + PStatThread _thread; #else // DO_PSTATS INLINE PStatTimer(PStatCollector &) { } diff --git a/panda/src/putil/clockObject.I b/panda/src/putil/clockObject.I index 0fdfe60e20..0e108dfc15 100644 --- a/panda/src/putil/clockObject.I +++ b/panda/src/putil/clockObject.I @@ -87,8 +87,8 @@ get_mode() const { // frame remains in sync with each other. //////////////////////////////////////////////////////////////////// INLINE double ClockObject:: -get_frame_time() const { - CDReader cdata(_cycler); +get_frame_time(Thread *current_frame) const { + CDReader cdata(_cycler, current_frame); return cdata->_reported_frame_time; } @@ -152,8 +152,8 @@ reset() { // that have been rendered. //////////////////////////////////////////////////////////////////// INLINE int ClockObject:: -get_frame_count() const { - CDReader cdata(_cycler); +get_frame_count(Thread *current_thread) const { + CDReader cdata(_cycler, current_thread); return cdata->_frame_count; } @@ -167,8 +167,9 @@ get_frame_count() const { // M_non_real_time mode. //////////////////////////////////////////////////////////////////// INLINE double ClockObject:: -get_net_frame_rate() const { - return (double)get_frame_count() / get_frame_time(); +get_net_frame_rate(Thread *current_thread) const { + CDReader cdata(_cycler, current_thread); + return (double)cdata->_frame_count / cdata->_reported_frame_time; } //////////////////////////////////////////////////////////////////// @@ -179,8 +180,8 @@ get_net_frame_rate() const { // to tick(). //////////////////////////////////////////////////////////////////// INLINE double ClockObject:: -get_dt() const { - CDReader cdata(_cycler); +get_dt(Thread *current_thread) const { + CDReader cdata(_cycler, current_thread); if (_max_dt > 0.0) { return min(_max_dt, cdata->_dt); } @@ -196,9 +197,9 @@ get_dt() const { // this has no effect. //////////////////////////////////////////////////////////////////// INLINE void ClockObject:: -set_dt(double dt) { - nassertv(Thread::get_current_pipeline_stage() == 0); - CDWriter cdata(_cycler); +set_dt(double dt, Thread *current_thread) { + nassertv(current_thread->get_pipeline_stage() == 0); + CDWriter cdata(_cycler, current_thread); cdata->_dt = dt; } @@ -308,8 +309,8 @@ get_average_frame_rate_interval() const { // M_non_real_time mode. //////////////////////////////////////////////////////////////////// INLINE double ClockObject:: -get_average_frame_rate() const { - CDStageReader cdata(_cycler, 0); +get_average_frame_rate(Thread *current_thread) const { + CDStageReader cdata(_cycler, 0, current_thread); if (_ticks.size() <= 1) { return 0.0; } else { @@ -328,8 +329,8 @@ get_average_frame_rate() const { // resynchronize with any external clocks. //////////////////////////////////////////////////////////////////// INLINE bool ClockObject:: -check_errors() { - CDReader cdata(_cycler); // Just to hold a mutex. +check_errors(Thread *current_thread) { + CDReader cdata(_cycler, current_thread); // Just to hold a mutex. int orig_error_count = _error_count; _error_count = _true_clock->get_error_count(); return (_error_count != orig_error_count); diff --git a/panda/src/putil/clockObject.cxx b/panda/src/putil/clockObject.cxx index 3ca96be819..bc6e6f4d0e 100644 --- a/panda/src/putil/clockObject.cxx +++ b/panda/src/putil/clockObject.cxx @@ -80,8 +80,8 @@ set_real_time(double time) { // only for occasional special adjustments. //////////////////////////////////////////////////////////////////// void ClockObject:: -set_frame_time(double time) { - nassertv(Thread::get_current_pipeline_stage() == 0); +set_frame_time(double time, Thread *current_thread) { + nassertv(current_thread->get_pipeline_stage() == 0); #ifdef NOTIFY_DEBUG if (this == _global_clock && _mode != M_slave) { util_cat.warning() @@ -89,7 +89,7 @@ set_frame_time(double time) { << " seconds.\n"; } #endif // NOTIFY_DEBUG - CDWriter cdata(_cycler); + CDWriter cdata(_cycler, current_thread); _actual_frame_time = time; cdata->_reported_frame_time = time; } @@ -102,8 +102,8 @@ set_frame_time(double time) { // set_frame_time(). //////////////////////////////////////////////////////////////////// void ClockObject:: -set_frame_count(int frame_count) { - nassertv(Thread::get_current_pipeline_stage() == 0); +set_frame_count(int frame_count, Thread *current_thread) { + nassertv(current_thread->get_pipeline_stage() == 0); #ifdef NOTIFY_DEBUG if (this == _global_clock && _mode != M_slave) { util_cat.warning() @@ -111,7 +111,7 @@ set_frame_count(int frame_count) { << frame_count - get_frame_count() << " frames.\n"; } #endif // NOTIFY_DEBUG - CDWriter cdata(_cycler); + CDWriter cdata(_cycler, current_thread); cdata->_frame_count = frame_count; } @@ -126,9 +126,9 @@ set_frame_count(int frame_count) { // dt. //////////////////////////////////////////////////////////////////// void ClockObject:: -tick() { - nassertv(Thread::get_current_pipeline_stage() == 0); - CDWriter cdata(_cycler); +tick(Thread *current_thread) { + nassertv(current_thread->get_pipeline_stage() == 0); + CDWriter cdata(_cycler, current_thread); double old_reported_time = cdata->_reported_frame_time; if (_mode != M_slave) { @@ -207,9 +207,9 @@ tick() { // of time). //////////////////////////////////////////////////////////////////// void ClockObject:: -sync_frame_time() { +sync_frame_time(Thread *current_thread) { if (_mode == M_normal) { - CDWriter cdata(_cycler); + CDWriter cdata(_cycler, current_thread); cdata->_reported_frame_time = get_real_time(); } } diff --git a/panda/src/putil/clockObject.h b/panda/src/putil/clockObject.h index fd34864b63..68a4ad7576 100644 --- a/panda/src/putil/clockObject.h +++ b/panda/src/putil/clockObject.h @@ -79,20 +79,20 @@ PUBLISHED: INLINE void set_mode(Mode mode); INLINE Mode get_mode() const; - INLINE double get_frame_time() const; + INLINE double get_frame_time(Thread *current_thread = Thread::get_current_thread()) const; INLINE double get_real_time() const; INLINE double get_long_time() const; INLINE void reset(); void set_real_time(double time); - void set_frame_time(double time); - void set_frame_count(int frame_count); + void set_frame_time(double time, Thread *current_thread = Thread::get_current_thread()); + void set_frame_count(int frame_count, Thread *current_thread = Thread::get_current_thread()); - INLINE int get_frame_count() const; - INLINE double get_net_frame_rate() const; + INLINE int get_frame_count(Thread *current_thread = Thread::get_current_thread()) const; + INLINE double get_net_frame_rate(Thread *current_thread = Thread::get_current_thread()) const; - INLINE double get_dt() const; - INLINE void set_dt(double dt); + INLINE double get_dt(Thread *current_thread = Thread::get_current_thread()) const; + INLINE void set_dt(double dt, Thread *current_thread = Thread::get_current_thread()); INLINE double get_max_dt() const; INLINE void set_max_dt(double max_dt); @@ -102,12 +102,12 @@ PUBLISHED: INLINE void set_average_frame_rate_interval(double time); INLINE double get_average_frame_rate_interval() const; - INLINE double get_average_frame_rate() const; + INLINE double get_average_frame_rate(Thread *current_thread = Thread::get_current_thread()) const; - void tick(); - void sync_frame_time(); + void tick(Thread *current_thread); + void sync_frame_time(Thread *current_thread); - INLINE bool check_errors(); + INLINE bool check_errors(Thread *current_thread); INLINE static ClockObject *get_global_clock(); diff --git a/panda/src/testbed/pview.cxx b/panda/src/testbed/pview.cxx index fa743a42db..8aef135abc 100644 --- a/panda/src/testbed/pview.cxx +++ b/panda/src/testbed/pview.cxx @@ -50,9 +50,11 @@ ConfigVariableBool pview_test_hack bool output_screenshot(Filename &fn) { + Thread *current_thread = Thread::get_current_thread(); + // Only one frame crashes. - framework.do_frame(); - framework.do_frame(); + framework.do_frame(current_thread); + framework.do_frame(current_thread); WindowFramework *wf = framework.get_window(0); bool ok = wf->get_graphics_window()->save_screenshot(fn, "from pview"); @@ -313,8 +315,9 @@ main(int argc, char *argv[]) { // Allow a couple of frames to go by so the window will be fully // created and the text will be visible. - framework.do_frame(); - framework.do_frame(); + Thread *current_thread = Thread::get_current_thread(); + framework.do_frame(current_thread); + framework.do_frame(current_thread); } window->enable_keyboard(); diff --git a/panda/src/text/textAssembler.cxx b/panda/src/text/textAssembler.cxx index c92d24a285..800d5a80d8 100644 --- a/panda/src/text/textAssembler.cxx +++ b/panda/src/text/textAssembler.cxx @@ -763,6 +763,8 @@ assemble_row(TextAssembler::TextString::const_iterator &si, TextAssembler::PlacedGlyphs &row_placed_glyphs, float &row_width, float &line_height, TextProperties::Alignment &align) { + Thread *current_thread = Thread::get_current_thread(); + line_height = 0.0f; float xpos = 0.0f; align = TextProperties::A_left; @@ -863,7 +865,8 @@ assemble_row(TextAssembler::TextString::const_iterator &si, // glyph, so go get that. LPoint3f min_vert, max_vert; bool found_any = false; - placement->calc_tight_bounds(min_vert, max_vert, found_any); + placement->calc_tight_bounds(min_vert, max_vert, found_any, + current_thread); if (found_any) { LPoint3f centroid = (min_vert + max_vert) / 2.0f; @@ -1168,7 +1171,9 @@ tack_on_accent(char accent_mark, TextAssembler::CheesyPosition position, TextAssembler::GlyphPlacement *placement) const { TextFont *font = properties->get_font(); nassertr(font != (TextFont *)NULL, false); - + + Thread *current_thread = Thread::get_current_thread(); + const TextGlyph *accent_glyph; if (font->get_glyph(accent_mark, accent_glyph) || font->get_glyph(toupper(accent_mark), accent_glyph)) { @@ -1176,7 +1181,8 @@ tack_on_accent(char accent_mark, TextAssembler::CheesyPosition position, if (accent_geom != (Geom *)NULL) { LPoint3f min_accent, max_accent; bool found_any = false; - accent_geom->calc_tight_bounds(min_accent, max_accent, found_any); + accent_geom->calc_tight_bounds(min_accent, max_accent, found_any, + current_thread); if (found_any) { float t, u; LMatrix4f accent_mat; @@ -1431,10 +1437,11 @@ tack_on_accent(char accent_mark, TextAssembler::CheesyPosition position, //////////////////////////////////////////////////////////////////// void TextAssembler::GlyphPlacement:: calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, - bool &found_any) const { + bool &found_any, Thread *current_thread) const { Pieces::const_iterator pi; for (pi = _pieces.begin(); pi != _pieces.end(); ++pi) { - (*pi)._geom->calc_tight_bounds(min_point, max_point, found_any); + (*pi)._geom->calc_tight_bounds(min_point, max_point, found_any, + current_thread); } } diff --git a/panda/src/text/textAssembler.h b/panda/src/text/textAssembler.h index aac909e8d3..c2144bd5fe 100644 --- a/panda/src/text/textAssembler.h +++ b/panda/src/text/textAssembler.h @@ -109,7 +109,7 @@ private: public: INLINE void add_piece(Geom *geom, const RenderState *state); void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, - bool &found_any) const; + bool &found_any, Thread *current_thread) const; void assign_to(GeomNode *geom_node, const RenderState *state) const; void assign_copy_to(GeomNode *geom_node, const RenderState *state, const LMatrix4f &xform) const; diff --git a/panda/src/text/textNode.cxx b/panda/src/text/textNode.cxx index 7c8cf56bd4..ddf6229ecc 100644 --- a/panda/src/text/textNode.cxx +++ b/panda/src/text/textNode.cxx @@ -495,15 +495,16 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types, //////////////////////////////////////////////////////////////////// CPT(TransformState) TextNode:: calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, - const TransformState *transform) const { + const TransformState *transform, Thread *current_thread) const { CPT(TransformState) next_transform = - PandaNode::calc_tight_bounds(min_point, max_point, found_any, transform); + PandaNode::calc_tight_bounds(min_point, max_point, found_any, transform, + current_thread); check_rebuild(); if (_internal_geom != (PandaNode *)NULL) { _internal_geom->calc_tight_bounds(min_point, max_point, - found_any, next_transform); + found_any, next_transform, current_thread); } return next_transform; @@ -579,9 +580,9 @@ is_renderable() const { // thing. //////////////////////////////////////////////////////////////////// PT(BoundingVolume) TextNode:: -compute_internal_bounds(int pipeline_stage) const { +compute_internal_bounds(int pipeline_stage, Thread *current_thread) const { // First, get ourselves a fresh, empty bounding volume. - PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage); + PT(BoundingVolume) bound = PandaNode::compute_internal_bounds(pipeline_stage, current_thread); nassertr(bound != (BoundingVolume *)NULL, bound); GeometricBoundingVolume *gbv = DCAST(GeometricBoundingVolume, bound); diff --git a/panda/src/text/textNode.h b/panda/src/text/textNode.h index e4022cf001..4639b4e007 100644 --- a/panda/src/text/textNode.h +++ b/panda/src/text/textNode.h @@ -232,13 +232,14 @@ public: virtual CPT(TransformState) calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, - const TransformState *transform) const; + const TransformState *transform, + Thread *current_thread) const; virtual bool has_cull_callback() const; virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data); virtual bool is_renderable() const; - virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage) const; + virtual PT(BoundingVolume) compute_internal_bounds(int pipeline_stage, Thread *current_thread) const; private: INLINE void invalidate_no_measure(); diff --git a/panda/src/tform/driveInterface.cxx b/panda/src/tform/driveInterface.cxx index aceef2a5df..56964764b2 100644 --- a/panda/src/tform/driveInterface.cxx +++ b/panda/src/tform/driveInterface.cxx @@ -223,7 +223,7 @@ force_dgraph() { output.set_data(_transform_output, EventParameter(_transform)); output.set_data(_velocity_output, EventParameter(_velocity)); - DataGraphTraverser dg_trav; + DataGraphTraverser dg_trav(Thread::get_current_thread()); dg_trav.traverse_below(this, output); dg_trav.collect_leftovers(); } diff --git a/panda/src/wgldisplay/wglGraphicsBuffer.cxx b/panda/src/wgldisplay/wglGraphicsBuffer.cxx index a742190dc2..5d9ee95163 100644 --- a/panda/src/wgldisplay/wglGraphicsBuffer.cxx +++ b/panda/src/wgldisplay/wglGraphicsBuffer.cxx @@ -68,7 +68,7 @@ wglGraphicsBuffer:: // should be skipped. //////////////////////////////////////////////////////////////////// bool wglGraphicsBuffer:: -begin_frame(FrameMode mode) { +begin_frame(FrameMode mode, Thread *current_thread) { begin_frame_spam(); if (_gsg == (GraphicsStateGuardian *)NULL) { @@ -100,7 +100,7 @@ begin_frame(FrameMode mode) { } _gsg->set_current_properties(&get_fb_properties()); - return _gsg->begin_frame(); + return _gsg->begin_frame(current_thread); } //////////////////////////////////////////////////////////////////// @@ -111,7 +111,7 @@ begin_frame(FrameMode mode) { // should do whatever finalization is required. //////////////////////////////////////////////////////////////////// void wglGraphicsBuffer:: -end_frame(FrameMode mode) { +end_frame(FrameMode mode, Thread *current_thread) { end_frame_spam(); nassertv(_gsg != (GraphicsStateGuardian *)NULL); @@ -120,7 +120,7 @@ end_frame(FrameMode mode) { copy_to_textures(); } - _gsg->end_frame(); + _gsg->end_frame(current_thread); if (mode == FM_render) { trigger_flip(); diff --git a/panda/src/wgldisplay/wglGraphicsBuffer.h b/panda/src/wgldisplay/wglGraphicsBuffer.h index 1a89432795..8c348cc31e 100644 --- a/panda/src/wgldisplay/wglGraphicsBuffer.h +++ b/panda/src/wgldisplay/wglGraphicsBuffer.h @@ -49,8 +49,8 @@ public: GraphicsOutput *host); virtual ~wglGraphicsBuffer(); - virtual bool begin_frame(FrameMode mode); - virtual void end_frame(FrameMode mode); + virtual bool begin_frame(FrameMode mode, Thread *current_thread); + virtual void end_frame(FrameMode mode, Thread *current_thread); virtual void select_cube_map(int cube_map_index); diff --git a/panda/src/wgldisplay/wglGraphicsWindow.cxx b/panda/src/wgldisplay/wglGraphicsWindow.cxx index 7c76d31a35..2d984df14b 100644 --- a/panda/src/wgldisplay/wglGraphicsWindow.cxx +++ b/panda/src/wgldisplay/wglGraphicsWindow.cxx @@ -161,7 +161,7 @@ wglGraphicsWindow:: // should be skipped. //////////////////////////////////////////////////////////////////// bool wglGraphicsWindow:: -begin_frame(FrameMode mode) { +begin_frame(FrameMode mode, Thread *current_thread) { begin_frame_spam(); if (_gsg == (GraphicsStateGuardian *)NULL) { @@ -182,7 +182,7 @@ begin_frame(FrameMode mode) { } _gsg->set_current_properties(&get_fb_properties()); - return _gsg->begin_frame(); + return _gsg->begin_frame(current_thread); } //////////////////////////////////////////////////////////////////// @@ -193,7 +193,7 @@ begin_frame(FrameMode mode) { // should do whatever finalization is required. //////////////////////////////////////////////////////////////////// void wglGraphicsWindow:: -end_frame(FrameMode mode) { +end_frame(FrameMode mode, Thread *current_thread) { end_frame_spam(); @@ -203,7 +203,7 @@ end_frame(FrameMode mode) { copy_to_textures(); } - _gsg->end_frame(); + _gsg->end_frame(current_thread); if (mode == FM_render) { trigger_flip(); diff --git a/panda/src/wgldisplay/wglGraphicsWindow.h b/panda/src/wgldisplay/wglGraphicsWindow.h index 3bc2401a3c..0ed1b36cfb 100644 --- a/panda/src/wgldisplay/wglGraphicsWindow.h +++ b/panda/src/wgldisplay/wglGraphicsWindow.h @@ -37,8 +37,8 @@ public: GraphicsOutput *host); virtual ~wglGraphicsWindow(); - virtual bool begin_frame(FrameMode mode); - virtual void end_frame(FrameMode mode); + virtual bool begin_frame(FrameMode mode, Thread *current_thread); + virtual void end_frame(FrameMode mode, Thread *current_thread); virtual void begin_flip();