1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
41 /*---------------------------------------------------------------------------*/
42 /*---------------------------------------------------------------------------*/
44 template<class ObjectT> inline
45 ObjectT *ShaderVectorCache<ObjectT>::find(const IdStore &vIds)
47 typename ObjectStore::const_iterator sIt =
48 std::lower_bound(_vObjectStore.begin(),
52 if(sIt == _vObjectStore.end())
57 if(sIt->first != vIds)
65 template<class ObjectT> inline
66 bool ShaderVectorCache<ObjectT>::add (const IdStore &vIds,
69 bool returnValue = false;
71 typename ObjectStore::iterator sIt = std::lower_bound(_vObjectStore.begin(),
76 if(sIt == _vObjectStore.end())
78 _vObjectStore.push_back(StoreElement(vIds, pObject));
82 else if(sIt->first != vIds)
84 _vObjectStore.insert(sIt, StoreElement(vIds, pObject));
92 template<class ObjectT> inline
93 void ShaderVectorCache<ObjectT>::sub(UInt32 uiIdx)
95 typename ObjectStore:: iterator sIt = _vObjectStore.begin();
96 typename ObjectStore::const_iterator sEnd = _vObjectStore.end ();
101 IdStore::const_iterator idIt = std::find(sIt->first.begin(),
105 if(idIt != sIt->first.end())
107 sIt = _vObjectStore.erase(sIt);
108 sEnd = _vObjectStore.end();
117 template<class ObjectT> inline
118 void ShaderVectorCache<ObjectT>::dumpDot(const Char8 *szFilename)
122 template<class ObjectT>
123 template <typename ElemDestFunc> inline
124 void ShaderVectorCache<ObjectT>::destroy(ElemDestFunc destFunc)
126 #ifndef OSG_SHC_REF_CLEANUP
127 typename ObjectStore:: iterator sIt = _vObjectStore.begin();
128 typename ObjectStore::const_iterator sEnd = _vObjectStore.end ();
130 for(; sIt != sEnd; ++sIt)
132 (destFunc)(sIt->second);
140 template<class ObjectT> inline
141 ShaderVectorCache<ObjectT>::ShaderVectorCache(void) :
146 template<class ObjectT> inline
147 ShaderVectorCache<ObjectT>::~ShaderVectorCache(void)
153 /*---------------------------------------------------------------------------*/
154 /*---------------------------------------------------------------------------*/
156 template<class ObjectT> inline
157 ObjectT *ShaderMapCache<ObjectT>::find(const IdStore &vIds)
159 typename ObjectStore::const_iterator sIt = _vObjectStore.find(vIds);
161 if(sIt == _vObjectStore.end())
169 template<class ObjectT> inline
170 bool ShaderMapCache<ObjectT>::add (const IdStore &vIds,
173 bool returnValue = false;
175 typename ObjectStore::iterator sIt = _vObjectStore.lower_bound(vIds);
178 if(sIt == _vObjectStore.end() || sIt->first != vIds)
180 _vObjectStore.insert(sIt, std::make_pair(vIds, pObject));
188 template<class ObjectT> inline
189 void ShaderMapCache<ObjectT>::sub(UInt32 uiIdx)
191 typename ObjectStore:: iterator sIt = _vObjectStore.begin();
192 typename ObjectStore::const_iterator sEnd = _vObjectStore.end ();
194 std::vector<IdStore> vDestKeys;
198 IdStore::const_iterator idIt = std::find(sIt->first.begin(),
202 if(idIt != sIt->first.end())
204 vDestKeys.push_back(sIt->first);
210 std::vector<IdStore>::const_iterator kIt = vDestKeys.begin();
211 std::vector<IdStore>::const_iterator kEnd = vDestKeys.end ();
213 for(; kIt != kEnd; ++kIt)
215 _vObjectStore.erase(*kIt);
219 template<class ObjectT> inline
220 void ShaderMapCache<ObjectT>::dumpDot(const Char8 *szFilename)
224 template<class ObjectT>
225 template <typename ElemDestFunc> inline
226 void ShaderMapCache<ObjectT>::destroy(ElemDestFunc destFunc)
228 #ifndef OSG_SHC_REF_CLEANUP
229 typename ObjectStore:: iterator sIt = _vObjectStore.begin();
230 typename ObjectStore::const_iterator sEnd = _vObjectStore.end ();
232 for(; sIt != sEnd; ++sIt)
234 (destFunc)(sIt->second);
242 template<class ObjectT> inline
243 ShaderMapCache<ObjectT>::ShaderMapCache(void) :
248 template<class ObjectT> inline
249 ShaderMapCache<ObjectT>::~ShaderMapCache(void)
255 /*---------------------------------------------------------------------------*/
256 /*---------------------------------------------------------------------------*/
259 #if defined(WIN32) || defined(__APPLE__) || \
260 defined(__GXX_EXPERIMENTAL_CXX0X__)
261 template<class ObjectT, UInt32 LevelBits>
262 const Real32 ShaderCacheTreeV0<ObjectT, LevelBits>::LevelFactor =
266 template<class ObjectT, UInt32 LevelBits> inline
267 ShaderCacheTreeV0<ObjectT, LevelBits>::TreeNode::TreeNode(void) :
275 memset(&(_vChildren[0]), 0, LevelSize * sizeof(TreeNode *));
278 template<class ObjectT, UInt32 LevelBits> inline
279 ShaderCacheTreeV0<ObjectT, LevelBits>::TreeNode::~TreeNode(void)
286 template<class ObjectT, UInt32 LevelBits> inline
287 void ShaderCacheTreeV0<ObjectT, LevelBits>::TreeNode::clear(void)
293 memset(&(_vChildren[0]), 0, LevelSize * sizeof(TreeNode *));
297 static UInt16 IdxToBits[9] =
312 template<class ObjectT, UInt32 LevelBits> inline
313 ObjectT *ShaderCacheTreeV0<ObjectT, LevelBits>::find(const IdStore &vIds)
318 ObjectT *returnValue = NULL;
320 IdType uiStartId = vIds[0] - 1;
321 IdType uiStartLevel = IdType(uiStartId * LevelFactor);
324 UInt32 uiLastId = vIds.size();
327 if(uiStartLevel >= _vLevelEntries.size())
329 uiStartLevel = _vLevelEntries.size() - 1;
333 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
334 UInt32 uiCurrBits = 0x0000;
335 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
337 if(pCurrNode == NULL)
340 for(; uiCurrId < uiLastId; ++uiCurrId)
342 UInt32 uiCurrIdx = vIds[uiCurrId] - uiLevelSub;
344 if(uiCurrIdx <= LevelBits)
346 uiCurrBits |= IdxToBits[uiCurrIdx];
352 pCurrNode = pCurrNode->_vChildren[uiCurrBits];
354 if(pCurrNode == NULL)
361 uiLevelSub += LevelBits;
362 uiCurrIdx -= LevelBits;
364 while(uiCurrIdx > LevelBits)
366 pCurrNode = pCurrNode->_vChildren[0];
368 if(pCurrNode == NULL)
372 uiLevelSub += LevelBits;
373 uiCurrIdx -= LevelBits;
376 if(pCurrNode == NULL)
381 uiCurrBits |= IdxToBits[uiCurrIdx];
385 if(pCurrNode != NULL)
387 pCurrNode = pCurrNode->_vChildren[uiCurrBits];
389 if(pCurrNode != NULL)
391 returnValue = pCurrNode->_pObject;
399 template<class ObjectT, UInt32 LevelBits> inline
400 bool ShaderCacheTreeV0<ObjectT, LevelBits>::add(const IdStore &vIds,
403 bool returnValue = false;
408 IdType uiStartId = vIds[0] - 1;
410 IdType uiStartLevel = IdType(uiStartId * LevelFactor);
413 UInt32 uiLastId = vIds.size();
416 if(uiStartLevel >= _vLevelEntries.size())
418 uiStartLevel = _vLevelEntries.size() - 1;
421 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
423 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
424 TreeNode *pNextNode = NULL;
426 UInt32 uiCurrBits = 0x0000;
428 for(; uiCurrId < uiLastId; ++uiCurrId)
430 UInt32 uiCurrIdx = vIds[uiCurrId] - uiLevelSub;
432 if(uiCurrIdx <= LevelBits)
434 uiCurrBits |= IdxToBits[uiCurrIdx];
440 pNextNode = pCurrNode->_vChildren[uiCurrBits];
442 if(pNextNode == NULL)
444 pNextNode = allocateNode();
446 pCurrNode->_vChildren[uiCurrBits] = pNextNode;
448 if(uiStartLevel == _vLevelEntries.size() - 1)
450 if(_vLevelEntries.back()->_vChildren[0] == NULL)
452 TreeNode *pTmpNode = allocateNode();
454 _vLevelEntries.back()->_vChildren[0] = pTmpNode;
456 _vLevelEntries.push_back(pTmpNode);
458 pTmpNode->_pNext = pNextNode;
459 pNextNode->_pPrev = pTmpNode;
463 _vLevelEntries.push_back(pNextNode);
469 _vLevelEntries[uiStartLevel]->_vChildren[0]->_pNext;
471 if(pNextNode->_pNext != NULL)
473 pNextNode->_pNext->_pPrev = pNextNode;
476 _vLevelEntries[uiStartLevel]->_vChildren[0]->_pNext =
480 _vLevelEntries[uiStartLevel]->_vChildren[0];
488 pCurrNode = pNextNode;
490 uiLevelSub += LevelBits;
491 uiCurrIdx -= LevelBits;
493 while(uiCurrIdx > LevelBits)
495 if(pCurrNode->_vChildren[0] == NULL)
497 pNextNode = allocateNode();
499 pCurrNode->_vChildren[0] = pNextNode;
501 if(uiStartLevel == _vLevelEntries.size() - 1)
503 if(_vLevelEntries.back()->_vChildren[0] == NULL)
505 TreeNode *pTmpNode = allocateNode();
507 _vLevelEntries.back()->_vChildren[0] = pTmpNode;
509 _vLevelEntries.push_back(pTmpNode);
511 pTmpNode->_pNext = pNextNode;
512 pNextNode->_pPrev = pTmpNode;
516 _vLevelEntries.push_back(pNextNode);
522 _vLevelEntries[uiStartLevel]->
523 _vChildren[0]->_pNext;
525 if(pNextNode->_pNext != NULL)
527 pNextNode->_pNext->_pPrev = pNextNode;
530 _vLevelEntries[uiStartLevel]->_vChildren[0]->_pNext=
534 _vLevelEntries[uiStartLevel]->_vChildren[0];
538 pCurrNode = pCurrNode->_vChildren[0];
540 uiLevelSub += LevelBits;
541 uiCurrIdx -= LevelBits;
547 uiCurrBits |= IdxToBits[uiCurrIdx];
551 if(pCurrNode != NULL)
553 TreeNode *pNextNode = pCurrNode->_vChildren[uiCurrBits];
555 if(pNextNode != NULL)
557 if(pNextNode->_pObject == NULL)
559 pNextNode->_pObject = pObject;
565 OSG_ASSERT(pNextNode->_pObject == pObject);
570 pNextNode = allocateNode();
572 pCurrNode->_vChildren[uiCurrBits] = pNextNode;
574 if(uiStartLevel == _vLevelEntries.size() - 1)
579 _vLevelEntries.push_back(pNextNode);
583 TreeNode *pTmpNode = allocateNode();
585 _vLevelEntries.back()->_vChildren[0] = pTmpNode;
587 _vLevelEntries.push_back(pTmpNode);
589 pTmpNode->_pNext = pNextNode;
590 pNextNode->_pPrev = pTmpNode;
596 _vLevelEntries[uiStartLevel]->_vChildren[0]->_pNext;
598 if(pNextNode->_pNext != NULL)
600 pNextNode->_pNext->_pPrev = pNextNode;
603 _vLevelEntries[uiStartLevel]->_vChildren[0]->_pNext =
607 _vLevelEntries[uiStartLevel]->_vChildren[0];
610 pNextNode->_pObject = pObject;
619 template<class ObjectT, UInt32 LevelBits> inline
620 void ShaderCacheTreeV0<ObjectT, LevelBits>::sub(UInt32 uiIdx)
622 IdType uiStartLevel = IdType((uiIdx - 1) * LevelFactor);
624 if(uiStartLevel >= _vLevelEntries.size())
629 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
630 UInt32 uiCurrIdx = uiIdx - uiLevelSub;
631 UInt32 uiCurrBits = IdxToBits[uiCurrIdx];
633 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
635 for(; pCurrNode != NULL; pCurrNode = pCurrNode->_pNext)
637 for(UInt32 i = 0; i < LevelSize; ++i)
639 TreeNode *pChild = pCurrNode->_vChildren[i];
641 if(0x0000 != (i & uiCurrBits) && pChild != NULL)
643 if(pChild->_pNext == NULL)
645 pChild->_pPrev->_pNext = NULL;
649 pChild->_pPrev->_pNext = pChild->_pNext;
650 pChild->_pNext->_pPrev = pChild->_pPrev;
653 pChild->_pPrev = NULL;
654 pChild->_pNext = NULL;
656 eraseNode(pCurrNode->_vChildren[i]);
657 pCurrNode->_vChildren[i] = NULL;
663 template<class ObjectT, UInt32 LevelBits> inline
664 void ShaderCacheTreeV0<ObjectT, LevelBits>::dumpDot(const Char8 *szFilename)
666 FILE *pOut = fopen(szFilename, "w");
670 fprintf(pOut, "digraph structs\n");
671 fprintf(pOut, "{\n");
672 fprintf(pOut, "node [shape=record];\n");
674 std::vector<std::vector<TreeNode *> > vLevelStore;
676 dumpDotNode(_pRoot, pOut, vLevelStore, 0);
679 fprintf(pOut, "struct%d\n", 0);
680 fprintf(pOut, "[\n");
681 fprintf(pOut, " label=\"");
683 for(UInt32 i = 0; i < _vLevelEntries.size(); ++i)
685 if(_vLevelEntries[i] != NULL)
687 fprintf(pOut, "<l%d> %d", i, i);
691 fprintf(pOut, "<l%d> NIL", i);
694 if(i == _vLevelEntries.size() - 1)
696 fprintf(pOut, "\"\n");
704 fprintf(pOut, "]\n");
707 for(UInt32 i = 0; i < _vLevelEntries.size(); ++i)
709 if(_vLevelEntries[i] != NULL)
711 fprintf(pOut, "struct%d:l%d -> struct%d:l%d;\n",
713 _vLevelEntries[i]->_uiNodeId, 0);
717 for(UInt32 i = 0; i < vLevelStore.size(); ++i)
719 fprintf(pOut, "{ rank=same;");
721 for(UInt32 j = 0; j < vLevelStore[i].size(); ++j)
723 TreeNode *pChild = vLevelStore[i][j];
727 fprintf(pOut, "\"struct%d\";",
732 fprintf(pOut, "}\n");
736 fprintf(pOut, "}\n");
741 template<class ObjectT, UInt32 LevelBits> inline
742 void ShaderCacheTreeV0<ObjectT, LevelBits>::dumpDotNode(
745 std::vector<std::vector<TreeNode *> > &vLevelStore,
752 if(uiLevel == vLevelStore.size())
754 vLevelStore.push_back(std::vector<TreeNode *>());
757 fprintf(pOut, "struct%d\n", pNode->_uiNodeId);
758 fprintf(pOut, "[\n");
759 fprintf(pOut, " label=\"");
761 if(pNode->_pPrev != NULL)
763 fprintf(pOut, "<prev> P|");
767 fprintf(pOut, "<prev> P:NIL|");
770 for(UInt32 i = 0; i < LevelSize; ++i)
772 if(pNode->_vChildren[i] != NULL)
774 fprintf(pOut, "<l%d> %d|", i, i);
778 fprintf(pOut, "<l%d> NIL|", i);
782 if(pNode->_pObject != NULL)
784 fprintf(pOut, "<val> VAL:Obj|");
788 fprintf(pOut, "<val> VAL:NIL|");
791 if(pNode->_pNext != NULL)
793 fprintf(pOut, "<next> N\"\n");
797 fprintf(pOut, "<next> N:NIL\"\n");
800 fprintf(pOut, "]\n");
802 for(UInt32 i = 0; i < LevelSize; ++i)
804 TreeNode *pChild = pNode->_vChildren[i];
808 dumpDotNode(pChild, pOut, vLevelStore, uiLevel + 1);
810 fprintf(pOut, "struct%d:l%d -> struct%d:l%d;\n",
811 pNode ->_uiNodeId, i,
812 pChild->_uiNodeId, UInt32(LevelSize/2));
816 if(pNode->_pNext != NULL)
818 fprintf(pOut, "struct%d:next -> struct%d:prev;\n",
820 pNode->_pNext->_uiNodeId);
822 if(pNode->_pPrev != NULL)
824 fprintf(pOut, "struct%d:prev -> struct%d:next;\n",
826 pNode->_pPrev->_uiNodeId);
830 fprintf(pOut, "{ rank=same;");
832 for(UInt32 i = 0; i < LevelSize; ++i)
834 TreeNode *pChild = pNode->_vChildren[i];
838 fprintf(pOut, "\"struct%d\";",
844 fprintf(pOut, "}\n");
847 vLevelStore[uiLevel].push_back(pNode);
852 template<class ObjectT, UInt32 LevelBits> inline
853 ShaderCacheTreeV0<ObjectT, LevelBits>::ShaderCacheTreeV0(void) :
861 _pRoot = allocateNode();
863 _vLevelEntries.push_back(_pRoot);
866 template<class ObjectT, UInt32 LevelBits> inline
867 ShaderCacheTreeV0<ObjectT, LevelBits>::~ShaderCacheTreeV0(void)
869 typename std::deque <TreeNode *>::const_iterator qIt =
870 _qFreeElements.begin();
872 typename std::deque <TreeNode *>::const_iterator qEnd =
873 _qFreeElements.end();
875 for(; qIt != qEnd; ++qIt)
881 template<class ObjectT, UInt32 LevelBits> inline
882 typename ShaderCacheTreeV0<ObjectT, LevelBits>::TreeNode *
883 ShaderCacheTreeV0<ObjectT, LevelBits>::allocateNode(void)
885 TreeNode *returnValue = NULL;
887 if(_qFreeElements.empty() == false)
889 returnValue = _qFreeElements.back();
891 _qFreeElements.pop_back();
893 returnValue->clear();
897 returnValue = new TreeNode();
900 returnValue->_uiNodeId = ++_uiNodeCount;
905 UInt64 rU = reinterpret_cast<UInt64>(returnValue);
907 OSG_ASSERT((rU & 0x0001) == 0x0000);
913 template<class ObjectT, UInt32 LevelBits> inline
914 void ShaderCacheTreeV0<ObjectT, LevelBits>::eraseNode(TreeNode *pNode)
916 for(UInt32 i = 0; i < LevelSize; ++i)
918 if(pNode->_vChildren[i] != NULL)
920 eraseNode(pNode->_vChildren[i]);
924 pNode->_pObject = NULL;
926 _qFreeElements.push_back(pNode);
929 template<class ObjectT, UInt32 LevelBits>
930 template <typename ElemDestFunc> inline
931 void ShaderCacheTreeV0<ObjectT, LevelBits>::destroyNode(TreeNode *pNode,
932 ElemDestFunc destFunc)
937 UInt32 uiChildStart = 0;
939 if(pNode->_pPrev == NULL)
942 for(UInt32 i = uiChildStart; i < LevelSize; ++i)
944 if(pNode->_vChildren[i] != NULL)
946 destroyNode(pNode->_vChildren[i], destFunc);
950 if(pNode->_pObject != NULL)
952 #ifndef OSG_SHC_REF_CLEANUP
953 (destFunc)(pNode->_pObject);
955 pNode->_pObject = NULL;
961 template<class ObjectT, UInt32 LevelBits>
962 template <typename ElemDestFunc> inline
963 void ShaderCacheTreeV0<ObjectT, LevelBits>::destroy(ElemDestFunc destFunc)
965 destroyNode(_pRoot, destFunc);
967 _vLevelEntries[0] = NULL;
976 /*---------------------------------------------------------------------------*/
977 /*---------------------------------------------------------------------------*/
980 template<typename Object1T, typename RefCountPol1,
981 typename Object2T, typename RefCountPol2> inline
982 VariantPtr<Object1T, RefCountPol1,
983 Object2T, RefCountPol2>::VariantPtr(void)
988 template<typename Object1T, typename RefCountPol1,
989 typename Object2T, typename RefCountPol2> inline
990 VariantPtr<Object1T, RefCountPol1,
991 Object2T, RefCountPol2>::~VariantPtr(void)
993 if(_val._uiIntVal & UIMaskChoice) //isObj1
995 _val._uiIntVal &= UIMaskPtr;
997 RefCountPol1::subRef(_val._pObj1);
1001 template<typename Object1T, typename RefCountPol1,
1002 typename Object2T, typename RefCountPol2> inline
1003 Object1T *VariantPtr<Object1T, RefCountPol1,
1004 Object2T, RefCountPol2>::asT1(void) const
1007 if(_val._uiIntVal & UIMaskChoice) //isObj1
1009 MemberU returnValue = { _val._uiIntVal & UIMaskPtr };
1011 return returnValue._pObj1;
1017 template<typename Object1T, typename RefCountPol1,
1018 typename Object2T, typename RefCountPol2> inline
1019 Object2T *VariantPtr<Object1T, RefCountPol1,
1020 Object2T, RefCountPol2>::asT2(void) const
1023 if(!(_val._uiIntVal & UIMaskChoice)) //!isObj1
1029 template<typename Object1T, typename RefCountPol1,
1030 typename Object2T, typename RefCountPol2> inline
1031 void VariantPtr<Object1T, RefCountPol1,
1032 Object2T, RefCountPol2>::setAsT1(Object1T * const rhs)
1034 if(_val._uiIntVal & UIMaskChoice) //isObj1
1036 _val._uiIntVal &= UIMaskPtr;
1038 RefCountPol1::setRefd(_val._pObj1, rhs);
1042 RefCountPol1::addRef(rhs);
1048 _val._uiIntVal |= UIMaskChoice;
1052 template<typename Object1T, typename RefCountPol1,
1053 typename Object2T, typename RefCountPol2> inline
1054 void VariantPtr<Object1T, RefCountPol1,
1055 Object2T, RefCountPol2>::setAsT2(Object2T * const rhs)
1057 if(_val._uiIntVal & UIMaskChoice) //isObj1
1059 _val._uiIntVal &= UIMaskPtr;
1061 RefCountPol1::subRef(_val._pObj1);
1068 template<typename Object1T, typename RefCountPol1,
1069 typename Object2T, typename RefCountPol2> inline
1070 void VariantPtr<Object1T, RefCountPol1,
1071 Object2T, RefCountPol2>::operator =(Object1T * const rhs)
1076 template<typename Object1T, typename RefCountPol1,
1077 typename Object2T, typename RefCountPol2> inline
1078 void VariantPtr<Object1T, RefCountPol1,
1079 Object2T, RefCountPol2>::operator =(Object2T * const rhs)
1085 template<typename Object1T, typename RefCountPol1,
1086 typename Object2T, typename RefCountPol2> inline
1087 Object2T *VariantPtr<Object1T, RefCountPol1,
1088 Object2T, RefCountPol2>::operator ->(void) const
1090 return this->asT2();
1096 /*---------------------------------------------------------------------------*/
1097 /*---------------------------------------------------------------------------*/
1099 #if defined(WIN32) || defined(__APPLE__) || \
1100 defined(__GXX_EXPERIMENTAL_CXX0X__)
1101 template<class ObjectT, UInt32 LevelBits>
1102 const Real32 ShaderCacheTreeV1<ObjectT, LevelBits>::LevelFactor =
1106 template<class ObjectT, UInt32 LevelBits> inline
1107 ShaderCacheTreeV1<ObjectT, LevelBits>::TreeNode::TreeNode(void) :
1117 template<class ObjectT, UInt32 LevelBits> inline
1118 ShaderCacheTreeV1<ObjectT, LevelBits>::TreeNode::~TreeNode(void)
1124 for(UInt32 i = 0; i < LevelSize; ++i)
1126 _vChildren[i].setAsT1(NULL);
1130 template<class ObjectT, UInt32 LevelBits> inline
1131 void ShaderCacheTreeV1<ObjectT, LevelBits>::TreeNode::clear(void)
1137 for(UInt32 i = 0; i < LevelSize; ++i)
1139 _vChildren[i].setAsT1(NULL);
1145 template<class ObjectT, UInt32 LevelBits> inline
1146 ObjectT *ShaderCacheTreeV1<ObjectT, LevelBits>::find(const IdStore &vIds)
1151 ObjectT *returnValue = NULL;
1153 IdType uiStartId = vIds[0] - 1;
1154 IdType uiStartLevel = IdType(uiStartId * LevelFactor);
1156 UInt32 uiCurrId = 0;
1157 UInt32 uiLastId = vIds.size();
1160 if(uiStartLevel >= _vLevelEntries.size())
1162 uiStartLevel = _vLevelEntries.size() - 1;
1166 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
1167 UInt32 uiCurrBits = 0x0000;
1168 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
1170 if(pCurrNode == NULL)
1173 for(; uiCurrId < uiLastId; ++uiCurrId)
1175 UInt32 uiCurrIdx = vIds[uiCurrId] - uiLevelSub;
1177 if(uiCurrIdx <= LevelBits)
1179 uiCurrBits |= IdxToBits[uiCurrIdx];
1185 pCurrNode = pCurrNode->_vChildren[uiCurrBits].asT2();
1187 if(pCurrNode == NULL)
1192 uiCurrBits = 0x0000;
1194 uiLevelSub += LevelBits;
1195 uiCurrIdx -= LevelBits;
1197 while(uiCurrIdx > LevelBits)
1199 pCurrNode = pCurrNode->_vChildren[0].asT2();
1201 if(pCurrNode == NULL)
1205 uiLevelSub += LevelBits;
1206 uiCurrIdx -= LevelBits;
1209 if(pCurrNode == NULL)
1214 uiCurrBits |= IdxToBits[uiCurrIdx];
1218 if(pCurrNode != NULL)
1220 TreeNode *pNext = pCurrNode->_vChildren[uiCurrBits].asT2();
1224 returnValue = pNext->_pObject;
1228 returnValue = pCurrNode->_vChildren[uiCurrBits].asT1();
1236 template<class ObjectT, UInt32 LevelBits> inline
1237 bool ShaderCacheTreeV1<ObjectT, LevelBits>::add(const IdStore &vIds,
1240 bool returnValue = false;
1245 IdType uiStartId = vIds[0] - 1;
1247 IdType uiStartLevel = IdType(uiStartId * LevelFactor);
1249 UInt32 uiCurrId = 0;
1250 UInt32 uiLastId = vIds.size();
1253 if(uiStartLevel >= _vLevelEntries.size())
1255 uiStartLevel = _vLevelEntries.size() - 1;
1258 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
1260 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
1261 TreeNode *pNextNode = NULL;
1263 UInt32 uiCurrBits = 0x0000;
1265 for(; uiCurrId < uiLastId; ++uiCurrId)
1267 UInt32 uiCurrIdx = vIds[uiCurrId] - uiLevelSub;
1269 if(uiCurrIdx <= LevelBits)
1271 uiCurrBits |= IdxToBits[uiCurrIdx];
1277 pNextNode = pCurrNode->_vChildren[uiCurrBits].asT2();
1279 if(pNextNode == NULL)
1281 pNextNode = allocateNode();
1283 if(pCurrNode->_vChildren[uiCurrBits].asT1() != NULL)
1285 pNextNode->_pObject =
1286 pCurrNode->_vChildren[uiCurrBits].asT1();
1289 pCurrNode->_vChildren[uiCurrBits] = pNextNode;
1291 if(uiStartLevel == _vLevelEntries.size() - 1)
1293 if(_vLevelEntries.back()->_vChildren[0].asT2() == NULL)
1295 TreeNode *pTmpNode = allocateNode();
1297 _vLevelEntries.back()->_vChildren[0] = pTmpNode;
1299 _vLevelEntries.push_back(pTmpNode);
1301 pTmpNode->_pNext = pNextNode;
1302 pNextNode->_pPrev = pTmpNode;
1306 _vLevelEntries.push_back(pNextNode);
1312 _vLevelEntries[uiStartLevel]->_vChildren[0]->_pNext;
1314 if(pNextNode->_pNext != NULL)
1316 pNextNode->_pNext->_pPrev = pNextNode;
1319 _vLevelEntries[uiStartLevel]->_vChildren[0]->_pNext =
1323 _vLevelEntries[uiStartLevel]->_vChildren[0].asT2();
1329 uiCurrBits = 0x0000;
1331 pCurrNode = pNextNode;
1333 uiLevelSub += LevelBits;
1334 uiCurrIdx -= LevelBits;
1336 while(uiCurrIdx > LevelBits)
1338 if(pCurrNode->_vChildren[0].asT2() == NULL)
1340 pNextNode = allocateNode();
1342 pCurrNode->_vChildren[0] = pNextNode;
1344 if(uiStartLevel == _vLevelEntries.size() - 1)
1346 if(_vLevelEntries.back()->_vChildren[0].asT2() == NULL)
1348 TreeNode *pTmpNode = allocateNode();
1350 _vLevelEntries.back()->_vChildren[0] = pTmpNode;
1352 _vLevelEntries.push_back(pTmpNode);
1354 pTmpNode->_pNext = pNextNode;
1355 pNextNode->_pPrev = pTmpNode;
1359 _vLevelEntries.push_back(pNextNode);
1365 _vLevelEntries[uiStartLevel]->
1366 _vChildren[0]->_pNext;
1368 if(pNextNode->_pNext != NULL)
1370 pNextNode->_pNext->_pPrev = pNextNode;
1373 _vLevelEntries[uiStartLevel]->_vChildren[0]->_pNext=
1377 _vLevelEntries[uiStartLevel]->_vChildren[0].asT2();
1381 pCurrNode = pCurrNode->_vChildren[0].asT2();
1383 uiLevelSub += LevelBits;
1384 uiCurrIdx -= LevelBits;
1390 uiCurrBits |= IdxToBits[uiCurrIdx];
1394 if(pCurrNode != NULL)
1396 TreeNode *pNextNode = pCurrNode->_vChildren[uiCurrBits].asT2();
1398 if(pNextNode != NULL)
1400 if(pNextNode->_pObject == NULL)
1402 pNextNode->_pObject = pObject;
1408 OSG_ASSERT(pNextNode->_pObject == pObject);
1413 pCurrNode->_vChildren[uiCurrBits] = pObject;
1422 template<class ObjectT, UInt32 LevelBits> inline
1423 void ShaderCacheTreeV1<ObjectT, LevelBits>::sub(UInt32 uiIdx)
1425 IdType uiStartLevel = IdType((uiIdx - 1) * LevelFactor);
1427 if(uiStartLevel >= _vLevelEntries.size())
1432 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
1433 UInt32 uiCurrIdx = uiIdx - uiLevelSub;
1434 UInt32 uiCurrBits = IdxToBits[uiCurrIdx];
1436 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
1438 for(; pCurrNode != NULL; pCurrNode = pCurrNode->_pNext)
1440 for(UInt32 i = 0; i < LevelSize; ++i)
1442 TreeNode *pChild = pCurrNode->_vChildren[i].asT2();
1444 if(0x0000 != (i & uiCurrBits) && pChild != NULL)
1446 if(pChild->_pNext == NULL)
1448 pChild->_pPrev->_pNext = NULL;
1452 pChild->_pPrev->_pNext = pChild->_pNext;
1453 pChild->_pNext->_pPrev = pChild->_pPrev;
1456 pChild->_pPrev = NULL;
1457 pChild->_pNext = NULL;
1459 eraseNode(pCurrNode->_vChildren[i].asT2());
1460 pCurrNode->_vChildren[i].setAsT2(NULL);
1462 else if(pCurrNode->_vChildren[i].asT1() != NULL)
1464 pCurrNode->_vChildren[i].setAsT1(NULL);
1470 template<class ObjectT, UInt32 LevelBits> inline
1471 void ShaderCacheTreeV1<ObjectT, LevelBits>::dumpDot(const Char8 *szFilename)
1473 FILE *pOut = fopen(szFilename, "w");
1477 fprintf(pOut, "digraph structs\n");
1478 fprintf(pOut, "{\n");
1479 fprintf(pOut, "rankdir = LR;\n");
1480 fprintf(pOut, "splines=false\n");
1482 fprintf(pOut, "node [shape=record];\n");
1484 fprintf(pOut, "struct%d\n", 0);
1485 fprintf(pOut, "[\n");
1486 fprintf(pOut, " label=\"");
1488 for(UInt32 i = 0; i < _vLevelEntries.size(); ++i)
1490 if(_vLevelEntries[i] != NULL)
1492 fprintf(pOut, "<l%d> %d", i, i);
1496 fprintf(pOut, "<l%d> NIL", i);
1499 if(i == _vLevelEntries.size() - 1)
1501 fprintf(pOut, "\"\n");
1509 fprintf(pOut, "]\n");
1511 fprintf(pOut, "node [width = 1.5];\n");
1513 std::vector<std::vector<TreeNode *> > vLevelStore;
1515 dumpDotNode(_pRoot, pOut, vLevelStore, 0);
1518 for(UInt32 i = 0; i < _vLevelEntries.size(); ++i)
1520 if(_vLevelEntries[i] != NULL)
1523 "struct%d:l%d -> struct%d:prev [color=\"green\"];\n",
1525 _vLevelEntries[i]->_uiNodeId);
1529 for(UInt32 i = 0; i < vLevelStore.size(); ++i)
1531 fprintf(pOut, "{ rank=same;");
1533 for(UInt32 j = 0; j < vLevelStore[i].size(); ++j)
1535 TreeNode *pChild = vLevelStore[i][j];
1539 fprintf(pOut, "\"struct%d\";",
1544 fprintf(pOut, "}\n");
1549 fprintf(pOut, "}\n");
1554 template<class ObjectT, UInt32 LevelBits> inline
1555 void ShaderCacheTreeV1<ObjectT, LevelBits>::dumpDotNode(
1558 std::vector<std::vector<TreeNode *> > &vLevelStore,
1565 if(uiLevel == vLevelStore.size())
1567 vLevelStore.push_back(std::vector<TreeNode *>());
1570 fprintf(pOut, "struct%d\n", pNode->_uiNodeId);
1571 fprintf(pOut, "[\n");
1572 fprintf(pOut, " label=\"{");
1574 if(pNode->_pPrev != NULL)
1576 fprintf(pOut, "<prev> P|");
1580 fprintf(pOut, "<prev> P:NIL|");
1583 for(UInt32 i = 0; i < LevelSize; ++i)
1585 if(pNode->_vChildren[i].asT1() != NULL)
1587 fprintf(pOut, "<l%d> O:%d|", i, i);
1589 else if(pNode->_vChildren[i].asT2() != NULL)
1591 fprintf(pOut, "<l%d> C:%d|", i, i);
1595 fprintf(pOut, "<l%d> NIL|", i);
1599 if(pNode->_pObject != NULL)
1601 fprintf(pOut, "<val> VAL:Obj|");
1605 fprintf(pOut, "<val> VAL:NIL|");
1608 if(pNode->_pNext != NULL)
1610 fprintf(pOut, "<next> N}\"\n");
1614 fprintf(pOut, "<next> N:NIL}\"\n");
1617 fprintf(pOut, "]\n");
1619 for(UInt32 i = 0; i < LevelSize; ++i)
1621 TreeNode *pChild = pNode->_vChildren[i].asT2();
1625 dumpDotNode(pChild, pOut, vLevelStore, uiLevel + 1);
1628 "struct%d:l%d -> struct%d:l%d [constraint=\"false\"];\n",
1629 pNode ->_uiNodeId, i,
1630 pChild->_uiNodeId, i);
1634 if(pNode->_pNext != NULL)
1636 fprintf(pOut, "struct%d:next -> struct%d:prev;\n",
1638 pNode->_pNext->_uiNodeId);
1640 if(pNode->_pPrev != NULL)
1642 fprintf(pOut, "struct%d:prev -> struct%d:next;\n",
1644 pNode->_pPrev->_uiNodeId);
1647 vLevelStore[uiLevel].push_back(pNode);
1651 template<class ObjectT, UInt32 LevelBits> inline
1652 ShaderCacheTreeV1<ObjectT, LevelBits>::ShaderCacheTreeV1(void) :
1660 _pRoot = allocateNode();
1662 _vLevelEntries.push_back(_pRoot);
1665 template<class ObjectT, UInt32 LevelBits> inline
1666 ShaderCacheTreeV1<ObjectT, LevelBits>::~ShaderCacheTreeV1(void)
1668 typename std::deque <TreeNode *>::const_iterator qIt =
1669 _qFreeElements.begin();
1671 typename std::deque <TreeNode *>::const_iterator qEnd =
1672 _qFreeElements.end();
1674 for(; qIt != qEnd; ++qIt)
1680 template<class ObjectT, UInt32 LevelBits> inline
1681 typename ShaderCacheTreeV1<ObjectT, LevelBits>::TreeNode *
1682 ShaderCacheTreeV1<ObjectT, LevelBits>::allocateNode(void)
1684 TreeNode *returnValue = NULL;
1686 if(_qFreeElements.empty() == false)
1688 returnValue = _qFreeElements.back();
1690 _qFreeElements.pop_back();
1692 returnValue->clear();
1696 returnValue = new TreeNode();
1699 returnValue->_uiNodeId = ++_uiNodeCount;
1704 UIntPointer rU = reinterpret_cast<UIntPointer>(returnValue);
1706 OSG_ASSERT((rU & 0x0001) == 0x0000);
1712 template<class ObjectT, UInt32 LevelBits> inline
1713 void ShaderCacheTreeV1<ObjectT, LevelBits>::eraseNode(TreeNode *pNode)
1715 for(UInt32 i = 0; i < LevelSize; ++i)
1717 if(pNode->_vChildren[i].asT2() != NULL)
1719 eraseNode(pNode->_vChildren[i].asT2());
1723 pNode->_vChildren[i].setAsT1(NULL);
1727 pNode->_pObject = NULL;
1729 _qFreeElements.push_back(pNode);
1732 template<class ObjectT, UInt32 LevelBits>
1733 template <typename ElemDestFunc> inline
1734 void ShaderCacheTreeV1<ObjectT, LevelBits>::destroyNode(TreeNode *pNode,
1735 ElemDestFunc destFunc)
1740 UInt32 uiChildStart = 0;
1742 if(pNode->_pPrev == NULL)
1745 for(UInt32 i = uiChildStart; i < LevelSize; ++i)
1747 if(pNode->_vChildren[i].asT2() != NULL)
1749 destroyNode(pNode->_vChildren[i].asT2(), destFunc);
1751 else if(pNode->_vChildren[i].asT1() != NULL)
1753 #ifndef OSG_SHC_REF_CLEANUP
1754 ObjectT *pObj = pNode->_vChildren[i].asT1();
1757 pNode->_vChildren[i].setAsT1(NULL);
1761 if(pNode->_pObject != NULL)
1763 #ifndef OSG_SHC_REF_CLEANUP
1764 (destFunc)(pNode->_pObject);
1766 pNode->_pObject = NULL;
1772 template<class ObjectT, UInt32 LevelBits>
1773 template <typename ElemDestFunc> inline
1774 void ShaderCacheTreeV1<ObjectT, LevelBits>::destroy(ElemDestFunc destFunc)
1776 destroyNode(_pRoot, destFunc);
1778 _vLevelEntries[0] = NULL;
1788 /*---------------------------------------------------------------------------*/
1789 /*---------------------------------------------------------------------------*/
1791 #if defined(WIN32) || defined(__APPLE__) || \
1792 defined(__GXX_EXPERIMENTAL_CXX0X__)
1793 template<class ObjectT, UInt32 LevelBits>
1794 const Real32 ShaderCacheTreeV2<ObjectT, LevelBits>::LevelFactor =
1798 template<class ObjectT, UInt32 LevelBits> inline
1799 ShaderCacheTreeV2<ObjectT, LevelBits>::TreeNode::TreeNode(void) :
1807 memset(&(_vJumps[0]), 0, LevelSize * sizeof(UInt16));
1810 template<class ObjectT, UInt32 LevelBits> inline
1811 ShaderCacheTreeV2<ObjectT, LevelBits>::TreeNode::~TreeNode(void)
1817 for(UInt32 i = 0; i < LevelSize; ++i)
1819 _vChildren[i].setAsT1(NULL);
1823 template<class ObjectT, UInt32 LevelBits> inline
1824 void ShaderCacheTreeV2<ObjectT, LevelBits>::TreeNode::clear(void)
1830 for(UInt32 i = 0; i < LevelSize; ++i)
1832 _vChildren[i].setAsT1(NULL);
1835 memset(&(_vJumps[0]), 0, LevelSize * sizeof(UInt16));
1840 template<class ObjectT, UInt32 LevelBits> inline
1841 ObjectT *ShaderCacheTreeV2<ObjectT, LevelBits>::find(const IdStore &vIds)
1846 ObjectT *returnValue = NULL;
1848 IdType uiStartId = vIds[0] - 1;
1849 IdType uiStartLevel = IdType(uiStartId * LevelFactor);
1851 UInt32 uiCurrId = 0;
1852 UInt32 uiLastId = vIds.size();
1855 if(uiStartLevel >= _vLevelEntries.size())
1857 uiStartLevel = _vLevelEntries.size() - 1;
1861 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
1862 UInt32 uiCurrBits = 0x0000;
1863 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
1864 TreeNode *pNextNode = NULL;
1866 if(pCurrNode == NULL)
1869 for(; uiCurrId < uiLastId; ++uiCurrId)
1871 UInt32 uiCurrIdx = vIds[uiCurrId] - uiLevelSub;
1872 UInt16 uiJumpDist = 1;
1874 if(uiCurrIdx <= LevelBits)
1876 uiCurrBits |= IdxToBits[uiCurrIdx];
1882 pNextNode = pCurrNode->_vChildren[uiCurrBits].asT2();
1884 if(pNextNode == NULL)
1886 pCurrNode = pNextNode;
1890 uiJumpDist = UInt16((uiCurrIdx - 1) * LevelFactor);
1891 UInt32 uiTargetLevel = uiStartLevel + uiJumpDist;
1893 if(uiJumpDist < pCurrNode->_vJumps[uiCurrBits])
1899 if(uiJumpDist > pCurrNode->_vJumps[uiCurrBits])
1901 uiLevelSub += LevelBits * pCurrNode->_vJumps[uiCurrBits];
1902 uiCurrIdx -= LevelBits * pCurrNode->_vJumps[uiCurrBits];
1903 uiJumpDist -= pCurrNode->_vJumps[uiCurrBits];
1905 pCurrNode = pNextNode;
1906 pNextNode = pCurrNode->_vChildren[0].asT2();
1908 uiCurrBits = 0x0000;
1912 if(uiCurrIdx <= LevelBits)
1917 if(uiJumpDist == pCurrNode->_vJumps[0])
1922 if(uiJumpDist < pCurrNode->_vJumps[0])
1928 if(pNextNode == NULL)
1934 LevelBits * pCurrNode->_vJumps[0];
1937 LevelBits * pCurrNode->_vJumps[0];
1939 uiJumpDist -= pCurrNode->_vJumps[0];
1941 pCurrNode = pNextNode;
1942 pNextNode = pCurrNode->_vChildren[0].asT2();
1946 pCurrNode = pNextNode;
1948 if(pCurrNode == NULL)
1953 uiCurrBits = 0x0000;
1955 uiStartLevel = uiTargetLevel;
1956 uiLevelSub = (uiStartLevel * LevelBits);
1958 uiCurrIdx -= uiJumpDist * LevelBits;
1961 uiCurrBits |= IdxToBits[uiCurrIdx];
1965 if(pCurrNode != NULL)
1967 TreeNode *pNext = pCurrNode->_vChildren[uiCurrBits].asT2();
1971 returnValue = pNext->_pObject;
1975 returnValue = pCurrNode->_vChildren[uiCurrBits].asT1();
1983 template<class ObjectT, UInt32 LevelBits> inline
1984 bool ShaderCacheTreeV2<ObjectT, LevelBits>::add(const IdStore &vIds,
1987 bool returnValue = false;
1992 IdType uiStartId = vIds[0] - 1;
1994 IdType uiStartLevel = IdType(uiStartId * LevelFactor);
1996 UInt32 uiCurrId = 0;
1997 UInt32 uiLastId = vIds.size();
2000 if(uiStartLevel >= _vLevelEntries.size())
2002 uiStartLevel = _vLevelEntries.size() - 1;
2006 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
2007 TreeNode *pNextNode = NULL;
2009 UInt32 uiCurrBits = 0x0000;
2011 if(pCurrNode == NULL)
2013 UInt32 uiLastValidLE = 0;
2015 for(Int32 i = uiStartLevel; i >= 0; --i)
2017 if(_vLevelEntries[i] != NULL)
2024 uiStartLevel = uiLastValidLE;
2025 pCurrNode = _vLevelEntries[uiStartLevel];
2028 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
2030 for(; uiCurrId < uiLastId; ++uiCurrId)
2032 UInt32 uiCurrIdx = vIds[uiCurrId] - uiLevelSub;
2033 UInt16 uiJumpDist = 1;
2035 if(uiCurrIdx <= LevelBits)
2037 uiCurrBits |= IdxToBits[uiCurrIdx];
2043 pNextNode = pCurrNode->_vChildren[uiCurrBits].asT2();
2045 uiJumpDist = UInt16((uiCurrIdx - 1) * LevelFactor);
2046 UInt32 uiTargetLevel = uiStartLevel + uiJumpDist;
2048 if(pNextNode != NULL)
2050 if(uiJumpDist > pCurrNode->_vJumps[uiCurrBits])
2052 uiLevelSub += LevelBits * pCurrNode->_vJumps[uiCurrBits];
2053 uiCurrIdx -= LevelBits * pCurrNode->_vJumps[uiCurrBits];
2054 uiJumpDist -= pCurrNode->_vJumps[uiCurrBits];
2056 pCurrNode = pNextNode;
2057 pNextNode = pCurrNode->_vChildren[0].asT2();
2059 uiCurrBits = 0x0000;
2063 if(uiCurrIdx <= LevelBits)
2068 if(pNextNode == NULL)
2073 if(uiJumpDist <= pCurrNode->_vJumps[0])
2079 LevelBits * pCurrNode->_vJumps[0];
2082 LevelBits * pCurrNode->_vJumps[0];
2084 uiJumpDist -= pCurrNode->_vJumps[0];
2086 pCurrNode = pNextNode;
2087 pNextNode = pCurrNode->_vChildren[0].asT2();
2091 if(uiJumpDist < pCurrNode->_vJumps[uiCurrBits])
2093 pNextNode = allocateNode();
2095 pNextNode->_vJumps[0] =
2096 pCurrNode->_vJumps [uiCurrBits] - uiJumpDist;
2098 pNextNode->_vChildren[0] =
2099 pCurrNode->_vChildren[uiCurrBits].asT2();
2101 pNextNode->_pObject =
2102 pCurrNode->_vChildren[uiCurrBits].asT2()->_pObject;
2104 pCurrNode->_vChildren[uiCurrBits].asT2()->_pObject = NULL;
2106 pCurrNode->_vJumps [uiCurrBits] = uiJumpDist;
2107 pCurrNode->_vChildren[uiCurrBits] = pNextNode;
2109 if(_vLevelEntries[uiTargetLevel] == NULL)
2111 UInt32 uiLastValidLE = 0;
2113 for(Int32 i = uiTargetLevel; i >= 0; --i)
2115 if(_vLevelEntries[i] != NULL)
2122 if(_vLevelEntries[uiLastValidLE] == pCurrNode &&
2125 _vLevelEntries[uiTargetLevel] = pNextNode;
2129 TreeNode *pTmpNode = allocateNode();
2132 uiLastValidLE]->_vChildren[0].asT2() != NULL)
2134 pTmpNode->_vChildren[0] =
2136 uiLastValidLE]->_vChildren[0].asT2();
2138 pTmpNode->_vJumps[0] =
2140 uiLastValidLE]->_vJumps[0] -
2141 (uiTargetLevel - uiLastValidLE);
2144 _vLevelEntries[uiLastValidLE]->_vChildren[0] =
2146 _vLevelEntries[uiLastValidLE]->_vJumps [0] =
2147 uiTargetLevel - uiLastValidLE;
2149 _vLevelEntries[uiTargetLevel] = pTmpNode;
2151 pTmpNode ->_pNext = pNextNode;
2152 pNextNode->_pPrev = pTmpNode;
2158 _vLevelEntries[uiTargetLevel]->_pNext;
2160 if(pNextNode->_pNext != NULL)
2162 pNextNode->_pNext->_pPrev = pNextNode;
2165 _vLevelEntries[uiTargetLevel]->_pNext = pNextNode;
2167 pNextNode->_pPrev = _vLevelEntries[uiTargetLevel];
2172 if(pNextNode == NULL)
2174 pNextNode = allocateNode();
2176 pCurrNode->_vJumps [uiCurrBits] = uiJumpDist;
2178 if(pCurrNode->_vChildren[uiCurrBits].asT1() != NULL)
2180 pNextNode->_pObject =
2181 pCurrNode->_vChildren[uiCurrBits].asT1();
2184 pCurrNode->_vChildren[uiCurrBits] = pNextNode;
2186 if(uiTargetLevel >= _vLevelEntries.size())
2188 _vLevelEntries.resize(uiTargetLevel + 1, NULL);
2190 UInt32 uiLastValidLE = 0;
2192 for(Int32 i = uiTargetLevel; i >= 0; --i)
2194 if(_vLevelEntries[i] != NULL)
2201 if(_vLevelEntries[uiLastValidLE] == pCurrNode &&
2204 _vLevelEntries[uiTargetLevel] = pNextNode;
2208 TreeNode *pTmpNode = allocateNode();
2210 _vLevelEntries[uiLastValidLE]->_vChildren[0] = pTmpNode;
2211 _vLevelEntries[uiLastValidLE]->_vJumps [0] =
2212 uiTargetLevel - uiLastValidLE;
2214 _vLevelEntries[uiTargetLevel] = pTmpNode;
2216 pTmpNode ->_pNext = pNextNode;
2217 pNextNode->_pPrev = pTmpNode;
2222 if(_vLevelEntries[uiTargetLevel] == NULL)
2224 UInt32 uiLastValidLE = 0;
2226 for(Int32 i = uiTargetLevel; i >= 0; --i)
2228 if(_vLevelEntries[i] != NULL)
2235 TreeNode *pTmpNode = allocateNode();
2238 uiLastValidLE]->_vChildren[0].asT2() != NULL)
2240 pTmpNode->_vChildren[0] =
2242 uiLastValidLE]->_vChildren[0].asT2();
2244 pTmpNode->_vJumps[0] =
2245 _vLevelEntries[uiLastValidLE]->_vJumps[0] -
2246 (uiTargetLevel - uiLastValidLE);
2249 _vLevelEntries[uiLastValidLE]->_vChildren[0] = pTmpNode;
2250 _vLevelEntries[uiLastValidLE]->_vJumps [0] =
2251 uiTargetLevel - uiLastValidLE;
2253 _vLevelEntries[uiTargetLevel] = pTmpNode;
2255 pTmpNode ->_pNext = pNextNode;
2256 pNextNode->_pPrev = pTmpNode;
2261 _vLevelEntries[uiTargetLevel]->_pNext;
2263 if(pNextNode->_pNext != NULL)
2265 pNextNode->_pNext->_pPrev = pNextNode;
2268 _vLevelEntries[uiTargetLevel]->_pNext = pNextNode;
2270 pNextNode->_pPrev = _vLevelEntries[uiTargetLevel];
2276 pCurrNode = pNextNode;
2278 uiCurrBits = 0x0000;
2280 uiStartLevel = uiTargetLevel;
2281 uiLevelSub = (uiStartLevel * LevelBits);
2283 uiCurrIdx -= uiJumpDist * LevelBits;
2285 uiCurrBits |= IdxToBits[uiCurrIdx];
2289 if(pCurrNode != NULL)
2291 TreeNode *pNextNode = pCurrNode->_vChildren[uiCurrBits].asT2();
2293 if(pNextNode != NULL)
2295 if(pNextNode->_pObject == NULL)
2297 pNextNode->_pObject = pObject;
2303 OSG_ASSERT(pNextNode->_pObject == pObject);
2308 pCurrNode->_vChildren[uiCurrBits] = pObject;
2317 template<class ObjectT, UInt32 LevelBits> inline
2318 void ShaderCacheTreeV2<ObjectT, LevelBits>::sub(UInt32 uiIdx)
2320 IdType uiStartLevel = IdType((uiIdx - 1) * LevelFactor);
2322 if(uiStartLevel >= _vLevelEntries.size())
2327 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
2328 UInt32 uiCurrIdx = uiIdx - uiLevelSub;
2329 UInt32 uiCurrBits = IdxToBits[uiCurrIdx];
2331 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
2333 for(; pCurrNode != NULL; pCurrNode = pCurrNode->_pNext)
2335 for(UInt32 i = 0; i < LevelSize; ++i)
2337 TreeNode *pChild = pCurrNode->_vChildren[i].asT2();
2339 if(0x0000 != (i & uiCurrBits) && pChild != NULL)
2341 if(pChild->_pNext == NULL)
2343 pChild->_pPrev->_pNext = NULL;
2347 pChild->_pPrev->_pNext = pChild->_pNext;
2348 pChild->_pNext->_pPrev = pChild->_pPrev;
2351 pChild->_pPrev = NULL;
2352 pChild->_pNext = NULL;
2354 eraseNode(pCurrNode->_vChildren[i].asT2());
2355 pCurrNode->_vJumps [i] = 0;
2356 pCurrNode->_vChildren[i].setAsT2(NULL);
2358 else if(pCurrNode->_vChildren[i].asT1() != NULL)
2360 pCurrNode->_vChildren[i].setAsT1(NULL);
2361 pCurrNode->_vJumps [i] = 0;
2367 #define OSG_DUMP_LEVELENTRIES
2369 template<class ObjectT, UInt32 LevelBits> inline
2370 void ShaderCacheTreeV2<ObjectT, LevelBits>::dumpDot(const Char8 *szFilename)
2372 FILE *pOut = fopen(szFilename, "w");
2376 fprintf(pOut, "digraph structs\n");
2377 fprintf(pOut, "{\n");
2378 fprintf(pOut, "rankdir = LR;\n");
2379 fprintf(pOut, "splines=false\n");
2381 fprintf(pOut, "node [shape=record];\n");
2383 fprintf(pOut, "struct%d\n", 0);
2384 fprintf(pOut, "[\n");
2385 fprintf(pOut, " label=\"");
2387 for(UInt32 i = 0; i < _vLevelEntries.size(); ++i)
2389 if(_vLevelEntries[i] != NULL)
2391 fprintf(pOut, "<l%d> %d", i, i);
2395 fprintf(pOut, "<l%d> NIL", i);
2398 if(i == _vLevelEntries.size() - 1)
2400 fprintf(pOut, "\"\n");
2408 fprintf(pOut, "]\n");
2410 fprintf(pOut, "node [width = 1.5];\n");
2412 std::vector<std::vector<TreeNode *> > vLevelStore;
2414 dumpDotNode(_pRoot, pOut, vLevelStore, 0);
2417 #ifdef OSG_DUMP_LEVELENTRIES
2418 for(UInt32 i = 0; i < _vLevelEntries.size(); ++i)
2420 if(_vLevelEntries[i] != NULL)
2423 "struct%d:l%d -> struct%d:prev [color=\"green\"];\n",
2425 _vLevelEntries[i]->_uiNodeId);
2431 for(UInt32 i = 0; i < vLevelStore.size(); ++i)
2433 fprintf(pOut, "{ rank=same;");
2435 for(UInt32 j = 0; j < vLevelStore[i].size(); ++j)
2437 TreeNode *pChild = vLevelStore[i][j];
2441 fprintf(pOut, "\"struct%d\";",
2446 fprintf(pOut, "}\n");
2451 fprintf(pOut, "}\n");
2456 template<class ObjectT, UInt32 LevelBits> inline
2457 void ShaderCacheTreeV2<ObjectT, LevelBits>::dumpDotNode(
2460 std::vector<std::vector<TreeNode *> > &vLevelStore,
2467 if(uiLevel == vLevelStore.size())
2469 vLevelStore.push_back(std::vector<TreeNode *>());
2472 fprintf(pOut, "struct%d\n", pNode->_uiNodeId);
2473 fprintf(pOut, "[\n");
2474 fprintf(pOut, " label=\"{");
2476 if(pNode->_pPrev != NULL)
2478 fprintf(pOut, "<prev> P|");
2482 fprintf(pOut, "<prev> P:NIL|");
2485 for(UInt32 i = 0; i < LevelSize; ++i)
2487 if(pNode->_vChildren[i].asT1() != NULL)
2489 if(osgIsPower2(i) == true)
2491 fprintf(pOut, "<l%d> _O:%d|", i, i);
2495 fprintf(pOut, "<l%d> O:%d|", i, i);
2498 else if(pNode->_vChildren[i].asT2() != NULL)
2500 if(osgIsPower2(i) == true)
2502 fprintf(pOut, "<l%d> _C:%d (%d)|", i, i, pNode->_vJumps[i]);
2506 fprintf(pOut, "<l%d> C:%d (%d)|", i, i, pNode->_vJumps[i]);
2511 if(osgIsPower2(i) == true)
2513 fprintf(pOut, "<l%d> _NIL|", i);
2517 fprintf(pOut, "<l%d> NIL|", i);
2522 if(pNode->_pObject != NULL)
2524 fprintf(pOut, "<val> VAL:Obj|");
2528 fprintf(pOut, "<val> VAL:NIL|");
2531 if(pNode->_pNext != NULL)
2533 fprintf(pOut, "<next> N}\"\n");
2537 fprintf(pOut, "<next> N:NIL}\"\n");
2540 fprintf(pOut, "]\n");
2542 for(UInt32 i = 0; i < LevelSize; ++i)
2544 TreeNode *pChild = pNode->_vChildren[i].asT2();
2548 dumpDotNode(pChild, pOut, vLevelStore, uiLevel + 1);
2551 "struct%d:l%d -> struct%d:l%d [constraint=\"false\"];\n",
2552 pNode ->_uiNodeId, i,
2553 pChild->_uiNodeId, i);
2557 if(pNode->_pNext != NULL)
2559 fprintf(pOut, "struct%d:next -> struct%d:prev;\n",
2561 pNode->_pNext->_uiNodeId);
2563 if(pNode->_pPrev != NULL)
2565 fprintf(pOut, "struct%d:prev -> struct%d:next;\n",
2567 pNode->_pPrev->_uiNodeId);
2570 vLevelStore[uiLevel].push_back(pNode);
2574 template<class ObjectT, UInt32 LevelBits> inline
2575 ShaderCacheTreeV2<ObjectT, LevelBits>::ShaderCacheTreeV2(void) :
2583 _pRoot = allocateNode();
2585 _vLevelEntries.push_back(_pRoot);
2588 template<class ObjectT, UInt32 LevelBits> inline
2589 ShaderCacheTreeV2<ObjectT, LevelBits>::~ShaderCacheTreeV2(void)
2591 typename std::deque <TreeNode *>::iterator qIt =
2592 _qFreeElements.begin();
2594 typename std::deque <TreeNode *>::const_iterator qEnd =
2595 _qFreeElements.end();
2597 for(; qIt != qEnd; ++qIt)
2604 typename std::vector<TreeNode *>::iterator vIt = _vLevelEntries.begin();
2605 typename std::vector<TreeNode *>::iterator vEnd = _vLevelEntries.end ();
2607 for(; vIt != vEnd; ++vIt)
2615 template<class ObjectT, UInt32 LevelBits> inline
2616 typename ShaderCacheTreeV2<ObjectT, LevelBits>::TreeNode *
2617 ShaderCacheTreeV2<ObjectT, LevelBits>::allocateNode(void)
2619 TreeNode *returnValue = NULL;
2621 if(_qFreeElements.empty() == false)
2623 returnValue = _qFreeElements.back();
2625 _qFreeElements.pop_back();
2627 returnValue->clear();
2631 returnValue = new TreeNode();
2634 returnValue->_uiNodeId = ++_uiNodeCount;
2639 UIntPointer rU = reinterpret_cast<UIntPointer>(returnValue);
2641 OSG_ASSERT((rU & 0x0001) == 0x0000);
2647 template<class ObjectT, UInt32 LevelBits> inline
2648 void ShaderCacheTreeV2<ObjectT, LevelBits>::eraseNode(TreeNode *pNode)
2650 for(UInt32 i = 0; i < LevelSize; ++i)
2652 if(pNode->_vChildren[i].asT2() != NULL)
2654 eraseNode(pNode->_vChildren[i].asT2());
2656 pNode->_vChildren[i].setAsT2(NULL);
2660 pNode->_vChildren[i].setAsT1(NULL);
2664 pNode->_pObject = NULL;
2666 _qFreeElements.push_back(pNode);
2669 template<class ObjectT, UInt32 LevelBits>
2670 template <typename ElemDestFunc> inline
2671 void ShaderCacheTreeV2<ObjectT, LevelBits>::destroyNode(TreeNode *pNode,
2672 ElemDestFunc destFunc)
2677 for(UInt32 i = 0; i < LevelSize; ++i)
2679 if(pNode->_vChildren[i].asT2() != NULL)
2681 destroyNode(pNode->_vChildren[i].asT2(), destFunc);
2683 else if(pNode->_vChildren[i].asT1() != NULL)
2685 #ifndef OSG_SHC_REF_CLEANUP
2686 ObjectT *pObj = pNode->_vChildren[i].asT1();
2689 pNode->_vChildren[i].setAsT1(NULL);
2693 if(pNode->_pObject != NULL)
2695 #ifndef OSG_SHC_REF_CLEANUP
2696 (destFunc)(pNode->_pObject);
2698 pNode->_pObject = NULL;
2704 template<class ObjectT, UInt32 LevelBits>
2705 template <typename ElemDestFunc> inline
2706 void ShaderCacheTreeV2<ObjectT, LevelBits>::destroy(ElemDestFunc destFunc)
2708 destroyNode(_pRoot, destFunc);
2710 _vLevelEntries[0] = NULL;
2720 /*---------------------------------------------------------------------------*/
2721 /*---------------------------------------------------------------------------*/
2723 #if defined(WIN32) || defined(__APPLE__) || \
2724 defined(__GXX_EXPERIMENTAL_CXX0X__)
2725 template<class ObjectT, UInt32 LevelBits>
2726 const Real32 ShaderCacheTreeV3<ObjectT, LevelBits>::LevelFactor =
2730 template<class ObjectT, UInt32 LevelBits> inline
2731 ShaderCacheTreeV3<ObjectT, LevelBits>::TreeNode::TreeNode(void) :
2739 memset(&(_vJumps[0]), 0, LevelSize * sizeof(UInt16));
2742 template<class ObjectT, UInt32 LevelBits> inline
2743 ShaderCacheTreeV3<ObjectT, LevelBits>::TreeNode::~TreeNode(void)
2749 for(UInt32 i = 0; i < LevelSize; ++i)
2751 _vChildren[i].setAsT1(NULL);
2755 template<class ObjectT, UInt32 LevelBits> inline
2756 void ShaderCacheTreeV3<ObjectT, LevelBits>::TreeNode::clear(void)
2762 for(UInt32 i = 0; i < LevelSize; ++i)
2764 _vChildren[i].setAsT1(NULL);
2767 memset(&(_vJumps[0]), 0, LevelSize * sizeof(UInt16));
2772 template<class ObjectT, UInt32 LevelBits> inline
2773 ObjectT *ShaderCacheTreeV3<ObjectT, LevelBits>::find(const IdStore &vIds)
2775 if(vIds.size() < 1 || _pRoot == NULL)
2778 ObjectT *returnValue = NULL;
2780 IdType uiStartId = vIds[0] - 1;
2781 IdType uiStartLevel = IdType(uiStartId * LevelFactor);
2783 UInt32 uiCurrId = 0;
2784 UInt32 uiLastId = UInt32(vIds.size());
2787 if(uiStartLevel >= _vLevelEntries.size())
2789 uiStartLevel = IdType(_vLevelEntries.size() - 1);
2793 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
2794 UInt32 uiCurrBits = 0x0000;
2795 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
2796 TreeNode *pNextNode = NULL;
2798 if(pCurrNode == NULL)
2801 for(; uiCurrId < uiLastId; ++uiCurrId)
2803 UInt32 uiCurrIdx = vIds[uiCurrId] - uiLevelSub;
2804 UInt16 uiJumpDist = 1;
2806 if(uiCurrIdx <= LevelBits)
2808 uiCurrBits |= IdxToBits[uiCurrIdx];
2814 pNextNode = pCurrNode->_vChildren[uiCurrBits].asT2();
2816 if(pNextNode == NULL)
2818 pCurrNode = pNextNode;
2822 uiJumpDist = UInt16((uiCurrIdx - 1) * LevelFactor);
2823 UInt32 uiTargetLevel = uiStartLevel + uiJumpDist;
2825 if(uiJumpDist < pCurrNode->_vJumps[uiCurrBits])
2831 if(uiJumpDist > pCurrNode->_vJumps[uiCurrBits])
2833 uiLevelSub += LevelBits * pCurrNode->_vJumps[uiCurrBits];
2834 uiCurrIdx -= LevelBits * pCurrNode->_vJumps[uiCurrBits];
2835 uiJumpDist -= pCurrNode->_vJumps[uiCurrBits];
2837 pCurrNode = pNextNode;
2838 pNextNode = pCurrNode->_vChildren[0].asT2();
2840 uiCurrBits = 0x0000;
2844 if(uiCurrIdx <= LevelBits)
2849 if(uiJumpDist == pCurrNode->_vJumps[0])
2854 if(uiJumpDist < pCurrNode->_vJumps[0])
2860 if(pNextNode == NULL)
2866 LevelBits * pCurrNode->_vJumps[0];
2869 LevelBits * pCurrNode->_vJumps[0];
2871 uiJumpDist -= pCurrNode->_vJumps[0];
2873 pCurrNode = pNextNode;
2874 pNextNode = pCurrNode->_vChildren[0].asT2();
2878 pCurrNode = pNextNode;
2880 if(pCurrNode == NULL)
2885 uiCurrBits = 0x0000;
2887 uiStartLevel = uiTargetLevel;
2888 uiLevelSub = (uiStartLevel * LevelBits);
2890 uiCurrIdx -= uiJumpDist * LevelBits;
2893 uiCurrBits |= IdxToBits[uiCurrIdx];
2897 if(pCurrNode != NULL)
2899 TreeNode *pNext = pCurrNode->_vChildren[uiCurrBits].asT2();
2903 returnValue = pNext->_pObject;
2907 returnValue = pCurrNode->_vChildren[uiCurrBits].asT1();
2915 template<class ObjectT, UInt32 LevelBits> inline
2916 bool ShaderCacheTreeV3<ObjectT, LevelBits>::add(const IdStore &vIds,
2919 bool returnValue = false;
2924 IdType uiStartId = vIds[0] - 1;
2926 IdType uiStartLevel = IdType(uiStartId * LevelFactor);
2928 UInt32 uiCurrId = 0;
2929 UInt32 uiLastId = UInt32(vIds.size());
2932 FDEBUG(("scv3::add : "));
2933 for(UInt32 i = 0; i < uiLastId; ++i)
2935 FDEBUG(("%d ", vIds[i]));
2942 _pRoot = allocateNode();
2944 OSG_ASSERT(_vLevelEntries.size() == 0);
2946 _vLevelEntries.push_back(_pRoot);
2949 if(uiStartLevel >= _vLevelEntries.size())
2951 uiStartLevel = IdType(_vLevelEntries.size() - 1);
2955 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
2956 TreeNode *pNextNode = NULL;
2958 UInt32 uiCurrBits = 0x0000;
2960 if(pCurrNode == NULL)
2962 UInt32 uiLastValidLE = 0;
2964 for(Int32 i = uiStartLevel; i >= 0; --i)
2966 if(_vLevelEntries[i] != NULL)
2973 uiStartLevel = uiLastValidLE;
2974 pCurrNode = _vLevelEntries[uiStartLevel];
2977 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
2979 for(; uiCurrId < uiLastId; ++uiCurrId)
2981 UInt32 uiCurrIdx = vIds[uiCurrId] - uiLevelSub;
2982 UInt16 uiJumpDist = 1;
2984 if(uiCurrIdx <= LevelBits)
2986 uiCurrBits |= IdxToBits[uiCurrIdx];
2992 pNextNode = pCurrNode->_vChildren[uiCurrBits].asT2();
2994 uiJumpDist = UInt16((uiCurrIdx - 1) * LevelFactor);
2995 UInt32 uiTargetLevel = uiStartLevel + uiJumpDist;
2997 if(pNextNode != NULL)
2999 if(uiJumpDist > pCurrNode->_vJumps[uiCurrBits])
3001 uiLevelSub += LevelBits * pCurrNode->_vJumps[uiCurrBits];
3002 uiCurrIdx -= LevelBits * pCurrNode->_vJumps[uiCurrBits];
3003 uiJumpDist -= pCurrNode->_vJumps[uiCurrBits];
3005 pCurrNode = pNextNode;
3006 pNextNode = pCurrNode->_vChildren[0].asT2();
3008 uiCurrBits = 0x0000;
3012 if(uiCurrIdx <= LevelBits)
3017 if(pNextNode == NULL)
3022 if(uiJumpDist <= pCurrNode->_vJumps[0])
3028 LevelBits * pCurrNode->_vJumps[0];
3031 LevelBits * pCurrNode->_vJumps[0];
3033 uiJumpDist -= pCurrNode->_vJumps[0];
3035 pCurrNode = pNextNode;
3036 pNextNode = pCurrNode->_vChildren[0].asT2();
3040 if(uiJumpDist < pCurrNode->_vJumps[uiCurrBits])
3042 pNextNode = allocateNode();
3044 pNextNode->_vJumps[0] =
3045 pCurrNode->_vJumps [uiCurrBits] - uiJumpDist;
3047 pNextNode->_vChildren[0] =
3048 pCurrNode->_vChildren[uiCurrBits].asT2();
3050 pNextNode->_pObject =
3051 pCurrNode->_vChildren[uiCurrBits].asT2()->_pObject;
3053 pCurrNode->_vChildren[uiCurrBits].asT2()->_pObject = NULL;
3055 pCurrNode->_vJumps [uiCurrBits] = uiJumpDist;
3056 pCurrNode->_vChildren[uiCurrBits] = pNextNode;
3058 if(_vLevelEntries[uiTargetLevel] == NULL)
3060 UInt32 uiLastValidLE = 0;
3062 for(Int32 i = uiTargetLevel; i >= 0; --i)
3064 if(_vLevelEntries[i] != NULL)
3071 if(_vLevelEntries[uiLastValidLE] == pCurrNode &&
3074 _vLevelEntries[uiTargetLevel] = pNextNode;
3078 TreeNode *pTmpNode = allocateNode();
3081 uiLastValidLE]->_vChildren[0].asT2() != NULL)
3083 pTmpNode->_vChildren[0] =
3085 uiLastValidLE]->_vChildren[0].asT2();
3087 pTmpNode->_vJumps[0] =
3089 uiLastValidLE]->_vJumps[0] -
3090 (uiTargetLevel - uiLastValidLE);
3093 _vLevelEntries[uiLastValidLE]->_vChildren[0] =
3095 _vLevelEntries[uiLastValidLE]->_vJumps [0] =
3096 uiTargetLevel - uiLastValidLE;
3098 _vLevelEntries[uiTargetLevel] = pTmpNode;
3100 pTmpNode ->_pNext = pNextNode;
3101 pNextNode->_pPrev = pTmpNode;
3107 _vLevelEntries[uiTargetLevel]->_pNext;
3109 if(pNextNode->_pNext != NULL)
3111 pNextNode->_pNext->_pPrev = pNextNode;
3114 _vLevelEntries[uiTargetLevel]->_pNext = pNextNode;
3116 pNextNode->_pPrev = _vLevelEntries[uiTargetLevel];
3121 if(pNextNode == NULL)
3123 pNextNode = allocateNode();
3125 pCurrNode->_vJumps [uiCurrBits] = uiJumpDist;
3127 if(pCurrNode->_vChildren[uiCurrBits].asT1() != NULL)
3129 pNextNode->_pObject =
3130 pCurrNode->_vChildren[uiCurrBits].asT1();
3133 pCurrNode->_vChildren[uiCurrBits] = pNextNode;
3135 if(uiTargetLevel >= _vLevelEntries.size())
3137 _vLevelEntries.resize(uiTargetLevel + 1, NULL);
3139 UInt32 uiLastValidLE = 0;
3141 for(Int32 i = uiTargetLevel; i >= 0; --i)
3143 if(_vLevelEntries[i] != NULL)
3150 if(_vLevelEntries[uiLastValidLE] == pCurrNode &&
3153 _vLevelEntries[uiTargetLevel] = pNextNode;
3157 TreeNode *pTmpNode = allocateNode();
3159 _vLevelEntries[uiLastValidLE]->_vChildren[0] = pTmpNode;
3160 _vLevelEntries[uiLastValidLE]->_vJumps [0] =
3161 uiTargetLevel - uiLastValidLE;
3163 _vLevelEntries[uiTargetLevel] = pTmpNode;
3165 pTmpNode ->_pNext = pNextNode;
3166 pNextNode->_pPrev = pTmpNode;
3171 if(_vLevelEntries[uiTargetLevel] == NULL)
3173 UInt32 uiLastValidLE = 0;
3175 for(Int32 i = uiTargetLevel; i >= 0; --i)
3177 if(_vLevelEntries[i] != NULL)
3184 TreeNode *pTmpNode = allocateNode();
3187 uiLastValidLE]->_vChildren[0].asT2() != NULL)
3189 pTmpNode->_vChildren[0] =
3191 uiLastValidLE]->_vChildren[0].asT2();
3193 pTmpNode->_vJumps[0] =
3194 _vLevelEntries[uiLastValidLE]->_vJumps[0] -
3195 (uiTargetLevel - uiLastValidLE);
3199 _vLevelEntries[uiLastValidLE]->_vChildren[0] = pTmpNode;
3200 _vLevelEntries[uiLastValidLE]->_vJumps [0] =
3201 uiTargetLevel - uiLastValidLE;
3203 _vLevelEntries[uiTargetLevel] = pTmpNode;
3205 pTmpNode ->_pNext = pNextNode;
3206 pNextNode->_pPrev = pTmpNode;
3211 _vLevelEntries[uiTargetLevel]->_pNext;
3213 if(pNextNode->_pNext != NULL)
3215 pNextNode->_pNext->_pPrev = pNextNode;
3218 _vLevelEntries[uiTargetLevel]->_pNext = pNextNode;
3220 pNextNode->_pPrev = _vLevelEntries[uiTargetLevel];
3226 pCurrNode = pNextNode;
3228 uiCurrBits = 0x0000;
3230 uiStartLevel = uiTargetLevel;
3231 uiLevelSub = (uiStartLevel * LevelBits);
3233 uiCurrIdx -= uiJumpDist * LevelBits;
3235 uiCurrBits |= IdxToBits[uiCurrIdx];
3239 if(pCurrNode != NULL)
3241 TreeNode *pNextNode = pCurrNode->_vChildren[uiCurrBits].asT2();
3243 if(pNextNode != NULL)
3245 if(pNextNode->_pObject == NULL)
3247 pNextNode->_pObject = pObject;
3253 OSG_ASSERT(pNextNode->_pObject == pObject);
3258 pCurrNode->_vChildren[uiCurrBits] = pObject;
3267 template<class ObjectT, UInt32 LevelBits> inline
3268 void ShaderCacheTreeV3<ObjectT, LevelBits>::sub(UInt32 uiIdx)
3271 FDEBUG(("scv3::sub : %d\n", uiIdx));
3274 IdType uiStartLevel = IdType((uiIdx - 1) * LevelFactor);
3276 if(uiStartLevel >= _vLevelEntries.size())
3281 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
3282 UInt32 uiCurrIdx = uiIdx - uiLevelSub;
3283 UInt32 uiCurrBits = IdxToBits[uiCurrIdx];
3285 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
3287 for(; pCurrNode != NULL; pCurrNode = pCurrNode->_pNext)
3289 for(UInt32 i = 0; i < LevelSize; ++i)
3291 TreeNode *pChild = pCurrNode->_vChildren[i].asT2();
3293 if(0x0000 != (i & uiCurrBits) && pChild != NULL)
3295 if(pChild->_pNext == NULL)
3297 pChild->_pPrev->_pNext = NULL;
3301 pChild->_pPrev->_pNext = pChild->_pNext;
3302 pChild->_pNext->_pPrev = pChild->_pPrev;
3305 pChild->_pPrev = NULL;
3306 pChild->_pNext = NULL;
3308 eraseNode(pCurrNode->_vChildren[i].asT2());
3309 pCurrNode->_vJumps [i] = 0;
3310 pCurrNode->_vChildren[i].setAsT2(NULL);
3312 else if(pCurrNode->_vChildren[i].asT1() != NULL)
3314 pCurrNode->_vChildren[i].setAsT1(NULL);
3315 pCurrNode->_vJumps [i] = 0;
3321 #define OSG_DUMP_LEVELENTRIES
3323 template<class ObjectT, UInt32 LevelBits> inline
3324 void ShaderCacheTreeV3<ObjectT,
3325 LevelBits>::dumpDot(const Char8 *szFilename,
3326 bool dumpEmptyLevelEntries)
3328 FILE *pOut = fopen(szFilename, "w");
3332 fprintf(pOut, "digraph structs\n");
3333 fprintf(pOut, "{\n");
3334 fprintf(pOut, "rankdir = LR;\n");
3335 fprintf(pOut, "splines=false\n");
3337 fprintf(pOut, "node [shape=record];\n");
3339 fprintf(pOut, "struct%d\n", 0);
3340 fprintf(pOut, "[\n");
3341 fprintf(pOut, " label=\"");
3343 for(UInt32 i = 0; i < _vLevelEntries.size(); ++i)
3345 if(_vLevelEntries[i] != NULL)
3347 fprintf(pOut, "<l%d> %d", i, i);
3351 if(dumpEmptyLevelEntries == true)
3352 fprintf(pOut, "<l%d> NIL", i);
3355 if(i == _vLevelEntries.size() - 1)
3357 fprintf(pOut, "\"\n");
3361 if(_vLevelEntries[i] != NULL || dumpEmptyLevelEntries == true)
3366 fprintf(pOut, "]\n");
3368 fprintf(pOut, "node [width = 1.5];\n");
3370 std::vector<std::vector<TreeNode *> > vLevelStore;
3372 dumpDotNode(_pRoot, pOut, vLevelStore, 0);
3375 #ifdef OSG_DUMP_LEVELENTRIES
3376 for(UInt32 i = 0; i < _vLevelEntries.size(); ++i)
3378 if(_vLevelEntries[i] != NULL)
3381 "struct%d:l%d -> struct%d:prev [color=\"green\"];\n",
3383 _vLevelEntries[i]->_uiNodeId);
3389 for(UInt32 i = 0; i < vLevelStore.size(); ++i)
3391 fprintf(pOut, "{ rank=same;");
3393 for(UInt32 j = 0; j < vLevelStore[i].size(); ++j)
3395 TreeNode *pChild = vLevelStore[i][j];
3399 fprintf(pOut, "\"struct%d\";",
3404 fprintf(pOut, "}\n");
3409 fprintf(pOut, "}\n");
3414 template<class ObjectT, UInt32 LevelBits> inline
3415 void ShaderCacheTreeV3<ObjectT, LevelBits>::dumpDotNode(
3418 std::vector<std::vector<TreeNode *> > &vLevelStore,
3425 if(uiLevel == vLevelStore.size())
3427 vLevelStore.push_back(std::vector<TreeNode *>());
3430 fprintf(pOut, "struct%d\n", pNode->_uiNodeId);
3431 fprintf(pOut, "[\n");
3432 fprintf(pOut, " label=\"{");
3434 if(pNode->_pPrev != NULL)
3436 fprintf(pOut, "<prev> P|");
3440 fprintf(pOut, "<prev> P:NIL|");
3443 for(UInt32 i = 0; i < LevelSize; ++i)
3445 if(pNode->_vChildren[i].asT1() != NULL)
3447 if(osgIsPower2(i) == true)
3449 fprintf(pOut, "<l%d> _O:%d|", i, i);
3453 fprintf(pOut, "<l%d> O:%d|", i, i);
3456 else if(pNode->_vChildren[i].asT2() != NULL)
3458 if(osgIsPower2(i) == true)
3460 fprintf(pOut, "<l%d> _C:%d (%d)|", i, i, pNode->_vJumps[i]);
3464 fprintf(pOut, "<l%d> C:%d (%d)|", i, i, pNode->_vJumps[i]);
3469 if(osgIsPower2(i) == true)
3471 fprintf(pOut, "<l%d> _NIL|", i);
3475 fprintf(pOut, "<l%d> NIL|", i);
3480 if(pNode->_pObject != NULL)
3482 fprintf(pOut, "<val> VAL:Obj|");
3486 fprintf(pOut, "<val> VAL:NIL|");
3489 if(pNode->_pNext != NULL)
3491 fprintf(pOut, "<next> N}\"\n");
3495 fprintf(pOut, "<next> N:NIL}\"\n");
3498 fprintf(pOut, "]\n");
3500 for(UInt32 i = 0; i < LevelSize; ++i)
3502 TreeNode *pChild = pNode->_vChildren[i].asT2();
3506 dumpDotNode(pChild, pOut, vLevelStore, uiLevel + 1);
3509 "struct%d:l%d -> struct%d:l%d [constraint=\"false\"];\n",
3510 pNode ->_uiNodeId, i,
3511 pChild->_uiNodeId, i);
3515 if(pNode->_pNext != NULL)
3517 fprintf(pOut, "struct%d:next -> struct%d:prev;\n",
3519 pNode->_pNext->_uiNodeId);
3521 if(pNode->_pPrev != NULL)
3523 fprintf(pOut, "struct%d:prev -> struct%d:next;\n",
3525 pNode->_pPrev->_uiNodeId);
3528 vLevelStore[uiLevel].push_back(pNode);
3532 template<class ObjectT, UInt32 LevelBits> inline
3533 ShaderCacheTreeV3<ObjectT, LevelBits>::ShaderCacheTreeV3(void) :
3541 _pRoot = allocateNode();
3543 _vLevelEntries.push_back(_pRoot);
3546 template<class ObjectT, UInt32 LevelBits> inline
3547 ShaderCacheTreeV3<ObjectT, LevelBits>::~ShaderCacheTreeV3(void)
3549 typename std::deque <TreeNode *>::iterator qIt =
3550 _qFreeElements.begin();
3552 typename std::deque <TreeNode *>::const_iterator qEnd =
3553 _qFreeElements.end();
3555 for(; qIt != qEnd; ++qIt)
3562 typename std::vector<TreeNode *>::iterator vIt = _vLevelEntries.begin();
3563 typename std::vector<TreeNode *>::iterator vEnd = _vLevelEntries.end ();
3565 for(; vIt != vEnd; ++vIt)
3573 template<class ObjectT, UInt32 LevelBits> inline
3574 typename ShaderCacheTreeV3<ObjectT, LevelBits>::TreeNode *
3575 ShaderCacheTreeV3<ObjectT, LevelBits>::allocateNode(void)
3577 TreeNode *returnValue = NULL;
3579 if(_qFreeElements.empty() == false)
3581 returnValue = _qFreeElements.back();
3583 _qFreeElements.pop_back();
3585 returnValue->clear();
3589 returnValue = new TreeNode();
3592 returnValue->_uiNodeId = ++_uiNodeCount;
3597 UIntPointer rU = reinterpret_cast<UIntPointer>(returnValue);
3599 OSG_ASSERT((rU & 0x0001) == 0x0000);
3605 template<class ObjectT, UInt32 LevelBits> inline
3606 void ShaderCacheTreeV3<ObjectT, LevelBits>::eraseNode(TreeNode *pNode)
3608 for(UInt32 i = 0; i < LevelSize; ++i)
3610 if(pNode->_vChildren[i].asT2() != NULL)
3612 eraseNode(pNode->_vChildren[i].asT2());
3614 pNode->_vChildren[i].setAsT2(NULL);
3618 pNode->_vChildren[i].setAsT1(NULL);
3622 pNode->_pObject = NULL;
3624 _qFreeElements.push_back(pNode);
3627 template<class ObjectT, UInt32 LevelBits>
3628 template <typename ElemDestFunc> inline
3629 void ShaderCacheTreeV3<ObjectT, LevelBits>::destroyNode(TreeNode *pNode,
3630 ElemDestFunc destFunc)
3635 UInt32 uiChildStart = 0;
3637 for(UInt32 i = uiChildStart; i < LevelSize; ++i)
3639 if(pNode->_vChildren[i].asT2() != NULL)
3641 destroyNode(pNode->_vChildren[i].asT2(), destFunc);
3643 else if(pNode->_vChildren[i].asT1() != NULL)
3645 #ifndef OSG_SHC_REF_CLEANUP
3646 ObjectT *pObj = pNode->_vChildren[i].asT1();
3649 pNode->_vChildren[i].setAsT1(NULL);
3653 if(pNode->_pObject != NULL)
3655 #ifndef OSG_SHC_REF_CLEANUP
3656 (destFunc)(pNode->_pObject);
3658 pNode->_pObject = NULL;
3664 template<class ObjectT, UInt32 LevelBits>
3665 template <typename ElemDestFunc> inline
3666 void ShaderCacheTreeV3<ObjectT, LevelBits>::destroy(ElemDestFunc destFunc)
3668 destroyNode(_pRoot, destFunc);
3670 TreeNodeVecIt leIt = _vLevelEntries.begin();
3671 TreeNodeVecConstIt leEnd = _vLevelEntries.end ();
3673 for(; leIt != leEnd; ++leIt)
3678 _vLevelEntries.clear();