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);
thread->set_min_pipeline_stage(pipeline_stage);
_pipeline->set_min_stages(pipeline_stage + 1);
thread->start(TP_normal, true, true);
_threads[name] = thread;

View File

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

View File

@ -30,6 +30,17 @@ get_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
// Access: Public

View File

@ -30,13 +30,20 @@ Pipeline *Pipeline::_render_pipeline = (Pipeline *)NULL;
////////////////////////////////////////////////////////////////////
Pipeline::
Pipeline(const string &name, int num_stages) :
Namable(name),
_num_stages(num_stages)
Namable(name)
{
#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;
_cycling = false;
#endif // THREADED_PIPELINE
set_num_stages(num_stages);
}
////////////////////////////////////////////////////////////////////
@ -48,6 +55,9 @@ Pipeline::
~Pipeline() {
#ifdef THREADED_PIPELINE
nassertv(_num_cyclers == 0);
nassertv(_prev == this && _next == this);
_prev = NULL;
_next = NULL;
nassertv(!_cycling);
#endif // THREADED_PIPELINE
}
@ -148,6 +158,54 @@ cycle() {
#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
////////////////////////////////////////////////////////////////////
// Function: Pipeline::add_cycler
@ -162,7 +220,8 @@ add_cycler(PipelineCyclerTrueImpl *cycler) {
nassertv(!cycler->_dirty);
nassertv(!_cycling);
++_num_cyclers;
cycler->insert_before(this);
#ifdef DEBUG_THREADS
inc_cycler_type(_all_cycler_types, cycler->get_parent_type(), 1);
#endif
@ -213,6 +272,7 @@ remove_cycler(PipelineCyclerTrueImpl *cycler) {
nassertv(!_cycling);
--_num_cyclers;
cycler->remove_from_list();
#ifdef DEBUG_THREADS
inc_cycler_type(_all_cycler_types, cycler->get_parent_type(), -1);
@ -280,12 +340,13 @@ void Pipeline::
make_render_pipeline() {
ConfigVariableInt pipeline_stages
("pipeline-stages", 1,
PRC_DESC("The number of stages in the render pipeline. This is only "
"meaningful if threaded pipelining is compiled into Panda, in "
"which case you should set this to 1, 2, or 3, according to "
"your application's threading model. You may set it larger "
"than your application requires, but this will incur additional "
"overhead."));
PRC_DESC("The initial number of stages in the render pipeline. This is "
"only meaningful if threaded pipelining is compiled into "
"Panda. In most cases, you should not set this at all anyway, "
"since the pipeline can automatically grow stages as needed, "
"but it will not remove stages automatically, and having more "
"pipeline stages than your application requires will incur "
"additional runtime overhead."));
nassertv(_render_pipeline == (Pipeline *)NULL);
_render_pipeline = new Pipeline("render", pipeline_stages);

View File

@ -20,6 +20,7 @@
#define PIPELINE_H
#include "pandabase.h"
#include "pipelineCyclerLinks.h"
#include "namable.h"
#include "pset.h"
#include "reMutex.h"
@ -40,7 +41,7 @@ struct PipelineCyclerTrueImpl;
// pipeline. Other specialty pipelines may be created
// as needed.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA Pipeline : public Namable {
class EXPCL_PANDA Pipeline : public PipelineCyclerLinks, public Namable {
public:
Pipeline(const string &name, int num_stages);
~Pipeline();
@ -49,6 +50,8 @@ public:
void cycle();
void set_num_stages(int num_stages);
INLINE void set_min_stages(int min_stages);
INLINE int get_num_stages() const;
#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"
#if defined(DO_PIPELINING) && defined(HAVE_THREADS)
#ifdef THREADED_PIPELINE
#include "config_util.h"
#include "pipeline.h"
@ -343,8 +343,8 @@ void PipelineCyclerTrueImpl::CyclerMutex::
output(ostream &out) const {
_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"
#if defined(DO_PIPELINING) && defined(HAVE_THREADS)
#ifdef THREADED_PIPELINE
#include "pipelineCyclerLinks.h"
#include "cycleData.h"
#include "pointerTo.h"
#include "thread.h"
@ -46,7 +47,9 @@ class Pipeline;
// mainly to be consistent with
// PipelineCyclerTrivialImpl.
////////////////////////////////////////////////////////////////////
struct EXPCL_PANDA PipelineCyclerTrueImpl {
struct EXPCL_PANDA PipelineCyclerTrueImpl : public PipelineCyclerLinks {
private:
PipelineCyclerTrueImpl();
public:
PipelineCyclerTrueImpl(CycleData *initial_data, Pipeline *pipeline = NULL);
PipelineCyclerTrueImpl(const PipelineCyclerTrueImpl &copy);
@ -91,7 +94,7 @@ public:
#ifdef DEBUG_THREADS
virtual void output(ostream &out) const;
PipelineCyclerTrueImpl *_cycler;
#endif
#endif // DEBUG_THREADS
};
private:
@ -115,7 +118,7 @@ private:
#include "pipelineCyclerTrueImpl.I"
#endif // DO_PIPELINING && HAVE_THREADS
#endif // THREADED_PIPELINE
#endif