OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <set> | 5 #include <set> |
6 #include <string> | 6 #include <string> |
7 #include "app/gfx/gl/gl_implementation.h" | 7 #include "app/gfx/gl/gl_implementation.h" |
8 #include "gpu/command_buffer/service/feature_info.h" | 8 #include "gpu/command_buffer/service/feature_info.h" |
9 #include "gpu/command_buffer/service/gl_utils.h" | 9 #include "gpu/command_buffer/service/gl_utils.h" |
10 #include "gpu/GLES2/gles2_command_buffer.h" | 10 #include "gpu/GLES2/gles2_command_buffer.h" |
11 | 11 |
12 namespace gpu { | 12 namespace gpu { |
13 namespace gles2 { | 13 namespace gles2 { |
14 | 14 |
15 FeatureInfo::FeatureInfo() { | 15 FeatureInfo::FeatureInfo() : requestable_extensions_dirty_(false) { |
16 } | 16 } |
17 | 17 |
18 // Helps query for extensions. | 18 // Helps query for extensions. |
19 class ExtensionHelper { | 19 class ExtensionHelper { |
20 public: | 20 public: |
21 ExtensionHelper(const char* extensions, const char* desired_features) | 21 ExtensionHelper(const char* extensions, const char* desired_features) |
22 : desire_all_features_(false) { | 22 : desire_all_features_(false) { |
23 // Check for "*" | 23 // Check for "*" |
24 if (desired_features && | 24 if (desired_features && |
25 desired_features[0] == '*' && | 25 desired_features[0] == '*' && |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
82 AddFeatures(allowed_features); | 82 AddFeatures(allowed_features); |
83 return true; | 83 return true; |
84 } | 84 } |
85 | 85 |
86 void FeatureInfo::AddFeatures(const char* desired_features) { | 86 void FeatureInfo::AddFeatures(const char* desired_features) { |
87 // Figure out what extensions to turn on. | 87 // Figure out what extensions to turn on. |
88 ExtensionHelper ext( | 88 ExtensionHelper ext( |
89 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)), | 89 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)), |
90 desired_features); | 90 desired_features); |
91 | 91 |
92 bool npot_ok = false; | |
93 | |
94 AddExtensionString("GL_CHROMIUM_map_sub"); | 92 AddExtensionString("GL_CHROMIUM_map_sub"); |
95 AddExtensionString("GL_CHROMIUM_copy_texture_to_parent_texture"); | 93 AddExtensionString("GL_CHROMIUM_copy_texture_to_parent_texture"); |
96 AddExtensionString("GL_CHROMIUM_resource_safe"); | 94 AddExtensionString("GL_CHROMIUM_resource_safe"); |
97 AddExtensionString("GL_CHROMIUM_resize"); | 95 AddExtensionString("GL_CHROMIUM_resize"); |
98 AddExtensionString("GL_CHROMIUM_strict_attribs"); | 96 AddExtensionString("GL_CHROMIUM_strict_attribs"); |
99 | 97 |
100 // Only turn this feature on if it is requested. Not by default. | 98 // Only turn this feature on if it is requested. Not by default. |
101 if (desired_features && ext.Desire("GL_CHROMIUM_webglsl")) { | 99 if (desired_features && ext.Desire("GL_CHROMIUM_webglsl")) { |
102 AddExtensionString("GL_CHROMIUM_webglsl"); | 100 AddExtensionString("GL_CHROMIUM_webglsl"); |
103 feature_flags_.chromium_webglsl = true; | 101 feature_flags_.chromium_webglsl = true; |
102 } else { | |
103 AddRequestableExtensionString("GL_CHROMIUM_webglsl"); | |
104 } | 104 } |
105 | 105 |
106 // Check if we should allow GL_EXT_texture_compression_dxt1 and | 106 // Check if we should allow GL_EXT_texture_compression_dxt1 and |
107 // GL_EXT_texture_compression_s3tc. | 107 // GL_EXT_texture_compression_s3tc. |
108 bool enable_dxt1 = false; | 108 bool enable_dxt1 = false; |
109 bool enable_s3tc = false; | 109 bool enable_s3tc = false; |
110 | 110 |
111 if (ext.HaveAndDesire("GL_EXT_texture_compression_dxt1")) { | 111 DoSimpleTestForEnablingExtension( |
112 &ext, "GL_EXT_texture_compression_dxt1", &enable_dxt1); | |
113 DoSimpleTestForEnablingExtension( | |
114 &ext, "GL_EXT_texture_compression_s3tc", &enable_s3tc); | |
115 if (enable_s3tc) | |
112 enable_dxt1 = true; | 116 enable_dxt1 = true; |
113 } | |
114 if (ext.HaveAndDesire("GL_EXT_texture_compression_s3tc")) { | |
115 enable_dxt1 = true; | |
116 enable_s3tc = true; | |
117 } | |
118 | 117 |
119 if (enable_dxt1) { | 118 if (enable_dxt1) { |
120 AddExtensionString("GL_EXT_texture_compression_dxt1"); | 119 AddExtensionString("GL_EXT_texture_compression_dxt1"); |
121 validators_.compressed_texture_format.AddValue( | 120 validators_.compressed_texture_format.AddValue( |
122 GL_COMPRESSED_RGB_S3TC_DXT1_EXT); | 121 GL_COMPRESSED_RGB_S3TC_DXT1_EXT); |
123 validators_.compressed_texture_format.AddValue( | 122 validators_.compressed_texture_format.AddValue( |
124 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); | 123 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); |
125 } | 124 } |
126 | 125 |
127 if (enable_s3tc) { | 126 if (enable_s3tc) { |
128 AddExtensionString("GL_EXT_texture_compression_s3tc"); | 127 AddExtensionString("GL_EXT_texture_compression_s3tc"); |
129 validators_.compressed_texture_format.AddValue( | 128 validators_.compressed_texture_format.AddValue( |
130 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT); | 129 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT); |
131 validators_.compressed_texture_format.AddValue( | 130 validators_.compressed_texture_format.AddValue( |
132 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT); | 131 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT); |
133 } | 132 } |
134 | 133 |
135 // Check if we should enable GL_EXT_texture_filter_anisotropic. | 134 // Check if we should enable GL_EXT_texture_filter_anisotropic. |
136 if (ext.HaveAndDesire("GL_EXT_texture_filter_anisotropic")) { | 135 bool enable_anisotropic = false; |
136 DoSimpleTestForEnablingExtension( | |
137 &ext, "GL_EXT_texture_filter_anisotropic", &enable_anisotropic); | |
138 if (enable_anisotropic) { | |
137 AddExtensionString("GL_EXT_texture_filter_anisotropic"); | 139 AddExtensionString("GL_EXT_texture_filter_anisotropic"); |
138 validators_.texture_parameter.AddValue( | 140 validators_.texture_parameter.AddValue( |
139 GL_TEXTURE_MAX_ANISOTROPY_EXT); | 141 GL_TEXTURE_MAX_ANISOTROPY_EXT); |
140 validators_.g_l_state.AddValue( | 142 validators_.g_l_state.AddValue( |
141 GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT); | 143 GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT); |
142 } | 144 } |
143 | 145 |
144 // Check if we should support GL_OES_packed_depth_stencil and/or | 146 // Check if we should support GL_OES_packed_depth_stencil and/or |
145 // GL_GOOGLE_depth_texture. | 147 // GL_GOOGLE_depth_texture. |
146 // NOTE: GL_OES_depth_texture requires support for depth | 148 // NOTE: GL_OES_depth_texture requires support for depth |
147 // cubemaps. GL_ARB_depth_texture requires other features that | 149 // cubemaps. GL_ARB_depth_texture requires other features that |
148 // GL_OES_packed_depth_stencil does not provide. Therefore we made up | 150 // GL_OES_packed_depth_stencil does not provide. Therefore we made up |
149 // GL_GOOGLE_depth_texture. | 151 // GL_GOOGLE_depth_texture. |
150 bool enable_depth_texture = false; | 152 bool enable_depth_texture = false; |
151 if (ext.Desire("GL_GOOGLE_depth_texture") && | 153 if (ext.Have("GL_ARB_depth_texture") || |
152 (ext.Have("GL_ARB_depth_texture") || | 154 ext.Have("GL_OES_depth_texture")) { |
153 ext.Have("GL_OES_depth_texture"))) { | 155 if (ext.Desire("GL_GOOGLE_depth_texture")) { |
154 enable_depth_texture = true; | 156 enable_depth_texture = true; |
155 AddExtensionString("GL_GOOGLE_depth_texture"); | 157 AddExtensionString("GL_GOOGLE_depth_texture"); |
156 validators_.texture_internal_format.AddValue(GL_DEPTH_COMPONENT); | 158 validators_.texture_internal_format.AddValue(GL_DEPTH_COMPONENT); |
157 validators_.texture_format.AddValue(GL_DEPTH_COMPONENT); | 159 validators_.texture_format.AddValue(GL_DEPTH_COMPONENT); |
158 validators_.pixel_type.AddValue(GL_UNSIGNED_SHORT); | 160 validators_.pixel_type.AddValue(GL_UNSIGNED_SHORT); |
159 validators_.pixel_type.AddValue(GL_UNSIGNED_INT); | 161 validators_.pixel_type.AddValue(GL_UNSIGNED_INT); |
162 } else { | |
163 AddRequestableExtensionString("GL_GOOGLE_depth_texture"); | |
164 } | |
160 } | 165 } |
166 | |
161 // TODO(gman): Add depth types fo ElementsPerGroup and BytesPerElement | 167 // TODO(gman): Add depth types fo ElementsPerGroup and BytesPerElement |
162 | 168 bool enable_packed_depth_stencil = false; |
163 if (ext.Desire("GL_OES_packed_depth_stencil") && | 169 DoSimpleTestForEnablingExtension( |
164 (ext.Have("GL_EXT_packed_depth_stencil") || | 170 &ext, "GL_OES_packed_depth_stencil", "GL_EXT_packed_depth_stencil", |
165 ext.Have("GL_OES_packed_depth_stencil"))) { | 171 &enable_packed_depth_stencil); |
172 if (enable_packed_depth_stencil) { | |
166 AddExtensionString("GL_OES_packed_depth_stencil"); | 173 AddExtensionString("GL_OES_packed_depth_stencil"); |
167 if (enable_depth_texture) { | 174 if (enable_depth_texture) { |
168 validators_.texture_internal_format.AddValue(GL_DEPTH_STENCIL); | 175 validators_.texture_internal_format.AddValue(GL_DEPTH_STENCIL); |
169 validators_.texture_format.AddValue(GL_DEPTH_STENCIL); | 176 validators_.texture_format.AddValue(GL_DEPTH_STENCIL); |
170 validators_.pixel_type.AddValue(GL_UNSIGNED_INT_24_8); | 177 validators_.pixel_type.AddValue(GL_UNSIGNED_INT_24_8); |
171 } | 178 } |
172 validators_.render_buffer_format.AddValue(GL_DEPTH24_STENCIL8); | 179 validators_.render_buffer_format.AddValue(GL_DEPTH24_STENCIL8); |
173 } | 180 } |
174 | 181 |
175 bool enable_texture_format_bgra8888 = false; | 182 bool enable_texture_format_bgra8888 = false; |
176 bool enable_read_format_bgra = false; | 183 bool enable_read_format_bgra = false; |
177 // Check if we should allow GL_EXT_texture_format_BGRA8888 | 184 // Check if we should allow GL_EXT_texture_format_BGRA8888 |
178 if (ext.Desire("GL_EXT_texture_format_BGRA8888") && | 185 DoSimpleTestForEnablingExtension( |
179 (ext.Have("GL_EXT_texture_format_BGRA8888") || | 186 &ext, |
180 ext.Have("GL_APPLE_texture_format_BGRA8888"))) { | 187 "GL_EXT_texture_format_BGRA8888", |
181 enable_texture_format_bgra8888 = true; | 188 "GL_APPLE_texture_format_BGRA8888", |
182 } | 189 &enable_texture_format_bgra8888); |
183 | 190 |
184 if (ext.HaveAndDesire("GL_EXT_bgra")) { | 191 bool temp_bgra_variable = false; |
192 DoSimpleTestForEnablingExtension(&ext, "GL_EXT_bgra", &temp_bgra_variable); | |
193 if (temp_bgra_variable) { | |
185 enable_texture_format_bgra8888 = true; | 194 enable_texture_format_bgra8888 = true; |
186 enable_read_format_bgra = true; | 195 enable_read_format_bgra = true; |
187 } | 196 } |
188 | 197 |
189 if (ext.HaveAndDesire("GL_EXT_read_format_bgra")) { | 198 DoSimpleTestForEnablingExtension( |
199 &ext, "GL_EXT_read_format_bgra", &temp_bgra_variable); | |
200 if (temp_bgra_variable) { | |
190 enable_read_format_bgra = true; | 201 enable_read_format_bgra = true; |
191 } | 202 } |
192 | 203 |
193 if (enable_texture_format_bgra8888) { | 204 if (enable_texture_format_bgra8888) { |
194 AddExtensionString("GL_EXT_texture_format_BGRA8888"); | 205 AddExtensionString("GL_EXT_texture_format_BGRA8888"); |
195 validators_.texture_internal_format.AddValue(GL_BGRA_EXT); | 206 validators_.texture_internal_format.AddValue(GL_BGRA_EXT); |
196 validators_.texture_format.AddValue(GL_BGRA_EXT); | 207 validators_.texture_format.AddValue(GL_BGRA_EXT); |
197 } | 208 } |
198 | 209 |
199 if (enable_read_format_bgra) { | 210 if (enable_read_format_bgra) { |
200 AddExtensionString("GL_EXT_read_format_bgra"); | 211 AddExtensionString("GL_EXT_read_format_bgra"); |
201 validators_.read_pixel_format.AddValue(GL_BGRA_EXT); | 212 validators_.read_pixel_format.AddValue(GL_BGRA_EXT); |
202 } | 213 } |
203 | 214 |
204 // Check if we should allow GL_OES_texture_npot | 215 // Check if we should allow GL_OES_texture_npot |
205 if (ext.Desire("GL_OES_texture_npot") && | 216 bool npot_ok = false; |
206 (ext.Have("GL_ARB_texture_non_power_of_two") || | 217 |
207 ext.Have("GL_OES_texture_npot"))) { | 218 DoSimpleTestForEnablingExtension( |
219 &ext, "GL_OES_texture_npot", "GL_ARB_texture_non_power_of_two", | |
220 &npot_ok); | |
221 if (npot_ok) { | |
208 AddExtensionString("GL_OES_texture_npot"); | 222 AddExtensionString("GL_OES_texture_npot"); |
209 npot_ok = true; | |
210 } | 223 } |
211 | 224 |
212 // Check if we should allow GL_OES_texture_float, GL_OES_texture_half_float, | 225 // Check if we should allow GL_OES_texture_float, GL_OES_texture_half_float, |
213 // GL_OES_texture_float_linear, GL_OES_texture_half_float_linear | 226 // GL_OES_texture_float_linear, GL_OES_texture_half_float_linear |
214 bool enable_texture_float = false; | 227 bool enable_texture_float = false; |
215 bool enable_texture_float_linear = false; | 228 bool enable_texture_float_linear = false; |
216 bool enable_texture_half_float = false; | 229 bool enable_texture_half_float = false; |
217 bool enable_texture_half_float_linear = false; | 230 bool enable_texture_half_float_linear = false; |
218 if (ext.HaveAndDesire("GL_ARB_texture_float")) { | 231 |
219 enable_texture_float = true; | 232 // Note that we do not allow requests for the GL_ARB_texture_float |
220 enable_texture_float_linear = true; | 233 // extension directly, since it implies the existence of internal |
221 enable_texture_half_float = true; | 234 // formats that don't exist in GL_OES_texture_float. |
222 enable_texture_half_float_linear = true; | 235 DoSimpleTestForEnablingExtension( |
223 } else { | 236 &ext, "GL_OES_texture_float", "GL_ARB_texture_float", |
224 if (ext.HaveAndDesire("GL_OES_texture_float")) { | 237 &enable_texture_float); |
225 enable_texture_float = true; | 238 DoSimpleTestForEnablingExtension( |
226 if (ext.HaveAndDesire("GL_OES_texture_float_linear")) { | 239 &ext, "GL_OES_texture_float_linear", "GL_ARB_texture_float", |
227 enable_texture_float_linear = true; | 240 &enable_texture_float_linear); |
228 } | 241 DoSimpleTestForEnablingExtension( |
229 } | 242 &ext, "GL_OES_texture_half_float", "GL_ARB_texture_float", |
230 if (ext.HaveAndDesire("GL_OES_texture_half_float")) { | 243 &enable_texture_half_float); |
231 enable_texture_half_float = true; | 244 DoSimpleTestForEnablingExtension( |
232 if (ext.HaveAndDesire("GL_OES_texture_half_float_linear")) { | 245 &ext, "GL_OES_texture_half_float_linear", "GL_ARB_texture_float", |
233 enable_texture_half_float_linear = true; | 246 &enable_texture_half_float_linear); |
234 } | |
235 } | |
236 } | |
237 | 247 |
238 if (enable_texture_float) { | 248 if (enable_texture_float) { |
239 validators_.pixel_type.AddValue(GL_FLOAT); | 249 validators_.pixel_type.AddValue(GL_FLOAT); |
240 AddExtensionString("GL_OES_texture_float"); | 250 AddExtensionString("GL_OES_texture_float"); |
241 if (enable_texture_float_linear) { | 251 if (enable_texture_float_linear) { |
242 AddExtensionString("GL_OES_texture_float_linear"); | 252 AddExtensionString("GL_OES_texture_float_linear"); |
243 } | 253 } |
244 } | 254 } |
245 | 255 |
246 if (enable_texture_half_float) { | 256 if (enable_texture_half_float) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
282 // TODO(gman): Add support for these extensions. | 292 // TODO(gman): Add support for these extensions. |
283 // GL_OES_depth32 | 293 // GL_OES_depth32 |
284 // GL_OES_element_index_uint | 294 // GL_OES_element_index_uint |
285 | 295 |
286 feature_flags_.enable_texture_float_linear = enable_texture_float_linear; | 296 feature_flags_.enable_texture_float_linear = enable_texture_float_linear; |
287 feature_flags_.enable_texture_half_float_linear = | 297 feature_flags_.enable_texture_half_float_linear = |
288 enable_texture_half_float_linear; | 298 enable_texture_half_float_linear; |
289 feature_flags_.npot_ok = npot_ok; | 299 feature_flags_.npot_ok = npot_ok; |
290 } | 300 } |
291 | 301 |
302 const std::string& FeatureInfo::RequestableExtensions() { | |
303 if (requestable_extensions_dirty_) { | |
304 requestable_extensions_ = ""; | |
305 for (size_t i = 0; i < requestable_extensions_list_.size(); ++i) { | |
306 if (i > 0) | |
307 requestable_extensions_ += " "; | |
308 requestable_extensions_ += requestable_extensions_list_[i]; | |
309 } | |
310 } | |
311 return requestable_extensions_; | |
312 } | |
313 | |
314 void FeatureInfo::DoSimpleTestForEnablingExtension( | |
315 void* extensions_helper, const char* extension, bool* should_enable) { | |
316 *should_enable = false; | |
317 ExtensionHelper* helper = static_cast<ExtensionHelper*>(extensions_helper); | |
318 if (helper->Have(extension)) { | |
319 if (helper->Desire(extension)) { | |
320 *should_enable = true; | |
321 } else { | |
322 AddRequestableExtensionString(extension); | |
323 } | |
324 } | |
325 } | |
326 | |
327 void FeatureInfo::DoSimpleTestForEnablingExtension( | |
328 void* extensions_helper, const char* extension, | |
329 const char* alternate_extension, bool* should_enable) { | |
330 *should_enable = false; | |
331 ExtensionHelper* helper = static_cast<ExtensionHelper*>(extensions_helper); | |
332 if (helper->Have(extension) || | |
333 helper->Have(alternate_extension)) { | |
334 if (helper->Desire(extension)) { | |
335 *should_enable = true; | |
336 } else { | |
337 AddRequestableExtensionString(extension); | |
338 } | |
339 } | |
340 } | |
341 | |
292 void FeatureInfo::AddExtensionString(const std::string& str) { | 342 void FeatureInfo::AddExtensionString(const std::string& str) { |
293 if (extensions_.find(str) == std::string::npos) { | 343 if (extensions_.find(str) == std::string::npos) { |
294 extensions_ += (extensions_.empty() ? "" : " ") + str; | 344 extensions_ += (extensions_.empty() ? "" : " ") + str; |
345 RemoveRequestableExtensionString(str); | |
greggman
2010/12/04 01:28:44
Why remove added extensions? Shouldn't the list of
| |
346 } | |
347 } | |
348 | |
349 void FeatureInfo::AddRequestableExtensionString(const std::string& str) { | |
350 if (extensions_.find(str) == std::string::npos) { | |
351 for (size_t i = 0; i < requestable_extensions_list_.size(); ++i) { | |
352 if (requestable_extensions_list_[i] == str) { | |
353 break; | |
354 } | |
355 } | |
356 requestable_extensions_list_.push_back(str); | |
357 requestable_extensions_dirty_ = true; | |
358 } | |
359 } | |
360 | |
361 void FeatureInfo::RemoveRequestableExtensionString(const std::string& str) { | |
362 for (size_t i = 0; i < requestable_extensions_list_.size(); ++i) { | |
363 if (requestable_extensions_list_[i] == str) { | |
364 requestable_extensions_list_.erase( | |
365 requestable_extensions_list_.begin() + i); | |
366 requestable_extensions_dirty_ = true; | |
367 break; | |
368 } | |
295 } | 369 } |
296 } | 370 } |
297 | 371 |
298 } // namespace gles2 | 372 } // namespace gles2 |
299 } // namespace gpu | 373 } // namespace gpu |
300 | 374 |
301 | 375 |
302 | 376 |
OLD | NEW |