GLContextFeatures.cpp (22397B)
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 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/. */ 5 6 #include "GLContext.h" 7 #include "nsPrintfCString.h" 8 9 namespace mozilla { 10 namespace gl { 11 12 const size_t kMAX_EXTENSION_GROUP_SIZE = 5; 13 14 enum class GLVersion : uint32_t { 15 NONE = 0, // Feature is not supported natively by GL 16 GL1_2 = 120, 17 GL1_3 = 130, 18 GL2 = 200, 19 GL2_1 = 210, 20 GL3 = 300, 21 GL3_1 = 310, 22 GL3_2 = 320, 23 GL3_3 = 330, 24 GL4 = 400, 25 GL4_1 = 410, 26 GL4_2 = 420, 27 GL4_3 = 430, 28 }; 29 30 enum class GLESVersion : uint32_t { 31 NONE = 0, // Feature is not support natively by GL ES 32 ES2 = 200, 33 ES3 = 300, 34 ES3_1 = 310, 35 ES3_2 = 320, 36 }; 37 38 // ARB_ES2_compatibility is natively supported in OpenGL 4.1. 39 static const GLVersion kGLCoreVersionForES2Compat = GLVersion::GL4_1; 40 41 // ARB_ES3_compatibility is natively supported in OpenGL 4.3. 42 static const GLVersion kGLCoreVersionForES3Compat = GLVersion::GL4_3; 43 44 struct FeatureInfo { 45 const char* mName; 46 47 /* The (desktop) OpenGL version that provides this feature */ 48 GLVersion mOpenGLVersion; 49 50 /* The OpenGL ES version that provides this feature */ 51 GLESVersion mOpenGLESVersion; 52 53 /* If there is an ARB extension, and its function symbols are 54 * not decorated with an ARB suffix, then its extension ID should go 55 * here, and NOT in mExtensions. For example, ARB_vertex_array_object 56 * functions do not have an ARB suffix, because it is an extension that 57 * was created to match core GL functionality and will never differ. 58 * Some ARB extensions do have a suffix, if they were created before 59 * a core version of the functionality existed. 60 * 61 * If there is no such ARB extension, pass 0 (GLContext::Extension_None) 62 */ 63 GLContext::GLExtensions mARBExtensionWithoutARBSuffix; 64 65 /* Extensions that also provide this feature */ 66 GLContext::GLExtensions mExtensions[kMAX_EXTENSION_GROUP_SIZE]; 67 }; 68 69 static const FeatureInfo sFeatureInfoArr[] = { 70 {"bind_buffer_offset", 71 GLVersion::NONE, 72 GLESVersion::NONE, 73 GLContext::Extension_None, 74 { 75 76 GLContext::EXT_transform_feedback, GLContext::NV_transform_feedback2, 77 GLContext::Extensions_End}}, 78 {"blend_minmax", 79 GLVersion::GL2, 80 GLESVersion::ES3, 81 GLContext::Extension_None, 82 {GLContext::EXT_blend_minmax, GLContext::Extensions_End}}, 83 {"clear_buffers", 84 GLVersion::GL3, 85 GLESVersion::ES3, 86 GLContext::Extension_None, 87 {GLContext::Extensions_End}}, 88 {"copy_buffer", 89 GLVersion::GL3_1, 90 GLESVersion::ES3, 91 GLContext::ARB_copy_buffer, 92 {GLContext::Extensions_End}}, 93 {"depth_clamp", 94 GLVersion::GL3_2, 95 GLESVersion::NONE, 96 GLContext::Extension_None, 97 {GLContext::ARB_depth_clamp, GLContext::EXT_depth_clamp, 98 GLContext::Extensions_End}}, 99 {"depth_texture", 100 GLVersion::GL2, 101 GLESVersion::ES3, 102 GLContext::Extension_None, 103 {GLContext::ARB_depth_texture, GLContext::OES_depth_texture, 104 // Intentionally avoid putting ANGLE_depth_texture here, 105 // it does not offer quite the same functionality. 106 GLContext::Extensions_End}}, 107 {"draw_buffers", 108 GLVersion::GL2, 109 GLESVersion::ES3, 110 GLContext::Extension_None, 111 {GLContext::ARB_draw_buffers, GLContext::EXT_draw_buffers, 112 GLContext::Extensions_End}}, 113 {"draw_buffers_indexed", 114 GLVersion::GL3, 115 GLESVersion::ES3_2, 116 GLContext::Extension_None, 117 {GLContext::OES_draw_buffers_indexed, GLContext::Extensions_End}}, 118 {"draw_instanced", 119 GLVersion::GL3_1, 120 GLESVersion::ES3, 121 GLContext::Extension_None, 122 {GLContext::ARB_draw_instanced, GLContext::EXT_draw_instanced, 123 GLContext::NV_draw_instanced, GLContext::ANGLE_instanced_arrays, 124 GLContext::Extensions_End}}, 125 {"element_index_uint", 126 GLVersion::GL2, 127 GLESVersion::ES3, 128 GLContext::Extension_None, 129 {GLContext::OES_element_index_uint, GLContext::Extensions_End}}, 130 {"ES2_compatibility", 131 kGLCoreVersionForES2Compat, 132 GLESVersion::ES2, // OpenGL ES version 133 GLContext::ARB_ES2_compatibility, // no suffix on ARB extension 134 {GLContext::Extensions_End}}, 135 {"ES3_compatibility", 136 kGLCoreVersionForES3Compat, 137 GLESVersion::ES3, // OpenGL ES version 138 GLContext::ARB_ES3_compatibility, // no suffix on ARB extension 139 {GLContext::Extensions_End}}, 140 {"EXT_color_buffer_float", 141 GLVersion::GL3, 142 GLESVersion::ES3_2, 143 GLContext::Extension_None, 144 {GLContext::EXT_color_buffer_float, GLContext::Extensions_End}}, 145 {// Removes clamping for float color outputs from frag shaders. 146 "frag_color_float", 147 GLVersion::GL3, 148 GLESVersion::ES3, 149 GLContext::Extension_None, 150 {GLContext::ARB_color_buffer_float, GLContext::EXT_color_buffer_float, 151 GLContext::EXT_color_buffer_half_float, 152 GLContext::CHROMIUM_color_buffer_float_rgba, GLContext::Extensions_End}}, 153 {"frag_depth", 154 GLVersion::GL2, 155 GLESVersion::ES3, 156 GLContext::Extension_None, 157 {GLContext::EXT_frag_depth, GLContext::Extensions_End}}, 158 {// Check for just the blit framebuffer blit part of 159 // ARB_framebuffer_object 160 "framebuffer_blit", 161 GLVersion::GL3, 162 GLESVersion::ES3, 163 GLContext::ARB_framebuffer_object, 164 {GLContext::ANGLE_framebuffer_blit, GLContext::EXT_framebuffer_blit, 165 GLContext::NV_framebuffer_blit, GLContext::Extensions_End}}, 166 {// Check for just the multisample renderbuffer part of 167 // ARB_framebuffer_object 168 "framebuffer_multisample", 169 GLVersion::GL3, 170 GLESVersion::ES3, 171 GLContext::ARB_framebuffer_object, 172 {GLContext::ANGLE_framebuffer_multisample, 173 GLContext::APPLE_framebuffer_multisample, 174 GLContext::EXT_framebuffer_multisample, 175 GLContext::EXT_multisampled_render_to_texture, 176 GLContext::Extensions_End}}, 177 {// ARB_framebuffer_object support 178 "framebuffer_object", 179 GLVersion::GL3, 180 GLESVersion::ES3, 181 GLContext::ARB_framebuffer_object, 182 {GLContext::Extensions_End}}, 183 {// EXT_framebuffer_object/OES_framebuffer_object support 184 "framebuffer_object_EXT_OES", 185 GLVersion::GL3, 186 GLESVersion::ES2, 187 GLContext::Extension_None, 188 {GLContext::EXT_framebuffer_object, GLContext::OES_framebuffer_object, 189 GLContext::Extensions_End}}, 190 {"get_integer_indexed", 191 GLVersion::GL3, 192 GLESVersion::ES3, 193 GLContext::Extension_None, 194 {GLContext::EXT_draw_buffers2, GLContext::Extensions_End}}, 195 {"get_integer64_indexed", 196 GLVersion::GL3_2, 197 GLESVersion::ES3, 198 GLContext::Extension_None, 199 {GLContext::Extensions_End}}, 200 {"get_query_object_i64v", 201 GLVersion::GL3_3, 202 GLESVersion::NONE, 203 GLContext::ARB_timer_query, 204 {GLContext::ANGLE_timer_query, GLContext::EXT_disjoint_timer_query, 205 GLContext::EXT_timer_query, GLContext::Extensions_End}}, 206 { 207 "get_query_object_iv", 208 GLVersion::GL2, 209 GLESVersion::NONE, 210 GLContext::Extension_None, 211 {GLContext::Extensions_End} 212 /* 213 * XXX_get_query_object_iv only provide GetQueryObjectiv provided by 214 * ARB_occlusion_query (added by OpenGL 2.0). 215 */ 216 }, 217 {"gpu_shader4", 218 GLVersion::GL3, 219 GLESVersion::ES3, 220 GLContext::Extension_None, 221 {GLContext::EXT_gpu_shader4, GLContext::Extensions_End}}, 222 {"instanced_arrays", 223 GLVersion::GL3_3, 224 GLESVersion::ES3, 225 GLContext::Extension_None, 226 {GLContext::ARB_instanced_arrays, GLContext::NV_instanced_arrays, 227 GLContext::ANGLE_instanced_arrays, GLContext::Extensions_End}}, 228 { 229 "instanced_non_arrays", 230 GLVersion::GL3_3, 231 GLESVersion::ES3, 232 GLContext::Extension_None, 233 {GLContext::ARB_instanced_arrays, GLContext::Extensions_End} 234 /* This is an expanded version of `instanced_arrays` that allows for all 235 * enabled active attrib arrays to have non-zero divisors. 236 * ANGLE_instanced_arrays and NV_instanced_arrays forbid this, but GLES3 237 * has no such restriction. 238 */ 239 }, 240 {"internalformat_query", 241 GLVersion::GL4_2, 242 GLESVersion::ES3, 243 GLContext::ARB_internalformat_query, 244 {GLContext::Extensions_End}}, 245 {"invalidate_framebuffer", 246 GLVersion::GL4_3, 247 GLESVersion::ES3, 248 GLContext::ARB_invalidate_subdata, 249 {GLContext::Extensions_End}}, 250 {"map_buffer_range", 251 GLVersion::GL3, 252 GLESVersion::ES3, 253 GLContext::ARB_map_buffer_range, 254 {GLContext::EXT_map_buffer_range, GLContext::Extensions_End}}, 255 {"multiview", 256 GLVersion::NONE, 257 GLESVersion::NONE, 258 GLContext::Extension_None, 259 {GLContext::ANGLE_multiview, GLContext::OVR_multiview2, 260 GLContext::Extensions_End}}, 261 { 262 "occlusion_query", 263 GLVersion::GL2, 264 GLESVersion::NONE, 265 GLContext::Extension_None, 266 {GLContext::Extensions_End} 267 // XXX_occlusion_query depend on ARB_occlusion_query (added in 268 // OpenGL 2.0) 269 }, 270 { 271 "occlusion_query_boolean", 272 kGLCoreVersionForES3Compat, 273 GLESVersion::ES3, 274 GLContext::ARB_ES3_compatibility, 275 {GLContext::EXT_occlusion_query_boolean, GLContext::Extensions_End} 276 /* 277 * XXX_occlusion_query_boolean provide ANY_SAMPLES_PASSED_CONSERVATIVE, 278 * but EXT_occlusion_query_boolean is only a OpenGL ES extension. But 279 * it is supported on desktop if ARB_ES3_compatibility because 280 * EXT_occlusion_query_boolean (added in OpenGL ES 3.0). 281 */ 282 }, 283 { 284 "occlusion_query2", 285 GLVersion::GL3_3, 286 GLESVersion::ES3, 287 GLContext::Extension_None, 288 {GLContext::ARB_occlusion_query2, GLContext::ARB_ES3_compatibility, 289 GLContext::EXT_occlusion_query_boolean, GLContext::Extensions_End} 290 /* 291 * XXX_occlusion_query2 (add in OpenGL 3.3) provide ANY_SAMPLES_PASSED, 292 * which is provided by ARB_occlusion_query2, 293 * EXT_occlusion_query_boolean (added in OpenGL ES 3.0) and 294 * ARB_ES3_compatibility 295 */ 296 }, 297 {"packed_depth_stencil", 298 GLVersion::GL3, 299 GLESVersion::ES3, 300 GLContext::Extension_None, 301 {GLContext::EXT_packed_depth_stencil, GLContext::OES_packed_depth_stencil, 302 GLContext::Extensions_End}}, 303 {"prim_restart", 304 GLVersion::GL3_1, 305 GLESVersion::NONE, 306 GLContext::Extension_None, 307 {// GLContext::NV_primitive_restart, // Has different enum values. 308 GLContext::Extensions_End}}, 309 {"prim_restart_fixed", 310 kGLCoreVersionForES3Compat, 311 GLESVersion::ES3, 312 GLContext::ARB_ES3_compatibility, 313 {GLContext::Extensions_End}}, 314 {"provoking_vertex", 315 GLVersion::GL3_2, 316 GLESVersion::NONE, 317 GLContext::ARB_provoking_vertex, 318 {GLContext::ANGLE_provoking_vertex, GLContext::EXT_provoking_vertex, 319 GLContext::Extensions_End}}, 320 {"query_counter", 321 GLVersion::GL3_3, 322 GLESVersion::NONE, 323 GLContext::ARB_timer_query, 324 {GLContext::ANGLE_timer_query, GLContext::EXT_disjoint_timer_query, 325 // EXT_timer_query does NOT support GL_TIMESTAMP retrieval with 326 // QueryCounter. 327 GLContext::Extensions_End}}, 328 { 329 "query_objects", 330 GLVersion::GL2, 331 GLESVersion::ES3, 332 GLContext::Extension_None, 333 {GLContext::ANGLE_timer_query, GLContext::EXT_disjoint_timer_query, 334 GLContext::EXT_occlusion_query_boolean, GLContext::Extensions_End} 335 /* 336 * XXX_query_objects only provide entry points commonly supported by 337 * ARB_occlusion_query (added in OpenGL 2.0), 338 * EXT_occlusion_query_boolean (added in OpenGL ES 3.0), and 339 * ARB_timer_query (added in OpenGL 3.3) 340 */ 341 }, 342 {"query_time_elapsed", 343 GLVersion::GL3_3, 344 GLESVersion::NONE, 345 GLContext::ARB_timer_query, 346 {GLContext::ANGLE_timer_query, GLContext::EXT_disjoint_timer_query, 347 GLContext::EXT_timer_query, GLContext::Extensions_End}}, 348 {"read_buffer", 349 GLVersion::GL2, 350 GLESVersion::ES3, 351 GLContext::Extension_None, 352 {GLContext::Extensions_End}}, 353 {"renderbuffer_color_float", 354 GLVersion::GL3, 355 GLESVersion::ES3_2, 356 GLContext::Extension_None, 357 {GLContext::ARB_texture_float, GLContext::EXT_color_buffer_float, 358 GLContext::CHROMIUM_color_buffer_float_rgba, GLContext::Extensions_End}}, 359 {"renderbuffer_color_half_float", 360 GLVersion::GL3, 361 GLESVersion::ES3_2, 362 GLContext::Extension_None, 363 {GLContext::ARB_texture_float, GLContext::EXT_color_buffer_float, 364 GLContext::EXT_color_buffer_half_float, GLContext::Extensions_End}}, 365 {"robust_buffer_access_behavior", 366 GLVersion::NONE, 367 GLESVersion::NONE, 368 GLContext::Extension_None, 369 {GLContext::ARB_robust_buffer_access_behavior, 370 GLContext::KHR_robust_buffer_access_behavior, GLContext::Extensions_End}}, 371 {"robustness", 372 GLVersion::NONE, 373 GLESVersion::NONE, 374 GLContext::Extension_None, 375 {GLContext::ARB_robustness, GLContext::EXT_robustness, 376 GLContext::KHR_robustness, GLContext::Extensions_End}}, 377 {"sRGB", 378 GLVersion::GL3, 379 GLESVersion::ES3, 380 GLContext::ARB_framebuffer_sRGB, 381 {GLContext::EXT_sRGB, GLContext::EXT_framebuffer_sRGB, 382 GLContext::Extensions_End}}, 383 {"sampler_objects", 384 GLVersion::GL3_3, 385 GLESVersion::ES3, 386 GLContext::ARB_sampler_objects, 387 {GLContext::Extensions_End}}, 388 {"seamless_cube_map_opt_in", 389 GLVersion::GL3_2, 390 GLESVersion::NONE, 391 GLContext::ARB_seamless_cube_map, 392 {GLContext::Extensions_End}}, 393 {"shader_texture_lod", 394 GLVersion::GL3, 395 GLESVersion::ES3, 396 GLContext::Extension_None, 397 {GLContext::ARB_shader_texture_lod, GLContext::EXT_shader_texture_lod, 398 GLContext::Extensions_End}}, 399 {// Do we have separate DRAW and READ framebuffer bind points? 400 "split_framebuffer", 401 GLVersion::GL3, 402 GLESVersion::ES3, 403 GLContext::ARB_framebuffer_object, 404 {GLContext::ANGLE_framebuffer_blit, 405 GLContext::APPLE_framebuffer_multisample, GLContext::EXT_framebuffer_blit, 406 GLContext::NV_framebuffer_blit, GLContext::Extensions_End}}, 407 {"standard_derivatives", 408 GLVersion::GL2, 409 GLESVersion::ES3, 410 GLContext::Extension_None, 411 {GLContext::OES_standard_derivatives, GLContext::Extensions_End}}, 412 {"sync", 413 GLVersion::GL3_2, 414 GLESVersion::ES3, 415 GLContext::Extension_None, 416 {GLContext::ARB_sync, GLContext::APPLE_sync, GLContext::Extensions_End}}, 417 {"texture_3D", 418 GLVersion::GL1_2, 419 GLESVersion::ES3, 420 GLContext::Extension_None, 421 {GLContext::OES_texture_3D, GLContext::Extensions_End}}, 422 {"texture_3D_compressed", 423 GLVersion::GL1_3, 424 GLESVersion::ES3, 425 GLContext::Extension_None, 426 {GLContext::ARB_texture_compression, GLContext::OES_texture_3D, 427 GLContext::Extensions_End}}, 428 {"texture_3D_copy", 429 GLVersion::GL1_2, 430 GLESVersion::ES3, 431 GLContext::Extension_None, 432 {GLContext::EXT_copy_texture, GLContext::OES_texture_3D, 433 GLContext::Extensions_End}}, 434 {"texture_compression_bptc", 435 GLVersion::GL4_2, 436 GLESVersion::NONE, 437 GLContext::Extension_None, 438 {GLContext::ARB_texture_compression_bptc, 439 GLContext::EXT_texture_compression_bptc, GLContext::Extensions_End}}, 440 {"texture_compression_rgtc", 441 GLVersion::GL3, 442 GLESVersion::NONE, 443 GLContext::Extension_None, 444 {GLContext::ARB_texture_compression_rgtc, 445 GLContext::EXT_texture_compression_rgtc, GLContext::Extensions_End}}, 446 {"texture_float", 447 GLVersion::GL3, 448 GLESVersion::ES3, 449 GLContext::Extension_None, 450 {GLContext::ARB_texture_float, GLContext::OES_texture_float, 451 GLContext::Extensions_End}}, 452 {"texture_float_linear", 453 GLVersion::GL3_1, 454 GLESVersion::NONE, 455 GLContext::Extension_None, 456 {GLContext::ARB_texture_float, GLContext::OES_texture_float_linear, 457 GLContext::Extensions_End}}, 458 { 459 "texture_half_float", 460 GLVersion::GL3, 461 GLESVersion::ES3, 462 GLContext::Extension_None, 463 {GLContext::ARB_half_float_pixel, GLContext::ARB_texture_float, 464 GLContext::NV_half_float, GLContext::Extensions_End} 465 /** 466 * We are not including OES_texture_half_float in this feature, because: 467 * GL_HALF_FLOAT = 0x140B 468 * GL_HALF_FLOAT_ARB = 0x140B == GL_HALF_FLOAT 469 * GL_HALF_FLOAT_NV = 0x140B == GL_HALF_FLOAT 470 * GL_HALF_FLOAT_OES = 0x8D61 != GL_HALF_FLOAT 471 * WebGL handles this specifically with an OES_texture_half_float check. 472 */ 473 }, 474 {"texture_half_float_linear", 475 GLVersion::GL3_1, 476 GLESVersion::ES3, 477 GLContext::Extension_None, 478 {GLContext::ARB_half_float_pixel, GLContext::ARB_texture_float, 479 GLContext::NV_half_float, GLContext::OES_texture_half_float_linear, 480 GLContext::Extensions_End}}, 481 {"texture_non_power_of_two", 482 GLVersion::GL2, 483 GLESVersion::ES3, 484 GLContext::Extension_None, 485 {GLContext::ARB_texture_non_power_of_two, GLContext::OES_texture_npot, 486 GLContext::Extensions_End}}, 487 {"texture_norm16", 488 GLVersion::GL3_1, 489 GLESVersion::ES3_1, 490 GLContext::EXT_texture_norm16, 491 {GLContext::Extensions_End}}, 492 {"texture_rg", 493 GLVersion::GL3, 494 GLESVersion::ES3, 495 GLContext::ARB_texture_rg, 496 {GLContext::Extensions_End}}, 497 {"texture_storage", 498 GLVersion::GL4_2, 499 GLESVersion::ES3, 500 GLContext::ARB_texture_storage, 501 {/* 502 * Not including GL_EXT_texture_storage here because it 503 * doesn't guarantee glTexStorage3D, which is required for 504 * WebGL 2. 505 */ 506 GLContext::Extensions_End}}, 507 {"texture_swizzle", 508 GLVersion::GL3_3, 509 GLESVersion::ES3, 510 GLContext::ARB_texture_swizzle, 511 {GLContext::Extensions_End}}, 512 {"transform_feedback2", 513 GLVersion::GL4, 514 GLESVersion::ES3, 515 GLContext::ARB_transform_feedback2, 516 {GLContext::NV_transform_feedback2, GLContext::Extensions_End}}, 517 {"uniform_buffer_object", 518 GLVersion::GL3_1, 519 GLESVersion::ES3, 520 GLContext::ARB_uniform_buffer_object, 521 {GLContext::Extensions_End}}, 522 {"uniform_matrix_nonsquare", 523 GLVersion::GL2_1, 524 GLESVersion::ES3, 525 GLContext::Extension_None, 526 {GLContext::Extensions_End}}, 527 {"vertex_array_object", 528 GLVersion::GL3, 529 GLESVersion::ES3, 530 GLContext::ARB_vertex_array_object, // ARB extension 531 {GLContext::OES_vertex_array_object, GLContext::APPLE_vertex_array_object, 532 GLContext::Extensions_End}}}; 533 534 static inline const FeatureInfo& GetFeatureInfo(GLFeature feature) { 535 static_assert(std::size(sFeatureInfoArr) == size_t(GLFeature::EnumMax), 536 "Mismatched lengths for sFeatureInfoInfos and GLFeature enums"); 537 538 MOZ_ASSERT(feature < GLFeature::EnumMax, 539 "GLContext::GetFeatureInfoInfo : unknown <feature>"); 540 541 return sFeatureInfoArr[size_t(feature)]; 542 } 543 544 static inline uint32_t ProfileVersionForFeature(GLFeature feature, 545 ContextProfile profile) { 546 MOZ_ASSERT(profile != ContextProfile::Unknown, 547 "GLContext::ProfileVersionForFeature : unknown <profile>"); 548 549 const FeatureInfo& featureInfo = GetFeatureInfo(feature); 550 551 if (profile == ContextProfile::OpenGLES) 552 return (uint32_t)featureInfo.mOpenGLESVersion; 553 554 return (uint32_t)featureInfo.mOpenGLVersion; 555 } 556 557 static bool IsFeaturePartOfProfileVersion(GLFeature feature, 558 ContextProfile profile, 559 unsigned int version) { 560 unsigned int profileVersion = ProfileVersionForFeature(feature, profile); 561 562 /** 563 * if `profileVersion` is zero, it means that no version of the profile 564 * added support for the feature. 565 */ 566 return profileVersion && version >= profileVersion; 567 } 568 569 bool GLContext::IsFeatureProvidedByCoreSymbols(GLFeature feature) { 570 if (IsFeaturePartOfProfileVersion(feature, mProfile, mVersion)) return true; 571 572 if (IsExtensionSupported( 573 GetFeatureInfo(feature).mARBExtensionWithoutARBSuffix)) 574 return true; 575 576 return false; 577 } 578 579 const char* GLContext::GetFeatureName(GLFeature feature) { 580 return GetFeatureInfo(feature).mName; 581 } 582 583 void GLContext::InitFeatures() { 584 for (size_t featureId = 0; featureId < size_t(GLFeature::EnumMax); 585 featureId++) { 586 GLFeature feature = GLFeature(featureId); 587 588 if (IsFeaturePartOfProfileVersion(feature, mProfile, mVersion)) { 589 mAvailableFeatures[featureId] = true; 590 continue; 591 } 592 593 mAvailableFeatures[featureId] = false; 594 595 const FeatureInfo& featureInfo = GetFeatureInfo(feature); 596 597 if (IsExtensionSupported(featureInfo.mARBExtensionWithoutARBSuffix)) { 598 mAvailableFeatures[featureId] = true; 599 continue; 600 } 601 602 for (size_t j = 0; true; j++) { 603 MOZ_ASSERT(j < kMAX_EXTENSION_GROUP_SIZE, 604 "kMAX_EXTENSION_GROUP_SIZE too small"); 605 606 if (featureInfo.mExtensions[j] == GLContext::Extensions_End) break; 607 608 if (IsExtensionSupported(featureInfo.mExtensions[j])) { 609 mAvailableFeatures[featureId] = true; 610 break; 611 } 612 } 613 } 614 615 if (ShouldDumpExts()) { 616 for (size_t featureId = 0; featureId < size_t(GLFeature::EnumMax); 617 featureId++) { 618 GLFeature feature = GLFeature(featureId); 619 printf_stderr("[%s] Feature::%s\n", 620 IsSupported(feature) ? "enabled" : "disabled", 621 GetFeatureName(feature)); 622 } 623 } 624 } 625 626 void GLContext::MarkUnsupported(GLFeature feature) { 627 mAvailableFeatures[size_t(feature)] = false; 628 629 const FeatureInfo& featureInfo = GetFeatureInfo(feature); 630 631 for (size_t i = 0; true; i++) { 632 MOZ_ASSERT(i < kMAX_EXTENSION_GROUP_SIZE, 633 "kMAX_EXTENSION_GROUP_SIZE too small"); 634 635 if (featureInfo.mExtensions[i] == GLContext::Extensions_End) break; 636 637 MarkExtensionUnsupported(featureInfo.mExtensions[i]); 638 } 639 640 MOZ_ASSERT(!IsSupported(feature), "GLContext::MarkUnsupported has failed!"); 641 642 NS_WARNING( 643 nsPrintfCString("%s marked as unsupported", GetFeatureName(feature)) 644 .get()); 645 } 646 647 } /* namespace gl */ 648 } /* namespace mozilla */