featureSet.cpp

Engine/source/shaderGen/featureSet.cpp

More...

Detailed Description

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include "platform/platform.h"
 25#include "shaderGen/featureSet.h"
 26
 27#include "shaderGen/featureType.h"
 28#include "platform/profiler.h"
 29#include "core/util/hashFunction.h"
 30
 31
 32const FeatureSet FeatureSet::EmptySet;
 33
 34
 35S32 QSORT_CALLBACK FeatureSet::_typeCmp( const FeatureInfo* a, const FeatureInfo* b )
 36{
 37   if ( a->type->getGroup() < b->type->getGroup() )
 38      return -1;
 39   else if ( a->type->getGroup() > b->type->getGroup() )
 40      return 1;
 41   else if ( a->index < b->index )
 42      return -1;
 43   else if ( a->index > b->index )
 44      return 1;
 45   else if ( a->type->getOrder() < b->type->getOrder() )
 46      return -1;
 47   else if ( a->type->getOrder() > b->type->getOrder() )
 48      return 1;
 49   else
 50      return 0;
 51}
 52
 53void FeatureSet::_rebuildDesc()
 54{
 55   PROFILE_SCOPE( FeatureSet_RebuildDesc );
 56
 57   // First get the features in the proper order.
 58   mFeatures.sort( _typeCmp );
 59
 60   String desc;
 61
 62   for ( U32 i=0; i < mFeatures.size(); i++ )
 63      desc +=  String::ToString( "%s,%d\n", 
 64               mFeatures[i].type->getName().c_str(),
 65               mFeatures[i].index );
 66
 67   // By interning the description we have only
 68   // one instance in the system and we get fast
 69   // pointer compares for equality.
 70   mDescription = desc.intern();
 71}
 72
 73const FeatureType& FeatureSet::getAt( U32 index, S32 *outIndex ) const 
 74{
 75   // We want to make sure we access the features in the
 76   // correct order.  By asking for the description we ensure
 77   // the feature set is properly sorted.
 78   getDescription();
 79
 80   if ( outIndex )
 81      *outIndex = mFeatures[index].index;
 82
 83   return *mFeatures[index].type; 
 84}
 85
 86void FeatureSet::clear()
 87{
 88   mDescription.clear();
 89   mFeatures.clear();
 90}
 91
 92FeatureSet& FeatureSet::operator=( const FeatureSet &h )
 93{
 94   clear();
 95   merge( h );
 96   return *this;
 97}
 98
 99bool FeatureSet::hasFeature( const FeatureType &type, S32 index ) const
100{
101   PROFILE_SCOPE(FeatureSet_hasFeature);
102
103   for ( U32 i = 0; i < mFeatures.size(); i++)
104   {
105      if (  mFeatures[i].type == &type &&
106            ( index < 0 || mFeatures[i].index == index ) )
107         return true;
108   }
109
110   return false;
111}
112
113void FeatureSet::setFeature( const FeatureType &type, bool set, S32 index )
114{
115   for ( U32 i=0; i < mFeatures.size(); i++ )
116   {
117      const FeatureInfo &info = mFeatures[i];
118      if ( info.type == &type && info.index == index )
119      {
120         if ( set )
121            return;
122         else
123         {
124            mFeatures.erase_fast( i );
125            mDescription.clear();
126            return;
127         }
128      }
129   }
130
131   if ( !set )
132      return;
133
134   FeatureInfo info;
135   info.type = &type;
136   info.index = index;
137   mFeatures.push_back( info );
138
139   mDescription.clear();
140}
141
142void FeatureSet::addFeature( const FeatureType &type, S32 index )
143{
144   for ( U32 i=0; i < mFeatures.size(); i++ )
145   {
146      const FeatureInfo &info = mFeatures[i];
147      if (  info.type == &type && 
148            info.index == index )
149         return;
150   }
151
152   FeatureInfo info;
153   info.type = &type;
154   info.index = index;
155   mFeatures.push_back( info );
156
157   mDescription.clear();
158}
159
160void FeatureSet::removeFeature( const FeatureType &type )
161{
162   for ( U32 i=0; i < mFeatures.size(); i++ )
163   {
164      const FeatureInfo &info = mFeatures[i];
165      if ( info.type == &type )
166      {
167         mFeatures.erase_fast( i );
168         mDescription.clear();
169         return;
170      }
171   }
172}
173
174S32 FeatureSet::getNextFeatureIndex( const FeatureType &type, S32 index ) const
175{
176   for ( U32 i=0; i < mFeatures.size(); i++ )
177   {
178      const FeatureInfo &info = mFeatures[i];
179      if ( info.type == &type && info.index > index )
180         return i;
181   }
182
183   return -1;
184}
185
186void FeatureSet::filter( const FeatureSet &features )
187{
188   PROFILE_SCOPE( FeatureSet_Filter );
189
190   for ( U32 i=0; i < mFeatures.size(); )
191   {
192      if ( !features.hasFeature( *mFeatures[i].type ) )
193         mFeatures.erase_fast( i );
194      else
195         i++;
196   }
197
198   mDescription.clear();
199}
200
201void FeatureSet::exclude( const FeatureSet &features )
202{
203   PROFILE_SCOPE( FeatureSet_Exclude );
204
205   for ( U32 i=0; i < features.mFeatures.size(); i++ )
206      removeFeature( *features.mFeatures[i].type );
207
208   mDescription.clear();
209}
210
211void FeatureSet::merge( const FeatureSet &features )
212{
213   PROFILE_SCOPE( FeatureSet_Merge );
214
215   if ( mFeatures.empty() )
216   {
217      mFeatures.merge( features.mFeatures );
218      mDescription = features.mDescription;
219      return;
220   }
221
222   for ( U32 i=0; i < features.mFeatures.size(); i++ )
223      addFeature( *features.mFeatures[i].type, 
224                  features.mFeatures[i].index );
225}
226
227