From ffc92f23c82bd7b02a7c364cefd6b8df7f40cc1f Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 25 Apr 2006 16:55:19 +0000 Subject: [PATCH] more factoring of Thread::get_current_thread --- panda/src/cull/cullBinBackToFront.cxx | 6 +- panda/src/cull/cullBinBackToFront.h | 2 +- panda/src/cull/cullBinFixed.cxx | 6 +- panda/src/cull/cullBinFixed.h | 2 +- panda/src/cull/cullBinFrontToBack.cxx | 4 +- panda/src/cull/cullBinFrontToBack.h | 2 +- panda/src/cull/cullBinOcclusionTest.cxx | 34 +- panda/src/cull/cullBinOcclusionTest.h | 11 +- panda/src/cull/cullBinStateSorted.cxx | 6 +- panda/src/cull/cullBinStateSorted.h | 2 +- panda/src/cull/cullBinUnsorted.cxx | 6 +- panda/src/cull/cullBinUnsorted.h | 2 +- panda/src/cull/drawCullHandler.cxx | 2 +- panda/src/display/displayRegion.I | 465 ++++++++++++++++++ panda/src/display/displayRegion.cxx | 175 +------ panda/src/display/displayRegion.h | 77 ++- panda/src/display/graphicsEngine.cxx | 208 +++++--- panda/src/display/graphicsEngine.h | 44 +- panda/src/display/graphicsOutput.cxx | 9 +- panda/src/display/graphicsOutput.h | 4 +- panda/src/display/graphicsStateGuardian.cxx | 5 +- panda/src/display/graphicsStateGuardian.h | 3 +- panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx | 7 +- panda/src/dxgsg8/dxGraphicsStateGuardian8.h | 3 +- panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 7 +- panda/src/dxgsg9/dxGraphicsStateGuardian9.h | 3 +- .../glstuff/glGraphicsStateGuardian_src.cxx | 9 +- .../src/glstuff/glGraphicsStateGuardian_src.h | 3 +- panda/src/gobj/geom.cxx | 3 +- panda/src/gobj/geom.h | 3 +- panda/src/pgraph/cullBin.cxx | 10 - panda/src/pgraph/cullBin.h | 2 +- panda/src/pgraph/cullHandler.I | 7 +- panda/src/pgraph/cullHandler.cxx | 9 +- panda/src/pgraph/cullHandler.h | 6 +- panda/src/pgraph/cullResult.cxx | 4 +- panda/src/pgraph/cullResult.h | 2 +- panda/src/pgraph/cullableObject.I | 4 +- panda/src/pgraph/cullableObject.h | 3 +- 39 files changed, 789 insertions(+), 371 deletions(-) diff --git a/panda/src/cull/cullBinBackToFront.cxx b/panda/src/cull/cullBinBackToFront.cxx index c2e84b728c..2c2c6f8f60 100644 --- a/panda/src/cull/cullBinBackToFront.cxx +++ b/panda/src/cull/cullBinBackToFront.cxx @@ -93,17 +93,17 @@ finish_cull(SceneSetup *) { //////////////////////////////////////////////////////////////////// // Function: CullBinBackToFront::draw -// Access: Public +// Access: Public, Virtual // Description: Draws all the geoms in the bin, in the appropriate // order. //////////////////////////////////////////////////////////////////// void CullBinBackToFront:: -draw() { +draw(Thread *current_thread) { PStatTimer timer(_draw_this_pcollector); Objects::const_iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi)._object; - CullHandler::draw(object, _gsg); + CullHandler::draw(object, _gsg, current_thread); } } diff --git a/panda/src/cull/cullBinBackToFront.h b/panda/src/cull/cullBinBackToFront.h index 614819dbc5..6fe980e633 100644 --- a/panda/src/cull/cullBinBackToFront.h +++ b/panda/src/cull/cullBinBackToFront.h @@ -45,7 +45,7 @@ public: virtual void add_object(CullableObject *object); virtual void finish_cull(SceneSetup *scene_setup); - virtual void draw(); + virtual void draw(Thread *current_thread); private: class ObjectData { diff --git a/panda/src/cull/cullBinFixed.cxx b/panda/src/cull/cullBinFixed.cxx index 8a9082a537..a7de0694d5 100644 --- a/panda/src/cull/cullBinFixed.cxx +++ b/panda/src/cull/cullBinFixed.cxx @@ -81,17 +81,17 @@ finish_cull(SceneSetup *) { //////////////////////////////////////////////////////////////////// // Function: CullBinFixed::draw -// Access: Public +// Access: Public, Virtual // Description: Draws all the geoms in the bin, in the appropriate // order. //////////////////////////////////////////////////////////////////// void CullBinFixed:: -draw() { +draw(Thread *current_thread) { PStatTimer timer(_draw_this_pcollector); Objects::const_iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi)._object; - CullHandler::draw(object, _gsg); + CullHandler::draw(object, _gsg, current_thread); } } diff --git a/panda/src/cull/cullBinFixed.h b/panda/src/cull/cullBinFixed.h index 3a22995245..a0b3a98b3f 100644 --- a/panda/src/cull/cullBinFixed.h +++ b/panda/src/cull/cullBinFixed.h @@ -47,7 +47,7 @@ public: virtual void add_object(CullableObject *object); virtual void finish_cull(SceneSetup *scene_setup); - virtual void draw(); + virtual void draw(Thread *current_thread); private: class ObjectData { diff --git a/panda/src/cull/cullBinFrontToBack.cxx b/panda/src/cull/cullBinFrontToBack.cxx index bddf080f15..01ecb46ba5 100644 --- a/panda/src/cull/cullBinFrontToBack.cxx +++ b/panda/src/cull/cullBinFrontToBack.cxx @@ -98,12 +98,12 @@ finish_cull(SceneSetup *) { // order. //////////////////////////////////////////////////////////////////// void CullBinFrontToBack:: -draw() { +draw(Thread *current_thread) { PStatTimer timer(_draw_this_pcollector); Objects::const_iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi)._object; - CullHandler::draw(object, _gsg); + CullHandler::draw(object, _gsg, current_thread); } } diff --git a/panda/src/cull/cullBinFrontToBack.h b/panda/src/cull/cullBinFrontToBack.h index 440c2f474c..635f88b014 100644 --- a/panda/src/cull/cullBinFrontToBack.h +++ b/panda/src/cull/cullBinFrontToBack.h @@ -45,7 +45,7 @@ public: virtual void add_object(CullableObject *object); virtual void finish_cull(SceneSetup *scene_setup); - virtual void draw(); + virtual void draw(Thread *current_thread); private: class ObjectData { diff --git a/panda/src/cull/cullBinOcclusionTest.cxx b/panda/src/cull/cullBinOcclusionTest.cxx index 222fd19b60..eaee817edb 100644 --- a/panda/src/cull/cullBinOcclusionTest.cxx +++ b/panda/src/cull/cullBinOcclusionTest.cxx @@ -195,7 +195,7 @@ finish_cull(SceneSetup *scene_setup) { // order. //////////////////////////////////////////////////////////////////// void CullBinOcclusionTest:: -draw() { +draw(Thread *current_thread) { PStatTimer timer(_draw_this_pcollector); // We'll want to know the near plane distance. @@ -205,7 +205,7 @@ draw() { int num_drawn_previous; { MutexHolder holder(_prev_draw->_visible_lock); - num_drawn_previous = _root.draw_previous(*this); + num_drawn_previous = _root.draw_previous(*this, current_thread); } if (cull_cat.is_spam()) { @@ -215,9 +215,9 @@ draw() { // Now draw the objects that may or may not remain. int num_drawn; - num_drawn = _root.draw(*this); + num_drawn = _root.draw(*this, current_thread); if (show_octree) { - _root.draw_wireframe(*this); + _root.draw_wireframe(*this, current_thread); } while (!_pending_nodes.empty()) { @@ -239,9 +239,9 @@ draw() { if (num_fragments != 0) { // The octree cell is at least partially visible. Draw it, and // continue recursion. - num_drawn += pending._octree_node->draw(*this); + num_drawn += pending._octree_node->draw(*this, current_thread); if (show_octree) { - pending._octree_node->draw_wireframe(*this); + pending._octree_node->draw_wireframe(*this, current_thread); } } _pending_nodes.pop_front(); @@ -475,7 +475,7 @@ compute_distance(const LMatrix4f &world_mat, // occlusion query object representing this test. //////////////////////////////////////////////////////////////////// PT(OcclusionQueryContext) CullBinOcclusionTest::OctreeNode:: -occlusion_test(CullBinOcclusionTest &bin) { +occlusion_test(CullBinOcclusionTest &bin, Thread *current_thread) { // Draw the bounding volume for visualization. This is // complicated because we're doing this at such a low level, here // in the middle of the draw task--we've already completed the @@ -500,7 +500,7 @@ occlusion_test(CullBinOcclusionTest &bin) { PStatTimer timer(bin._draw_occlusion_pcollector); bin._gsg->begin_occlusion_query(); - viz->draw(bin._gsg, munger, munged_data); + viz->draw(bin._gsg, munger, munged_data, current_thread); return bin._gsg->end_occlusion_query(); } @@ -512,7 +512,7 @@ occlusion_test(CullBinOcclusionTest &bin) { // objects drawn. //////////////////////////////////////////////////////////////////// int CullBinOcclusionTest::OctreeNode:: -draw_previous(CullBinOcclusionTest &bin) { +draw_previous(CullBinOcclusionTest &bin, Thread *current_thread) { int num_drawn = 0; if (!_objects.empty()) { @@ -523,7 +523,7 @@ draw_previous(CullBinOcclusionTest &bin) { VisibleGeom vg(object->_geom, object->_net_transform); if (bin._prev_draw->_visible_geoms.find(vg) != bin._prev_draw->_visible_geoms.end()) { // This object is visible. - CullHandler::draw(object, bin._gsg); + CullHandler::draw(object, bin._gsg, current_thread); object->_already_drawn = true; ++num_drawn; } @@ -536,7 +536,7 @@ draw_previous(CullBinOcclusionTest &bin) { // farthest. int index = bin._corners_front_to_back[i]; if (_corners[index] != (OctreeNode *)NULL) { - num_drawn += _corners[index]->draw_previous(bin); + num_drawn += _corners[index]->draw_previous(bin, current_thread); } } @@ -551,7 +551,7 @@ draw_previous(CullBinOcclusionTest &bin) { // nested nodes. Returns the number of objects drawn. //////////////////////////////////////////////////////////////////// int CullBinOcclusionTest::OctreeNode:: -draw(CullBinOcclusionTest &bin) { +draw(CullBinOcclusionTest &bin, Thread *current_thread) { // If the node is being drawn, it must have passed the occlusion // test. Flag it as such. _is_visible = true; @@ -568,7 +568,7 @@ draw(CullBinOcclusionTest &bin) { for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi)._object; if (!object->_already_drawn) { - CullHandler::draw(object, bin._gsg); + CullHandler::draw(object, bin._gsg, current_thread); object->_already_drawn = true; ++num_drawn; } @@ -588,7 +588,7 @@ draw(CullBinOcclusionTest &bin) { // some or all of the cube would be clipped), but it's not // likely that anything will be occluding something so close // to the camera anyway. - _corners[index]->draw(bin); + _corners[index]->draw(bin, current_thread); } else { // Otherwise, if the entire cube is in front of the near @@ -597,7 +597,7 @@ draw(CullBinOcclusionTest &bin) { // through the depth test. PendingNode pending; pending._octree_node = _corners[index]; - pending._query = _corners[index]->occlusion_test(bin); + pending._query = _corners[index]->occlusion_test(bin, current_thread); // We push it onto the list of nodes that are awaiting // feedback from the graphics pipe. This way we can go work @@ -617,7 +617,7 @@ draw(CullBinOcclusionTest &bin) { // for debugging and visualization purposes. //////////////////////////////////////////////////////////////////// void CullBinOcclusionTest::OctreeNode:: -draw_wireframe(CullBinOcclusionTest &bin) { +draw_wireframe(CullBinOcclusionTest &bin, Thread *current_thread) { // As above, this is complicated because we're doing this at such a // low level. CPT(TransformState) net_transform = TransformState::make_pos_hpr_scale @@ -635,7 +635,7 @@ draw_wireframe(CullBinOcclusionTest &bin) { munger->munge_geom(viz, munged_data); bin._gsg->set_state_and_transform(state, internal_transform); - viz->draw(bin._gsg, munger, munged_data); + viz->draw(bin._gsg, munger, munged_data, current_thread); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/cull/cullBinOcclusionTest.h b/panda/src/cull/cullBinOcclusionTest.h index bd512cb62f..db60b5b040 100644 --- a/panda/src/cull/cullBinOcclusionTest.h +++ b/panda/src/cull/cullBinOcclusionTest.h @@ -59,7 +59,7 @@ public: virtual void add_object(CullableObject *object); virtual void finish_cull(SceneSetup *scene_setup); - virtual void draw(); + virtual void draw(Thread *current_thread); private: void draw_next(); @@ -121,10 +121,11 @@ private: void compute_distance(const LMatrix4f &world_mat, CullBinOcclusionTest &bin); - PT(OcclusionQueryContext) occlusion_test(CullBinOcclusionTest &bin); - int draw_previous(CullBinOcclusionTest &bin); - int draw(CullBinOcclusionTest &bin); - void draw_wireframe(CullBinOcclusionTest &bin); + PT(OcclusionQueryContext) occlusion_test(CullBinOcclusionTest &bin, + Thread *current_thread); + int draw_previous(CullBinOcclusionTest &bin, Thread *current_thread); + int draw(CullBinOcclusionTest &bin, Thread *current_thread); + void draw_wireframe(CullBinOcclusionTest &bin, Thread *current_thread); void record_visible_geoms(VisibleGeoms &visible_geoms); INLINE void initial_assign(const ObjectData &object_data); diff --git a/panda/src/cull/cullBinStateSorted.cxx b/panda/src/cull/cullBinStateSorted.cxx index 998a2cad6d..9568140bad 100644 --- a/panda/src/cull/cullBinStateSorted.cxx +++ b/panda/src/cull/cullBinStateSorted.cxx @@ -80,17 +80,17 @@ finish_cull(SceneSetup *) { //////////////////////////////////////////////////////////////////// // Function: CullBinStateSorted::draw -// Access: Public +// Access: Public, Virtual // Description: Draws all the geoms in the bin, in the appropriate // order. //////////////////////////////////////////////////////////////////// void CullBinStateSorted:: -draw() { +draw(Thread *current_thread) { PStatTimer timer(_draw_this_pcollector); Objects::const_iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi)._object; - CullHandler::draw(object, _gsg); + CullHandler::draw(object, _gsg, current_thread); } } diff --git a/panda/src/cull/cullBinStateSorted.h b/panda/src/cull/cullBinStateSorted.h index 1e3c0a0d3d..c52405e606 100644 --- a/panda/src/cull/cullBinStateSorted.h +++ b/panda/src/cull/cullBinStateSorted.h @@ -49,7 +49,7 @@ public: virtual void add_object(CullableObject *object); virtual void finish_cull(SceneSetup *scene_setup); - virtual void draw(); + virtual void draw(Thread *current_thread); private: class ObjectData { diff --git a/panda/src/cull/cullBinUnsorted.cxx b/panda/src/cull/cullBinUnsorted.cxx index f651e0c530..557d59c30b 100644 --- a/panda/src/cull/cullBinUnsorted.cxx +++ b/panda/src/cull/cullBinUnsorted.cxx @@ -61,17 +61,17 @@ add_object(CullableObject *object) { //////////////////////////////////////////////////////////////////// // Function: CullBinUnsorted::draw -// Access: Public +// Access: Public, Virtual // Description: Draws all the objects in the bin, in the appropriate // order. //////////////////////////////////////////////////////////////////// void CullBinUnsorted:: -draw() { +draw(Thread *current_thread) { PStatTimer timer(_draw_this_pcollector); Objects::iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi); - CullHandler::draw(object, _gsg); + CullHandler::draw(object, _gsg, current_thread); } } diff --git a/panda/src/cull/cullBinUnsorted.h b/panda/src/cull/cullBinUnsorted.h index 9791752d54..1f00f8cc03 100644 --- a/panda/src/cull/cullBinUnsorted.h +++ b/panda/src/cull/cullBinUnsorted.h @@ -39,7 +39,7 @@ public: static CullBin *make_bin(const string &name, GraphicsStateGuardianBase *gsg); virtual void add_object(CullableObject *object); - virtual void draw(); + virtual void draw(Thread *current_thread); private: typedef pvector Objects; diff --git a/panda/src/cull/drawCullHandler.cxx b/panda/src/cull/drawCullHandler.cxx index 49e872e21b..373bfd3f85 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); + draw(object, _gsg, Thread::get_current_thread()); delete object; } diff --git a/panda/src/display/displayRegion.I b/panda/src/display/displayRegion.I index 67cd071b70..4c547fc09c 100644 --- a/panda/src/display/displayRegion.I +++ b/panda/src/display/displayRegion.I @@ -28,6 +28,99 @@ operator < (const DisplayRegion &other) const { return get_sort() < other.get_sort(); } +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_dimensions +// Access: Published +// Description: Retrieves the coordinates of the DisplayRegion's +// rectangle within its GraphicsOutput. These numbers +// will be in the range [0..1]. +//////////////////////////////////////////////////////////////////// +INLINE void DisplayRegion:: +get_dimensions(float &l, float &r, float &b, float &t) const { + CDReader cdata(_cycler); + l = cdata->_l; + r = cdata->_r; + b = cdata->_b; + t = cdata->_t; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_left +// Access: Published +// Description: Retrieves the x coordinate of the left edge of the +// rectangle within its GraphicsOutput. This number +// will be in the range [0..1]. +//////////////////////////////////////////////////////////////////// +INLINE float DisplayRegion:: +get_left() const { + CDReader cdata(_cycler); + return cdata->_l; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_right +// Access: Published +// Description: Retrieves the x coordinate of the right edge of the +// rectangle within its GraphicsOutput. This number +// will be in the range [0..1]. +//////////////////////////////////////////////////////////////////// +INLINE float DisplayRegion:: +get_right() const { + CDReader cdata(_cycler); + return cdata->_r; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_bottom +// Access: Published +// Description: Retrieves the y coordinate of the bottom edge of +// the rectangle within its GraphicsOutput. This +// number will be in the range [0..1]. +//////////////////////////////////////////////////////////////////// +INLINE float DisplayRegion:: +get_bottom() const { + CDReader cdata(_cycler); + return cdata->_b; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_top +// Access: Published +// Description: Retrieves the y coordinate of the top edge of the +// rectangle within its GraphicsOutput. This number +// will be in the range [0..1]. +//////////////////////////////////////////////////////////////////// +INLINE float DisplayRegion:: +get_top() const { + CDReader cdata(_cycler); + return cdata->_t; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_window +// Access: Published +// Description: Returns the GraphicsOutput that this DisplayRegion is +// ultimately associated with, or NULL if no window is +// associated. +//////////////////////////////////////////////////////////////////// +INLINE GraphicsOutput *DisplayRegion:: +get_window() const { + return _window; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_camera +// Access: Published +// Description: Returns the camera associated with this +// DisplayRegion, or an empty NodePath if no camera is +// associated. +//////////////////////////////////////////////////////////////////// +INLINE NodePath DisplayRegion:: +get_camera() const { + CDReader cdata(_cycler); + return cdata->_camera; +} + //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::is_active // Access: Published @@ -130,6 +223,76 @@ get_cube_map_index() const { return cdata->_cube_map_index; } +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_pixels +// Access: Published +// Description: Retrieves the coordinates of the DisplayRegion within +// its window, in pixels. +//////////////////////////////////////////////////////////////////// +INLINE void DisplayRegion:: +get_pixels(int &pl, int &pr, int &pb, int &pt) const { + CDReader cdata(_cycler); + pl = cdata->_pl; + pr = cdata->_pr; + pb = cdata->_pb; + pt = cdata->_pt; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_region_pixels +// Access: Published +// Description: Retrieves the coordinates of the DisplayRegion within +// its window, as the pixel location of its bottom-left +// corner, along with a pixel width and height. +//////////////////////////////////////////////////////////////////// +INLINE void DisplayRegion:: +get_region_pixels(int &xo, int &yo, int &w, int &h) const { + CDReader cdata(_cycler); + xo = cdata->_pl; + yo = cdata->_pb; + w = cdata->_pr - cdata->_pl; + h = cdata->_pt - cdata->_pb; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_region_pixels_i +// Access: Published +// Description: Similar to get_region_pixels(), but returns the upper +// left corner, and the pixel numbers are numbered from +// the top-left corner down, in the DirectX way of +// things. +//////////////////////////////////////////////////////////////////// +INLINE void DisplayRegion:: +get_region_pixels_i(int &xo, int &yo, int &w, int &h) const { + CDReader cdata(_cycler); + xo = cdata->_pl; + yo = cdata->_pti; + w = cdata->_pr - cdata->_pl; + h = cdata->_pbi - cdata->_pti; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_pixel_width +// Access: Published +// Description: Returns the width of the DisplayRegion in pixels. +//////////////////////////////////////////////////////////////////// +INLINE int DisplayRegion:: +get_pixel_width() const { + CDReader cdata(_cycler); + return cdata->_pr - cdata->_pl; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_pixel_height +// Access: Published +// Description: Returns the height of the DisplayRegion in pixels. +//////////////////////////////////////////////////////////////////// +INLINE int DisplayRegion:: +get_pixel_height() const { + CDReader cdata(_cycler); + return cdata->_pt - cdata->_pb; +} + //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::set_cull_result // Access: Public @@ -199,6 +362,308 @@ CDataCull(const DisplayRegion::CDataCull ©) : { } +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE DisplayRegionPipelineReader:: +DisplayRegionPipelineReader(DisplayRegion *object, Thread *current_thread) : + _object(object), + _current_thread(current_thread), + _cdata(object->_cycler.read(current_thread)) +{ +#ifdef _DEBUG + nassertv(_object->test_ref_count_nonzero()); +#ifdef DO_PIPELINING + nassertv(_cdata->test_ref_count_nonzero()); +#endif // DO_PIPELINING +#endif // _DEBUG +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::Copy Constructor +// Access: Private +// Description: Don't attempt to copy these objects. +//////////////////////////////////////////////////////////////////// +INLINE DisplayRegionPipelineReader:: +DisplayRegionPipelineReader(const DisplayRegionPipelineReader &) { + nassertv(false); +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::Copy Assignment Operator +// Access: Private +// Description: Don't attempt to copy these objects. +//////////////////////////////////////////////////////////////////// +INLINE void DisplayRegionPipelineReader:: +operator = (const DisplayRegionPipelineReader &) { + nassertv(false); +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE DisplayRegionPipelineReader:: +~DisplayRegionPipelineReader() { +#ifdef _DEBUG + nassertv(_object->test_ref_count_nonzero()); +#ifdef DO_PIPELINING + nassertv(_cdata->test_ref_count_nonzero()); +#endif // DO_PIPELINING +#endif // _DEBUG + _object->_cycler.release_read(_cdata); + +#ifdef _DEBUG + _object = NULL; + _cdata = NULL; +#endif // _DEBUG +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_object +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE DisplayRegion *DisplayRegionPipelineReader:: +get_object() const { + return _object; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_current_thread +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE Thread *DisplayRegionPipelineReader:: +get_current_thread() const { + return _current_thread; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::is_any_clear_active +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool DisplayRegionPipelineReader:: +is_any_clear_active() const { + return _object->is_any_clear_active(); +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_dimensions +// Access: Public +// Description: Retrieves the coordinates of the DisplayRegion's +// rectangle within its GraphicsOutput. These numbers +// will be in the range [0..1]. +//////////////////////////////////////////////////////////////////// +INLINE void DisplayRegionPipelineReader:: +get_dimensions(float &l, float &r, float &b, float &t) const { + l = _cdata->_l; + r = _cdata->_r; + b = _cdata->_b; + t = _cdata->_t; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_left +// Access: Public +// Description: Retrieves the x coordinate of the left edge of the +// rectangle within its GraphicsOutput. This number +// will be in the range [0..1]. +//////////////////////////////////////////////////////////////////// +INLINE float DisplayRegionPipelineReader:: +get_left() const { + return _cdata->_l; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_right +// Access: Public +// Description: Retrieves the x coordinate of the right edge of the +// rectangle within its GraphicsOutput. This number +// will be in the range [0..1]. +//////////////////////////////////////////////////////////////////// +INLINE float DisplayRegionPipelineReader:: +get_right() const { + return _cdata->_r; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_bottom +// Access: Public +// Description: Retrieves the y coordinate of the bottom edge of +// the rectangle within its GraphicsOutput. This +// number will be in the range [0..1]. +//////////////////////////////////////////////////////////////////// +INLINE float DisplayRegionPipelineReader:: +get_bottom() const { + return _cdata->_b; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_top +// Access: Public +// Description: Retrieves the y coordinate of the top edge of the +// rectangle within its GraphicsOutput. This number +// will be in the range [0..1]. +//////////////////////////////////////////////////////////////////// +INLINE float DisplayRegionPipelineReader:: +get_top() const { + return _cdata->_t; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_window +// Access: Public +// Description: Returns the GraphicsOutput that this DisplayRegion is +// ultimately associated with, or NULL if no window is +// associated. +//////////////////////////////////////////////////////////////////// +INLINE GraphicsOutput *DisplayRegionPipelineReader:: +get_window() const { + return _object->_window; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_camera +// Access: Public +// Description: Returns the camera associated with this +// DisplayRegion, or an empty NodePath if no camera is +// associated. +//////////////////////////////////////////////////////////////////// +INLINE NodePath DisplayRegionPipelineReader:: +get_camera() const { + return _cdata->_camera; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::is_active +// Access: Public +// Description: Returns the active flag associated with the +// DisplayRegion. +//////////////////////////////////////////////////////////////////// +INLINE bool DisplayRegionPipelineReader:: +is_active() const { + return _cdata->_active; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_sort +// Access: Public +// Description: Returns the sort value associated with the +// DisplayRegion. +//////////////////////////////////////////////////////////////////// +INLINE int DisplayRegionPipelineReader:: +get_sort() const { + return _cdata->_sort; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_stereo_channel +// Access: Public +// Description: Returns whether the DisplayRegion is specified as the +// left or right channel of a stereo pair, or whether it +// is a normal, monocular image. See +// set_stereo_channel(). +//////////////////////////////////////////////////////////////////// +INLINE Lens::StereoChannel DisplayRegionPipelineReader:: +get_stereo_channel() { + return _cdata->_stereo_channel; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_clear_depth_between_eyes +// Access: Public +// Description: Returns whether the depth buffer is cleared again +// between the left and right eyes of a stereo +// DisplayRegion. See set_clear_depth_between_eyes(). +//////////////////////////////////////////////////////////////////// +INLINE bool DisplayRegionPipelineReader:: +get_clear_depth_between_eyes() const { + return _object->_clear_depth_between_eyes; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_cube_map_index +// Access: Public +// Description: Returns the cube map face index associated with this +// particular DisplayRegion, or -1 if it is not +// associated with a cube map. See +// set_cube_map_index(). +//////////////////////////////////////////////////////////////////// +INLINE int DisplayRegionPipelineReader:: +get_cube_map_index() const { + return _cdata->_cube_map_index; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_pixels +// Access: Public +// Description: Retrieves the coordinates of the DisplayRegion within +// its window, in pixels. +//////////////////////////////////////////////////////////////////// +INLINE void DisplayRegionPipelineReader:: +get_pixels(int &pl, int &pr, int &pb, int &pt) const { + pl = _cdata->_pl; + pr = _cdata->_pr; + pb = _cdata->_pb; + pt = _cdata->_pt; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_region_pixels +// Access: Public +// Description: Retrieves the coordinates of the DisplayRegion within +// its window, as the pixel location of its bottom-left +// corner, along with a pixel width and height. +//////////////////////////////////////////////////////////////////// +INLINE void DisplayRegionPipelineReader:: +get_region_pixels(int &xo, int &yo, int &w, int &h) const { + xo = _cdata->_pl; + yo = _cdata->_pb; + w = _cdata->_pr - _cdata->_pl; + h = _cdata->_pt - _cdata->_pb; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_region_pixels_i +// Access: Public +// Description: Similar to get_region_pixels(), but returns the upper +// left corner, and the pixel numbers are numbered from +// the top-left corner down, in the DirectX way of +// things. +//////////////////////////////////////////////////////////////////// +INLINE void DisplayRegionPipelineReader:: +get_region_pixels_i(int &xo, int &yo, int &w, int &h) const { + xo = _cdata->_pl; + yo = _cdata->_pti; + w = _cdata->_pr - _cdata->_pl; + h = _cdata->_pbi - _cdata->_pti; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_pixel_width +// Access: Public +// Description: Returns the width of the DisplayRegion in pixels. +//////////////////////////////////////////////////////////////////// +INLINE int DisplayRegionPipelineReader:: +get_pixel_width() const { + return _cdata->_pr - _cdata->_pl; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_pixel_height +// Access: Public +// Description: Returns the height of the DisplayRegion in pixels. +//////////////////////////////////////////////////////////////////// +INLINE int DisplayRegionPipelineReader:: +get_pixel_height() const { + return _cdata->_pt - _cdata->_pb; +} + INLINE ostream &operator << (ostream &out, const DisplayRegion &dr) { dr.output(out); return out; diff --git a/panda/src/display/displayRegion.cxx b/panda/src/display/displayRegion.cxx index 0b3adbdb97..a80792e63a 100644 --- a/panda/src/display/displayRegion.cxx +++ b/panda/src/display/displayRegion.cxx @@ -105,74 +105,6 @@ cleanup() { cdata->_cull_result = NULL; } -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_dimensions -// Access: Published -// Description: Retrieves the coordinates of the DisplayRegion's -// rectangle within its GraphicsOutput. These numbers -// will be in the range [0..1]. -//////////////////////////////////////////////////////////////////// -void DisplayRegion:: -get_dimensions(float &l, float &r, float &b, float &t) const { - CDReader cdata(_cycler); - l = cdata->_l; - r = cdata->_r; - b = cdata->_b; - t = cdata->_t; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_left -// Access: Published -// Description: Retrieves the x coordinate of the left edge of the -// rectangle within its GraphicsOutput. This number -// will be in the range [0..1]. -//////////////////////////////////////////////////////////////////// -float DisplayRegion:: -get_left() const { - CDReader cdata(_cycler); - return cdata->_l; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_right -// Access: Published -// Description: Retrieves the x coordinate of the right edge of the -// rectangle within its GraphicsOutput. This number -// will be in the range [0..1]. -//////////////////////////////////////////////////////////////////// -float DisplayRegion:: -get_right() const { - CDReader cdata(_cycler); - return cdata->_r; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_bottom -// Access: Published -// Description: Retrieves the y coordinate of the bottom edge of -// the rectangle within its GraphicsOutput. This -// number will be in the range [0..1]. -//////////////////////////////////////////////////////////////////// -float DisplayRegion:: -get_bottom() const { - CDReader cdata(_cycler); - return cdata->_b; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_top -// Access: Published -// Description: Retrieves the y coordinate of the top edge of the -// rectangle within its GraphicsOutput. This number -// will be in the range [0..1]. -//////////////////////////////////////////////////////////////////// -float DisplayRegion:: -get_top() const { - CDReader cdata(_cycler); - return cdata->_t; -} - //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::set_dimensions // Access: Published @@ -198,18 +130,6 @@ set_dimensions(float l, float r, float b, float t) { } } -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_window -// Access: Published -// Description: Returns the GraphicsOutput that this DisplayRegion is -// ultimately associated with, or NULL if no window is -// associated. -//////////////////////////////////////////////////////////////////// -GraphicsOutput *DisplayRegion:: -get_window() const { - return _window; -} - //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::get_pipe // Access: Published @@ -264,19 +184,6 @@ set_camera(const NodePath &camera) { cdata->_camera = camera; } -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_camera -// Access: Published -// Description: Returns the camera associated with this -// DisplayRegion, or an empty NodePath if no camera is -// associated. -//////////////////////////////////////////////////////////////////// -NodePath DisplayRegion:: -get_camera() const { - CDReader cdata(_cycler); - return cdata->_camera; -} - //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::set_active // Access: Published @@ -425,76 +332,6 @@ compute_pixels_all_stages(int x_size, int y_size) { CLOSE_ITERATE_ALL_STAGES(_cycler); } -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_pixels -// Access: Published -// Description: Retrieves the coordinates of the DisplayRegion within -// its window, in pixels. -//////////////////////////////////////////////////////////////////// -void DisplayRegion:: -get_pixels(int &pl, int &pr, int &pb, int &pt) const { - CDReader cdata(_cycler); - pl = cdata->_pl; - pr = cdata->_pr; - pb = cdata->_pb; - pt = cdata->_pt; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_region_pixels -// Access: Published -// Description: Retrieves the coordinates of the DisplayRegion within -// its window, as the pixel location of its bottom-left -// corner, along with a pixel width and height. -//////////////////////////////////////////////////////////////////// -void DisplayRegion:: -get_region_pixels(int &xo, int &yo, int &w, int &h) const { - CDReader cdata(_cycler); - xo = cdata->_pl; - yo = cdata->_pb; - w = cdata->_pr - cdata->_pl; - h = cdata->_pt - cdata->_pb; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_region_pixels_i -// Access: Published -// Description: Similar to get_region_pixels(), but returns the upper -// left corner, and the pixel numbers are numbered from -// the top-left corner down, in the DirectX way of -// things. -//////////////////////////////////////////////////////////////////// -void DisplayRegion:: -get_region_pixels_i(int &xo, int &yo, int &w, int &h) const { - CDReader cdata(_cycler); - xo = cdata->_pl; - yo = cdata->_pti; - w = cdata->_pr - cdata->_pl; - h = cdata->_pbi - cdata->_pti; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_pixel_width -// Access: Published -// Description: Returns the width of the DisplayRegion in pixels. -//////////////////////////////////////////////////////////////////// -int DisplayRegion:: -get_pixel_width() const { - CDReader cdata(_cycler); - return cdata->_pr - cdata->_pl; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_pixel_height -// Access: Published -// Description: Returns the height of the DisplayRegion in pixels. -//////////////////////////////////////////////////////////////////// -int DisplayRegion:: -get_pixel_height() const { - CDReader cdata(_cycler); - return cdata->_pt - cdata->_pb; -} - //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::output // Access: Published @@ -773,3 +610,15 @@ CycleData *DisplayRegion::CDataCull:: make_copy() const { return new CDataCull(*this); } + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_pipe +// Access: Public +// Description: Returns the GraphicsPipe that this DisplayRegion is +// ultimately associated with, or NULL if no pipe is +// associated. +//////////////////////////////////////////////////////////////////// +GraphicsPipe *DisplayRegionPipelineReader:: +get_pipe() const { + return (_object->_window != (GraphicsOutput *)NULL) ? _object->_window->get_pipe() : NULL; +} diff --git a/panda/src/display/displayRegion.h b/panda/src/display/displayRegion.h index 4995cf0e4d..0aec79207e 100644 --- a/panda/src/display/displayRegion.h +++ b/panda/src/display/displayRegion.h @@ -34,7 +34,7 @@ #include "pipelineCycler.h" #include "config_display.h" #include "lens.h" - +#include "deletedChain.h" #include "plist.h" class GraphicsOutput; @@ -70,18 +70,18 @@ public: INLINE bool operator < (const DisplayRegion &other) const; PUBLISHED: - void get_dimensions(float &l, float &r, float &b, float &t) const; - float get_left() const; - float get_right() const; - float get_bottom() const; - float get_top() const; + INLINE void get_dimensions(float &l, float &r, float &b, float &t) const; + INLINE float get_left() const; + INLINE float get_right() const; + INLINE float get_bottom() const; + INLINE float get_top() const; void set_dimensions(float l, float r, float b, float t); - GraphicsOutput *get_window() const; + INLINE GraphicsOutput *get_window() const; GraphicsPipe *get_pipe() const; void set_camera(const NodePath &camera); - NodePath get_camera() const; + INLINE NodePath get_camera() const; void set_active(bool active); INLINE bool is_active() const; @@ -102,12 +102,12 @@ PUBLISHED: void compute_pixels_all_stages(); void compute_pixels(int x_size, int y_size); void compute_pixels_all_stages(int x_size, int y_size); - void get_pixels(int &pl, int &pr, int &pb, int &pt) const; - void get_region_pixels(int &xo, int &yo, int &w, int &h) const; - void get_region_pixels_i(int &xo, int &yo, int &w, int &h) const; + INLINE void get_pixels(int &pl, int &pr, int &pb, int &pt) const; + INLINE void get_region_pixels(int &xo, int &yo, int &w, int &h) const; + INLINE void get_region_pixels_i(int &xo, int &yo, int &w, int &h) const; - int get_pixel_width() const; - int get_pixel_height() const; + INLINE int get_pixel_width() const; + INLINE int get_pixel_height() const; void output(ostream &out) const; @@ -212,6 +212,57 @@ private: static TypeHandle _type_handle; friend class GraphicsOutput; + friend class DisplayRegionPipelineReader; +}; + +//////////////////////////////////////////////////////////////////// +// Class : DisplayRegionPipelineReader +// Description : Encapsulates the data from a DisplayRegion, +// pre-fetched for one stage of the pipeline. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA DisplayRegionPipelineReader { +public: + INLINE DisplayRegionPipelineReader(DisplayRegion *object, Thread *current_thread); +private: + INLINE DisplayRegionPipelineReader(const DisplayRegionPipelineReader ©); + INLINE void operator = (const DisplayRegionPipelineReader ©); + +public: + INLINE ~DisplayRegionPipelineReader(); + ALLOC_DELETED_CHAIN(DisplayRegionPipelineReader); + + INLINE DisplayRegion *get_object() const; + INLINE Thread *get_current_thread() const; + + INLINE bool is_any_clear_active() const; + + INLINE void get_dimensions(float &l, float &r, float &b, float &t) const; + INLINE float get_left() const; + INLINE float get_right() const; + INLINE float get_bottom() const; + INLINE float get_top() const; + + INLINE GraphicsOutput *get_window() const; + GraphicsPipe *get_pipe() const; + + INLINE NodePath get_camera() const; + INLINE bool is_active() const; + INLINE int get_sort() const; + INLINE Lens::StereoChannel get_stereo_channel(); + INLINE bool get_clear_depth_between_eyes() const; + INLINE int get_cube_map_index() const; + + INLINE void get_pixels(int &pl, int &pr, int &pb, int &pt) const; + INLINE void get_region_pixels(int &xo, int &yo, int &w, int &h) const; + INLINE void get_region_pixels_i(int &xo, int &yo, int &w, int &h) const; + + INLINE int get_pixel_width() const; + INLINE int get_pixel_height() const; + +private: + DisplayRegion *_object; + Thread *_current_thread; + const DisplayRegion::CData *_cdata; }; INLINE ostream &operator << (ostream &out, const DisplayRegion &dr); diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index 30b69c0235..b47b38346a 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -434,6 +434,8 @@ make_output(GraphicsPipe *pipe, //////////////////////////////////////////////////////////////////// bool GraphicsEngine:: remove_window(GraphicsOutput *window) { + Thread *current_thread = Thread::get_current_thread(); + // First, make sure we know what this window is. PT(GraphicsOutput) ptwin = window; size_t count; @@ -449,7 +451,7 @@ remove_window(GraphicsOutput *window) { return false; } - do_remove_window(window); + do_remove_window(window, current_thread); nassertr(count == 1, true); return true; @@ -464,16 +466,18 @@ remove_window(GraphicsOutput *window) { //////////////////////////////////////////////////////////////////// void GraphicsEngine:: remove_all_windows() { + Thread *current_thread = Thread::get_current_thread(); + Windows::iterator wi; for (wi = _windows.begin(); wi != _windows.end(); ++wi) { GraphicsOutput *win = (*wi); - do_remove_window(win); + do_remove_window(win, current_thread); } _windows.clear(); - _app.do_close(this); - _app.do_pending(this); + _app.do_close(this, current_thread); + _app.do_pending(this, current_thread); terminate_threads(); } @@ -542,6 +546,8 @@ get_window(int n) const { //////////////////////////////////////////////////////////////////// void GraphicsEngine:: render_frame() { + Thread *current_thread = Thread::get_current_thread(); + // Anything that happens outside of GraphicsEngine::render_frame() // is deemed to be App. #ifdef DO_PSTATS @@ -569,7 +575,7 @@ render_frame() { } if (_flip_state != FS_flip) { - do_flip_frame(); + do_flip_frame(current_thread); } // Are any of the windows ready to be deleted? @@ -579,7 +585,7 @@ render_frame() { for (wi = _windows.begin(); wi != _windows.end(); ++wi) { GraphicsOutput *win = (*wi); if (win->get_delete_flag()) { - do_remove_window(win); + do_remove_window(win, current_thread); } else { new_windows.push_back(win); @@ -612,7 +618,7 @@ render_frame() { // Now it's time to do any drawing from the main frame--after all of // the App code has executed, but before we begin the next frame. - _app.do_frame(this); + _app.do_frame(this, current_thread); // Grab each thread's mutex again after all windows have flipped, // and wait for the thread to finish. @@ -756,6 +762,8 @@ render_frame() { //////////////////////////////////////////////////////////////////// void GraphicsEngine:: open_windows() { + Thread *current_thread = Thread::get_current_thread(); + MutexHolder holder(_lock); if (!_windows_sorted) { @@ -765,8 +773,8 @@ open_windows() { // We do it twice, to allow both cull and draw to process the // window. for (int i = 0; i < 2; ++i) { - _app.do_windows(this); - _app.do_pending(this); + _app.do_windows(this, current_thread); + _app.do_pending(this, current_thread); PStatTimer timer(_wait_pcollector); Threads::const_iterator ti; @@ -796,10 +804,11 @@ open_windows() { //////////////////////////////////////////////////////////////////// void GraphicsEngine:: sync_frame() { + Thread *current_thread = Thread::get_current_thread(); MutexHolder holder(_lock); if (_flip_state == FS_draw) { - do_sync_frame(); + do_sync_frame(current_thread); } } @@ -814,10 +823,11 @@ sync_frame() { //////////////////////////////////////////////////////////////////// void GraphicsEngine:: flip_frame() { + Thread *current_thread = Thread::get_current_thread(); MutexHolder holder(_lock); if (_flip_state != FS_flip) { - do_flip_frame(); + do_flip_frame(current_thread); } } @@ -952,7 +962,8 @@ set_window_sort(GraphicsOutput *window, int sort) { // threading model begins with the "-" character. //////////////////////////////////////////////////////////////////// void GraphicsEngine:: -cull_and_draw_together(const GraphicsEngine::Windows &wlist) { +cull_and_draw_together(const GraphicsEngine::Windows &wlist, + Thread *current_thread) { PStatTimer timer(_cull_pcollector); Windows::const_iterator wi; @@ -960,13 +971,13 @@ cull_and_draw_together(const GraphicsEngine::Windows &wlist) { GraphicsOutput *win = (*wi); if (win->is_active() && win->get_gsg()->is_active()) { if (win->begin_frame(GraphicsOutput::FM_render)) { - win->clear(); + win->clear(current_thread); int num_display_regions = win->get_num_active_display_regions(); for (int i = 0; i < num_display_regions; i++) { DisplayRegion *dr = win->get_active_display_region(i); if (dr != (DisplayRegion *)NULL) { - cull_and_draw_together(win, dr); + cull_and_draw_together(win, dr, current_thread); } } win->end_frame(GraphicsOutput::FM_render); @@ -995,30 +1006,40 @@ cull_and_draw_together(const GraphicsEngine::Windows &wlist) { // cull_and_draw_together(), above. //////////////////////////////////////////////////////////////////// void GraphicsEngine:: -cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr) { +cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr, + Thread *current_thread) { GraphicsStateGuardian *gsg = win->get_gsg(); nassertv(gsg != (GraphicsStateGuardian *)NULL); - win->change_scenes(dr); - gsg->prepare_display_region(dr, dr->get_stereo_channel()); + DisplayRegionPipelineReader *dr_reader = + new DisplayRegionPipelineReader(dr, current_thread); - PT(SceneSetup) scene_setup = setup_scene(gsg, dr); + win->change_scenes(dr_reader); + gsg->prepare_display_region(dr_reader, dr_reader->get_stereo_channel()); + + PT(SceneSetup) scene_setup = setup_scene(gsg, dr_reader); if (!gsg->set_scene(scene_setup)) { // The scene or lens is inappropriate somehow. display_cat.error() << gsg->get_type() << " cannot render scene with specified lens.\n"; } else { - if (dr->is_any_clear_active()) { + if (dr_reader->is_any_clear_active()) { gsg->clear(dr); } DrawCullHandler cull_handler(gsg); if (gsg->begin_scene()) { - do_cull(&cull_handler, scene_setup, gsg); + delete dr_reader; + dr_reader = NULL; + do_cull(&cull_handler, scene_setup, gsg, current_thread); gsg->end_scene(); } } + + if (dr_reader != (DisplayRegionPipelineReader *)NULL) { + delete dr_reader; + } } //////////////////////////////////////////////////////////////////// @@ -1030,7 +1051,7 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr) { // drawing. //////////////////////////////////////////////////////////////////// void GraphicsEngine:: -cull_to_bins(const GraphicsEngine::Windows &wlist) { +cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) { PStatTimer timer(_cull_pcollector); // Keep track of the cameras we have already used in this thread to @@ -1046,13 +1067,17 @@ cull_to_bins(const GraphicsEngine::Windows &wlist) { for (int i = 0; i < num_display_regions; ++i) { DisplayRegion *dr = win->get_active_display_region(i); if (dr != (DisplayRegion *)NULL) { - NodePath camera = dr->get_camera(); + DisplayRegionPipelineReader *dr_reader = + new DisplayRegionPipelineReader(dr, current_thread); + NodePath camera = dr_reader->get_camera(); AlreadyCulled::iterator aci = already_culled.insert(AlreadyCulled::value_type(camera, NULL)).first; if ((*aci).second == NULL) { // We have not used this camera already in this thread. // Perform the cull operation. + delete dr_reader; + dr_reader = NULL; (*aci).second = dr; - cull_to_bins(win, dr); + cull_to_bins(win, dr, current_thread); } else { // We have already culled a scene using this camera in @@ -1064,7 +1089,11 @@ cull_to_bins(const GraphicsEngine::Windows &wlist) { // the other DisplayRegion. DisplayRegion *other_dr = (*aci).second; dr->set_cull_result(other_dr->get_cull_result(), - setup_scene(win->get_gsg(), dr)); + setup_scene(win->get_gsg(), dr_reader)); + } + + if (dr_reader != (DisplayRegionPipelineReader *)NULL) { + delete dr_reader; } } } @@ -1079,7 +1108,7 @@ cull_to_bins(const GraphicsEngine::Windows &wlist) { // above. //////////////////////////////////////////////////////////////////// void GraphicsEngine:: -cull_to_bins(GraphicsOutput *win, DisplayRegion *dr) { +cull_to_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) { GraphicsStateGuardian *gsg = win->get_gsg(); nassertv(gsg != (GraphicsStateGuardian *)NULL); @@ -1093,12 +1122,13 @@ cull_to_bins(GraphicsOutput *win, DisplayRegion *dr) { } else { cull_result = new CullResult(gsg); } - scene_setup = setup_scene(gsg, dr); + DisplayRegionPipelineReader dr_reader(dr, current_thread); + scene_setup = setup_scene(gsg, &dr_reader); } if (scene_setup != (SceneSetup *)NULL) { BinCullHandler cull_handler(cull_result); - do_cull(&cull_handler, scene_setup, gsg); + do_cull(&cull_handler, scene_setup, gsg, current_thread); { PStatTimer timer(_cull_sort_pcollector); @@ -1119,19 +1149,19 @@ cull_to_bins(GraphicsOutput *win, DisplayRegion *dr) { // cull_to_bins(). //////////////////////////////////////////////////////////////////// void GraphicsEngine:: -draw_bins(const GraphicsEngine::Windows &wlist) { +draw_bins(const GraphicsEngine::Windows &wlist, Thread *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)) { - win->clear(); + win->clear(current_thread); int num_display_regions = win->get_num_active_display_regions(); for (int i = 0; i < num_display_regions; ++i) { DisplayRegion *dr = win->get_active_display_region(i); if (dr != (DisplayRegion *)NULL) { - draw_bins(win, dr); + draw_bins(win, dr, current_thread); } } win->end_frame(GraphicsOutput::FM_render); @@ -1161,14 +1191,14 @@ draw_bins(const GraphicsEngine::Windows &wlist) { // particular DisplayRegion. //////////////////////////////////////////////////////////////////// void GraphicsEngine:: -draw_bins(GraphicsOutput *win, DisplayRegion *dr) { +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(); if (cull_result != (CullResult *)NULL && scene_setup != (SceneSetup *)NULL) { - do_draw(cull_result, scene_setup, win, dr); + do_draw(cull_result, scene_setup, win, dr, current_thread); } } @@ -1180,7 +1210,7 @@ draw_bins(GraphicsOutput *win, DisplayRegion *dr) { // graphics context both get created. //////////////////////////////////////////////////////////////////// void GraphicsEngine:: -make_contexts(const GraphicsEngine::Windows &wlist) { +make_contexts(const GraphicsEngine::Windows &wlist, Thread *current_thread) { Windows::const_iterator wi; for (wi = wlist.begin(); wi != wlist.end(); ++wi) { GraphicsOutput *win = (*wi); @@ -1198,7 +1228,7 @@ make_contexts(const GraphicsEngine::Windows &wlist) { // list of windows. This is run in the window thread. //////////////////////////////////////////////////////////////////// void GraphicsEngine:: -process_events(const GraphicsEngine::Windows &wlist) { +process_events(const GraphicsEngine::Windows &wlist, Thread *current_thread) { Windows::const_iterator wi; for (wi = wlist.begin(); wi != wlist.end(); ++wi) { GraphicsOutput *win = (*wi); @@ -1214,7 +1244,7 @@ process_events(const GraphicsEngine::Windows &wlist) { // the given list. This is run in the draw thread. //////////////////////////////////////////////////////////////////// void GraphicsEngine:: -flip_windows(const GraphicsEngine::Windows &wlist) { +flip_windows(const GraphicsEngine::Windows &wlist, Thread *current_thread) { Windows::const_iterator wi; for (wi = wlist.begin(); wi != wlist.end(); ++wi) { GraphicsOutput *win = (*wi); @@ -1239,7 +1269,7 @@ flip_windows(const GraphicsEngine::Windows &wlist) { // is already held before this method is called. //////////////////////////////////////////////////////////////////// void GraphicsEngine:: -do_sync_frame() { +do_sync_frame(Thread *current_thread) { nassertv(_lock.debug_is_locked()); // Statistics @@ -1266,7 +1296,7 @@ do_sync_frame() { // is already held before this method is called. //////////////////////////////////////////////////////////////////// void GraphicsEngine:: -do_flip_frame() { +do_flip_frame(Thread *current_thread) { nassertv(_lock.debug_is_locked()); // Statistics @@ -1291,7 +1321,7 @@ do_flip_frame() { } // Now signal all of our threads to flip the windows. - _app.do_flip(this); + _app.do_flip(this, current_thread); { Threads::const_iterator ti; @@ -1316,7 +1346,7 @@ do_flip_frame() { // reason. //////////////////////////////////////////////////////////////////// PT(SceneSetup) GraphicsEngine:: -setup_scene(GraphicsStateGuardian *gsg, DisplayRegion *dr) { +setup_scene(GraphicsStateGuardian *gsg, DisplayRegionPipelineReader *dr) { PStatTimer timer(_cull_setup_pcollector); GraphicsOutput *window = dr->get_window(); @@ -1380,7 +1410,7 @@ setup_scene(GraphicsStateGuardian *gsg, DisplayRegion *dr) { initial_state = initial_state->compose(get_invert_polygon_state()); } - scene_setup->set_display_region(dr); + scene_setup->set_display_region(dr->get_object()); scene_setup->set_viewport_size(dr->get_pixel_width(), dr->get_pixel_height()); scene_setup->set_scene_root(scene_root); scene_setup->set_camera_path(camera); @@ -1400,7 +1430,7 @@ setup_scene(GraphicsStateGuardian *gsg, DisplayRegion *dr) { //////////////////////////////////////////////////////////////////// void GraphicsEngine:: do_cull(CullHandler *cull_handler, SceneSetup *scene_setup, - GraphicsStateGuardian *gsg) { + GraphicsStateGuardian *gsg, Thread *current_thread) { CullTraverser trav(gsg); trav.set_cull_handler(cull_handler); trav.set_depth_offset_decals(depth_offset_decals && gsg->depth_offset_decals()); @@ -1439,21 +1469,24 @@ do_cull(CullHandler *cull_handler, SceneSetup *scene_setup, //////////////////////////////////////////////////////////////////// void GraphicsEngine:: do_draw(CullResult *cull_result, SceneSetup *scene_setup, - GraphicsOutput *win, DisplayRegion *dr) { + GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) { // Statistics PStatTimer timer(_draw_pcollector); - GraphicsStateGuardian *gsg = win->get_gsg(); - win->change_scenes(dr); + DisplayRegionPipelineReader *dr_reader = + new DisplayRegionPipelineReader(dr, current_thread); - if (dr->get_stereo_channel() == Lens::SC_stereo) { + GraphicsStateGuardian *gsg = win->get_gsg(); + win->change_scenes(dr_reader); + + if (dr_reader->get_stereo_channel() == Lens::SC_stereo) { // A special case. For a stereo DisplayRegion, we render the left // eye, followed by the right eye. - if (dr->is_any_clear_active()) { - gsg->prepare_display_region(dr, Lens::SC_stereo); - gsg->clear(dr); + if (dr_reader->is_any_clear_active()) { + gsg->prepare_display_region(dr_reader, Lens::SC_stereo); + gsg->clear(dr_reader->get_object()); } - gsg->prepare_display_region(dr, Lens::SC_left); + gsg->prepare_display_region(dr_reader, Lens::SC_left); if (!gsg->set_scene(scene_setup)) { // The scene or lens is inappropriate somehow. @@ -1461,19 +1494,24 @@ do_draw(CullResult *cull_result, SceneSetup *scene_setup, << gsg->get_type() << " cannot render scene with specified lens.\n"; } else { if (gsg->begin_scene()) { - cull_result->draw(); + delete dr_reader; + dr_reader = NULL; + cull_result->draw(current_thread); gsg->end_scene(); + dr_reader = new DisplayRegionPipelineReader(dr, current_thread); } - if (dr->get_clear_depth_between_eyes()) { + if (dr_reader->get_clear_depth_between_eyes()) { DrawableRegion clear_region; clear_region.set_clear_depth_active(true); clear_region.set_clear_depth(dr->get_clear_depth()); gsg->clear(&clear_region); } - gsg->prepare_display_region(dr, Lens::SC_right); + gsg->prepare_display_region(dr_reader, Lens::SC_right); gsg->set_scene(scene_setup); if (gsg->begin_scene()) { - cull_result->draw(); + delete dr_reader; + dr_reader = NULL; + cull_result->draw(current_thread); gsg->end_scene(); } } @@ -1481,22 +1519,28 @@ do_draw(CullResult *cull_result, SceneSetup *scene_setup, } else { // For a mono DisplayRegion, or a left/right eye only // DisplayRegion, we just render that. - gsg->prepare_display_region(dr, dr->get_stereo_channel()); + gsg->prepare_display_region(dr_reader, dr_reader->get_stereo_channel()); if (!gsg->set_scene(scene_setup)) { // The scene or lens is inappropriate somehow. display_cat.error() << gsg->get_type() << " cannot render scene with specified lens.\n"; } else { - if (dr->is_any_clear_active()) { - gsg->clear(dr); + if (dr_reader->is_any_clear_active()) { + gsg->clear(dr_reader->get_object()); } if (gsg->begin_scene()) { - cull_result->draw(); + delete dr_reader; + dr_reader = NULL; + cull_result->draw(current_thread); gsg->end_scene(); } } } + + if (dr_reader != (DisplayRegionPipelineReader *)NULL) { + delete dr_reader; + } } //////////////////////////////////////////////////////////////////// @@ -1564,7 +1608,7 @@ do_add_window(GraphicsOutput *window, GraphicsStateGuardian *gsg, // _windows list itself. //////////////////////////////////////////////////////////////////// void GraphicsEngine:: -do_remove_window(GraphicsOutput *window) { +do_remove_window(GraphicsOutput *window, Thread *current_thread) { PT(GraphicsPipe) pipe = window->get_pipe(); window->_pipe = (GraphicsPipe *)NULL; @@ -1582,7 +1626,7 @@ do_remove_window(GraphicsOutput *window) { // If the window happened to be controlled by the app thread, we // might as well close it now rather than waiting for next frame. - _app.do_pending(this); + _app.do_pending(this, current_thread); if (display_cat.is_debug()) { display_cat.debug() @@ -1858,16 +1902,16 @@ resort_windows() { // the draw list, etc. //////////////////////////////////////////////////////////////////// void GraphicsEngine::WindowRenderer:: -do_frame(GraphicsEngine *engine) { +do_frame(GraphicsEngine *engine, Thread *current_thread) { PStatTimer timer(engine->_do_frame_pcollector); MutexHolder holder(_wl_lock); do_callbacks(CB_pre_frame); - engine->cull_to_bins(_cull); - engine->cull_and_draw_together(_cdraw); - engine->draw_bins(_draw); - engine->process_events(_window); + engine->cull_to_bins(_cull, current_thread); + engine->cull_and_draw_together(_cdraw, current_thread); + engine->draw_bins(_draw, current_thread); + engine->process_events(_window, current_thread); // If any GSG's on the list have no more outstanding pointers, clean // them up. (We are in the draw thread for all of these GSG's.) @@ -1902,13 +1946,13 @@ do_frame(GraphicsEngine *engine) { // only if you want these things to open immediately.) //////////////////////////////////////////////////////////////////// void GraphicsEngine::WindowRenderer:: -do_windows(GraphicsEngine *engine) { +do_windows(GraphicsEngine *engine, Thread *current_thread) { MutexHolder holder(_wl_lock); - engine->process_events(_window); + engine->process_events(_window, current_thread); - engine->make_contexts(_cdraw); - engine->make_contexts(_draw); + engine->make_contexts(_cdraw, current_thread); + engine->make_contexts(_draw, current_thread); } //////////////////////////////////////////////////////////////////// @@ -1918,10 +1962,10 @@ do_windows(GraphicsEngine *engine) { // thread. //////////////////////////////////////////////////////////////////// void GraphicsEngine::WindowRenderer:: -do_flip(GraphicsEngine *engine) { +do_flip(GraphicsEngine *engine, Thread *current_thread) { MutexHolder holder(_wl_lock); - engine->flip_windows(_cdraw); - engine->flip_windows(_draw); + engine->flip_windows(_cdraw, current_thread); + engine->flip_windows(_draw, current_thread); } //////////////////////////////////////////////////////////////////// @@ -1930,7 +1974,7 @@ do_flip(GraphicsEngine *engine) { // Description: Closes all the windows on the _window list. //////////////////////////////////////////////////////////////////// void GraphicsEngine::WindowRenderer:: -do_close(GraphicsEngine *engine) { +do_close(GraphicsEngine *engine, Thread *current_thread) { MutexHolder holder(_wl_lock); Windows::iterator wi; for (wi = _window.begin(); wi != _window.end(); ++wi) { @@ -1963,7 +2007,7 @@ do_close(GraphicsEngine *engine) { // removed from the WindowRenderer. //////////////////////////////////////////////////////////////////// void GraphicsEngine::WindowRenderer:: -do_pending(GraphicsEngine *engine) { +do_pending(GraphicsEngine *engine, Thread *current_thread) { MutexHolder holder(_wl_lock); if (!_pending_close.empty()) { @@ -2076,6 +2120,8 @@ RenderThread(const string &name, GraphicsEngine *engine) : //////////////////////////////////////////////////////////////////// void GraphicsEngine::RenderThread:: thread_main() { + Thread *current_thread = Thread::get_current_thread(); + MutexHolder holder(_cv_mutex); while (true) { nassertv(_cv_mutex.debug_is_locked()); @@ -2085,26 +2131,26 @@ thread_main() { break; case TS_do_frame: - do_pending(_engine); - do_frame(_engine); + do_pending(_engine, current_thread); + do_frame(_engine, current_thread); break; case TS_do_flip: - do_flip(_engine); + do_flip(_engine, current_thread); break; case TS_do_release: - do_pending(_engine); + do_pending(_engine, current_thread); break; case TS_do_windows: - do_windows(_engine); - do_pending(_engine); + do_windows(_engine, current_thread); + do_pending(_engine, current_thread); break; case TS_terminate: - do_pending(_engine); - do_close(_engine); + do_pending(_engine, current_thread); + do_close(_engine, current_thread); _thread_state = TS_done; _cv_done.signal(); return; diff --git a/panda/src/display/graphicsEngine.h b/panda/src/display/graphicsEngine.h index 7b1b0231dc..b4b7d99e89 100644 --- a/panda/src/display/graphicsEngine.h +++ b/panda/src/display/graphicsEngine.h @@ -152,30 +152,32 @@ private: void set_window_sort(GraphicsOutput *window, int sort); - void cull_and_draw_together(const Windows &wlist); - void cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr); + void cull_and_draw_together(const Windows &wlist, Thread *current_thread); + void cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr, + Thread *current_thread); - void cull_to_bins(const Windows &wlist); - void cull_to_bins(GraphicsOutput *win, DisplayRegion *dr); - void draw_bins(const Windows &wlist); - void draw_bins(GraphicsOutput *win, DisplayRegion *dr); - void make_contexts(const Windows &wlist); + void cull_to_bins(const Windows &wlist, Thread *current_thread); + void cull_to_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread); + void draw_bins(const Windows &wlist, Thread *current_thread); + void draw_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread); + void make_contexts(const Windows &wlist, Thread *current_thread); - void process_events(const Windows &wlist); - void flip_windows(const Windows &wlist); - void do_sync_frame(); - void do_flip_frame(); + void process_events(const Windows &wlist, Thread *current_thread); + void flip_windows(const Windows &wlist, Thread *current_thread); + void do_sync_frame(Thread *current_thread); + void do_flip_frame(Thread *current_thread); INLINE void close_gsg(GraphicsPipe *pipe, GraphicsStateGuardian *gsg); - PT(SceneSetup) setup_scene(GraphicsStateGuardian *gsg, DisplayRegion *dr); + PT(SceneSetup) setup_scene(GraphicsStateGuardian *gsg, + DisplayRegionPipelineReader *dr); void do_cull(CullHandler *cull_handler, SceneSetup *scene_setup, - GraphicsStateGuardian *gsg); + GraphicsStateGuardian *gsg, Thread *current_thread); void do_draw(CullResult *cull_result, SceneSetup *scene_setup, - GraphicsOutput *win, DisplayRegion *dr); + GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread); void do_add_window(GraphicsOutput *window, GraphicsStateGuardian *gsg, const GraphicsThreadingModel &threading_model); - void do_remove_window(GraphicsOutput *window); + void do_remove_window(GraphicsOutput *window, Thread *current_thread); void do_resort_windows(); void terminate_threads(); @@ -275,12 +277,12 @@ private: void add_window(Windows &wlist, GraphicsOutput *window); void remove_window(GraphicsOutput *window); void resort_windows(); - void do_frame(GraphicsEngine *engine); - void do_windows(GraphicsEngine *engine); - void do_flip(GraphicsEngine *engine); - void do_release(GraphicsEngine *engine); - void do_close(GraphicsEngine *engine); - void do_pending(GraphicsEngine *engine); + void do_frame(GraphicsEngine *engine, Thread *current_thread); + void do_windows(GraphicsEngine *engine, Thread *current_thread); + void do_flip(GraphicsEngine *engine, Thread *current_thread); + void do_release(GraphicsEngine *engine, Thread *current_thread); + void do_close(GraphicsEngine *engine, Thread *current_thread); + void do_pending(GraphicsEngine *engine, Thread *current_thread); bool any_done_gsgs() const; bool add_callback(CallbackTime callback_time, const Callback &callback); diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index a39f39d244..0587e0dcbb 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -971,7 +971,7 @@ prepare_for_deletion() { // This function is called only within the draw thread. //////////////////////////////////////////////////////////////////// void GraphicsOutput:: -clear() { +clear(Thread *current_thread) { if (is_any_clear_active()) { if (display_cat.is_spam()) { display_cat.spam() @@ -981,7 +981,8 @@ clear() { nassertv(_gsg != (GraphicsStateGuardian *)NULL); - _gsg->prepare_display_region(_default_display_region, Lens::SC_mono); + DisplayRegionPipelineReader dr_reader(_default_display_region, current_thread); + _gsg->prepare_display_region(&dr_reader, Lens::SC_mono); _gsg->clear(this); } } @@ -1049,14 +1050,14 @@ copy_to_textures() { // of a cube map. //////////////////////////////////////////////////////////////////// void GraphicsOutput:: -change_scenes(DisplayRegion *new_dr) { +change_scenes(DisplayRegionPipelineReader *new_dr) { int new_cube_map_index = new_dr->get_cube_map_index(); if (new_cube_map_index != -1 && new_cube_map_index != _cube_map_index) { int old_cube_map_index = _cube_map_index; DisplayRegion *old_cube_map_dr = _cube_map_dr; _cube_map_index = new_cube_map_index; - _cube_map_dr = new_dr; + _cube_map_dr = new_dr->get_object(); for (int i=0; iget_object(); _current_stereo_channel = stereo_channel; _stereo_buffer_mask = ~0; diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 08f68da476..d030619117 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -28,6 +28,7 @@ #include "graphicsThreadingModel.h" #include "graphicsPipe.h" #include "sceneSetup.h" +#include "displayRegion.h" #include "luse.h" #include "coordinateSystem.h" #include "factory.h" @@ -174,7 +175,7 @@ public: const LMatrix4f *fetch_specified_value(ShaderContext::ShaderMatSpec &spec, bool altered); const LMatrix4f *fetch_specified_part(ShaderContext::ShaderMatInput input, InternalName *name, LMatrix4f &t); - virtual void prepare_display_region(DisplayRegion *dr, + virtual void prepare_display_region(DisplayRegionPipelineReader *dr, Lens::StereoChannel stereo_channel); virtual CPT(TransformState) calc_projection_mat(const Lens *lens); diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index 784d75d6c9..a7109e1d03 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -556,12 +556,13 @@ do_clear(const RenderBuffer &buffer) { // scissor region and viewport) //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian8:: -prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel) { - nassertv(dr != (DisplayRegion *)NULL); +prepare_display_region(DisplayRegionPipelineReader *dr, + Lens::StereoChannel stereo_channel) { + nassertv(dr != (DisplayRegionPipelineReader *)NULL); GraphicsStateGuardian::prepare_display_region(dr, stereo_channel); int l, u, w, h; - _current_display_region->get_region_pixels_i(l, u, w, h); + dr->get_region_pixels_i(l, u, w, h); // Create the viewport D3DVIEWPORT8 vp = { l, u, w, h, 0.0f, 1.0f }; diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index 72aef3468e..8e2d5f223f 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -66,7 +66,8 @@ public: virtual void do_clear(const RenderBuffer &buffer); - virtual void prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel); + virtual void prepare_display_region(DisplayRegionPipelineReader *dr, + Lens::StereoChannel stereo_channel); virtual CPT(TransformState) calc_projection_mat(const Lens *lens); virtual bool prepare_lens(); diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 941aeaaaa8..2a6cb6ba0a 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -772,8 +772,9 @@ do_clear(const RenderBuffer &buffer) { // scissor region and viewport) //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: -prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel) { - nassertv(dr != (DisplayRegion *)NULL); +prepare_display_region(DisplayRegionPipelineReader *dr, + Lens::StereoChannel stereo_channel) { + nassertv(dr != (DisplayRegionPipelineReader *)NULL); GraphicsStateGuardian::prepare_display_region(dr, stereo_channel); // DBG_S dxgsg9_cat.debug ( ) << "DXGraphicsStateGuardian9::PRE prepare_display_region\n"; DBG_E @@ -781,7 +782,7 @@ prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel) { // DBG_S dxgsg9_cat.debug ( ) << "DXGraphicsStateGuardian9::prepare_display_region\n"; DBG_E int l, u, w, h; - _current_display_region->get_region_pixels_i(l, u, w, h); + dr->get_region_pixels_i(l, u, w, h); DBG_S dxgsg9_cat.debug ( ) << "display_region " << l << " " << u << " " << w << " " << h << "\n"; DBG_E diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index e5376d0897..4ca8d5e34b 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -102,7 +102,8 @@ public: virtual void do_clear(const RenderBuffer &buffer); - virtual void prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel); + virtual void prepare_display_region(DisplayRegionPipelineReader *dr, + Lens::StereoChannel stereo_channel); virtual CPT(TransformState) calc_projection_mat(const Lens *lens); virtual bool prepare_lens(); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index b35f907cb5..0a79b1318c 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1146,12 +1146,13 @@ do_clear(const RenderBuffer &buffer) { // scissor region and viewport) //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: -prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel) { - nassertv(dr != (DisplayRegion *)NULL); +prepare_display_region(DisplayRegionPipelineReader *dr, + Lens::StereoChannel stereo_channel) { + nassertv(dr != (DisplayRegionPipelineReader *)NULL); GraphicsStateGuardian::prepare_display_region(dr, stereo_channel); int l, b, w, h; - _current_display_region->get_region_pixels(l, b, w, h); + dr->get_region_pixels(l, b, w, h); _viewport_width = w; _viewport_height = h; GLint x = GLint(l); @@ -1159,7 +1160,7 @@ prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel) { GLsizei width = GLsizei(w); GLsizei height = GLsizei(h); - set_draw_buffer(get_render_buffer(_current_display_region->get_draw_buffer_type(), + set_draw_buffer(get_render_buffer(dr->get_object()->get_draw_buffer_type(), *_current_properties)); enable_scissor(true); GLP(Scissor)(x, y, width, height); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 1c30cf633c..46a9ae7f7d 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -95,7 +95,8 @@ public: virtual void do_clear(const RenderBuffer &buffer); - virtual void prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel); + virtual void prepare_display_region(DisplayRegionPipelineReader *dr, + Lens::StereoChannel stereo_channel); virtual CPT(TransformState) calc_projection_mat(const Lens *lens); virtual bool prepare_lens(); diff --git a/panda/src/gobj/geom.cxx b/panda/src/gobj/geom.cxx index 0901663259..86c3777716 100644 --- a/panda/src/gobj/geom.cxx +++ b/panda/src/gobj/geom.cxx @@ -930,8 +930,7 @@ prepare_now(PreparedGraphicsObjects *prepared_objects, //////////////////////////////////////////////////////////////////// void Geom:: draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger, - const GeomVertexData *vertex_data) const { - Thread *current_thread = Thread::get_current_thread(); + const GeomVertexData *vertex_data, Thread *current_thread) const { GeomPipelineReader geom_reader(this, current_thread); geom_reader.check_usage_hint(); diff --git a/panda/src/gobj/geom.h b/panda/src/gobj/geom.h index d059902cef..995278e6d0 100644 --- a/panda/src/gobj/geom.h +++ b/panda/src/gobj/geom.h @@ -126,7 +126,8 @@ public: void draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger, - const GeomVertexData *vertex_data) const; + const GeomVertexData *vertex_data, + Thread *current_thread) const; INLINE void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, diff --git a/panda/src/pgraph/cullBin.cxx b/panda/src/pgraph/cullBin.cxx index 41d1f0ee7e..b49bcb5e26 100644 --- a/panda/src/pgraph/cullBin.cxx +++ b/panda/src/pgraph/cullBin.cxx @@ -74,16 +74,6 @@ void CullBin:: finish_cull(SceneSetup *) { } -//////////////////////////////////////////////////////////////////// -// Function: CullBin::draw -// Access: Public, Virtual -// Description: Draws all the geoms in the bin, in the appropriate -// order. -//////////////////////////////////////////////////////////////////// -void CullBin:: -draw() { -} - //////////////////////////////////////////////////////////////////// // Function: CullBin::check_flash_color // Access: Private diff --git a/panda/src/pgraph/cullBin.h b/panda/src/pgraph/cullBin.h index 231d7387a2..8358eeee74 100644 --- a/panda/src/pgraph/cullBin.h +++ b/panda/src/pgraph/cullBin.h @@ -57,7 +57,7 @@ public: virtual void add_object(CullableObject *object)=0; virtual void finish_cull(SceneSetup *scene_setup); - virtual void draw()=0; + virtual void draw(Thread *current_thread)=0; INLINE bool has_flash_color() const; INLINE const Colorf &get_flash_color() const; diff --git a/panda/src/pgraph/cullHandler.I b/panda/src/pgraph/cullHandler.I index bbe1f97ad3..4d7f53504a 100644 --- a/panda/src/pgraph/cullHandler.I +++ b/panda/src/pgraph/cullHandler.I @@ -25,11 +25,12 @@ // the object. //////////////////////////////////////////////////////////////////// INLINE void CullHandler:: -draw(CullableObject *object, GraphicsStateGuardianBase *gsg) { +draw(CullableObject *object, GraphicsStateGuardianBase *gsg, + Thread *current_thread) { if (object->_next != (CullableObject *)NULL) { - draw_with_decals(object, gsg); + draw_with_decals(object, gsg, current_thread); } else { gsg->set_state_and_transform(object->_state, object->_internal_transform); - object->draw(gsg); + object->draw(gsg, current_thread); } } diff --git a/panda/src/pgraph/cullHandler.cxx b/panda/src/pgraph/cullHandler.cxx index 37a0b99fa9..0eb0cd2c5f 100644 --- a/panda/src/pgraph/cullHandler.cxx +++ b/panda/src/pgraph/cullHandler.cxx @@ -57,7 +57,8 @@ record_object(CullableObject *object, const CullTraverser *traverser) { // attached decals. //////////////////////////////////////////////////////////////////// void CullHandler:: -draw_with_decals(CullableObject *object, GraphicsStateGuardianBase *gsg) { +draw_with_decals(CullableObject *object, GraphicsStateGuardianBase *gsg, + Thread *current_thread) { // We draw with a three-step process. // First, render all of the base geometry for the first pass. @@ -66,7 +67,7 @@ draw_with_decals(CullableObject *object, GraphicsStateGuardianBase *gsg) { CullableObject *base = object; while (base != (CullableObject *)NULL && base->_geom != (Geom *)NULL) { gsg->set_state_and_transform(base->_state->compose(state), base->_internal_transform); - base->draw(gsg); + base->draw(gsg, current_thread); base = base->_next; } @@ -78,7 +79,7 @@ draw_with_decals(CullableObject *object, GraphicsStateGuardianBase *gsg) { CullableObject *decal = base->_next; while (decal != (CullableObject *)NULL) { gsg->set_state_and_transform(decal->_state->compose(state), decal->_internal_transform); - decal->draw(gsg); + decal->draw(gsg, current_thread); decal = decal->_next; } } @@ -89,7 +90,7 @@ draw_with_decals(CullableObject *object, GraphicsStateGuardianBase *gsg) { base = object; while (base != (CullableObject *)NULL && base->_geom != (Geom *)NULL) { gsg->set_state_and_transform(base->_state->compose(state), base->_internal_transform); - base->draw(gsg); + base->draw(gsg, current_thread); base = base->_next; } diff --git a/panda/src/pgraph/cullHandler.h b/panda/src/pgraph/cullHandler.h index fed5a9a865..913b508d4f 100644 --- a/panda/src/pgraph/cullHandler.h +++ b/panda/src/pgraph/cullHandler.h @@ -40,9 +40,11 @@ public: const CullTraverser *traverser); INLINE static void draw(CullableObject *object, - GraphicsStateGuardianBase *gsg); + GraphicsStateGuardianBase *gsg, + Thread *current_thread); static void draw_with_decals(CullableObject *object, - GraphicsStateGuardianBase *gsg); + GraphicsStateGuardianBase *gsg, + Thread *current_thread); }; #include "cullHandler.I" diff --git a/panda/src/pgraph/cullResult.cxx b/panda/src/pgraph/cullResult.cxx index ef4a6365df..3b87fde2c8 100644 --- a/panda/src/pgraph/cullResult.cxx +++ b/panda/src/pgraph/cullResult.cxx @@ -248,7 +248,7 @@ finish_cull(SceneSetup *scene_setup) { // order. //////////////////////////////////////////////////////////////////// void CullResult:: -draw() { +draw(Thread *current_thread) { // Ask the bin manager for the correct order to draw all the bins. CullBinManager *bin_manager = CullBinManager::get_global_ptr(); int num_bins = bin_manager->get_num_bins(); @@ -257,7 +257,7 @@ draw() { nassertv(bin_index >= 0); if (bin_index < (int)_bins.size() && _bins[bin_index] != (CullBin *)NULL) { - _bins[bin_index]->draw(); + _bins[bin_index]->draw(current_thread); } } } diff --git a/panda/src/pgraph/cullResult.h b/panda/src/pgraph/cullResult.h index 68943af69f..aee49de7d2 100644 --- a/panda/src/pgraph/cullResult.h +++ b/panda/src/pgraph/cullResult.h @@ -60,7 +60,7 @@ public: void add_object(CullableObject *object, const CullTraverser *traverser); void finish_cull(SceneSetup *scene_setup); - void draw(); + void draw(Thread *current_thread); public: static void bin_removed(int bin_index); diff --git a/panda/src/pgraph/cullableObject.I b/panda/src/pgraph/cullableObject.I index ab3dc2bd00..d40e5e6f52 100644 --- a/panda/src/pgraph/cullableObject.I +++ b/panda/src/pgraph/cullableObject.I @@ -121,8 +121,8 @@ has_decals() const { // from the draw thread. //////////////////////////////////////////////////////////////////// INLINE void CullableObject:: -draw(GraphicsStateGuardianBase *gsg) { - _geom->draw(gsg, _munger, _munged_data); +draw(GraphicsStateGuardianBase *gsg, Thread *current_thread) { + _geom->draw(gsg, _munger, _munged_data, current_thread); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/cullableObject.h b/panda/src/pgraph/cullableObject.h index f0965b0a5d..261f53cf2d 100644 --- a/panda/src/pgraph/cullableObject.h +++ b/panda/src/pgraph/cullableObject.h @@ -63,7 +63,8 @@ public: void munge_geom(GraphicsStateGuardianBase *gsg, GeomMunger *munger, const CullTraverser *traverser); - INLINE void draw(GraphicsStateGuardianBase *gsg); + INLINE void draw(GraphicsStateGuardianBase *gsg, + Thread *current_thread); public: ~CullableObject();