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<std::string, Uniform::Type, std::string> UniformCacheKey;
|
||||||
typedef boost::tuple<ref_ptr<Uniform>, SGPropertyChangeListener*> UniformCacheValue;
|
typedef boost::tuple<ref_ptr<Uniform>, SGPropertyChangeListener*> UniformCacheValue;
|
||||||
//std::map<UniformCacheKey,UniformCacheValue > uniformCache;
|
|
||||||
std::map<UniformCacheKey,ref_ptr<Uniform> > uniformCache;
|
std::map<UniformCacheKey,ref_ptr<Uniform> > uniformCache;
|
||||||
|
|
||||||
typedef std::queue<DeferredPropertyListener*> DeferredListenerList;
|
typedef std::queue<DeferredPropertyListener*> DeferredListenerList;
|
||||||
@ -147,8 +146,6 @@ ref_ptr<Uniform> UniformFactoryImpl::getUniform( Effect * effect,
|
|||||||
}
|
}
|
||||||
|
|
||||||
UniformCacheKey key = boost::make_tuple(name, uniformType, val);
|
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];
|
ref_ptr<Uniform> uniform = uniformCache[key];
|
||||||
|
|
||||||
if (uniform.valid()) {
|
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());
|
SG_LOG(SG_GL,SG_DEBUG,"new uniform " << name << " value " << uniformCache.size());
|
||||||
uniformCache[key] = uniform = new Uniform;
|
uniformCache[key] = uniform = new Uniform;
|
||||||
DeferredPropertyListener* updater = 0;
|
|
||||||
|
|
||||||
uniform->setName(name);
|
uniform->setName(name);
|
||||||
uniform->setType(uniformType);
|
uniform->setType(uniformType);
|
||||||
switch (uniformType) {
|
switch (uniformType) {
|
||||||
case Uniform::BOOL:
|
case Uniform::BOOL:
|
||||||
updater = initFromParameters(effect, valProp, uniform.get(),
|
initFromParameters(effect, valProp, uniform.get(),
|
||||||
static_cast<bool (Uniform::*)(bool)>(&Uniform::set),
|
static_cast<bool (Uniform::*)(bool)>(&Uniform::set),
|
||||||
options);
|
options);
|
||||||
break;
|
break;
|
||||||
case Uniform::FLOAT:
|
case Uniform::FLOAT:
|
||||||
updater = initFromParameters(effect, valProp, uniform.get(),
|
initFromParameters(effect, valProp, uniform.get(),
|
||||||
static_cast<bool (Uniform::*)(float)>(&Uniform::set),
|
static_cast<bool (Uniform::*)(float)>(&Uniform::set),
|
||||||
options);
|
options);
|
||||||
break;
|
break;
|
||||||
case Uniform::FLOAT_VEC3:
|
case Uniform::FLOAT_VEC3:
|
||||||
updater = initFromParameters(effect, valProp, uniform.get(),
|
initFromParameters(effect, valProp, uniform.get(),
|
||||||
static_cast<bool (Uniform::*)(const Vec3&)>(&Uniform::set),
|
static_cast<bool (Uniform::*)(const Vec3&)>(&Uniform::set),
|
||||||
vec3Names, options);
|
vec3Names, options);
|
||||||
break;
|
break;
|
||||||
case Uniform::FLOAT_VEC4:
|
case Uniform::FLOAT_VEC4:
|
||||||
updater = initFromParameters(effect, valProp, uniform.get(),
|
initFromParameters(effect, valProp, uniform.get(),
|
||||||
static_cast<bool (Uniform::*)(const Vec4&)>(&Uniform::set),
|
static_cast<bool (Uniform::*)(const Vec4&)>(&Uniform::set),
|
||||||
vec4Names, options);
|
vec4Names, options);
|
||||||
break;
|
break;
|
||||||
@ -190,7 +186,7 @@ ref_ptr<Uniform> UniformFactoryImpl::getUniform( Effect * effect,
|
|||||||
case Uniform::SAMPLER_1D_SHADOW:
|
case Uniform::SAMPLER_1D_SHADOW:
|
||||||
case Uniform::SAMPLER_2D_SHADOW:
|
case Uniform::SAMPLER_2D_SHADOW:
|
||||||
case Uniform::SAMPLER_CUBE:
|
case Uniform::SAMPLER_CUBE:
|
||||||
updater = initFromParameters(effect, valProp, uniform.get(),
|
initFromParameters(effect, valProp, uniform.get(),
|
||||||
static_cast<bool (Uniform::*)(int)>(&Uniform::set),
|
static_cast<bool (Uniform::*)(int)>(&Uniform::set),
|
||||||
options);
|
options);
|
||||||
break;
|
break;
|
||||||
@ -199,7 +195,6 @@ ref_ptr<Uniform> UniformFactoryImpl::getUniform( Effect * effect,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
addListener(updater);
|
|
||||||
return uniform;
|
return uniform;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1443,6 +1438,11 @@ bool Effect::realizeTechniques(const SGReaderWriterOptions* options)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Effect::addDeferredPropertyListener(DeferredPropertyListener* listener)
|
||||||
|
{
|
||||||
|
UniformFactory::instance()->addListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
void Effect::InitializeCallback::doUpdate(osg::Node* node, osg::NodeVisitor* nv)
|
void Effect::InitializeCallback::doUpdate(osg::Node* node, osg::NodeVisitor* nv)
|
||||||
{
|
{
|
||||||
EffectGeode* eg = dynamic_cast<EffectGeode*>(node);
|
EffectGeode* eg = dynamic_cast<EffectGeode*>(node);
|
||||||
@ -1455,16 +1455,6 @@ void Effect::InitializeCallback::doUpdate(osg::Node* node, osg::NodeVisitor* nv)
|
|||||||
|
|
||||||
// Initialize all queued listeners
|
// Initialize all queued listeners
|
||||||
UniformFactory::instance()->updateListeners(root);
|
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,
|
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
|
* things, like manipulations of the global property tree, are are
|
||||||
* only safe in the update process.
|
* 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 {
|
class DeferredPropertyListener {
|
||||||
public:
|
public:
|
||||||
virtual void activate(SGPropertyNode* propRoot) {};
|
virtual void activate(SGPropertyNode* propRoot) {};
|
||||||
virtual ~DeferredPropertyListener() {};
|
virtual ~DeferredPropertyListener() {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Effect : public osg::Object
|
class Effect : public osg::Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -111,16 +91,7 @@ public:
|
|||||||
* Build the techniques from the effect properties.
|
* Build the techniques from the effect properties.
|
||||||
*/
|
*/
|
||||||
bool realizeTechniques(const SGReaderWriterOptions* options = 0);
|
bool realizeTechniques(const SGReaderWriterOptions* options = 0);
|
||||||
/**
|
void addDeferredPropertyListener(DeferredPropertyListener* listener);
|
||||||
* 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); }
|
|
||||||
// Callback that is added to the effect geode to initialize the
|
// Callback that is added to the effect geode to initialize the
|
||||||
// effect.
|
// effect.
|
||||||
friend struct InitializeCallback;
|
friend struct InitializeCallback;
|
||||||
@ -129,7 +100,6 @@ public:
|
|||||||
void doUpdate(osg::Node* node, osg::NodeVisitor* nv);
|
void doUpdate(osg::Node* node, osg::NodeVisitor* nv);
|
||||||
};
|
};
|
||||||
protected:
|
protected:
|
||||||
std::vector<SGSharedPtr<Updater> > _extraData;
|
|
||||||
~Effect();
|
~Effect();
|
||||||
// Support for a cache of effects that inherit from this one, so
|
// Support for a cache of effects that inherit from this one, so
|
||||||
// Effect objects with the same parameters and techniques can be
|
// Effect objects with the same parameters and techniques can be
|
||||||
|
@ -607,33 +607,33 @@ inline void setDynamicVariance(osg::Object* obj)
|
|||||||
* used.
|
* used.
|
||||||
*/
|
*/
|
||||||
template<typename OSGParamType, typename ObjType, typename F>
|
template<typename OSGParamType, typename ObjType, typename F>
|
||||||
DeferredPropertyListener*
|
void
|
||||||
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
||||||
const F& setter, const SGReaderWriterOptions* options)
|
const F& setter, const SGReaderWriterOptions* options)
|
||||||
{
|
{
|
||||||
const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop);
|
const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop);
|
||||||
ScalarChangeListener<OSGParamType, ObjType, F>* listener = 0;
|
|
||||||
if (!valProp)
|
if (!valProp)
|
||||||
return listener;
|
return;
|
||||||
if (valProp->nChildren() == 0) {
|
if (valProp->nChildren() == 0) {
|
||||||
setter(obj, valProp->getValue<OSGParamType>());
|
setter(obj, valProp->getValue<OSGParamType>());
|
||||||
} else {
|
} else {
|
||||||
setDynamicVariance(obj);
|
setDynamicVariance(obj);
|
||||||
std::string propName = getGlobalProperty(valProp, options);
|
std::string propName = getGlobalProperty(valProp, options);
|
||||||
listener
|
ScalarChangeListener<OSGParamType, ObjType, F>* listener
|
||||||
= new ScalarChangeListener<OSGParamType, ObjType, F>(obj, setter,
|
= new ScalarChangeListener<OSGParamType, ObjType, F>(obj, setter,
|
||||||
propName);
|
propName);
|
||||||
|
effect->addDeferredPropertyListener(listener);
|
||||||
}
|
}
|
||||||
return listener;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename OSGParamType, typename ObjType, typename SetterReturn>
|
template<typename OSGParamType, typename ObjType, typename SetterReturn>
|
||||||
inline DeferredPropertyListener*
|
inline void
|
||||||
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
||||||
SetterReturn (ObjType::*setter)(const OSGParamType),
|
SetterReturn (ObjType::*setter)(const OSGParamType),
|
||||||
const SGReaderWriterOptions* options)
|
const SGReaderWriterOptions* options)
|
||||||
{
|
{
|
||||||
return initFromParameters<OSGParamType>(effect, prop, obj,
|
initFromParameters<OSGParamType>(effect, prop, obj,
|
||||||
boost::bind(setter, _1, _2), options);
|
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,
|
template<typename OSGParamType, typename ObjType, typename NameItrType,
|
||||||
typename F>
|
typename F>
|
||||||
DeferredPropertyListener*
|
void
|
||||||
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
||||||
const F& setter,
|
const F& setter,
|
||||||
NameItrType nameItr, const SGReaderWriterOptions* options)
|
NameItrType nameItr, const SGReaderWriterOptions* options)
|
||||||
{
|
{
|
||||||
typedef typename Bridge<OSGParamType>::sg_type sg_type;
|
typedef typename Bridge<OSGParamType>::sg_type sg_type;
|
||||||
DeferredPropertyListener* listener = 0;
|
|
||||||
const int numComponents = props::NumComponents<sg_type>::num_components;
|
const int numComponents = props::NumComponents<sg_type>::num_components;
|
||||||
const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop);
|
const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop);
|
||||||
if (!valProp)
|
if (!valProp)
|
||||||
return listener;
|
return;
|
||||||
if (valProp->nChildren() == 0) { // Has <use>?
|
if (valProp->nChildren() == 0) { // Has <use>?
|
||||||
setter(obj, Bridge<OSGParamType>::get(valProp->getValue<sg_type>()));
|
setter(obj, Bridge<OSGParamType>::get(valProp->getValue<sg_type>()));
|
||||||
} else {
|
} else {
|
||||||
@ -678,22 +677,23 @@ initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
|||||||
if (paramNames.empty())
|
if (paramNames.empty())
|
||||||
throw BuilderException();
|
throw BuilderException();
|
||||||
std::vector<std::string>::const_iterator pitr = paramNames.begin();
|
std::vector<std::string>::const_iterator pitr = paramNames.begin();
|
||||||
listener
|
DeferredPropertyListener* listener
|
||||||
= new_EEPropListener<sg_type>(make_OSGFunctor<OSGParamType>
|
= new_EEPropListener<sg_type>(make_OSGFunctor<OSGParamType>
|
||||||
(obj, setter),
|
(obj, setter),
|
||||||
0, pitr, pitr + numComponents);
|
0, pitr, pitr + numComponents);
|
||||||
|
effect->addDeferredPropertyListener(listener);
|
||||||
}
|
}
|
||||||
return listener;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename OSGParamType, typename ObjType, typename NameItrType,
|
template<typename OSGParamType, typename ObjType, typename NameItrType,
|
||||||
typename SetterReturn>
|
typename SetterReturn>
|
||||||
inline DeferredPropertyListener*
|
inline void
|
||||||
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
||||||
SetterReturn (ObjType::*setter)(const OSGParamType&),
|
SetterReturn (ObjType::*setter)(const OSGParamType&),
|
||||||
NameItrType nameItr, const SGReaderWriterOptions* options)
|
NameItrType nameItr, const SGReaderWriterOptions* options)
|
||||||
{
|
{
|
||||||
return initFromParameters<OSGParamType>(effect, prop, obj,
|
initFromParameters<OSGParamType>(effect, prop, obj,
|
||||||
boost::bind(setter, _1, _2), nameItr,
|
boost::bind(setter, _1, _2), nameItr,
|
||||||
options);
|
options);
|
||||||
}
|
}
|
||||||
|
@ -859,12 +859,9 @@ TexEnvCombine* buildTexEnvCombine(Effect* effect, const SGPropertyNode* envProp,
|
|||||||
#endif
|
#endif
|
||||||
const SGPropertyNode* colorNode = envProp->getChild("constant-color");
|
const SGPropertyNode* colorNode = envProp->getChild("constant-color");
|
||||||
if (colorNode) {
|
if (colorNode) {
|
||||||
DeferredPropertyListener* listener = initFromParameters(effect, colorNode, result,
|
initFromParameters(effect, colorNode, result,
|
||||||
&TexEnvCombine::setConstantColor, colorFields,
|
&TexEnvCombine::setConstantColor, colorFields,
|
||||||
options);
|
options);
|
||||||
if (listener != 0) {
|
|
||||||
SG_LOG(SG_ALL,SG_ALERT,"Texture with property defined parameter");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -961,8 +958,8 @@ private:
|
|||||||
string buffer;
|
string buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BufferNameChangeListener : public SGPropertyChangeListener, public InitializeWhenAdded,
|
class BufferNameChangeListener : public SGPropertyChangeListener,
|
||||||
public Effect::Updater {
|
public DeferredPropertyListener {
|
||||||
public:
|
public:
|
||||||
BufferNameChangeListener(Pass* p, int u, const std::string& pn) : pass(p), unit(u)
|
BufferNameChangeListener(Pass* p, int u, const std::string& pn) : pass(p), unit(u)
|
||||||
{
|
{
|
||||||
@ -978,7 +975,7 @@ public:
|
|||||||
const char* buffer = node->getStringValue();
|
const char* buffer = node->getStringValue();
|
||||||
pass->setBufferUnit(unit, buffer);
|
pass->setBufferUnit(unit, buffer);
|
||||||
}
|
}
|
||||||
void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot)
|
void activate(SGPropertyNode* propRoot)
|
||||||
{
|
{
|
||||||
SGPropertyNode* listenProp = makeNode(propRoot, *propName);
|
SGPropertyNode* listenProp = makeNode(propRoot, *propName);
|
||||||
delete propName;
|
delete propName;
|
||||||
@ -1014,7 +1011,7 @@ Texture* GBufferBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode*
|
|||||||
} else {
|
} else {
|
||||||
std::string propName = getGlobalProperty(nameProp, options);
|
std::string propName = getGlobalProperty(nameProp, options);
|
||||||
BufferNameChangeListener* listener = new BufferNameChangeListener(pass, unit, propName);
|
BufferNameChangeListener* listener = new BufferNameChangeListener(pass, unit, propName);
|
||||||
effect->addUpdater(listener);
|
effect->addDeferredPropertyListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return white for now. Would be overridden in Technique::ProcessDrawable
|
// Return white for now. Would be overridden in Technique::ProcessDrawable
|
||||||
|
Loading…
Reference in New Issue
Block a user