Further work to clean up UniformCache for Effects
This commit is contained in:
parent
2bf79a2fa1
commit
93a63a0678
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user