restore automatic pipeline expansion

This commit is contained in:
David Rose 2006-02-16 18:12:47 +00:00
parent 37b172d3d3
commit bf965cae20
9 changed files with 235 additions and 17 deletions

View File

@ -1605,6 +1605,7 @@ get_window_renderer(const string &name, int pipeline_stage) {
PT(RenderThread) thread = new RenderThread(name, this); PT(RenderThread) thread = new RenderThread(name, this);
thread->set_min_pipeline_stage(pipeline_stage); thread->set_min_pipeline_stage(pipeline_stage);
_pipeline->set_min_stages(pipeline_stage + 1);
thread->start(TP_normal, true, true); thread->start(TP_normal, true, true);
_threads[name] = thread; _threads[name] = thread;

View File

@ -51,6 +51,7 @@
nodePointerTo.h nodePointerTo.I \ nodePointerTo.h nodePointerTo.I \
pipeline.h pipeline.I \ pipeline.h pipeline.I \
pipelineCycler.h pipelineCycler.I \ pipelineCycler.h pipelineCycler.I \
pipelineCyclerLinks.h pipelineCyclerLinks.I \
pipelineCyclerBase.h \ pipelineCyclerBase.h \
pipelineCyclerDummyImpl.h pipelineCyclerDummyImpl.I \ pipelineCyclerDummyImpl.h pipelineCyclerDummyImpl.I \
pipelineCyclerTrivialImpl.h pipelineCyclerTrivialImpl.I \ pipelineCyclerTrivialImpl.h pipelineCyclerTrivialImpl.I \
@ -152,6 +153,7 @@
nodePointerTo.h nodePointerTo.I \ nodePointerTo.h nodePointerTo.I \
pipeline.h pipeline.I \ pipeline.h pipeline.I \
pipelineCycler.h pipelineCycler.I \ pipelineCycler.h pipelineCycler.I \
pipelineCyclerLinks.h pipelineCyclerLinks.I \
pipelineCyclerBase.h \ pipelineCyclerBase.h \
pipelineCyclerDummyImpl.h pipelineCyclerDummyImpl.I \ pipelineCyclerDummyImpl.h pipelineCyclerDummyImpl.I \
pipelineCyclerTrivialImpl.h pipelineCyclerTrivialImpl.I \ pipelineCyclerTrivialImpl.h pipelineCyclerTrivialImpl.I \

View File

@ -30,6 +30,17 @@ get_render_pipeline() {
return _render_pipeline; return _render_pipeline;
} }
////////////////////////////////////////////////////////////////////
// Function: Pipeline::set_min_stages
// Access: Public
// Description: Ensures that at least the indicated number of stages
// are in the pipeline.
////////////////////////////////////////////////////////////////////
INLINE void Pipeline::
set_min_stages(int min_stages) {
set_num_stages(max(min_stages, get_num_stages()));
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Pipeline::get_num_stages // Function: Pipeline::get_num_stages
// Access: Public // Access: Public

View File

@ -30,13 +30,20 @@ Pipeline *Pipeline::_render_pipeline = (Pipeline *)NULL;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
Pipeline:: Pipeline::
Pipeline(const string &name, int num_stages) : Pipeline(const string &name, int num_stages) :
Namable(name), Namable(name)
_num_stages(num_stages)
{ {
#ifdef THREADED_PIPELINE #ifdef THREADED_PIPELINE
// Set up the linked list of cyclers to be a circular list that
// begins with this object.
_prev = this;
_next = this;
_num_cyclers = 0; _num_cyclers = 0;
_cycling = false; _cycling = false;
#endif // THREADED_PIPELINE #endif // THREADED_PIPELINE
set_num_stages(num_stages);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -48,6 +55,9 @@ Pipeline::
~Pipeline() { ~Pipeline() {
#ifdef THREADED_PIPELINE #ifdef THREADED_PIPELINE
nassertv(_num_cyclers == 0); nassertv(_num_cyclers == 0);
nassertv(_prev == this && _next == this);
_prev = NULL;
_next = NULL;
nassertv(!_cycling); nassertv(!_cycling);
#endif // THREADED_PIPELINE #endif // THREADED_PIPELINE
} }
@ -148,6 +158,54 @@ cycle() {
#endif // THREADED_PIPELINE #endif // THREADED_PIPELINE
} }
////////////////////////////////////////////////////////////////////
// Function: Pipeline::set_num_stages
// Access: Public
// Description: Specifies the number of stages required for the
// pipeline.
////////////////////////////////////////////////////////////////////
void Pipeline::
set_num_stages(int num_stages) {
nassertv(num_stages >= 1);
#ifdef THREADED_PIPELINE
ReMutexHolder holder(_lock);
if (num_stages != _num_stages) {
// We need to lock every PipelineCycler object attached to this
// pipeline before we can adjust the number of stages.
PipelineCyclerLinks *links;
for (links = this->_next; links != this; links = links->_next) {
PipelineCyclerTrueImpl *cycler = (PipelineCyclerTrueImpl *)links;
cycler->_lock.lock();
}
_num_stages = num_stages;
for (links = this->_next; links != this; links = links->_next) {
PipelineCyclerTrueImpl *cycler = (PipelineCyclerTrueImpl *)links;
cycler->set_num_stages(num_stages);
}
// Now release them all.
int count = 0;
for (links = this->_next; links != this; links = links->_next) {
PipelineCyclerTrueImpl *cycler = (PipelineCyclerTrueImpl *)links;
cycler->_lock.release();
++count;
}
nassertv(count == _num_cyclers);
}
#else // THREADED_PIPELINE
if (_num_stages != 1) {
display_cat.warning()
<< "Requested " << pipeline_stages
<< " pipeline stages but multithreaded render pipelines not enabled in build.\n";
}
_num_stages = 1;
#endif // THREADED_PIPELINE
}
#ifdef THREADED_PIPELINE #ifdef THREADED_PIPELINE
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Pipeline::add_cycler // Function: Pipeline::add_cycler
@ -162,7 +220,8 @@ add_cycler(PipelineCyclerTrueImpl *cycler) {
nassertv(!cycler->_dirty); nassertv(!cycler->_dirty);
nassertv(!_cycling); nassertv(!_cycling);
++_num_cyclers; ++_num_cyclers;
cycler->insert_before(this);
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
inc_cycler_type(_all_cycler_types, cycler->get_parent_type(), 1); inc_cycler_type(_all_cycler_types, cycler->get_parent_type(), 1);
#endif #endif
@ -213,6 +272,7 @@ remove_cycler(PipelineCyclerTrueImpl *cycler) {
nassertv(!_cycling); nassertv(!_cycling);
--_num_cyclers; --_num_cyclers;
cycler->remove_from_list();
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
inc_cycler_type(_all_cycler_types, cycler->get_parent_type(), -1); inc_cycler_type(_all_cycler_types, cycler->get_parent_type(), -1);
@ -280,12 +340,13 @@ void Pipeline::
make_render_pipeline() { make_render_pipeline() {
ConfigVariableInt pipeline_stages ConfigVariableInt pipeline_stages
("pipeline-stages", 1, ("pipeline-stages", 1,
PRC_DESC("The number of stages in the render pipeline. This is only " PRC_DESC("The initial number of stages in the render pipeline. This is "
"meaningful if threaded pipelining is compiled into Panda, in " "only meaningful if threaded pipelining is compiled into "
"which case you should set this to 1, 2, or 3, according to " "Panda. In most cases, you should not set this at all anyway, "
"your application's threading model. You may set it larger " "since the pipeline can automatically grow stages as needed, "
"than your application requires, but this will incur additional " "but it will not remove stages automatically, and having more "
"overhead.")); "pipeline stages than your application requires will incur "
"additional runtime overhead."));
nassertv(_render_pipeline == (Pipeline *)NULL); nassertv(_render_pipeline == (Pipeline *)NULL);
_render_pipeline = new Pipeline("render", pipeline_stages); _render_pipeline = new Pipeline("render", pipeline_stages);

View File

@ -20,6 +20,7 @@
#define PIPELINE_H #define PIPELINE_H
#include "pandabase.h" #include "pandabase.h"
#include "pipelineCyclerLinks.h"
#include "namable.h" #include "namable.h"
#include "pset.h" #include "pset.h"
#include "reMutex.h" #include "reMutex.h"
@ -40,7 +41,7 @@ struct PipelineCyclerTrueImpl;
// pipeline. Other specialty pipelines may be created // pipeline. Other specialty pipelines may be created
// as needed. // as needed.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
class EXPCL_PANDA Pipeline : public Namable { class EXPCL_PANDA Pipeline : public PipelineCyclerLinks, public Namable {
public: public:
Pipeline(const string &name, int num_stages); Pipeline(const string &name, int num_stages);
~Pipeline(); ~Pipeline();
@ -49,6 +50,8 @@ public:
void cycle(); void cycle();
void set_num_stages(int num_stages);
INLINE void set_min_stages(int min_stages);
INLINE int get_num_stages() const; INLINE int get_num_stages() const;
#ifdef THREADED_PIPELINE #ifdef THREADED_PIPELINE

View File

@ -0,0 +1,83 @@
// Filename: pipelineCyclerLinks.I
// Created by: drose (16Feb06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifdef THREADED_PIPELINE
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerLinks::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE PipelineCyclerLinks::
PipelineCyclerLinks() {
#ifndef NDEBUG
_next = NULL;
_prev = NULL;
#endif
}
#endif // THREADED_PIPELINE
#ifdef THREADED_PIPELINE
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerLinks::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE PipelineCyclerLinks::
~PipelineCyclerLinks() {
nassertv(_next == NULL && _prev == NULL);
}
#endif // THREADED_PIPELINE
#ifdef THREADED_PIPELINE
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerLinks::remove_from_list
// Access: Private
// Description: Removes a PipelineCyclerLinks record from the
// doubly-linked list.
////////////////////////////////////////////////////////////////////
INLINE void PipelineCyclerLinks::
remove_from_list() {
nassertv(_prev->_next == this && _next->_prev == this);
_prev->_next = _next;
_next->_prev = _prev;
#ifndef NDEBUG
_next = NULL;
_prev = NULL;
#endif
}
#endif // THREADED_PIPELINE
#ifdef THREADED_PIPELINE
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerLinks::insert_before
// Access: Private
// Description: Adds a PipelineCyclerLinks record before the indicated
// node in the doubly-linked list.
////////////////////////////////////////////////////////////////////
INLINE void PipelineCyclerLinks::
insert_before(PipelineCyclerLinks *node) {
nassertv(node->_prev->_next == node && node->_next->_prev == node);
nassertv(_prev == (PipelineCyclerLinks *)NULL &&
_next == (PipelineCyclerLinks *)NULL);
_prev = node->_prev;
_next = node;
_prev->_next = this;
node->_prev = this;
}
#endif // THREADED_PIPELINE

View File

@ -0,0 +1,54 @@
// Filename: pipelineCyclerLinks.h
// Created by: drose (16Feb06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef PIPELINECYCLERLINKS_H
#define PIPELINECYCLERLINKS_H
#include "pandabase.h"
#include "selectThreadImpl.h" // for THREADED_PIPELINE definition
////////////////////////////////////////////////////////////////////
// Class : PipelineCyclerLinks
// Description : This just stores the pointers to implement a
// doubly-linked list of PipelineCyclers for a
// particular Pipeline object. We use a hand-rolled
// linked list rather than any STL container, because we
// want PipelineCyclers to be able to add and remove
// themselves from this list very quickly.
//
// These pointers are inherited from this separate class
// so the Pipeline object itself can be the root of the
// linked list.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA PipelineCyclerLinks {
protected:
#ifdef THREADED_PIPELINE
INLINE PipelineCyclerLinks();
INLINE ~PipelineCyclerLinks();
INLINE void remove_from_list();
INLINE void insert_before(PipelineCyclerLinks *node);
PipelineCyclerLinks *_prev, *_next;
#endif
friend class Pipeline;
};
#include "pipelineCyclerLinks.I"
#endif

View File

@ -18,7 +18,7 @@
#include "pipelineCyclerTrueImpl.h" #include "pipelineCyclerTrueImpl.h"
#if defined(DO_PIPELINING) && defined(HAVE_THREADS) #ifdef THREADED_PIPELINE
#include "config_util.h" #include "config_util.h"
#include "pipeline.h" #include "pipeline.h"
@ -343,8 +343,8 @@ void PipelineCyclerTrueImpl::CyclerMutex::
output(ostream &out) const { output(ostream &out) const {
_cycler->cheat()->output(out); _cycler->cheat()->output(out);
} }
#endif #endif // DEBUG_THREADS
#endif // DO_PIPELINING && HAVE_THREADS #endif // THREADED_PIPELINE

View File

@ -21,8 +21,9 @@
#include "pandabase.h" #include "pandabase.h"
#if defined(DO_PIPELINING) && defined(HAVE_THREADS) #ifdef THREADED_PIPELINE
#include "pipelineCyclerLinks.h"
#include "cycleData.h" #include "cycleData.h"
#include "pointerTo.h" #include "pointerTo.h"
#include "thread.h" #include "thread.h"
@ -46,7 +47,9 @@ class Pipeline;
// mainly to be consistent with // mainly to be consistent with
// PipelineCyclerTrivialImpl. // PipelineCyclerTrivialImpl.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
struct EXPCL_PANDA PipelineCyclerTrueImpl { struct EXPCL_PANDA PipelineCyclerTrueImpl : public PipelineCyclerLinks {
private:
PipelineCyclerTrueImpl();
public: public:
PipelineCyclerTrueImpl(CycleData *initial_data, Pipeline *pipeline = NULL); PipelineCyclerTrueImpl(CycleData *initial_data, Pipeline *pipeline = NULL);
PipelineCyclerTrueImpl(const PipelineCyclerTrueImpl &copy); PipelineCyclerTrueImpl(const PipelineCyclerTrueImpl &copy);
@ -91,7 +94,7 @@ public:
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
virtual void output(ostream &out) const; virtual void output(ostream &out) const;
PipelineCyclerTrueImpl *_cycler; PipelineCyclerTrueImpl *_cycler;
#endif #endif // DEBUG_THREADS
}; };
private: private:
@ -115,7 +118,7 @@ private:
#include "pipelineCyclerTrueImpl.I" #include "pipelineCyclerTrueImpl.I"
#endif // DO_PIPELINING && HAVE_THREADS #endif // THREADED_PIPELINE
#endif #endif