• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // Feature.h: Definition of structs to hold feature/workaround information.
7 //
8 
9 #ifndef ANGLE_PLATFORM_FEATURE_H_
10 #define ANGLE_PLATFORM_FEATURE_H_
11 
12 #include <map>
13 #include <string>
14 #include <vector>
15 
16 #define ANGLE_FEATURE_CONDITION(set, feature, cond)       \
17     do                                                    \
18     {                                                     \
19         (set)->feature.enabled   = cond;                  \
20         (set)->feature.condition = ANGLE_STRINGIFY(cond); \
21     } while (0)
22 
23 namespace angle
24 {
25 
26 enum class FeatureCategory
27 {
28     FrontendWorkarounds,
29     OpenGLWorkarounds,
30     D3DWorkarounds,
31     D3DCompilerWorkarounds,
32     VulkanWorkarounds,
33     VulkanFeatures,
34     MetalFeatures,
35 };
36 
37 constexpr char kFeatureCategoryFrontendWorkarounds[]    = "Frontend workarounds";
38 constexpr char kFeatureCategoryOpenGLWorkarounds[]      = "OpenGL workarounds";
39 constexpr char kFeatureCategoryD3DWorkarounds[]         = "D3D workarounds";
40 constexpr char kFeatureCategoryD3DCompilerWorkarounds[] = "D3D compiler workarounds";
41 constexpr char kFeatureCategoryVulkanWorkarounds[]      = "Vulkan workarounds";
42 constexpr char kFeatureCategoryVulkanFeatures[]         = "Vulkan features";
43 constexpr char kFeatureCategoryMetalFeatures[]          = "Metal features";
44 constexpr char kFeatureCategoryUnknown[]                = "Unknown";
45 
FeatureCategoryToString(const FeatureCategory & fc)46 inline const char *FeatureCategoryToString(const FeatureCategory &fc)
47 {
48     switch (fc)
49     {
50         case FeatureCategory::FrontendWorkarounds:
51             return kFeatureCategoryFrontendWorkarounds;
52             break;
53 
54         case FeatureCategory::OpenGLWorkarounds:
55             return kFeatureCategoryOpenGLWorkarounds;
56             break;
57 
58         case FeatureCategory::D3DWorkarounds:
59             return kFeatureCategoryD3DWorkarounds;
60             break;
61 
62         case FeatureCategory::D3DCompilerWorkarounds:
63             return kFeatureCategoryD3DCompilerWorkarounds;
64             break;
65 
66         case FeatureCategory::VulkanWorkarounds:
67             return kFeatureCategoryVulkanWorkarounds;
68             break;
69 
70         case FeatureCategory::VulkanFeatures:
71             return kFeatureCategoryVulkanFeatures;
72             break;
73 
74         case FeatureCategory::MetalFeatures:
75             return kFeatureCategoryMetalFeatures;
76             break;
77 
78         default:
79             return kFeatureCategoryUnknown;
80             break;
81     }
82 }
83 
84 constexpr char kFeatureStatusEnabled[]  = "enabled";
85 constexpr char kFeatureStatusDisabled[] = "disabled";
86 
FeatureStatusToString(const bool & status)87 inline const char *FeatureStatusToString(const bool &status)
88 {
89     if (status)
90     {
91         return kFeatureStatusEnabled;
92     }
93     return kFeatureStatusDisabled;
94 }
95 
96 struct Feature;
97 
98 using FeatureMap  = std::map<std::string, Feature *>;
99 using FeatureList = std::vector<const Feature *>;
100 
101 struct Feature
102 {
103     Feature(const Feature &other);
104     Feature(const char *name,
105             const FeatureCategory &category,
106             const char *description,
107             FeatureMap *const mapPtr,
108             const char *bug);
109     ~Feature();
110 
111     // The name of the workaround, lowercase, camel_case
112     const char *const name;
113 
114     // The category that the workaround belongs to. Eg. "Vulkan workarounds"
115     const FeatureCategory category;
116 
117     // A short description to be read by the user.
118     const char *const description;
119 
120     // A link to the bug, if any
121     const char *const bug;
122 
123     // Whether the workaround is enabled or not. Determined by heuristics like vendor ID and
124     // version, but may be overriden to any value.
125     bool enabled = false;
126 
127     // A stingified version of the condition used to set 'enabled'. ie "IsNvidia() && IsApple()"
128     const char *condition;
129 };
130 
131 inline Feature::Feature(const Feature &other) = default;
132 inline Feature::Feature(const char *name,
133                         const FeatureCategory &category,
134                         const char *description,
135                         FeatureMap *const mapPtr,
136                         const char *bug = "")
name(name)137     : name(name),
138       category(category),
139       description(description),
140       bug(bug),
141       enabled(false),
142       condition("")
143 {
144     if (mapPtr != nullptr)
145     {
146         (*mapPtr)[std::string(name)] = this;
147     }
148 }
149 
150 inline Feature::~Feature() = default;
151 
152 struct FeatureSetBase
153 {
154   public:
155     FeatureSetBase();
156     ~FeatureSetBase();
157 
158   private:
159     // Non-copyable
160     FeatureSetBase(const FeatureSetBase &other) = delete;
161     FeatureSetBase &operator=(const FeatureSetBase &other) = delete;
162 
163   protected:
164     FeatureMap members = FeatureMap();
165 
166   public:
overrideFeaturesFeatureSetBase167     void overrideFeatures(const std::vector<std::string> &feature_names, const bool enabled)
168     {
169         for (const std::string &name : feature_names)
170         {
171             if (members.find(name) != members.end())
172             {
173                 members[name]->enabled = enabled;
174             }
175         }
176     }
177 
populateFeatureListFeatureSetBase178     void populateFeatureList(FeatureList *features) const
179     {
180         for (FeatureMap::const_iterator it = members.begin(); it != members.end(); it++)
181         {
182             features->push_back(it->second);
183         }
184     }
185 };
186 
187 inline FeatureSetBase::FeatureSetBase()  = default;
188 inline FeatureSetBase::~FeatureSetBase() = default;
189 
190 }  // namespace angle
191 
192 #endif  // ANGLE_PLATFORM_WORKAROUND_H_
193