1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 2 * 3 * This library is open source and may be redistributed and/or modified under 4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 5 * (at your option) any later version. The full license is in LICENSE file 6 * included with this distribution, and on the openscenegraph.org website. 7 * 8 * This library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * OpenSceneGraph Public License for more details. 12*/ 13 14#ifndef OSGDB_SHAREDSTATEMANAGER 15#define OSGDB_SHAREDSTATEMANAGER 1 16 17 18#include <osg/NodeVisitor> 19#include <osg/Geode> 20 21#include <osgDB/Export> 22 23#include <OpenThreads/Mutex> 24 25#include <set> 26 27 28namespace osgDB { 29 30 class OSGDB_EXPORT SharedStateManager : public osg::NodeVisitor 31 { 32 public: 33 34 enum ShareMode 35 { 36 SHARE_NONE = 0, 37 SHARE_STATIC_TEXTURES = 1<<0, 38 SHARE_UNSPECIFIED_TEXTURES = 1<<1, 39 SHARE_DYNAMIC_TEXTURES = 1<<2, 40 SHARE_STATIC_STATESETS = 1<<3, 41 SHARE_UNSPECIFIED_STATESETS = 1<<4, 42 SHARE_DYNAMIC_STATESETS = 1<<5, 43 SHARE_TEXTURES = SHARE_STATIC_TEXTURES | SHARE_UNSPECIFIED_TEXTURES, 44 SHARE_STATESETS = SHARE_STATIC_STATESETS | SHARE_UNSPECIFIED_STATESETS, 45 SHARE_ALL = SHARE_TEXTURES | 46 SHARE_STATESETS 47 }; 48 49 SharedStateManager(unsigned int mode = SHARE_ALL); 50 51 META_NodeVisitor(osgDB, SharedStateManager) 52 53 void setShareMode(unsigned int mode); 54 55 unsigned int getShareMode() { return _shareMode; } 56 57 // Call right after each unload and before Registry cache prune. 58 void prune(); 59 60 // Call right after each load 61 void share(osg::Node *node, OpenThreads::Mutex *mt=0); 62 63 void apply(osg::Node& node); 64 void apply(osg::Geode& geode); 65 66 // Answers the question "Will this state set be eliminated by 67 // the SharedStateManager because an equivalent one has been 68 // seen already?" Safe to call from the pager thread. 69 bool isShared(osg::StateSet* stateSet); 70 71 bool isShared(osg::Texture* texture); 72 73 void releaseGLObjects(osg::State* state ) const; 74 75 protected: 76 77 inline bool shareTexture(osg::Object::DataVariance variance) 78 { 79 return _shareTexture[variance]; 80 } 81 82 inline bool shareStateSet(osg::Object::DataVariance variance) 83 { 84 return _shareStateSet[variance]; 85 } 86 87 88 void process(osg::StateSet* ss, osg::Object* parent); 89 osg::StateAttribute *find(osg::StateAttribute *sa); 90 osg::StateSet *find(osg::StateSet *ss); 91 void setStateSet(osg::StateSet* ss, osg::Object* object); 92 void shareTextures(osg::StateSet* ss); 93 94 struct CompareStateAttributes 95 { 96 bool operator()(const osg::ref_ptr<osg::StateAttribute>& lhs, 97 const osg::ref_ptr<osg::StateAttribute>& rhs) const 98 { 99 return *lhs < *rhs; 100 } 101 }; 102 103 struct CompareStateSets 104 { 105 bool operator()(const osg::ref_ptr<osg::StateSet>& lhs, 106 const osg::ref_ptr<osg::StateSet>& rhs) const 107 { 108 return lhs->compare(*rhs, true) < 0; 109 } 110 }; 111 112 // Lists of shared objects 113 typedef std::set< osg::ref_ptr<osg::StateAttribute>, CompareStateAttributes > TextureSet; 114 TextureSet _sharedTextureList; 115 116 typedef std::set< osg::ref_ptr<osg::StateSet>, CompareStateSets > StateSetSet; 117 StateSetSet _sharedStateSetList; 118 119 // Temporary lists just to avoid unnecessary find calls 120 typedef std::pair<osg::StateAttribute*, bool> TextureSharePair; 121 typedef std::map<osg::StateAttribute*, TextureSharePair> TextureTextureSharePairMap; 122 TextureTextureSharePairMap tmpSharedTextureList; 123 124 typedef std::pair<osg::StateSet*, bool> StateSetSharePair; 125 typedef std::map<osg::StateSet*, StateSetSharePair> StateSetStateSetSharePairMap; 126 StateSetStateSetSharePairMap tmpSharedStateSetList; 127 128 unsigned int _shareMode; 129 bool _shareTexture[3]; 130 bool _shareStateSet[3]; 131 132 // Share connection mutex 133 134 OpenThreads::Mutex *_mutex; 135 // Mutex for doing isShared queries from other threads 136 mutable OpenThreads::Mutex _listMutex; 137 }; 138 139} 140 141#endif 142