Bumping manifests a=b2g-bump
[gecko.git] / gfx / gl / GLContextFeatures.cpp
blobe2d6069e1b7a14f059e8852d5d4188fd192e74ac
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "GLContext.h"
8 #include "nsPrintfCString.h"
10 #ifdef XP_MACOSX
11 #include "nsCocoaFeatures.h"
12 #endif
14 namespace mozilla {
15 namespace gl {
17 const size_t kMAX_EXTENSION_GROUP_SIZE = 5;
19 // ARB_ES2_compatibility is natively supported in OpenGL 4.1.
20 static const unsigned int kGLCoreVersionForES2Compat = 410;
22 // ARB_ES3_compatibility is natively supported in OpenGL 4.3.
23 static const unsigned int kGLCoreVersionForES3Compat = 430;
25 struct FeatureInfo
27 const char* mName;
29 /* The (desktop) OpenGL version that provides this feature */
30 unsigned int mOpenGLVersion;
32 /* The OpenGL ES version that provides this feature */
33 unsigned int mOpenGLESVersion;
35 /* If there is an ARB extension, and its function symbols are
36 * not decorated with an ARB suffix, then its extension ID should go
37 * here, and NOT in mExtensions. For example, ARB_vertex_array_object
38 * functions do not have an ARB suffix, because it is an extension that
39 * was created to match core GL functionality and will never differ.
40 * Some ARB extensions do have a suffix, if they were created before
41 * a core version of the functionality existed.
43 * If there is no such ARB extension, pass 0 (GLContext::Extension_None)
45 GLContext::GLExtensions mARBExtensionWithoutARBSuffix;
47 /* Extensions that also provide this feature */
48 GLContext::GLExtensions mExtensions[kMAX_EXTENSION_GROUP_SIZE];
51 static const FeatureInfo sFeatureInfoArr[] = {
53 "bind_buffer_offset",
54 0, // OpenGL version
55 0, // OpenGL ES version
56 GLContext::Extension_None,
59 GLContext::EXT_transform_feedback,
60 GLContext::NV_transform_feedback,
61 GLContext::Extensions_End
65 "blend_minmax",
66 200, // OpenGL version
67 300, // OpenGL ES version
68 GLContext::Extension_None,
70 GLContext::EXT_blend_minmax,
71 GLContext::Extensions_End
75 "depth_texture",
76 200, // OpenGL version
77 300, // OpenGL ES version
78 GLContext::Extension_None,
80 GLContext::ARB_depth_texture,
81 GLContext::OES_depth_texture,
82 // Intentionally avoid putting ANGLE_depth_texture here,
83 // it does not offer quite the same functionality.
84 GLContext::Extensions_End
88 "draw_buffers",
89 200, // OpenGL version
90 300, // OpenGL ES version
91 GLContext::Extension_None,
93 GLContext::ARB_draw_buffers,
94 GLContext::EXT_draw_buffers,
95 GLContext::Extensions_End
99 "draw_instanced",
100 310, // OpenGL version
101 300, // OpenGL ES version
102 GLContext::Extension_None,
104 GLContext::ARB_draw_instanced,
105 GLContext::EXT_draw_instanced,
106 GLContext::NV_draw_instanced,
107 GLContext::ANGLE_instanced_arrays,
108 GLContext::Extensions_End
112 "draw_range_elements",
113 120, // OpenGL version
114 300, // OpenGL ES version
115 GLContext::Extension_None,
117 GLContext::EXT_draw_range_elements,
118 GLContext::Extensions_End
122 "element_index_uint",
123 200, // OpenGL version
124 300, // OpenGL ES version
125 GLContext::Extension_None,
127 GLContext::OES_element_index_uint,
128 GLContext::Extensions_End
132 "ES2_compatibility",
133 kGLCoreVersionForES2Compat,
134 200, // OpenGL ES version
135 GLContext::ARB_ES2_compatibility, // no suffix on ARB extension
137 GLContext::Extensions_End
141 "ES3_compatibility",
142 kGLCoreVersionForES3Compat,
143 300, // OpenGL ES version
144 GLContext::ARB_ES3_compatibility, // no suffix on ARB extension
146 GLContext::Extensions_End
150 // Removes clamping for float color outputs from frag shaders.
151 "frag_color_float",
152 300, // OpenGL version
153 300, // OpenGL ES version
154 GLContext::Extension_None,
156 GLContext::ARB_color_buffer_float,
157 GLContext::EXT_color_buffer_float,
158 GLContext::EXT_color_buffer_half_float,
159 GLContext::Extensions_End
163 "frag_depth",
164 200, // OpenGL version
165 300, // OpenGL ES version
166 GLContext::Extension_None,
168 GLContext::EXT_frag_depth,
169 GLContext::Extensions_End
173 "framebuffer_blit",
174 300, // OpenGL version
175 300, // OpenGL ES version
176 GLContext::Extension_None,
178 GLContext::EXT_framebuffer_blit,
179 GLContext::ANGLE_framebuffer_blit,
180 GLContext::Extensions_End
184 "framebuffer_multisample",
185 300, // OpenGL version
186 300, // OpenGL ES version
187 GLContext::Extension_None,
189 GLContext::EXT_framebuffer_multisample,
190 GLContext::ANGLE_framebuffer_multisample,
191 GLContext::Extensions_End
195 "framebuffer_object",
196 300, // OpenGL version
197 200, // OpenGL ES version
198 GLContext::ARB_framebuffer_object,
200 GLContext::EXT_framebuffer_object,
201 GLContext::Extensions_End
205 "get_query_object_iv",
206 200, // OpenGL version
207 0, // OpenGL ES version
208 GLContext::Extension_None,
210 GLContext::Extensions_End
213 * XXX_get_query_object_iv only provide GetQueryObjectiv provided by
214 * ARB_occlusion_query (added by OpenGL 2.0).
218 "instanced_arrays",
219 330, // OpenGL version
220 300, // OpenGL ES version
221 GLContext::Extension_None,
223 GLContext::ARB_instanced_arrays,
224 GLContext::NV_instanced_arrays,
225 GLContext::ANGLE_instanced_arrays,
226 GLContext::Extensions_End
230 "instanced_non_arrays",
231 330, // OpenGL version
232 300, // OpenGL ES version
233 GLContext::Extension_None,
235 GLContext::ARB_instanced_arrays,
236 GLContext::Extensions_End
238 /* This is an expanded version of `instanced_arrays` that allows for all
239 * enabled active attrib arrays to have non-zero divisors.
240 * ANGLE_instanced_arrays and NV_instanced_arrays forbid this, but GLES3
241 * has no such restriction.
245 "occlusion_query",
246 200, // OpenGL version
247 0, // OpenGL ES version
248 GLContext::Extension_None,
250 GLContext::Extensions_End
252 // XXX_occlusion_query depend on ARB_occlusion_query (added in OpenGL 2.0)
255 "occlusion_query_boolean",
256 kGLCoreVersionForES3Compat,
257 300, // OpenGL ES version
258 GLContext::ARB_ES3_compatibility,
260 GLContext::EXT_occlusion_query_boolean,
261 GLContext::Extensions_End
264 * XXX_occlusion_query_boolean provide ANY_SAMPLES_PASSED_CONSERVATIVE,
265 * but EXT_occlusion_query_boolean is only a OpenGL ES extension. But
266 * it is supported on desktop if ARB_ES3_compatibility because
267 * EXT_occlusion_query_boolean (added in OpenGL ES 3.0).
271 "occlusion_query2",
272 330, // = min(330, kGLCoreVersionForES3Compat),
273 300, // OpenGL ES version
274 GLContext::Extension_None,
276 GLContext::ARB_occlusion_query2,
277 GLContext::ARB_ES3_compatibility,
278 GLContext::EXT_occlusion_query_boolean,
279 GLContext::Extensions_End
282 * XXX_occlusion_query2 (add in OpenGL 3.3) provide ANY_SAMPLES_PASSED,
283 * which is provided by ARB_occlusion_query2, EXT_occlusion_query_boolean
284 * (added in OpenGL ES 3.0) and ARB_ES3_compatibility
288 "packed_depth_stencil",
289 300, // OpenGL version
290 300, // OpenGL ES version
291 GLContext::Extension_None,
293 GLContext::EXT_packed_depth_stencil,
294 GLContext::OES_packed_depth_stencil,
295 GLContext::Extensions_End
299 "query_objects",
300 200, // OpenGL version
301 300, // OpenGL ES version
302 GLContext::Extension_None,
304 GLContext::EXT_occlusion_query_boolean,
305 GLContext::Extensions_End
308 * XXX_query_objects only provide entry points commonly supported by
309 * ARB_occlusion_query (added in OpenGL 2.0) and EXT_occlusion_query_boolean
310 * (added in OpenGL ES 3.0)
314 "renderbuffer_float",
315 300, // OpenGL version
316 300, // OpenGL ES version
317 GLContext::Extension_None,
319 GLContext::ARB_texture_float,
320 GLContext::EXT_color_buffer_float,
321 GLContext::Extensions_End
325 "renderbuffer_half_float",
326 300, // OpenGL version
327 300, // OpenGL ES version
328 GLContext::Extension_None,
330 GLContext::ARB_texture_float,
331 GLContext::EXT_color_buffer_half_float,
332 GLContext::Extensions_End
336 "robustness",
337 0, // OpenGL version
338 0, // OpenGL ES version
339 GLContext::Extension_None,
341 GLContext::ARB_robustness,
342 GLContext::EXT_robustness,
343 GLContext::Extensions_End
347 "sRGB",
348 300, // OpenGL version
349 300, // OpenGL ES version
350 GLContext::Extension_None,
352 GLContext::EXT_sRGB,
353 GLContext::Extensions_End
357 "standard_derivatives",
358 200, // OpenGL version
359 300, // OpenGL ES version
360 GLContext::Extension_None,
362 GLContext::OES_standard_derivatives,
363 GLContext::Extensions_End
367 "texture_float",
368 300, // OpenGL version
369 300, // OpenGL ES version
370 GLContext::Extension_None,
372 GLContext::ARB_texture_float,
373 GLContext::OES_texture_float,
374 GLContext::Extensions_End
378 "texture_float_linear",
379 310, // OpenGL version
380 300, // OpenGL ES version
381 GLContext::Extension_None,
383 GLContext::ARB_texture_float,
384 GLContext::OES_texture_float_linear,
385 GLContext::Extensions_End
389 "texture_half_float",
390 300, // OpenGL version
391 300, // OpenGL ES version
392 GLContext::Extension_None,
394 GLContext::ARB_half_float_pixel,
395 GLContext::ARB_texture_float,
396 GLContext::NV_half_float,
397 GLContext::Extensions_End
400 * We are not including OES_texture_half_float in this feature, because:
401 * GL_HALF_FLOAT = 0x140B
402 * GL_HALF_FLOAT_ARB = 0x140B == GL_HALF_FLOAT
403 * GL_HALF_FLOAT_NV = 0x140B == GL_HALF_FLOAT
404 * GL_HALF_FLOAT_OES = 0x8D61 != GL_HALF_FLOAT
405 * WebGL handles this specifically with an OES_texture_half_float check.
409 "texture_half_float_linear",
410 310, // OpenGL version
411 300, // OpenGL ES version
412 GLContext::Extension_None,
414 GLContext::ARB_half_float_pixel,
415 GLContext::ARB_texture_float,
416 GLContext::NV_half_float,
417 GLContext::OES_texture_half_float_linear,
418 GLContext::Extensions_End
422 "texture_non_power_of_two",
423 200, // OpenGL version
424 300, // OpenGL ES version
425 GLContext::Extension_None,
427 GLContext::ARB_texture_non_power_of_two,
428 GLContext::OES_texture_npot,
429 GLContext::Extensions_End
433 "transform_feedback",
434 300, // OpenGL version
435 300, // OpenGL ES version
436 GLContext::Extension_None,
438 GLContext::EXT_transform_feedback,
439 GLContext::NV_transform_feedback,
440 GLContext::Extensions_End
444 "vertex_array_object",
445 300, // OpenGL version
446 300, // OpenGL ES version
447 GLContext::ARB_vertex_array_object, // ARB extension
449 GLContext::OES_vertex_array_object,
450 GLContext::APPLE_vertex_array_object,
451 GLContext::Extensions_End
456 static inline const FeatureInfo&
457 GetFeatureInfo(GLFeature feature)
459 static_assert(MOZ_ARRAY_LENGTH(sFeatureInfoArr) == size_t(GLFeature::EnumMax),
460 "Mismatched lengths for sFeatureInfoInfos and GLFeature enums");
462 MOZ_ASSERT(feature < GLFeature::EnumMax,
463 "GLContext::GetFeatureInfoInfo : unknown <feature>");
465 return sFeatureInfoArr[size_t(feature)];
468 static inline uint32_t
469 ProfileVersionForFeature(GLFeature feature, ContextProfile profile)
471 MOZ_ASSERT(profile != ContextProfile::Unknown,
472 "GLContext::ProfileVersionForFeature : unknown <profile>");
474 const FeatureInfo& featureInfo = GetFeatureInfo(feature);
476 if (profile == ContextProfile::OpenGLES) {
477 return featureInfo.mOpenGLESVersion;
480 return featureInfo.mOpenGLVersion;
483 bool
484 IsFeaturePartOfProfileVersion(GLFeature feature,
485 ContextProfile profile, unsigned int version)
487 unsigned int profileVersion = ProfileVersionForFeature(feature, profile);
490 * if `profileVersion` is zero, it means that no version of the profile
491 * added support for the feature.
493 return profileVersion && version >= profileVersion;
496 bool
497 GLContext::IsFeatureProvidedByCoreSymbols(GLFeature feature)
499 if (IsFeaturePartOfProfileVersion(feature, mProfile, mVersion))
500 return true;
502 if (IsExtensionSupported(GetFeatureInfo(feature).mARBExtensionWithoutARBSuffix))
503 return true;
505 return false;
508 const char*
509 GLContext::GetFeatureName(GLFeature feature)
511 return GetFeatureInfo(feature).mName;
514 static bool
515 CanReadSRGBFromFBOTexture(GLContext* gl)
517 if (!gl->WorkAroundDriverBugs())
518 return true;
520 #ifdef XP_MACOSX
521 // Bug 843668:
522 // MacOSX 10.6 reports to support EXT_framebuffer_sRGB and
523 // EXT_texture_sRGB but fails to convert from sRGB to linear
524 // when writing to an sRGB texture attached to an FBO.
525 if (!nsCocoaFeatures::OnLionOrLater()) {
526 return false;
528 #endif // XP_MACOSX
529 return true;
532 void
533 GLContext::InitFeatures()
535 for (size_t feature_index = 0; feature_index < size_t(GLFeature::EnumMax); feature_index++)
537 GLFeature feature = GLFeature(feature_index);
539 if (IsFeaturePartOfProfileVersion(feature, mProfile, mVersion)) {
540 mAvailableFeatures[feature_index] = true;
541 continue;
544 mAvailableFeatures[feature_index] = false;
546 const FeatureInfo& featureInfo = GetFeatureInfo(feature);
548 if (IsExtensionSupported(featureInfo.mARBExtensionWithoutARBSuffix))
550 mAvailableFeatures[feature_index] = true;
551 continue;
554 for (size_t j = 0; true; j++)
556 MOZ_ASSERT(j < kMAX_EXTENSION_GROUP_SIZE, "kMAX_EXTENSION_GROUP_SIZE too small");
558 if (featureInfo.mExtensions[j] == GLContext::Extensions_End) {
559 break;
562 if (IsExtensionSupported(featureInfo.mExtensions[j])) {
563 mAvailableFeatures[feature_index] = true;
564 break;
569 // Bug 843668: Work around limitation of the feature system.
570 // For sRGB support under OpenGL to match OpenGL ES spec, check for both
571 // EXT_texture_sRGB and EXT_framebuffer_sRGB is required.
572 const bool aresRGBExtensionsAvailable =
573 IsExtensionSupported(EXT_texture_sRGB) &&
574 (IsExtensionSupported(ARB_framebuffer_sRGB) ||
575 IsExtensionSupported(EXT_framebuffer_sRGB));
577 mAvailableFeatures[size_t(GLFeature::sRGB)] =
578 aresRGBExtensionsAvailable &&
579 CanReadSRGBFromFBOTexture(this);
582 void
583 GLContext::MarkUnsupported(GLFeature feature)
585 mAvailableFeatures[size_t(feature)] = false;
587 const FeatureInfo& featureInfo = GetFeatureInfo(feature);
589 for (size_t i = 0; true; i++)
591 MOZ_ASSERT(i < kMAX_EXTENSION_GROUP_SIZE, "kMAX_EXTENSION_GROUP_SIZE too small");
593 if (featureInfo.mExtensions[i] == GLContext::Extensions_End) {
594 break;
597 MarkExtensionUnsupported(featureInfo.mExtensions[i]);
600 MOZ_ASSERT(!IsSupported(feature), "GLContext::MarkUnsupported has failed!");
602 NS_WARNING(nsPrintfCString("%s marked as unsupported", GetFeatureName(feature)).get());
605 } /* namespace gl */
606 } /* namespace mozilla */