Further work to clean up UniformCache for Effects

This commit is contained in:
Stuart Buchanan 2014-09-27 22:05:30 +01:00
parent 2bf79a2fa1
commit 93a63a0678
4 changed files with 30 additions and 73 deletions

View File

@ -107,7 +107,6 @@ private:
typedef boost::tuple<std::string, Uniform::Type, std::string> UniformCacheKey;
typedef boost::tuple<ref_ptr<Uniform>, SGPropertyChangeListener*> UniformCacheValue;
//std::map<UniformCacheKey,UniformCacheValue > uniformCache;
std::map<UniformCacheKey,ref_ptr<Uniform> > uniformCache;
typedef std::queue<DeferredPropertyListener*> DeferredListenerList;
@ -147,8 +146,6 @@ ref_ptr<Uniform> UniformFactoryImpl::getUniform( Effect * effect,
}
UniformCacheKey key = boost::make_tuple(name, uniformType, val);
//UniformCacheValue value = uniformCache[key];
//ref_ptr<Uniform> uniform = value.get_head();
ref_ptr<Uniform> uniform = uniformCache[key];
if (uniform.valid()) {
@ -158,28 +155,27 @@ ref_ptr<Uniform> UniformFactoryImpl::getUniform( Effect * effect,
SG_LOG(SG_GL,SG_DEBUG,"new uniform " << name << " value " << uniformCache.size());
uniformCache[key] = uniform = new Uniform;
DeferredPropertyListener* updater = 0;
uniform->setName(name);
uniform->setType(uniformType);
switch (uniformType) {
case Uniform::BOOL:
updater = initFromParameters(effect, valProp, uniform.get(),
initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(bool)>(&Uniform::set),
options);
break;
case Uniform::FLOAT:
updater = initFromParameters(effect, valProp, uniform.get(),
initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(float)>(&Uniform::set),
options);
break;
case Uniform::FLOAT_VEC3:
updater = initFromParameters(effect, valProp, uniform.get(),
initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(const Vec3&)>(&Uniform::set),
vec3Names, options);
break;
case Uniform::FLOAT_VEC4:
updater = initFromParameters(effect, valProp, uniform.get(),
initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(const Vec4&)>(&Uniform::set),
vec4Names, options);
break;
@ -190,7 +186,7 @@ ref_ptr<Uniform> UniformFactoryImpl::getUniform( Effect * effect,
case Uniform::SAMPLER_1D_SHADOW:
case Uniform::SAMPLER_2D_SHADOW:
case Uniform::SAMPLER_CUBE:
updater = initFromParameters(effect, valProp, uniform.get(),
initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(int)>(&Uniform::set),
options);
break;
@ -199,7 +195,6 @@ ref_ptr<Uniform> UniformFactoryImpl::getUniform( Effect * effect,
break;
}
addListener(updater);
return uniform;
}
@ -1443,6 +1438,11 @@ bool Effect::realizeTechniques(const SGReaderWriterOptions* options)
return true;
}
void Effect::addDeferredPropertyListener(DeferredPropertyListener* listener)
{
UniformFactory::instance()->addListener(listener);
}
void Effect::InitializeCallback::doUpdate(osg::Node* node, osg::NodeVisitor* nv)
{
EffectGeode* eg = dynamic_cast<EffectGeode*>(node);
@ -1455,16 +1455,6 @@ void Effect::InitializeCallback::doUpdate(osg::Node* node, osg::NodeVisitor* nv)
// Initialize all queued listeners
UniformFactory::instance()->updateListeners(root);
for (vector<SGSharedPtr<Updater> >::iterator itr = effect->_extraData.begin(),
end = effect->_extraData.end();
itr != end;
++itr) {
InitializeWhenAdded* adder
= dynamic_cast<InitializeWhenAdded*>(itr->ptr());
if (adder)
adder->initOnAdd(effect, root);
}
}
bool Effect::Key::EqualTo::operator()(const Effect::Key& lhs,

View File

@ -54,32 +54,12 @@ class SGReaderWriterOptions;
* things, like manipulations of the global property tree, are are
* only safe in the update process.
*/
class InitializeWhenAdded
{
public:
InitializeWhenAdded() : _initialized(false) {};
virtual ~InitializeWhenAdded() {};
void initOnAdd(Effect* effect, SGPropertyNode* propRoot)
{
if (!_initialized) {
initOnAddImpl(effect, propRoot);
_initialized = true;
}
}
bool getInitialized() const { return _initialized; }
private:
virtual void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot) = 0;
bool _initialized;
};
class DeferredPropertyListener {
public:
virtual void activate(SGPropertyNode* propRoot) {};
virtual ~DeferredPropertyListener() {};
};
class Effect : public osg::Object
{
public:
@ -111,16 +91,7 @@ public:
* Build the techniques from the effect properties.
*/
bool realizeTechniques(const SGReaderWriterOptions* options = 0);
/**
* Updaters that should be derefed when the effect is
* deleted. Updaters arrange to be run by listening on properties
* or something.
*/
struct Updater : public virtual SGReferenced
{
virtual ~Updater() {}
};
void addUpdater(Updater* data) { _extraData.push_back(data); }
void addDeferredPropertyListener(DeferredPropertyListener* listener);
// Callback that is added to the effect geode to initialize the
// effect.
friend struct InitializeCallback;
@ -129,7 +100,6 @@ public:
void doUpdate(osg::Node* node, osg::NodeVisitor* nv);
};
protected:
std::vector<SGSharedPtr<Updater> > _extraData;
~Effect();
// Support for a cache of effects that inherit from this one, so
// Effect objects with the same parameters and techniques can be

View File

@ -607,33 +607,33 @@ inline void setDynamicVariance(osg::Object* obj)
* used.
*/
template<typename OSGParamType, typename ObjType, typename F>
DeferredPropertyListener*
void
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
const F& setter, const SGReaderWriterOptions* options)
{
const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop);
ScalarChangeListener<OSGParamType, ObjType, F>* listener = 0;
if (!valProp)
return listener;
return;
if (valProp->nChildren() == 0) {
setter(obj, valProp->getValue<OSGParamType>());
} else {
setDynamicVariance(obj);
std::string propName = getGlobalProperty(valProp, options);
listener
ScalarChangeListener<OSGParamType, ObjType, F>* listener
= new ScalarChangeListener<OSGParamType, ObjType, F>(obj, setter,
propName);
effect->addDeferredPropertyListener(listener);
}
return listener;
return;
}
template<typename OSGParamType, typename ObjType, typename SetterReturn>
inline DeferredPropertyListener*
inline void
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
SetterReturn (ObjType::*setter)(const OSGParamType),
const SGReaderWriterOptions* options)
{
return initFromParameters<OSGParamType>(effect, prop, obj,
initFromParameters<OSGParamType>(effect, prop, obj,
boost::bind(setter, _1, _2), options);
}
@ -658,17 +658,16 @@ initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
*/
template<typename OSGParamType, typename ObjType, typename NameItrType,
typename F>
DeferredPropertyListener*
void
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
const F& setter,
NameItrType nameItr, const SGReaderWriterOptions* options)
{
typedef typename Bridge<OSGParamType>::sg_type sg_type;
DeferredPropertyListener* listener = 0;
const int numComponents = props::NumComponents<sg_type>::num_components;
const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop);
if (!valProp)
return listener;
return;
if (valProp->nChildren() == 0) { // Has <use>?
setter(obj, Bridge<OSGParamType>::get(valProp->getValue<sg_type>()));
} else {
@ -678,22 +677,23 @@ initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
if (paramNames.empty())
throw BuilderException();
std::vector<std::string>::const_iterator pitr = paramNames.begin();
listener
DeferredPropertyListener* listener
= new_EEPropListener<sg_type>(make_OSGFunctor<OSGParamType>
(obj, setter),
0, pitr, pitr + numComponents);
effect->addDeferredPropertyListener(listener);
}
return listener;
return;
}
template<typename OSGParamType, typename ObjType, typename NameItrType,
typename SetterReturn>
inline DeferredPropertyListener*
inline void
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
SetterReturn (ObjType::*setter)(const OSGParamType&),
NameItrType nameItr, const SGReaderWriterOptions* options)
{
return initFromParameters<OSGParamType>(effect, prop, obj,
initFromParameters<OSGParamType>(effect, prop, obj,
boost::bind(setter, _1, _2), nameItr,
options);
}

View File

@ -859,12 +859,9 @@ TexEnvCombine* buildTexEnvCombine(Effect* effect, const SGPropertyNode* envProp,
#endif
const SGPropertyNode* colorNode = envProp->getChild("constant-color");
if (colorNode) {
DeferredPropertyListener* listener = initFromParameters(effect, colorNode, result,
initFromParameters(effect, colorNode, result,
&TexEnvCombine::setConstantColor, colorFields,
options);
if (listener != 0) {
SG_LOG(SG_ALL,SG_ALERT,"Texture with property defined parameter");
}
}
return result;
}
@ -961,8 +958,8 @@ private:
string buffer;
};
class BufferNameChangeListener : public SGPropertyChangeListener, public InitializeWhenAdded,
public Effect::Updater {
class BufferNameChangeListener : public SGPropertyChangeListener,
public DeferredPropertyListener {
public:
BufferNameChangeListener(Pass* p, int u, const std::string& pn) : pass(p), unit(u)
{
@ -978,7 +975,7 @@ public:
const char* buffer = node->getStringValue();
pass->setBufferUnit(unit, buffer);
}
void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot)
void activate(SGPropertyNode* propRoot)
{
SGPropertyNode* listenProp = makeNode(propRoot, *propName);
delete propName;
@ -1014,7 +1011,7 @@ Texture* GBufferBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode*
} else {
std::string propName = getGlobalProperty(nameProp, options);
BufferNameChangeListener* listener = new BufferNameChangeListener(pass, unit, propName);
effect->addUpdater(listener);
effect->addDeferredPropertyListener(listener);
}
// Return white for now. Would be overridden in Technique::ProcessDrawable