fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / State / Shader / Base / OSGShaderCache.cpp
blob025000b96770295afc2c40115d5f19f1ec8b09bc
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
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. *
18 * *
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. *
23 * *
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. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 #include "OSGConfig.h"
40 #include "OSGShaderCache.h"
41 #include "OSGShaderProgramVariableChunk.h"
43 #include "boost/bind.hpp"
46 OSG_BEGIN_NAMESPACE
48 /*-------------------------------------------------------------------------*/
49 /* Constructors */
51 ShaderCache::ShaderCache(void) :
52 #ifdef OSG_SHC_USE_REF
53 _vShaderStore (),
54 _vShaderVarStore(),
55 #endif
56 _oExeTree (),
57 _oVarTree ()
61 /*-------------------------------------------------------------------------*/
62 /* Destructor */
64 ShaderCache::~ShaderCache(void)
66 clear();
69 #if defined(OSG_SHC_USE_REF) && !defined(OSG_SHC_MODE_0)
70 bool operator < (const ShaderCache::StoreElement &rhs,
71 const ShaderCache::IdStore &lhs)
73 return rhs.first < lhs;
76 bool operator < (const ShaderCache::StoreVarElement &rhs,
77 const ShaderCache::IdStore &lhs)
79 return rhs.first < lhs;
81 #endif
83 ShaderExecutableChunk *ShaderCache::findShader(const IdStore &vIds)
85 #ifdef OSG_SHC_USE_REF
86 ShaderStore::const_iterator sIt = std::lower_bound(_vShaderStore.begin(),
87 _vShaderStore.end (),
88 vIds);
89 #endif
91 ShaderExecutableChunk *returnValue = _oExeTree.find(vIds);
93 #ifdef OSG_SHC_USE_REF
94 if(sIt == _vShaderStore.end())
96 #ifdef OSG_ASSERT_TREE
97 OSG_ASSERT(returnValue == NULL);
98 #endif
100 return NULL;
102 #endif
104 #ifdef OSG_SHC_USE_REF
105 if(sIt->first != vIds)
107 #ifdef OSG_ASSERT_TREE
108 OSG_ASSERT(returnValue == NULL);
109 #endif
111 return NULL;
113 #endif
115 #ifdef OSG_SHC_USE_REF
116 #ifdef OSG_ASSERT_TREE
117 OSG_ASSERT(returnValue == sIt->second);
118 #endif
119 #endif
121 #ifdef OSG_SHC_USE_REF
122 return sIt->second;
123 #else
124 return returnValue;
125 #endif
128 ShaderExecutableVarChunk *ShaderCache::findShaderVar(const IdStore &vIds)
130 #ifdef OSG_SHC_USE_REF
131 ShaderVarStore::const_iterator vIt =
132 std::lower_bound(_vShaderVarStore.begin(),
133 _vShaderVarStore.end (),
134 vIds );
135 #endif
137 ShaderExecutableVarChunk *returnValue = _oVarTree.find(vIds);
139 #ifdef OSG_SHC_USE_REF
140 if(vIt == _vShaderVarStore.end())
142 #ifdef OSG_ASSERT_TREE
143 OSG_ASSERT(returnValue == NULL);
144 #endif
146 return NULL;
148 #endif
150 #ifdef OSG_SHC_USE_REF
151 if(vIt->first != vIds)
153 #ifdef OSG_ASSERT_TREE
154 OSG_ASSERT(returnValue == NULL);
155 #endif
157 return NULL;
159 #endif
161 #ifdef OSG_SHC_USE_REF
162 #ifdef OSG_ASSERT_TREE
163 OSG_ASSERT(returnValue == vIt->second);
164 #endif
165 #endif
167 #ifdef OSG_SHC_USE_REF
168 return vIt->second;
169 #else
170 return returnValue;
171 #endif
174 void ShaderCache::addShader (const IdStore &vIds,
175 ShaderExecutableChunk *pShader)
177 #ifdef OSG_SHC_USE_REF
178 ShaderStore::iterator sIt = std::lower_bound(_vShaderStore.begin(),
179 _vShaderStore.end (),
180 vIds );
182 #ifdef OSG_ASSERT_TREE
183 bool bAdded = false;
184 #endif
186 if(sIt == _vShaderStore.end())
188 _vShaderStore.push_back(StoreElement(vIds, pShader));
190 #ifdef OSG_SHC_REF_CLEANUP
191 updateRemoveCallback(pShader);
192 #endif
194 #ifdef OSG_ASSERT_TREE
195 bAdded = true;
196 #endif
198 else if(sIt->first != vIds)
200 _vShaderStore.insert(sIt, StoreElement(vIds, pShader));
202 #ifdef OSG_SHC_REF_CLEANUP
203 updateRemoveCallback(pShader);
204 #endif
206 #ifdef OSG_ASSERT_TREE
207 bAdded = true;
208 #endif
210 #ifdef OSG_ASSERT_TREE
211 else
213 OSG_ASSERT(sIt->second == pShader);
215 #endif
216 #endif
218 if(_oExeTree.add(vIds, pShader) == true)
220 #ifdef OSG_SHC_USE_REF
221 #ifdef OSG_ASSERT_TREE
222 OSG_ASSERT(bAdded == true);
223 #endif
224 #endif
226 #ifndef OSG_SHC_REF_CLEANUP
227 updateRemoveCallback(pShader);
228 #endif
232 void ShaderCache::addShaderVar(const IdStore &vIds,
233 ShaderExecutableVarChunk *pVar)
235 #ifdef OSG_SHC_USE_REF
236 ShaderVarStore::iterator vIt =
237 std::lower_bound(_vShaderVarStore.begin(),
238 _vShaderVarStore.end (),
239 vIds );
241 #ifdef OSG_ASSERT_TREE
242 bool bAdded = false;
243 #endif
245 if(vIt == _vShaderVarStore.end())
247 _vShaderVarStore.push_back(StoreVarElement(vIds, pVar));
249 #ifdef OSG_SHC_REF_CLEANUP
250 updateRemoveCallback(pVar);
251 #endif
253 #ifdef OSG_ASSERT_TREE
254 bAdded = true;
255 #endif
257 else if(vIt->first != vIds)
259 _vShaderVarStore.insert(vIt, StoreVarElement(vIds, pVar));
261 #ifdef OSG_SHC_REF_CLEANUP
262 updateRemoveCallback(pVar);
263 #endif
265 #ifdef OSG_ASSERT_TREE
266 bAdded = true;
267 #endif
269 #ifdef OSG_ASSERT_TREE
270 else
272 OSG_ASSERT(vIt->second == pVar);
274 #endif
275 #endif
277 if(_oVarTree.add(vIds, pVar) == true)
279 #ifdef OSG_SHC_USE_REF
280 #ifdef OSG_ASSERT_TREE
281 OSG_ASSERT(bAdded == true);
282 #endif
283 #endif
285 #ifndef OSG_SHC_REF_CLEANUP
286 updateRemoveCallback(pVar);
287 #endif
291 void ShaderCache::clear(void)
293 #ifdef OSG_SHC_USE_REF
294 ShaderStore::const_iterator sIt = _vShaderStore.begin();
295 ShaderStore::const_iterator sEnd = _vShaderStore.end ();
297 #ifdef OSG_SHC_REF_CLEANUP
298 for(; sIt != sEnd; ++sIt)
300 clearShRemoveCallback(sIt->second);
302 #endif
303 #endif
305 _oExeTree.destroy(boost::bind(&ShaderCache::clearShRemoveCallback,
306 this,
307 _1));
309 #ifdef OSG_SHC_USE_REF
310 ShaderVarStore::const_iterator vIt = _vShaderVarStore.begin();
311 ShaderVarStore::const_iterator vEnd = _vShaderVarStore.end ();
313 #ifdef OSG_SHC_REF_CLEANUP
314 for(; vIt != vEnd; ++vIt)
316 clearVaRemoveCallback(vIt->second);
318 #endif
319 #endif
321 _oVarTree.destroy(boost::bind(&ShaderCache::clearVaRemoveCallback,
322 this,
323 _1));
326 void ShaderCache::dump(void)
328 #ifdef OSG_SHC_USE_REF
329 fprintf(stderr, "Dump shader cache \n");
331 ShaderStore::const_iterator sIt = _vShaderStore.begin();
332 ShaderStore::const_iterator sEnd = _vShaderStore.end ();
335 for(; sIt != sEnd; ++sIt)
337 IdStore::const_iterator idIt = sIt->first.begin();
338 IdStore::const_iterator idEnd = sIt->first.end ();
340 fprintf(stderr, " ");
342 for(; idIt != idEnd; ++idIt)
344 fprintf(stderr, "%d ", *idIt);
347 fprintf(stderr, ": %p\n", sIt->second.get());
351 ShaderVarStore::const_iterator vIt = _vShaderVarStore.begin();
352 ShaderVarStore::const_iterator vEnd = _vShaderVarStore.end ();
355 for(; vIt != vEnd; ++vIt)
357 IdStore::const_iterator idIt = vIt->first.begin();
358 IdStore::const_iterator idEnd = vIt->first.end ();
360 fprintf(stderr, " ");
362 for(; idIt != idEnd; ++idIt)
364 fprintf(stderr, "%d ", *idIt);
367 fprintf(stderr, ": %p\n", vIt->second.get());
369 #endif
371 _oExeTree.dumpDot("/tmp/exetree.dot");
372 _oVarTree.dumpDot("/tmp/vartree.dot");
375 void ShaderCache::updateRemoveCallback(ShaderExecutableChunk *pShader)
377 if(pShader == NULL)
378 return;
380 ShaderExecutableChunk::FragmentShaderIt fIt =
381 pShader->getMFFragmentShader()->begin();
382 ShaderExecutableChunk::FragmentShaderIt fEnd =
383 pShader->getMFFragmentShader()->end ();
385 for(; fIt != fEnd; ++fIt)
387 if(*fIt == NULL)
388 continue;
390 if((*fIt)->hasDestroyedFunctor(
391 boost::bind(&ShaderCache::removeShaderProgram,
392 this,
394 _2)) == false)
396 (*fIt)->addDestroyedFunctor(
397 boost::bind(&ShaderCache::removeShaderProgram,
398 this,
400 _2),
401 "");
405 ShaderExecutableChunk::GeometryShaderIt gIt =
406 pShader->getMFGeometryShader()->begin();
407 ShaderExecutableChunk::GeometryShaderIt gEnd =
408 pShader->getMFGeometryShader()->end ();
410 for(; gIt != gEnd; ++gIt)
412 if(*gIt == NULL)
413 continue;
415 if((*gIt)->hasDestroyedFunctor(
416 boost::bind(&ShaderCache::removeShaderProgram,
417 this,
419 _2)) == false)
421 (*gIt)->addDestroyedFunctor(
422 boost::bind(&ShaderCache::removeShaderProgram,
423 this,
425 _2),
426 "");
431 ShaderExecutableChunk::VertexShaderIt vIt =
432 pShader->getMFVertexShader()->begin();
433 ShaderExecutableChunk::VertexShaderIt vEnd =
434 pShader->getMFVertexShader()->end ();
436 for(; vIt != vEnd; ++vIt)
438 if(*vIt == NULL)
439 continue;
441 if((*vIt)->hasDestroyedFunctor(
442 boost::bind(&ShaderCache::removeShaderProgram,
443 this,
445 _2)) == false)
447 (*vIt)->addDestroyedFunctor(
448 boost::bind(&ShaderCache::removeShaderProgram,
449 this,
451 _2),
452 "");
457 void ShaderCache::clearShRemoveCallback(ShaderExecutableChunk *pShader)
459 if(pShader == NULL)
460 return;
462 ShaderExecutableChunk::FragmentShaderIt fIt =
463 pShader->getMFFragmentShader()->begin();
464 ShaderExecutableChunk::FragmentShaderIt fEnd =
465 pShader->getMFFragmentShader()->end ();
467 for(; fIt != fEnd; ++fIt)
469 if(*fIt == NULL)
470 continue;
472 (*fIt)->subDestroyedFunctor(
473 boost::bind(&ShaderCache::removeShaderProgram,
474 this,
476 _2));
479 ShaderExecutableChunk::GeometryShaderIt gIt =
480 pShader->getMFGeometryShader()->begin();
481 ShaderExecutableChunk::GeometryShaderIt gEnd =
482 pShader->getMFGeometryShader()->end ();
484 for(; gIt != gEnd; ++gIt)
486 if(*gIt == NULL)
487 continue;
489 (*gIt)->subDestroyedFunctor(
490 boost::bind(&ShaderCache::removeShaderProgram,
491 this,
493 _2));
497 ShaderExecutableChunk::VertexShaderIt vIt =
498 pShader->getMFVertexShader()->begin();
499 ShaderExecutableChunk::VertexShaderIt vEnd =
500 pShader->getMFVertexShader()->end ();
502 for(; vIt != vEnd; ++vIt)
504 if(*vIt == NULL)
505 continue;
507 (*vIt)->subDestroyedFunctor(
508 boost::bind(&ShaderCache::removeShaderProgram,
509 this,
511 _2));
517 void ShaderCache::updateRemoveCallback(ShaderExecutableVarChunk *pVar)
519 if(pVar == NULL)
520 return;
522 ShaderExecutableVarChunk::VarChunksIt vIt =
523 pVar->getMFProgramVarChunks()->begin();
524 ShaderExecutableVarChunk::VarChunksIt vEnd =
525 pVar->getMFProgramVarChunks()->end ();
527 for(; vIt != vEnd; ++vIt)
529 if(*vIt == NULL)
530 continue;
532 if((*vIt)->hasDestroyedFunctor(
533 boost::bind(&ShaderCache::removeShaderVar,
534 this,
536 _2)) == false)
538 (*vIt)->addDestroyedFunctor(
539 boost::bind(&ShaderCache::removeShaderVar,
540 this,
542 _2),
543 "");
548 void ShaderCache::clearVaRemoveCallback(ShaderExecutableVarChunk *pVar)
550 if(pVar == NULL)
551 return;
553 ShaderExecutableVarChunk::VarChunksIt vIt =
554 pVar->getMFProgramVarChunks()->begin();
555 ShaderExecutableVarChunk::VarChunksIt vEnd =
556 pVar->getMFProgramVarChunks()->end ();
558 for(; vIt != vEnd; ++vIt)
560 if(*vIt == NULL)
561 continue;
563 (*vIt)->subDestroyedFunctor(
564 boost::bind(&ShaderCache::removeShaderVar,
565 this,
567 _2));
572 void ShaderCache::removeShaderProgram(FieldContainer *pContainer,
573 ConstFieldMaskArg whichField)
575 ShaderProgram *pShaderProg = dynamic_cast<ShaderProgram *>(pContainer);
577 if(pShaderProg == NULL)
578 return;
580 UInt16 uiShaderId = pShaderProg->getProgramId();
582 #ifdef OSG_SHC_USE_REF
583 ShaderStore:: iterator sIt = _vShaderStore.begin();
584 ShaderStore::const_iterator sEnd = _vShaderStore.end ();
587 while(sIt != sEnd)
589 IdStore::const_iterator idIt = std::find(sIt->first.begin(),
590 sIt->first.end (),
591 uiShaderId);
593 if(idIt != sIt->first.end())
595 sIt = _vShaderStore.erase(sIt);
596 sEnd = _vShaderStore.end();
598 else
600 ++sIt;
603 #endif
605 _oExeTree.sub(uiShaderId);
609 void ShaderCache::removeShaderVar(FieldContainer *pContainer,
610 ConstFieldMaskArg whichField)
612 ShaderProgramVariableChunk *pShaderVar =
613 dynamic_cast<ShaderProgramVariableChunk *>(pContainer);
615 if(pShaderVar == NULL)
616 return;
618 UInt16 uiVarId = pShaderVar->getVariableId();
620 #ifdef OSG_SHC_USE_REF
621 ShaderVarStore:: iterator vIt = _vShaderVarStore.begin();
622 ShaderVarStore::const_iterator vEnd = _vShaderVarStore.end ();
624 while(vIt != vEnd)
626 IdStore::const_iterator idIt = std::find(vIt->first.begin(),
627 vIt->first.end (),
628 uiVarId);
630 if(idIt != vIt->first.end())
632 vIt = _vShaderVarStore.erase(vIt);
633 vEnd = _vShaderVarStore.end();
635 else
637 ++vIt;
640 #endif
642 _oVarTree.sub(uiVarId);
645 OSG_END_NAMESPACE