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 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) :
989 template<typename Object1T, typename RefCountPol1,
990 typename Object2T, typename RefCountPol2> inline
991 VariantPtr<Object1T, RefCountPol1,
992 Object2T, RefCountPol2>::~VariantPtr(void)
994 if(_val._uiIntVal & UIMaskChoice) //isObj1
996 _val._uiIntVal &= UIMaskPtr;
998 RefCountPol1::subRef(_val._pObj1);
1002 template<typename Object1T, typename RefCountPol1,
1003 typename Object2T, typename RefCountPol2> inline
1004 Object1T *VariantPtr<Object1T, RefCountPol1,
1005 Object2T, RefCountPol2>::asT1(void) const
1008 if(_val._uiIntVal & UIMaskChoice) //isObj1
1010 MemberU returnValue = { _val._uiIntVal & UIMaskPtr };
1012 return returnValue._pObj1;
1018 template<typename Object1T, typename RefCountPol1,
1019 typename Object2T, typename RefCountPol2> inline
1020 Object2T *VariantPtr<Object1T, RefCountPol1,
1021 Object2T, RefCountPol2>::asT2(void) const
1024 if(!(_val._uiIntVal & UIMaskChoice)) //!isObj1
1030 template<typename Object1T, typename RefCountPol1,
1031 typename Object2T, typename RefCountPol2> inline
1032 void VariantPtr<Object1T, RefCountPol1,
1033 Object2T, RefCountPol2>::setAsT1(Object1T * const rhs)
1035 if(_val._uiIntVal & UIMaskChoice) //isObj1
1037 _val._uiIntVal &= UIMaskPtr;
1039 RefCountPol1::setRefd(_val._pObj1, rhs);
1043 RefCountPol1::addRef(rhs);
1049 _val._uiIntVal |= UIMaskChoice;
1053 template<typename Object1T, typename RefCountPol1,
1054 typename Object2T, typename RefCountPol2> inline
1055 void VariantPtr<Object1T, RefCountPol1,
1056 Object2T, RefCountPol2>::setAsT2(Object2T * const rhs)
1058 if(_val._uiIntVal & UIMaskChoice) //isObj1
1060 _val._uiIntVal &= UIMaskPtr;
1062 RefCountPol1::subRef(_val._pObj1);
1069 template<typename Object1T, typename RefCountPol1,
1070 typename Object2T, typename RefCountPol2> inline
1071 const VariantPtr<Object1T, RefCountPol1,
1072 Object2T, RefCountPol2> &
1073 VariantPtr<Object1T, RefCountPol1,
1074 Object2T, RefCountPol2>::operator =(Object1T * const rhs)
1081 template<typename Object1T, typename RefCountPol1,
1082 typename Object2T, typename RefCountPol2> inline
1083 const VariantPtr<Object1T, RefCountPol1,
1084 Object2T, RefCountPol2> &
1085 VariantPtr<Object1T, RefCountPol1,
1086 Object2T, RefCountPol2>::operator =(Object2T * const rhs)
1094 template<typename Object1T, typename RefCountPol1,
1095 typename Object2T, typename RefCountPol2> inline
1096 Object2T *VariantPtr<Object1T, RefCountPol1,
1097 Object2T, RefCountPol2>::operator ->(void) const
1099 return this->asT2();
1105 /*---------------------------------------------------------------------------*/
1106 /*---------------------------------------------------------------------------*/
1108 #if defined(WIN32) || defined(__APPLE__) || \
1109 defined(__GXX_EXPERIMENTAL_CXX0X__)
1110 template<class ObjectT, UInt32 LevelBits>
1111 const Real32 ShaderCacheTreeV1<ObjectT, LevelBits>::LevelFactor =
1115 template<class ObjectT, UInt32 LevelBits> inline
1116 ShaderCacheTreeV1<ObjectT, LevelBits>::TreeNode::TreeNode(void) :
1126 template<class ObjectT, UInt32 LevelBits> inline
1127 ShaderCacheTreeV1<ObjectT, LevelBits>::TreeNode::~TreeNode(void)
1133 for(UInt32 i = 0; i < LevelSize; ++i)
1135 _vChildren[i].setAsT1(NULL);
1139 template<class ObjectT, UInt32 LevelBits> inline
1140 void ShaderCacheTreeV1<ObjectT, LevelBits>::TreeNode::clear(void)
1146 for(UInt32 i = 0; i < LevelSize; ++i)
1148 _vChildren[i].setAsT1(NULL);
1154 template<class ObjectT, UInt32 LevelBits> inline
1155 ObjectT *ShaderCacheTreeV1<ObjectT, LevelBits>::find(const IdStore &vIds)
1160 ObjectT *returnValue = NULL;
1162 IdType uiStartId = vIds[0] - 1;
1163 IdType uiStartLevel = IdType(uiStartId * LevelFactor);
1165 UInt32 uiCurrId = 0;
1166 UInt32 uiLastId = vIds.size();
1169 if(uiStartLevel >= _vLevelEntries.size())
1171 uiStartLevel = _vLevelEntries.size() - 1;
1175 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
1176 UInt32 uiCurrBits = 0x0000;
1177 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
1179 if(pCurrNode == NULL)
1182 for(; uiCurrId < uiLastId; ++uiCurrId)
1184 UInt32 uiCurrIdx = vIds[uiCurrId] - uiLevelSub;
1186 if(uiCurrIdx <= LevelBits)
1188 uiCurrBits |= IdxToBits[uiCurrIdx];
1194 pCurrNode = pCurrNode->_vChildren[uiCurrBits].asT2();
1196 if(pCurrNode == NULL)
1201 uiCurrBits = 0x0000;
1203 uiLevelSub += LevelBits;
1204 uiCurrIdx -= LevelBits;
1206 while(uiCurrIdx > LevelBits)
1208 pCurrNode = pCurrNode->_vChildren[0].asT2();
1210 if(pCurrNode == NULL)
1214 uiLevelSub += LevelBits;
1215 uiCurrIdx -= LevelBits;
1218 if(pCurrNode == NULL)
1223 uiCurrBits |= IdxToBits[uiCurrIdx];
1227 if(pCurrNode != NULL)
1229 TreeNode *pNext = pCurrNode->_vChildren[uiCurrBits].asT2();
1233 returnValue = pNext->_pObject;
1237 returnValue = pCurrNode->_vChildren[uiCurrBits].asT1();
1245 template<class ObjectT, UInt32 LevelBits> inline
1246 bool ShaderCacheTreeV1<ObjectT, LevelBits>::add(const IdStore &vIds,
1249 bool returnValue = false;
1254 IdType uiStartId = vIds[0] - 1;
1256 IdType uiStartLevel = IdType(uiStartId * LevelFactor);
1258 UInt32 uiCurrId = 0;
1259 UInt32 uiLastId = vIds.size();
1262 if(uiStartLevel >= _vLevelEntries.size())
1264 uiStartLevel = _vLevelEntries.size() - 1;
1267 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
1269 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
1270 TreeNode *pNextNode = NULL;
1272 UInt32 uiCurrBits = 0x0000;
1274 for(; uiCurrId < uiLastId; ++uiCurrId)
1276 UInt32 uiCurrIdx = vIds[uiCurrId] - uiLevelSub;
1278 if(uiCurrIdx <= LevelBits)
1280 uiCurrBits |= IdxToBits[uiCurrIdx];
1286 pNextNode = pCurrNode->_vChildren[uiCurrBits].asT2();
1288 if(pNextNode == NULL)
1290 pNextNode = allocateNode();
1292 if(pCurrNode->_vChildren[uiCurrBits].asT1() != NULL)
1294 pNextNode->_pObject =
1295 pCurrNode->_vChildren[uiCurrBits].asT1();
1298 pCurrNode->_vChildren[uiCurrBits] = pNextNode;
1300 if(uiStartLevel == _vLevelEntries.size() - 1)
1302 if(_vLevelEntries.back()->_vChildren[0].asT2() == NULL)
1304 TreeNode *pTmpNode = allocateNode();
1306 _vLevelEntries.back()->_vChildren[0] = pTmpNode;
1308 _vLevelEntries.push_back(pTmpNode);
1310 pTmpNode->_pNext = pNextNode;
1311 pNextNode->_pPrev = pTmpNode;
1315 _vLevelEntries.push_back(pNextNode);
1321 _vLevelEntries[uiStartLevel]->_vChildren[0]->_pNext;
1323 if(pNextNode->_pNext != NULL)
1325 pNextNode->_pNext->_pPrev = pNextNode;
1328 _vLevelEntries[uiStartLevel]->_vChildren[0]->_pNext =
1332 _vLevelEntries[uiStartLevel]->_vChildren[0].asT2();
1338 uiCurrBits = 0x0000;
1340 pCurrNode = pNextNode;
1342 uiLevelSub += LevelBits;
1343 uiCurrIdx -= LevelBits;
1345 while(uiCurrIdx > LevelBits)
1347 if(pCurrNode->_vChildren[0].asT2() == NULL)
1349 pNextNode = allocateNode();
1351 pCurrNode->_vChildren[0] = pNextNode;
1353 if(uiStartLevel == _vLevelEntries.size() - 1)
1355 if(_vLevelEntries.back()->_vChildren[0].asT2() == NULL)
1357 TreeNode *pTmpNode = allocateNode();
1359 _vLevelEntries.back()->_vChildren[0] = pTmpNode;
1361 _vLevelEntries.push_back(pTmpNode);
1363 pTmpNode->_pNext = pNextNode;
1364 pNextNode->_pPrev = pTmpNode;
1368 _vLevelEntries.push_back(pNextNode);
1374 _vLevelEntries[uiStartLevel]->
1375 _vChildren[0]->_pNext;
1377 if(pNextNode->_pNext != NULL)
1379 pNextNode->_pNext->_pPrev = pNextNode;
1382 _vLevelEntries[uiStartLevel]->_vChildren[0]->_pNext=
1386 _vLevelEntries[uiStartLevel]->_vChildren[0].asT2();
1390 pCurrNode = pCurrNode->_vChildren[0].asT2();
1392 uiLevelSub += LevelBits;
1393 uiCurrIdx -= LevelBits;
1399 uiCurrBits |= IdxToBits[uiCurrIdx];
1403 if(pCurrNode != NULL)
1405 pNextNode = pCurrNode->_vChildren[uiCurrBits].asT2();
1407 if(pNextNode != NULL)
1409 if(pNextNode->_pObject == NULL)
1411 pNextNode->_pObject = pObject;
1417 OSG_ASSERT(pNextNode->_pObject == pObject);
1422 pCurrNode->_vChildren[uiCurrBits] = pObject;
1431 template<class ObjectT, UInt32 LevelBits> inline
1432 void ShaderCacheTreeV1<ObjectT, LevelBits>::sub(UInt32 uiIdx)
1434 IdType uiStartLevel = IdType((uiIdx - 1) * LevelFactor);
1436 if(uiStartLevel >= _vLevelEntries.size())
1441 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
1442 UInt32 uiCurrIdx = uiIdx - uiLevelSub;
1443 UInt32 uiCurrBits = IdxToBits[uiCurrIdx];
1445 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
1447 for(; pCurrNode != NULL; pCurrNode = pCurrNode->_pNext)
1449 for(UInt32 i = 0; i < LevelSize; ++i)
1451 TreeNode *pChild = pCurrNode->_vChildren[i].asT2();
1453 if(0x0000 != (i & uiCurrBits) && pChild != NULL)
1455 if(pChild->_pNext == NULL)
1457 pChild->_pPrev->_pNext = NULL;
1461 pChild->_pPrev->_pNext = pChild->_pNext;
1462 pChild->_pNext->_pPrev = pChild->_pPrev;
1465 pChild->_pPrev = NULL;
1466 pChild->_pNext = NULL;
1468 eraseNode(pCurrNode->_vChildren[i].asT2());
1469 pCurrNode->_vChildren[i].setAsT2(NULL);
1471 else if(pCurrNode->_vChildren[i].asT1() != NULL)
1473 pCurrNode->_vChildren[i].setAsT1(NULL);
1479 template<class ObjectT, UInt32 LevelBits> inline
1480 void ShaderCacheTreeV1<ObjectT, LevelBits>::dumpDot(const Char8 *szFilename)
1482 FILE *pOut = fopen(szFilename, "w");
1486 fprintf(pOut, "digraph structs\n");
1487 fprintf(pOut, "{\n");
1488 fprintf(pOut, "rankdir = LR;\n");
1489 fprintf(pOut, "splines=false\n");
1491 fprintf(pOut, "node [shape=record];\n");
1493 fprintf(pOut, "struct%d\n", 0);
1494 fprintf(pOut, "[\n");
1495 fprintf(pOut, " label=\"");
1497 for(UInt32 i = 0; i < _vLevelEntries.size(); ++i)
1499 if(_vLevelEntries[i] != NULL)
1501 fprintf(pOut, "<l%d> %d", i, i);
1505 fprintf(pOut, "<l%d> NIL", i);
1508 if(i == _vLevelEntries.size() - 1)
1510 fprintf(pOut, "\"\n");
1518 fprintf(pOut, "]\n");
1520 fprintf(pOut, "node [width = 1.5];\n");
1522 std::vector<std::vector<TreeNode *> > vLevelStore;
1524 dumpDotNode(_pRoot, pOut, vLevelStore, 0);
1527 for(UInt32 i = 0; i < _vLevelEntries.size(); ++i)
1529 if(_vLevelEntries[i] != NULL)
1532 "struct%d:l%d -> struct%d:prev [color=\"green\"];\n",
1534 _vLevelEntries[i]->_uiNodeId);
1538 for(UInt32 i = 0; i < vLevelStore.size(); ++i)
1540 fprintf(pOut, "{ rank=same;");
1542 for(UInt32 j = 0; j < vLevelStore[i].size(); ++j)
1544 TreeNode *pChild = vLevelStore[i][j];
1548 fprintf(pOut, "\"struct%d\";",
1553 fprintf(pOut, "}\n");
1558 fprintf(pOut, "}\n");
1563 template<class ObjectT, UInt32 LevelBits> inline
1564 void ShaderCacheTreeV1<ObjectT, LevelBits>::dumpDotNode(
1567 std::vector<std::vector<TreeNode *> > &vLevelStore,
1574 if(uiLevel == vLevelStore.size())
1576 vLevelStore.push_back(std::vector<TreeNode *>());
1579 fprintf(pOut, "struct%d\n", pNode->_uiNodeId);
1580 fprintf(pOut, "[\n");
1581 fprintf(pOut, " label=\"{");
1583 if(pNode->_pPrev != NULL)
1585 fprintf(pOut, "<prev> P|");
1589 fprintf(pOut, "<prev> P:NIL|");
1592 for(UInt32 i = 0; i < LevelSize; ++i)
1594 if(pNode->_vChildren[i].asT1() != NULL)
1596 fprintf(pOut, "<l%d> O:%d|", i, i);
1598 else if(pNode->_vChildren[i].asT2() != NULL)
1600 fprintf(pOut, "<l%d> C:%d|", i, i);
1604 fprintf(pOut, "<l%d> NIL|", i);
1608 if(pNode->_pObject != NULL)
1610 fprintf(pOut, "<val> VAL:Obj|");
1614 fprintf(pOut, "<val> VAL:NIL|");
1617 if(pNode->_pNext != NULL)
1619 fprintf(pOut, "<next> N}\"\n");
1623 fprintf(pOut, "<next> N:NIL}\"\n");
1626 fprintf(pOut, "]\n");
1628 for(UInt32 i = 0; i < LevelSize; ++i)
1630 TreeNode *pChild = pNode->_vChildren[i].asT2();
1634 dumpDotNode(pChild, pOut, vLevelStore, uiLevel + 1);
1637 "struct%d:l%d -> struct%d:l%d [constraint=\"false\"];\n",
1638 pNode ->_uiNodeId, i,
1639 pChild->_uiNodeId, i);
1643 if(pNode->_pNext != NULL)
1645 fprintf(pOut, "struct%d:next -> struct%d:prev;\n",
1647 pNode->_pNext->_uiNodeId);
1649 if(pNode->_pPrev != NULL)
1651 fprintf(pOut, "struct%d:prev -> struct%d:next;\n",
1653 pNode->_pPrev->_uiNodeId);
1656 vLevelStore[uiLevel].push_back(pNode);
1660 template<class ObjectT, UInt32 LevelBits> inline
1661 ShaderCacheTreeV1<ObjectT, LevelBits>::ShaderCacheTreeV1(void) :
1669 _pRoot = allocateNode();
1671 _vLevelEntries.push_back(_pRoot);
1674 template<class ObjectT, UInt32 LevelBits> inline
1675 ShaderCacheTreeV1<ObjectT, LevelBits>::~ShaderCacheTreeV1(void)
1677 typename std::deque <TreeNode *>::const_iterator qIt =
1678 _qFreeElements.begin();
1680 typename std::deque <TreeNode *>::const_iterator qEnd =
1681 _qFreeElements.end();
1683 for(; qIt != qEnd; ++qIt)
1689 template<class ObjectT, UInt32 LevelBits> inline
1690 typename ShaderCacheTreeV1<ObjectT, LevelBits>::TreeNode *
1691 ShaderCacheTreeV1<ObjectT, LevelBits>::allocateNode(void)
1693 TreeNode *returnValue = NULL;
1695 if(_qFreeElements.empty() == false)
1697 returnValue = _qFreeElements.back();
1699 _qFreeElements.pop_back();
1701 returnValue->clear();
1705 returnValue = new TreeNode();
1708 returnValue->_uiNodeId = ++_uiNodeCount;
1713 UIntPointer rU = reinterpret_cast<UIntPointer>(returnValue);
1715 OSG_ASSERT((rU & 0x0001) == 0x0000);
1721 template<class ObjectT, UInt32 LevelBits> inline
1722 void ShaderCacheTreeV1<ObjectT, LevelBits>::eraseNode(TreeNode *pNode)
1724 for(UInt32 i = 0; i < LevelSize; ++i)
1726 if(pNode->_vChildren[i].asT2() != NULL)
1728 eraseNode(pNode->_vChildren[i].asT2());
1732 pNode->_vChildren[i].setAsT1(NULL);
1736 pNode->_pObject = NULL;
1738 _qFreeElements.push_back(pNode);
1741 template<class ObjectT, UInt32 LevelBits>
1742 template <typename ElemDestFunc> inline
1743 void ShaderCacheTreeV1<ObjectT, LevelBits>::destroyNode(TreeNode *pNode,
1744 ElemDestFunc destFunc)
1749 UInt32 uiChildStart = 0;
1751 if(pNode->_pPrev == NULL)
1754 for(UInt32 i = uiChildStart; i < LevelSize; ++i)
1756 if(pNode->_vChildren[i].asT2() != NULL)
1758 destroyNode(pNode->_vChildren[i].asT2(), destFunc);
1760 else if(pNode->_vChildren[i].asT1() != NULL)
1762 #ifndef OSG_SHC_REF_CLEANUP
1763 ObjectT *pObj = pNode->_vChildren[i].asT1();
1766 pNode->_vChildren[i].setAsT1(NULL);
1770 if(pNode->_pObject != NULL)
1772 #ifndef OSG_SHC_REF_CLEANUP
1773 (destFunc)(pNode->_pObject);
1775 pNode->_pObject = NULL;
1781 template<class ObjectT, UInt32 LevelBits>
1782 template <typename ElemDestFunc> inline
1783 void ShaderCacheTreeV1<ObjectT, LevelBits>::destroy(ElemDestFunc destFunc)
1785 destroyNode(_pRoot, destFunc);
1787 _vLevelEntries[0] = NULL;
1797 /*---------------------------------------------------------------------------*/
1798 /*---------------------------------------------------------------------------*/
1800 #if defined(WIN32) || defined(__APPLE__) || \
1801 defined(__GXX_EXPERIMENTAL_CXX0X__)
1802 template<class ObjectT, UInt32 LevelBits>
1803 const Real32 ShaderCacheTreeV2<ObjectT, LevelBits>::LevelFactor =
1807 template<class ObjectT, UInt32 LevelBits> inline
1808 ShaderCacheTreeV2<ObjectT, LevelBits>::TreeNode::TreeNode(void) :
1816 memset(&(_vJumps[0]), 0, LevelSize * sizeof(UInt16));
1819 template<class ObjectT, UInt32 LevelBits> inline
1820 ShaderCacheTreeV2<ObjectT, LevelBits>::TreeNode::~TreeNode(void)
1826 for(UInt32 i = 0; i < LevelSize; ++i)
1828 _vChildren[i].setAsT1(NULL);
1832 template<class ObjectT, UInt32 LevelBits> inline
1833 void ShaderCacheTreeV2<ObjectT, LevelBits>::TreeNode::clear(void)
1839 for(UInt32 i = 0; i < LevelSize; ++i)
1841 _vChildren[i].setAsT1(NULL);
1844 memset(&(_vJumps[0]), 0, LevelSize * sizeof(UInt16));
1849 template<class ObjectT, UInt32 LevelBits> inline
1850 ObjectT *ShaderCacheTreeV2<ObjectT, LevelBits>::find(const IdStore &vIds)
1855 ObjectT *returnValue = NULL;
1857 IdType uiStartId = vIds[0] - 1;
1858 IdType uiStartLevel = IdType(uiStartId * LevelFactor);
1860 UInt32 uiCurrId = 0;
1861 UInt32 uiLastId = vIds.size();
1864 if(uiStartLevel >= _vLevelEntries.size())
1866 uiStartLevel = _vLevelEntries.size() - 1;
1870 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
1871 UInt32 uiCurrBits = 0x0000;
1872 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
1873 TreeNode *pNextNode = NULL;
1875 if(pCurrNode == NULL)
1878 for(; uiCurrId < uiLastId; ++uiCurrId)
1880 UInt32 uiCurrIdx = vIds[uiCurrId] - uiLevelSub;
1881 UInt16 uiJumpDist = 1;
1883 if(uiCurrIdx <= LevelBits)
1885 uiCurrBits |= IdxToBits[uiCurrIdx];
1891 pNextNode = pCurrNode->_vChildren[uiCurrBits].asT2();
1893 if(pNextNode == NULL)
1895 pCurrNode = pNextNode;
1899 uiJumpDist = UInt16((uiCurrIdx - 1) * LevelFactor);
1900 UInt32 uiTargetLevel = uiStartLevel + uiJumpDist;
1902 if(uiJumpDist < pCurrNode->_vJumps[uiCurrBits])
1908 if(uiJumpDist > pCurrNode->_vJumps[uiCurrBits])
1910 uiLevelSub += LevelBits * pCurrNode->_vJumps[uiCurrBits];
1911 uiCurrIdx -= LevelBits * pCurrNode->_vJumps[uiCurrBits];
1912 uiJumpDist -= pCurrNode->_vJumps[uiCurrBits];
1914 pCurrNode = pNextNode;
1915 pNextNode = pCurrNode->_vChildren[0].asT2();
1917 uiCurrBits = 0x0000;
1921 if(uiCurrIdx <= LevelBits)
1926 if(uiJumpDist == pCurrNode->_vJumps[0])
1931 if(uiJumpDist < pCurrNode->_vJumps[0])
1937 if(pNextNode == NULL)
1943 LevelBits * pCurrNode->_vJumps[0];
1946 LevelBits * pCurrNode->_vJumps[0];
1948 uiJumpDist -= pCurrNode->_vJumps[0];
1950 pCurrNode = pNextNode;
1951 pNextNode = pCurrNode->_vChildren[0].asT2();
1955 pCurrNode = pNextNode;
1957 if(pCurrNode == NULL)
1962 uiCurrBits = 0x0000;
1964 uiStartLevel = uiTargetLevel;
1965 uiLevelSub = (uiStartLevel * LevelBits);
1967 uiCurrIdx -= uiJumpDist * LevelBits;
1970 uiCurrBits |= IdxToBits[uiCurrIdx];
1974 if(pCurrNode != NULL)
1976 TreeNode *pNext = pCurrNode->_vChildren[uiCurrBits].asT2();
1980 returnValue = pNext->_pObject;
1984 returnValue = pCurrNode->_vChildren[uiCurrBits].asT1();
1992 template<class ObjectT, UInt32 LevelBits> inline
1993 bool ShaderCacheTreeV2<ObjectT, LevelBits>::add(const IdStore &vIds,
1996 bool returnValue = false;
2001 IdType uiStartId = vIds[0] - 1;
2003 IdType uiStartLevel = IdType(uiStartId * LevelFactor);
2005 UInt32 uiCurrId = 0;
2006 UInt32 uiLastId = vIds.size();
2009 if(uiStartLevel >= _vLevelEntries.size())
2011 uiStartLevel = _vLevelEntries.size() - 1;
2015 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
2016 TreeNode *pNextNode = NULL;
2018 UInt32 uiCurrBits = 0x0000;
2020 if(pCurrNode == NULL)
2022 UInt32 uiLastValidLE = 0;
2024 for(Int32 i = uiStartLevel; i >= 0; --i)
2026 if(_vLevelEntries[i] != NULL)
2033 uiStartLevel = uiLastValidLE;
2034 pCurrNode = _vLevelEntries[uiStartLevel];
2037 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
2039 for(; uiCurrId < uiLastId; ++uiCurrId)
2041 UInt32 uiCurrIdx = vIds[uiCurrId] - uiLevelSub;
2042 UInt16 uiJumpDist = 1;
2044 if(uiCurrIdx <= LevelBits)
2046 uiCurrBits |= IdxToBits[uiCurrIdx];
2052 pNextNode = pCurrNode->_vChildren[uiCurrBits].asT2();
2054 uiJumpDist = UInt16((uiCurrIdx - 1) * LevelFactor);
2055 UInt32 uiTargetLevel = uiStartLevel + uiJumpDist;
2057 if(pNextNode != NULL)
2059 if(uiJumpDist > pCurrNode->_vJumps[uiCurrBits])
2061 uiLevelSub += LevelBits * pCurrNode->_vJumps[uiCurrBits];
2062 uiCurrIdx -= LevelBits * pCurrNode->_vJumps[uiCurrBits];
2063 uiJumpDist -= pCurrNode->_vJumps[uiCurrBits];
2065 pCurrNode = pNextNode;
2066 pNextNode = pCurrNode->_vChildren[0].asT2();
2068 uiCurrBits = 0x0000;
2072 if(uiCurrIdx <= LevelBits)
2077 if(pNextNode == NULL)
2082 if(uiJumpDist <= pCurrNode->_vJumps[0])
2088 LevelBits * pCurrNode->_vJumps[0];
2091 LevelBits * pCurrNode->_vJumps[0];
2093 uiJumpDist -= pCurrNode->_vJumps[0];
2095 pCurrNode = pNextNode;
2096 pNextNode = pCurrNode->_vChildren[0].asT2();
2100 if(uiJumpDist < pCurrNode->_vJumps[uiCurrBits])
2102 pNextNode = allocateNode();
2104 pNextNode->_vJumps[0] =
2105 pCurrNode->_vJumps [uiCurrBits] - uiJumpDist;
2107 pNextNode->_vChildren[0] =
2108 pCurrNode->_vChildren[uiCurrBits].asT2();
2110 pNextNode->_pObject =
2111 pCurrNode->_vChildren[uiCurrBits].asT2()->_pObject;
2113 pCurrNode->_vChildren[uiCurrBits].asT2()->_pObject = NULL;
2115 pCurrNode->_vJumps [uiCurrBits] = uiJumpDist;
2116 pCurrNode->_vChildren[uiCurrBits] = pNextNode;
2118 if(_vLevelEntries[uiTargetLevel] == NULL)
2120 UInt32 uiLastValidLE = 0;
2122 for(Int32 i = uiTargetLevel; i >= 0; --i)
2124 if(_vLevelEntries[i] != NULL)
2131 if(_vLevelEntries[uiLastValidLE] == pCurrNode &&
2134 _vLevelEntries[uiTargetLevel] = pNextNode;
2138 TreeNode *pTmpNode = allocateNode();
2141 uiLastValidLE]->_vChildren[0].asT2() != NULL)
2143 pTmpNode->_vChildren[0] =
2145 uiLastValidLE]->_vChildren[0].asT2();
2147 pTmpNode->_vJumps[0] =
2149 uiLastValidLE]->_vJumps[0] -
2150 (uiTargetLevel - uiLastValidLE);
2153 _vLevelEntries[uiLastValidLE]->_vChildren[0] =
2155 _vLevelEntries[uiLastValidLE]->_vJumps [0] =
2156 uiTargetLevel - uiLastValidLE;
2158 _vLevelEntries[uiTargetLevel] = pTmpNode;
2160 pTmpNode ->_pNext = pNextNode;
2161 pNextNode->_pPrev = pTmpNode;
2167 _vLevelEntries[uiTargetLevel]->_pNext;
2169 if(pNextNode->_pNext != NULL)
2171 pNextNode->_pNext->_pPrev = pNextNode;
2174 _vLevelEntries[uiTargetLevel]->_pNext = pNextNode;
2176 pNextNode->_pPrev = _vLevelEntries[uiTargetLevel];
2181 if(pNextNode == NULL)
2183 pNextNode = allocateNode();
2185 pCurrNode->_vJumps [uiCurrBits] = uiJumpDist;
2187 if(pCurrNode->_vChildren[uiCurrBits].asT1() != NULL)
2189 pNextNode->_pObject =
2190 pCurrNode->_vChildren[uiCurrBits].asT1();
2193 pCurrNode->_vChildren[uiCurrBits] = pNextNode;
2195 if(uiTargetLevel >= _vLevelEntries.size())
2197 _vLevelEntries.resize(uiTargetLevel + 1, NULL);
2199 UInt32 uiLastValidLE = 0;
2201 for(Int32 i = uiTargetLevel; i >= 0; --i)
2203 if(_vLevelEntries[i] != NULL)
2210 if(_vLevelEntries[uiLastValidLE] == pCurrNode &&
2213 _vLevelEntries[uiTargetLevel] = pNextNode;
2217 TreeNode *pTmpNode = allocateNode();
2219 _vLevelEntries[uiLastValidLE]->_vChildren[0] = pTmpNode;
2220 _vLevelEntries[uiLastValidLE]->_vJumps [0] =
2221 uiTargetLevel - uiLastValidLE;
2223 _vLevelEntries[uiTargetLevel] = pTmpNode;
2225 pTmpNode ->_pNext = pNextNode;
2226 pNextNode->_pPrev = pTmpNode;
2231 if(_vLevelEntries[uiTargetLevel] == NULL)
2233 UInt32 uiLastValidLE = 0;
2235 for(Int32 i = uiTargetLevel; i >= 0; --i)
2237 if(_vLevelEntries[i] != NULL)
2244 TreeNode *pTmpNode = allocateNode();
2247 uiLastValidLE]->_vChildren[0].asT2() != NULL)
2249 pTmpNode->_vChildren[0] =
2251 uiLastValidLE]->_vChildren[0].asT2();
2253 pTmpNode->_vJumps[0] =
2254 _vLevelEntries[uiLastValidLE]->_vJumps[0] -
2255 (uiTargetLevel - uiLastValidLE);
2258 _vLevelEntries[uiLastValidLE]->_vChildren[0] = pTmpNode;
2259 _vLevelEntries[uiLastValidLE]->_vJumps [0] =
2260 uiTargetLevel - uiLastValidLE;
2262 _vLevelEntries[uiTargetLevel] = pTmpNode;
2264 pTmpNode ->_pNext = pNextNode;
2265 pNextNode->_pPrev = pTmpNode;
2270 _vLevelEntries[uiTargetLevel]->_pNext;
2272 if(pNextNode->_pNext != NULL)
2274 pNextNode->_pNext->_pPrev = pNextNode;
2277 _vLevelEntries[uiTargetLevel]->_pNext = pNextNode;
2279 pNextNode->_pPrev = _vLevelEntries[uiTargetLevel];
2285 pCurrNode = pNextNode;
2287 uiCurrBits = 0x0000;
2289 uiStartLevel = uiTargetLevel;
2290 uiLevelSub = (uiStartLevel * LevelBits);
2292 uiCurrIdx -= uiJumpDist * LevelBits;
2294 uiCurrBits |= IdxToBits[uiCurrIdx];
2298 if(pCurrNode != NULL)
2300 pNextNode = pCurrNode->_vChildren[uiCurrBits].asT2();
2302 if(pNextNode != NULL)
2304 if(pNextNode->_pObject == NULL)
2306 pNextNode->_pObject = pObject;
2312 OSG_ASSERT(pNextNode->_pObject == pObject);
2317 pCurrNode->_vChildren[uiCurrBits] = pObject;
2326 template<class ObjectT, UInt32 LevelBits> inline
2327 void ShaderCacheTreeV2<ObjectT, LevelBits>::sub(UInt32 uiIdx)
2329 IdType uiStartLevel = IdType((uiIdx - 1) * LevelFactor);
2331 if(uiStartLevel >= _vLevelEntries.size())
2336 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
2337 UInt32 uiCurrIdx = uiIdx - uiLevelSub;
2338 UInt32 uiCurrBits = IdxToBits[uiCurrIdx];
2340 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
2342 for(; pCurrNode != NULL; pCurrNode = pCurrNode->_pNext)
2344 for(UInt32 i = 0; i < LevelSize; ++i)
2346 TreeNode *pChild = pCurrNode->_vChildren[i].asT2();
2348 if(0x0000 != (i & uiCurrBits) && pChild != NULL)
2350 if(pChild->_pNext == NULL)
2352 pChild->_pPrev->_pNext = NULL;
2356 pChild->_pPrev->_pNext = pChild->_pNext;
2357 pChild->_pNext->_pPrev = pChild->_pPrev;
2360 pChild->_pPrev = NULL;
2361 pChild->_pNext = NULL;
2363 eraseNode(pCurrNode->_vChildren[i].asT2());
2364 pCurrNode->_vJumps [i] = 0;
2365 pCurrNode->_vChildren[i].setAsT2(NULL);
2367 else if(pCurrNode->_vChildren[i].asT1() != NULL)
2369 pCurrNode->_vChildren[i].setAsT1(NULL);
2370 pCurrNode->_vJumps [i] = 0;
2376 #define OSG_DUMP_LEVELENTRIES
2378 template<class ObjectT, UInt32 LevelBits> inline
2379 void ShaderCacheTreeV2<ObjectT, LevelBits>::dumpDot(const Char8 *szFilename)
2381 FILE *pOut = fopen(szFilename, "w");
2385 fprintf(pOut, "digraph structs\n");
2386 fprintf(pOut, "{\n");
2387 fprintf(pOut, "rankdir = LR;\n");
2388 fprintf(pOut, "splines=false\n");
2390 fprintf(pOut, "node [shape=record];\n");
2392 fprintf(pOut, "struct%d\n", 0);
2393 fprintf(pOut, "[\n");
2394 fprintf(pOut, " label=\"");
2396 for(UInt32 i = 0; i < _vLevelEntries.size(); ++i)
2398 if(_vLevelEntries[i] != NULL)
2400 fprintf(pOut, "<l%d> %d", i, i);
2404 fprintf(pOut, "<l%d> NIL", i);
2407 if(i == _vLevelEntries.size() - 1)
2409 fprintf(pOut, "\"\n");
2417 fprintf(pOut, "]\n");
2419 fprintf(pOut, "node [width = 1.5];\n");
2421 std::vector<std::vector<TreeNode *> > vLevelStore;
2423 dumpDotNode(_pRoot, pOut, vLevelStore, 0);
2426 #ifdef OSG_DUMP_LEVELENTRIES
2427 for(UInt32 i = 0; i < _vLevelEntries.size(); ++i)
2429 if(_vLevelEntries[i] != NULL)
2432 "struct%d:l%d -> struct%d:prev [color=\"green\"];\n",
2434 _vLevelEntries[i]->_uiNodeId);
2440 for(UInt32 i = 0; i < vLevelStore.size(); ++i)
2442 fprintf(pOut, "{ rank=same;");
2444 for(UInt32 j = 0; j < vLevelStore[i].size(); ++j)
2446 TreeNode *pChild = vLevelStore[i][j];
2450 fprintf(pOut, "\"struct%d\";",
2455 fprintf(pOut, "}\n");
2460 fprintf(pOut, "}\n");
2465 template<class ObjectT, UInt32 LevelBits> inline
2466 void ShaderCacheTreeV2<ObjectT, LevelBits>::dumpDotNode(
2469 std::vector<std::vector<TreeNode *> > &vLevelStore,
2476 if(uiLevel == vLevelStore.size())
2478 vLevelStore.push_back(std::vector<TreeNode *>());
2481 fprintf(pOut, "struct%d\n", pNode->_uiNodeId);
2482 fprintf(pOut, "[\n");
2483 fprintf(pOut, " label=\"{");
2485 if(pNode->_pPrev != NULL)
2487 fprintf(pOut, "<prev> P|");
2491 fprintf(pOut, "<prev> P:NIL|");
2494 for(UInt32 i = 0; i < LevelSize; ++i)
2496 if(pNode->_vChildren[i].asT1() != NULL)
2498 if(osgIsPower2(i) == true)
2500 fprintf(pOut, "<l%d> _O:%d|", i, i);
2504 fprintf(pOut, "<l%d> O:%d|", i, i);
2507 else if(pNode->_vChildren[i].asT2() != NULL)
2509 if(osgIsPower2(i) == true)
2511 fprintf(pOut, "<l%d> _C:%d (%d)|", i, i, pNode->_vJumps[i]);
2515 fprintf(pOut, "<l%d> C:%d (%d)|", i, i, pNode->_vJumps[i]);
2520 if(osgIsPower2(i) == true)
2522 fprintf(pOut, "<l%d> _NIL|", i);
2526 fprintf(pOut, "<l%d> NIL|", i);
2531 if(pNode->_pObject != NULL)
2533 fprintf(pOut, "<val> VAL:Obj|");
2537 fprintf(pOut, "<val> VAL:NIL|");
2540 if(pNode->_pNext != NULL)
2542 fprintf(pOut, "<next> N}\"\n");
2546 fprintf(pOut, "<next> N:NIL}\"\n");
2549 fprintf(pOut, "]\n");
2551 for(UInt32 i = 0; i < LevelSize; ++i)
2553 TreeNode *pChild = pNode->_vChildren[i].asT2();
2557 dumpDotNode(pChild, pOut, vLevelStore, uiLevel + 1);
2560 "struct%d:l%d -> struct%d:l%d [constraint=\"false\"];\n",
2561 pNode ->_uiNodeId, i,
2562 pChild->_uiNodeId, i);
2566 if(pNode->_pNext != NULL)
2568 fprintf(pOut, "struct%d:next -> struct%d:prev;\n",
2570 pNode->_pNext->_uiNodeId);
2572 if(pNode->_pPrev != NULL)
2574 fprintf(pOut, "struct%d:prev -> struct%d:next;\n",
2576 pNode->_pPrev->_uiNodeId);
2579 vLevelStore[uiLevel].push_back(pNode);
2583 template<class ObjectT, UInt32 LevelBits> inline
2584 ShaderCacheTreeV2<ObjectT, LevelBits>::ShaderCacheTreeV2(void) :
2592 _pRoot = allocateNode();
2594 _vLevelEntries.push_back(_pRoot);
2597 template<class ObjectT, UInt32 LevelBits> inline
2598 ShaderCacheTreeV2<ObjectT, LevelBits>::~ShaderCacheTreeV2(void)
2600 typename std::deque <TreeNode *>::iterator qIt =
2601 _qFreeElements.begin();
2603 typename std::deque <TreeNode *>::const_iterator qEnd =
2604 _qFreeElements.end();
2606 for(; qIt != qEnd; ++qIt)
2613 typename std::vector<TreeNode *>::iterator vIt = _vLevelEntries.begin();
2614 typename std::vector<TreeNode *>::iterator vEnd = _vLevelEntries.end ();
2616 for(; vIt != vEnd; ++vIt)
2624 template<class ObjectT, UInt32 LevelBits> inline
2625 typename ShaderCacheTreeV2<ObjectT, LevelBits>::TreeNode *
2626 ShaderCacheTreeV2<ObjectT, LevelBits>::allocateNode(void)
2628 TreeNode *returnValue = NULL;
2630 if(_qFreeElements.empty() == false)
2632 returnValue = _qFreeElements.back();
2634 _qFreeElements.pop_back();
2636 returnValue->clear();
2640 returnValue = new TreeNode();
2643 returnValue->_uiNodeId = ++_uiNodeCount;
2648 UIntPointer rU = reinterpret_cast<UIntPointer>(returnValue);
2650 OSG_ASSERT((rU & 0x0001) == 0x0000);
2656 template<class ObjectT, UInt32 LevelBits> inline
2657 void ShaderCacheTreeV2<ObjectT, LevelBits>::eraseNode(TreeNode *pNode)
2659 for(UInt32 i = 0; i < LevelSize; ++i)
2661 if(pNode->_vChildren[i].asT2() != NULL)
2663 eraseNode(pNode->_vChildren[i].asT2());
2665 pNode->_vChildren[i].setAsT2(NULL);
2669 pNode->_vChildren[i].setAsT1(NULL);
2673 pNode->_pObject = NULL;
2675 _qFreeElements.push_back(pNode);
2678 template<class ObjectT, UInt32 LevelBits>
2679 template <typename ElemDestFunc> inline
2680 void ShaderCacheTreeV2<ObjectT, LevelBits>::destroyNode(TreeNode *pNode,
2681 ElemDestFunc destFunc)
2686 for(UInt32 i = 0; i < LevelSize; ++i)
2688 if(pNode->_vChildren[i].asT2() != NULL)
2690 destroyNode(pNode->_vChildren[i].asT2(), destFunc);
2692 else if(pNode->_vChildren[i].asT1() != NULL)
2694 #ifndef OSG_SHC_REF_CLEANUP
2695 ObjectT *pObj = pNode->_vChildren[i].asT1();
2698 pNode->_vChildren[i].setAsT1(NULL);
2702 if(pNode->_pObject != NULL)
2704 #ifndef OSG_SHC_REF_CLEANUP
2705 (destFunc)(pNode->_pObject);
2707 pNode->_pObject = NULL;
2713 template<class ObjectT, UInt32 LevelBits>
2714 template <typename ElemDestFunc> inline
2715 void ShaderCacheTreeV2<ObjectT, LevelBits>::destroy(ElemDestFunc destFunc)
2717 destroyNode(_pRoot, destFunc);
2719 _vLevelEntries[0] = NULL;
2729 /*---------------------------------------------------------------------------*/
2730 /*---------------------------------------------------------------------------*/
2732 #if defined(WIN32) || defined(__APPLE__) || \
2733 defined(__GXX_EXPERIMENTAL_CXX0X__)
2734 template<class ObjectT, UInt32 LevelBits>
2735 const Real32 ShaderCacheTreeV3<ObjectT, LevelBits>::LevelFactor =
2739 template<class ObjectT, UInt32 LevelBits> inline
2740 ShaderCacheTreeV3<ObjectT, LevelBits>::TreeNode::TreeNode(void) :
2748 memset(&(_vJumps[0]), 0, LevelSize * sizeof(UInt16));
2751 template<class ObjectT, UInt32 LevelBits> inline
2752 ShaderCacheTreeV3<ObjectT, LevelBits>::TreeNode::~TreeNode(void)
2758 for(UInt32 i = 0; i < LevelSize; ++i)
2760 _vChildren[i].setAsT1(NULL);
2764 template<class ObjectT, UInt32 LevelBits> inline
2765 void ShaderCacheTreeV3<ObjectT, LevelBits>::TreeNode::clear(void)
2771 for(UInt32 i = 0; i < LevelSize; ++i)
2773 _vChildren[i].setAsT1(NULL);
2776 memset(&(_vJumps[0]), 0, LevelSize * sizeof(UInt16));
2781 template<class ObjectT, UInt32 LevelBits> inline
2782 ObjectT *ShaderCacheTreeV3<ObjectT, LevelBits>::find(const IdStore &vIds)
2784 if(vIds.size() < 1 || _pRoot == NULL)
2787 ObjectT *returnValue = NULL;
2789 IdType uiStartId = vIds[0] - 1;
2790 IdType uiStartLevel = IdType(uiStartId * LevelFactor);
2792 UInt32 uiCurrId = 0;
2793 UInt32 uiLastId = UInt32(vIds.size());
2796 if(uiStartLevel >= _vLevelEntries.size())
2798 uiStartLevel = IdType(_vLevelEntries.size() - 1);
2802 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
2803 UInt32 uiCurrBits = 0x0000;
2804 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
2805 TreeNode *pNextNode = NULL;
2807 if(pCurrNode == NULL)
2810 for(; uiCurrId < uiLastId; ++uiCurrId)
2812 UInt32 uiCurrIdx = vIds[uiCurrId] - uiLevelSub;
2813 UInt16 uiJumpDist = 1;
2815 if(uiCurrIdx <= LevelBits)
2817 uiCurrBits |= IdxToBits[uiCurrIdx];
2823 pNextNode = pCurrNode->_vChildren[uiCurrBits].asT2();
2825 if(pNextNode == NULL)
2827 pCurrNode = pNextNode;
2831 uiJumpDist = UInt16((uiCurrIdx - 1) * LevelFactor);
2832 UInt32 uiTargetLevel = uiStartLevel + uiJumpDist;
2834 if(uiJumpDist < pCurrNode->_vJumps[uiCurrBits])
2840 if(uiJumpDist > pCurrNode->_vJumps[uiCurrBits])
2842 uiLevelSub += LevelBits * pCurrNode->_vJumps[uiCurrBits];
2843 uiCurrIdx -= LevelBits * pCurrNode->_vJumps[uiCurrBits];
2844 uiJumpDist -= pCurrNode->_vJumps[uiCurrBits];
2846 pCurrNode = pNextNode;
2847 pNextNode = pCurrNode->_vChildren[0].asT2();
2849 uiCurrBits = 0x0000;
2853 if(uiCurrIdx <= LevelBits)
2858 if(uiJumpDist == pCurrNode->_vJumps[0])
2863 if(uiJumpDist < pCurrNode->_vJumps[0])
2869 if(pNextNode == NULL)
2875 LevelBits * pCurrNode->_vJumps[0];
2878 LevelBits * pCurrNode->_vJumps[0];
2880 uiJumpDist -= pCurrNode->_vJumps[0];
2882 pCurrNode = pNextNode;
2883 pNextNode = pCurrNode->_vChildren[0].asT2();
2887 pCurrNode = pNextNode;
2889 if(pCurrNode == NULL)
2894 uiCurrBits = 0x0000;
2896 uiStartLevel = uiTargetLevel;
2897 uiLevelSub = (uiStartLevel * LevelBits);
2899 uiCurrIdx -= uiJumpDist * LevelBits;
2902 uiCurrBits |= IdxToBits[uiCurrIdx];
2906 if(pCurrNode != NULL)
2908 TreeNode *pNext = pCurrNode->_vChildren[uiCurrBits].asT2();
2912 returnValue = pNext->_pObject;
2916 returnValue = pCurrNode->_vChildren[uiCurrBits].asT1();
2924 template<class ObjectT, UInt32 LevelBits> inline
2925 bool ShaderCacheTreeV3<ObjectT, LevelBits>::add(const IdStore &vIds,
2928 bool returnValue = false;
2933 IdType uiStartId = vIds[0] - 1;
2935 IdType uiStartLevel = IdType(uiStartId * LevelFactor);
2937 UInt32 uiCurrId = 0;
2938 UInt32 uiLastId = UInt32(vIds.size());
2941 FDEBUG(("scv3::add : "));
2942 for(UInt32 i = 0; i < uiLastId; ++i)
2944 FDEBUG(("%d ", vIds[i]));
2951 _pRoot = allocateNode();
2953 OSG_ASSERT(_vLevelEntries.size() == 0);
2955 _vLevelEntries.push_back(_pRoot);
2958 if(uiStartLevel >= _vLevelEntries.size())
2960 uiStartLevel = IdType(_vLevelEntries.size() - 1);
2964 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
2965 TreeNode *pNextNode = NULL;
2967 UInt32 uiCurrBits = 0x0000;
2969 if(pCurrNode == NULL)
2971 UInt32 uiLastValidLE = 0;
2973 for(Int32 i = uiStartLevel; i >= 0; --i)
2975 if(_vLevelEntries[i] != NULL)
2982 uiStartLevel = uiLastValidLE;
2983 pCurrNode = _vLevelEntries[uiStartLevel];
2986 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
2988 for(; uiCurrId < uiLastId; ++uiCurrId)
2990 UInt32 uiCurrIdx = vIds[uiCurrId] - uiLevelSub;
2991 UInt16 uiJumpDist = 1;
2993 if(uiCurrIdx <= LevelBits)
2995 uiCurrBits |= IdxToBits[uiCurrIdx];
3001 pNextNode = pCurrNode->_vChildren[uiCurrBits].asT2();
3003 uiJumpDist = UInt16((uiCurrIdx - 1) * LevelFactor);
3004 UInt32 uiTargetLevel = uiStartLevel + uiJumpDist;
3006 if(pNextNode != NULL)
3008 if(uiJumpDist > pCurrNode->_vJumps[uiCurrBits])
3010 uiLevelSub += LevelBits * pCurrNode->_vJumps[uiCurrBits];
3011 uiCurrIdx -= LevelBits * pCurrNode->_vJumps[uiCurrBits];
3012 uiJumpDist -= pCurrNode->_vJumps[uiCurrBits];
3014 pCurrNode = pNextNode;
3015 pNextNode = pCurrNode->_vChildren[0].asT2();
3017 uiCurrBits = 0x0000;
3021 if(uiCurrIdx <= LevelBits)
3026 if(pNextNode == NULL)
3031 if(uiJumpDist <= pCurrNode->_vJumps[0])
3037 LevelBits * pCurrNode->_vJumps[0];
3040 LevelBits * pCurrNode->_vJumps[0];
3042 uiJumpDist -= pCurrNode->_vJumps[0];
3044 pCurrNode = pNextNode;
3045 pNextNode = pCurrNode->_vChildren[0].asT2();
3049 if(uiJumpDist < pCurrNode->_vJumps[uiCurrBits])
3051 pNextNode = allocateNode();
3053 pNextNode->_vJumps[0] =
3054 pCurrNode->_vJumps [uiCurrBits] - uiJumpDist;
3056 pNextNode->_vChildren[0] =
3057 pCurrNode->_vChildren[uiCurrBits].asT2();
3059 pNextNode->_pObject =
3060 pCurrNode->_vChildren[uiCurrBits].asT2()->_pObject;
3062 pCurrNode->_vChildren[uiCurrBits].asT2()->_pObject = NULL;
3064 pCurrNode->_vJumps [uiCurrBits] = uiJumpDist;
3065 pCurrNode->_vChildren[uiCurrBits] = pNextNode;
3067 if(_vLevelEntries[uiTargetLevel] == NULL)
3069 UInt32 uiLastValidLE = 0;
3071 for(Int32 i = uiTargetLevel; i >= 0; --i)
3073 if(_vLevelEntries[i] != NULL)
3080 if(_vLevelEntries[uiLastValidLE] == pCurrNode &&
3083 _vLevelEntries[uiTargetLevel] = pNextNode;
3087 TreeNode *pTmpNode = allocateNode();
3090 uiLastValidLE]->_vChildren[0].asT2() != NULL)
3092 pTmpNode->_vChildren[0] =
3094 uiLastValidLE]->_vChildren[0].asT2();
3096 pTmpNode->_vJumps[0] =
3098 uiLastValidLE]->_vJumps[0] -
3099 (uiTargetLevel - uiLastValidLE);
3102 _vLevelEntries[uiLastValidLE]->_vChildren[0] =
3104 _vLevelEntries[uiLastValidLE]->_vJumps [0] =
3105 uiTargetLevel - uiLastValidLE;
3107 _vLevelEntries[uiTargetLevel] = pTmpNode;
3109 pTmpNode ->_pNext = pNextNode;
3110 pNextNode->_pPrev = pTmpNode;
3116 _vLevelEntries[uiTargetLevel]->_pNext;
3118 if(pNextNode->_pNext != NULL)
3120 pNextNode->_pNext->_pPrev = pNextNode;
3123 _vLevelEntries[uiTargetLevel]->_pNext = pNextNode;
3125 pNextNode->_pPrev = _vLevelEntries[uiTargetLevel];
3130 if(pNextNode == NULL)
3132 pNextNode = allocateNode();
3134 pCurrNode->_vJumps [uiCurrBits] = uiJumpDist;
3136 if(pCurrNode->_vChildren[uiCurrBits].asT1() != NULL)
3138 pNextNode->_pObject =
3139 pCurrNode->_vChildren[uiCurrBits].asT1();
3142 pCurrNode->_vChildren[uiCurrBits] = pNextNode;
3144 if(uiTargetLevel >= _vLevelEntries.size())
3146 _vLevelEntries.resize(uiTargetLevel + 1, NULL);
3148 UInt32 uiLastValidLE = 0;
3150 for(Int32 i = uiTargetLevel; i >= 0; --i)
3152 if(_vLevelEntries[i] != NULL)
3159 if(_vLevelEntries[uiLastValidLE] == pCurrNode &&
3162 _vLevelEntries[uiTargetLevel] = pNextNode;
3166 TreeNode *pTmpNode = allocateNode();
3168 _vLevelEntries[uiLastValidLE]->_vChildren[0] = pTmpNode;
3169 _vLevelEntries[uiLastValidLE]->_vJumps [0] =
3170 uiTargetLevel - uiLastValidLE;
3172 _vLevelEntries[uiTargetLevel] = pTmpNode;
3174 pTmpNode ->_pNext = pNextNode;
3175 pNextNode->_pPrev = pTmpNode;
3180 if(_vLevelEntries[uiTargetLevel] == NULL)
3182 UInt32 uiLastValidLE = 0;
3184 for(Int32 i = uiTargetLevel; i >= 0; --i)
3186 if(_vLevelEntries[i] != NULL)
3193 TreeNode *pTmpNode = allocateNode();
3196 uiLastValidLE]->_vChildren[0].asT2() != NULL)
3198 pTmpNode->_vChildren[0] =
3200 uiLastValidLE]->_vChildren[0].asT2();
3202 pTmpNode->_vJumps[0] =
3203 _vLevelEntries[uiLastValidLE]->_vJumps[0] -
3204 (uiTargetLevel - uiLastValidLE);
3208 _vLevelEntries[uiLastValidLE]->_vChildren[0] = pTmpNode;
3209 _vLevelEntries[uiLastValidLE]->_vJumps [0] =
3210 uiTargetLevel - uiLastValidLE;
3212 _vLevelEntries[uiTargetLevel] = pTmpNode;
3214 pTmpNode ->_pNext = pNextNode;
3215 pNextNode->_pPrev = pTmpNode;
3220 _vLevelEntries[uiTargetLevel]->_pNext;
3222 if(pNextNode->_pNext != NULL)
3224 pNextNode->_pNext->_pPrev = pNextNode;
3227 _vLevelEntries[uiTargetLevel]->_pNext = pNextNode;
3229 pNextNode->_pPrev = _vLevelEntries[uiTargetLevel];
3235 pCurrNode = pNextNode;
3237 uiCurrBits = 0x0000;
3239 uiStartLevel = uiTargetLevel;
3240 uiLevelSub = (uiStartLevel * LevelBits);
3242 uiCurrIdx -= uiJumpDist * LevelBits;
3244 uiCurrBits |= IdxToBits[uiCurrIdx];
3248 if(pCurrNode != NULL)
3250 pNextNode = pCurrNode->_vChildren[uiCurrBits].asT2();
3252 if(pNextNode != NULL)
3254 if(pNextNode->_pObject == NULL)
3256 pNextNode->_pObject = pObject;
3262 OSG_ASSERT(pNextNode->_pObject == pObject);
3267 pCurrNode->_vChildren[uiCurrBits] = pObject;
3276 template<class ObjectT, UInt32 LevelBits> inline
3277 void ShaderCacheTreeV3<ObjectT, LevelBits>::sub(UInt32 uiIdx)
3280 FDEBUG(("scv3::sub : %d\n", uiIdx));
3283 IdType uiStartLevel = IdType((uiIdx - 1) * LevelFactor);
3285 if(uiStartLevel >= _vLevelEntries.size())
3290 UInt32 uiLevelSub = (uiStartLevel * LevelBits);
3291 UInt32 uiCurrIdx = uiIdx - uiLevelSub;
3292 UInt32 uiCurrBits = IdxToBits[uiCurrIdx];
3294 TreeNode *pCurrNode = _vLevelEntries[uiStartLevel];
3296 for(; pCurrNode != NULL; pCurrNode = pCurrNode->_pNext)
3298 for(UInt32 i = 0; i < LevelSize; ++i)
3300 if(0x0000 != (i & uiCurrBits))
3302 TreeNode *pChild = pCurrNode->_vChildren[i].asT2();
3306 if(pChild->_pNext == NULL)
3308 pChild->_pPrev->_pNext = NULL;
3312 pChild->_pPrev->_pNext = pChild->_pNext;
3313 pChild->_pNext->_pPrev = pChild->_pPrev;
3316 pChild->_pPrev = NULL;
3317 pChild->_pNext = NULL;
3319 eraseNode(pCurrNode->_vChildren[i].asT2());
3320 pCurrNode->_vJumps [i] = 0;
3321 pCurrNode->_vChildren[i].setAsT2(NULL);
3323 else if(pCurrNode->_vChildren[i].asT1() != NULL)
3325 pCurrNode->_vChildren[i].setAsT1(NULL);
3326 pCurrNode->_vJumps [i] = 0;
3333 #define OSG_DUMP_LEVELENTRIES
3335 template<class ObjectT, UInt32 LevelBits> inline
3336 void ShaderCacheTreeV3<ObjectT,
3337 LevelBits>::dumpDot(const Char8 *szFilename,
3338 bool dumpEmptyLevelEntries)
3340 FILE *pOut = fopen(szFilename, "w");
3344 fprintf(pOut, "digraph structs\n");
3345 fprintf(pOut, "{\n");
3346 fprintf(pOut, "rankdir = LR;\n");
3347 fprintf(pOut, "splines=false\n");
3349 fprintf(pOut, "node [shape=record];\n");
3351 fprintf(pOut, "struct%d\n", 0);
3352 fprintf(pOut, "[\n");
3353 fprintf(pOut, " label=\"");
3355 if(_vLevelEntries.empty())
3356 fprintf(pOut, "\"\n");
3358 for(UInt32 i = 0; i < _vLevelEntries.size(); ++i)
3360 if(_vLevelEntries[i] != NULL)
3362 fprintf(pOut, "<l%d> %d", i, i);
3366 if(dumpEmptyLevelEntries == true)
3367 fprintf(pOut, "<l%d> NIL", i);
3370 if(i == _vLevelEntries.size() - 1)
3372 fprintf(pOut, "\"\n");
3376 if(_vLevelEntries[i] != NULL || dumpEmptyLevelEntries == true)
3381 fprintf(pOut, "]\n");
3383 fprintf(pOut, "node [width = 1.5];\n");
3385 std::vector<std::vector<TreeNode *> > vLevelStore;
3387 dumpDotNode(_pRoot, pOut, vLevelStore, 0);
3390 #ifdef OSG_DUMP_LEVELENTRIES
3391 for(UInt32 i = 0; i < _vLevelEntries.size(); ++i)
3393 if(_vLevelEntries[i] != NULL)
3396 "struct%d:l%d -> struct%d:prev [color=\"green\"];\n",
3398 _vLevelEntries[i]->_uiNodeId);
3404 for(UInt32 i = 0; i < vLevelStore.size(); ++i)
3406 fprintf(pOut, "{ rank=same;");
3408 for(UInt32 j = 0; j < vLevelStore[i].size(); ++j)
3410 TreeNode *pChild = vLevelStore[i][j];
3414 fprintf(pOut, "\"struct%d\";",
3419 fprintf(pOut, "}\n");
3424 fprintf(pOut, "}\n");
3429 template<class ObjectT, UInt32 LevelBits> inline
3430 void ShaderCacheTreeV3<ObjectT, LevelBits>::dumpDotNode(
3433 std::vector<std::vector<TreeNode *> > &vLevelStore,
3440 if(uiLevel == vLevelStore.size())
3442 vLevelStore.push_back(std::vector<TreeNode *>());
3445 fprintf(pOut, "struct%d\n", pNode->_uiNodeId);
3446 fprintf(pOut, "[\n");
3447 fprintf(pOut, " label=\"{");
3449 if(pNode->_pPrev != NULL)
3451 fprintf(pOut, "<prev> P|");
3455 fprintf(pOut, "<prev> P:NIL|");
3458 for(UInt32 i = 0; i < LevelSize; ++i)
3460 if(pNode->_vChildren[i].asT1() != NULL)
3462 if(osgIsPower2(i) == true)
3464 fprintf(pOut, "<l%d> _O:%d|", i, i);
3468 fprintf(pOut, "<l%d> O:%d|", i, i);
3471 else if(pNode->_vChildren[i].asT2() != NULL)
3473 if(osgIsPower2(i) == true)
3475 fprintf(pOut, "<l%d> _C:%d (%d)|", i, i, pNode->_vJumps[i]);
3479 fprintf(pOut, "<l%d> C:%d (%d)|", i, i, pNode->_vJumps[i]);
3484 if(osgIsPower2(i) == true)
3486 fprintf(pOut, "<l%d> _NIL|", i);
3490 fprintf(pOut, "<l%d> NIL|", i);
3495 if(pNode->_pObject != NULL)
3497 fprintf(pOut, "<val> VAL:Obj|");
3501 fprintf(pOut, "<val> VAL:NIL|");
3504 if(pNode->_pNext != NULL)
3506 fprintf(pOut, "<next> N}\"\n");
3510 fprintf(pOut, "<next> N:NIL}\"\n");
3513 fprintf(pOut, "]\n");
3515 for(UInt32 i = 0; i < LevelSize; ++i)
3517 TreeNode *pChild = pNode->_vChildren[i].asT2();
3521 dumpDotNode(pChild, pOut, vLevelStore, uiLevel + 1);
3524 "struct%d:l%d -> struct%d:l%d [constraint=\"false\"];\n",
3525 pNode ->_uiNodeId, i,
3526 pChild->_uiNodeId, i);
3530 if(pNode->_pNext != NULL)
3532 fprintf(pOut, "struct%d:next -> struct%d:prev;\n",
3534 pNode->_pNext->_uiNodeId);
3536 if(pNode->_pPrev != NULL)
3538 fprintf(pOut, "struct%d:prev -> struct%d:next;\n",
3540 pNode->_pPrev->_uiNodeId);
3543 vLevelStore[uiLevel].push_back(pNode);
3547 template<class ObjectT, UInt32 LevelBits> inline
3548 ShaderCacheTreeV3<ObjectT, LevelBits>::ShaderCacheTreeV3(void) :
3556 _pRoot = allocateNode();
3558 _vLevelEntries.push_back(_pRoot);
3561 template<class ObjectT, UInt32 LevelBits> inline
3562 ShaderCacheTreeV3<ObjectT, LevelBits>::~ShaderCacheTreeV3(void)
3564 typename std::deque <TreeNode *>::iterator qIt =
3565 _qFreeElements.begin();
3567 typename std::deque <TreeNode *>::const_iterator qEnd =
3568 _qFreeElements.end();
3570 for(; qIt != qEnd; ++qIt)
3577 typename std::vector<TreeNode *>::iterator vIt = _vLevelEntries.begin();
3578 typename std::vector<TreeNode *>::iterator vEnd = _vLevelEntries.end ();
3580 for(; vIt != vEnd; ++vIt)
3588 template<class ObjectT, UInt32 LevelBits> inline
3589 typename ShaderCacheTreeV3<ObjectT, LevelBits>::TreeNode *
3590 ShaderCacheTreeV3<ObjectT, LevelBits>::allocateNode(void)
3592 TreeNode *returnValue = NULL;
3594 if(_qFreeElements.empty() == false)
3596 returnValue = _qFreeElements.back();
3598 _qFreeElements.pop_back();
3600 returnValue->clear();
3604 returnValue = new TreeNode();
3607 returnValue->_uiNodeId = ++_uiNodeCount;
3612 UIntPointer rU = reinterpret_cast<UIntPointer>(returnValue);
3614 OSG_ASSERT((rU & 0x0001) == 0x0000);
3620 template<class ObjectT, UInt32 LevelBits> inline
3621 void ShaderCacheTreeV3<ObjectT, LevelBits>::eraseNode(TreeNode *pNode)
3623 for(UInt32 i = 0; i < LevelSize; ++i)
3625 if(pNode->_vChildren[i].asT2() != NULL)
3627 eraseNode(pNode->_vChildren[i].asT2());
3629 pNode->_vChildren[i].setAsT2(NULL);
3633 pNode->_vChildren[i].setAsT1(NULL);
3637 pNode->_pObject = NULL;
3639 _qFreeElements.push_back(pNode);
3642 template<class ObjectT, UInt32 LevelBits>
3643 template <typename ElemDestFunc> inline
3644 void ShaderCacheTreeV3<ObjectT, LevelBits>::destroyNode(TreeNode *pNode,
3645 ElemDestFunc destFunc)
3650 UInt32 uiChildStart = 0;
3652 for(UInt32 i = uiChildStart; i < LevelSize; ++i)
3654 if(pNode->_vChildren[i].asT2() != NULL)
3656 destroyNode(pNode->_vChildren[i].asT2(), destFunc);
3658 else if(pNode->_vChildren[i].asT1() != NULL)
3660 #ifndef OSG_SHC_REF_CLEANUP
3661 ObjectT *pObj = pNode->_vChildren[i].asT1();
3664 pNode->_vChildren[i].setAsT1(NULL);
3668 if(pNode->_pObject != NULL)
3670 #ifndef OSG_SHC_REF_CLEANUP
3671 (destFunc)(pNode->_pObject);
3673 pNode->_pObject = NULL;
3679 template<class ObjectT, UInt32 LevelBits>
3680 template <typename ElemDestFunc> inline
3681 void ShaderCacheTreeV3<ObjectT, LevelBits>::destroy(ElemDestFunc destFunc)
3683 destroyNode(_pRoot, destFunc);
3685 TreeNodeVecIt leIt = _vLevelEntries.begin();
3686 TreeNodeVecConstIt leEnd = _vLevelEntries.end ();
3688 for(; leIt != leEnd; ++leIt)
3693 _vLevelEntries.clear();