1/* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 9#include "gl/GrGLInterface.h" 10#include "gl/GrGLExtensions.h" 11#include "gl/GrGLUtil.h" 12 13#include <stdio.h> 14 15const GrGLInterface* GrGLInterfaceAddTestDebugMarker(const GrGLInterface* interface, 16 GrGLInsertEventMarkerProc insertEventMarkerFn, 17 GrGLPushGroupMarkerProc pushGroupMarkerFn, 18 GrGLPopGroupMarkerProc popGroupMarkerFn) { 19 GrGLInterface* newInterface = GrGLInterface::NewClone(interface); 20 21 if (!newInterface->fExtensions.has("GL_EXT_debug_marker")) { 22 newInterface->fExtensions.add("GL_EXT_debug_marker"); 23 } 24 25 newInterface->fFunctions.fInsertEventMarker = insertEventMarkerFn; 26 newInterface->fFunctions.fPushGroupMarker = pushGroupMarkerFn; 27 newInterface->fFunctions.fPopGroupMarker = popGroupMarkerFn; 28 29 return newInterface; 30} 31 32GrGLInterface::GrGLInterface() { 33 fStandard = kNone_GrGLStandard; 34} 35 36GrGLInterface* GrGLInterface::NewClone(const GrGLInterface* interface) { 37 SkASSERT(interface); 38 39 GrGLInterface* clone = new GrGLInterface; 40 clone->fStandard = interface->fStandard; 41 clone->fExtensions = interface->fExtensions; 42 clone->fFunctions = interface->fFunctions; 43 return clone; 44} 45 46#ifdef SK_DEBUG 47 static int kIsDebug = 1; 48#else 49 static int kIsDebug = 0; 50#endif 51 52#define RETURN_FALSE_INTERFACE \ 53 if (kIsDebug) { SkDebugf("%s:%d GrGLInterface::validate() failed.\n", __FILE__, __LINE__); } \ 54 return false; 55 56bool GrGLInterface::validate() const { 57 58 if (kNone_GrGLStandard == fStandard) { 59 RETURN_FALSE_INTERFACE 60 } 61 62 if (!fExtensions.isInitialized()) { 63 RETURN_FALSE_INTERFACE 64 } 65 66 // functions that are always required 67 if (nullptr == fFunctions.fActiveTexture || 68 nullptr == fFunctions.fAttachShader || 69 nullptr == fFunctions.fBindAttribLocation || 70 nullptr == fFunctions.fBindBuffer || 71 nullptr == fFunctions.fBindTexture || 72 nullptr == fFunctions.fBlendColor || // -> GL >= 1.4 or extension, ES >= 2.0 73 nullptr == fFunctions.fBlendEquation || // -> GL >= 1.4 or extension, ES >= 2.0 74 nullptr == fFunctions.fBlendFunc || 75 nullptr == fFunctions.fBufferData || 76 nullptr == fFunctions.fBufferSubData || 77 nullptr == fFunctions.fClear || 78 nullptr == fFunctions.fClearColor || 79 nullptr == fFunctions.fClearStencil || 80 nullptr == fFunctions.fColorMask || 81 nullptr == fFunctions.fCompileShader || 82 nullptr == fFunctions.fCopyTexSubImage2D || 83 nullptr == fFunctions.fCreateProgram || 84 nullptr == fFunctions.fCreateShader || 85 nullptr == fFunctions.fCullFace || 86 nullptr == fFunctions.fDeleteBuffers || 87 nullptr == fFunctions.fDeleteProgram || 88 nullptr == fFunctions.fDeleteShader || 89 nullptr == fFunctions.fDeleteTextures || 90 nullptr == fFunctions.fDepthMask || 91 nullptr == fFunctions.fDisable || 92 nullptr == fFunctions.fDisableVertexAttribArray || 93 nullptr == fFunctions.fDrawArrays || 94 nullptr == fFunctions.fDrawElements || 95 nullptr == fFunctions.fEnable || 96 nullptr == fFunctions.fEnableVertexAttribArray || 97 nullptr == fFunctions.fFrontFace || 98 nullptr == fFunctions.fGenBuffers || 99 nullptr == fFunctions.fGenTextures || 100 nullptr == fFunctions.fGetBufferParameteriv || 101 nullptr == fFunctions.fGenerateMipmap || 102 nullptr == fFunctions.fGetError || 103 nullptr == fFunctions.fGetIntegerv || 104 nullptr == fFunctions.fGetProgramInfoLog || 105 nullptr == fFunctions.fGetProgramiv || 106 nullptr == fFunctions.fGetShaderInfoLog || 107 nullptr == fFunctions.fGetShaderiv || 108 nullptr == fFunctions.fGetString || 109 nullptr == fFunctions.fGetUniformLocation || 110#if 0 // Not included in Chrome yet 111 nullptr == fFunctions.fIsTexture || 112#endif 113 nullptr == fFunctions.fLinkProgram || 114 nullptr == fFunctions.fLineWidth || 115 nullptr == fFunctions.fPixelStorei || 116 nullptr == fFunctions.fReadPixels || 117 nullptr == fFunctions.fScissor || 118 nullptr == fFunctions.fShaderSource || 119 nullptr == fFunctions.fStencilFunc || 120 nullptr == fFunctions.fStencilMask || 121 nullptr == fFunctions.fStencilOp || 122 nullptr == fFunctions.fTexImage2D || 123 nullptr == fFunctions.fTexParameteri || 124 nullptr == fFunctions.fTexParameteriv || 125 nullptr == fFunctions.fTexSubImage2D || 126 nullptr == fFunctions.fUniform1f || 127 nullptr == fFunctions.fUniform1i || 128 nullptr == fFunctions.fUniform1fv || 129 nullptr == fFunctions.fUniform1iv || 130 nullptr == fFunctions.fUniform2f || 131 nullptr == fFunctions.fUniform2i || 132 nullptr == fFunctions.fUniform2fv || 133 nullptr == fFunctions.fUniform2iv || 134 nullptr == fFunctions.fUniform3f || 135 nullptr == fFunctions.fUniform3i || 136 nullptr == fFunctions.fUniform3fv || 137 nullptr == fFunctions.fUniform3iv || 138 nullptr == fFunctions.fUniform4f || 139 nullptr == fFunctions.fUniform4i || 140 nullptr == fFunctions.fUniform4fv || 141 nullptr == fFunctions.fUniform4iv || 142 nullptr == fFunctions.fUniformMatrix2fv || 143 nullptr == fFunctions.fUniformMatrix3fv || 144 nullptr == fFunctions.fUniformMatrix4fv || 145 nullptr == fFunctions.fUseProgram || 146 nullptr == fFunctions.fVertexAttrib1f || 147 nullptr == fFunctions.fVertexAttrib2fv || 148 nullptr == fFunctions.fVertexAttrib3fv || 149 nullptr == fFunctions.fVertexAttrib4fv || 150 nullptr == fFunctions.fVertexAttribPointer || 151 nullptr == fFunctions.fViewport || 152 nullptr == fFunctions.fBindFramebuffer || 153 nullptr == fFunctions.fBindRenderbuffer || 154 nullptr == fFunctions.fCheckFramebufferStatus || 155 nullptr == fFunctions.fDeleteFramebuffers || 156 nullptr == fFunctions.fDeleteRenderbuffers || 157 nullptr == fFunctions.fFinish || 158 nullptr == fFunctions.fFlush || 159 nullptr == fFunctions.fFramebufferRenderbuffer || 160 nullptr == fFunctions.fFramebufferTexture2D || 161 nullptr == fFunctions.fGetFramebufferAttachmentParameteriv || 162 nullptr == fFunctions.fGetRenderbufferParameteriv || 163 nullptr == fFunctions.fGenFramebuffers || 164 nullptr == fFunctions.fGenRenderbuffers || 165 nullptr == fFunctions.fRenderbufferStorage) { 166 RETURN_FALSE_INTERFACE 167 } 168 169 GrGLVersion glVer = GrGLGetVersion(this); 170 if (GR_GL_INVALID_VER == glVer) { 171 RETURN_FALSE_INTERFACE 172 } 173 174 // Now check that baseline ES/Desktop fns not covered above are present 175 // and that we have fn pointers for any advertised fExtensions that we will 176 // try to use. 177 178 // these functions are part of ES2, we assume they are available 179 // On the desktop we assume they are available if the extension 180 // is present or GL version is high enough. 181 if (kGLES_GrGLStandard == fStandard) { 182 if (nullptr == fFunctions.fStencilFuncSeparate || 183 nullptr == fFunctions.fStencilMaskSeparate || 184 nullptr == fFunctions.fStencilOpSeparate) { 185 RETURN_FALSE_INTERFACE 186 } 187 } else if (kGL_GrGLStandard == fStandard) { 188 189 if (glVer >= GR_GL_VER(2,0)) { 190 if (nullptr == fFunctions.fStencilFuncSeparate || 191 nullptr == fFunctions.fStencilMaskSeparate || 192 nullptr == fFunctions.fStencilOpSeparate) { 193 RETURN_FALSE_INTERFACE 194 } 195 } 196 if (glVer >= GR_GL_VER(3,0) && nullptr == fFunctions.fBindFragDataLocation) { 197 RETURN_FALSE_INTERFACE 198 } 199 if (glVer >= GR_GL_VER(2,0) || fExtensions.has("GL_ARB_draw_buffers")) { 200 if (nullptr == fFunctions.fDrawBuffers) { 201 RETURN_FALSE_INTERFACE 202 } 203 } 204 205 if (glVer >= GR_GL_VER(1,5) || fExtensions.has("GL_ARB_occlusion_query")) { 206 if (nullptr == fFunctions.fGenQueries || 207 nullptr == fFunctions.fDeleteQueries || 208 nullptr == fFunctions.fBeginQuery || 209 nullptr == fFunctions.fEndQuery || 210 nullptr == fFunctions.fGetQueryiv || 211 nullptr == fFunctions.fGetQueryObjectiv || 212 nullptr == fFunctions.fGetQueryObjectuiv) { 213 RETURN_FALSE_INTERFACE 214 } 215 } 216 if (glVer >= GR_GL_VER(3,3) || 217 fExtensions.has("GL_ARB_timer_query") || 218 fExtensions.has("GL_EXT_timer_query")) { 219 if (nullptr == fFunctions.fGetQueryObjecti64v || 220 nullptr == fFunctions.fGetQueryObjectui64v) { 221 RETURN_FALSE_INTERFACE 222 } 223 } 224 if (glVer >= GR_GL_VER(3,3) || fExtensions.has("GL_ARB_timer_query")) { 225 if (nullptr == fFunctions.fQueryCounter) { 226 RETURN_FALSE_INTERFACE 227 } 228 } 229 } 230 231 // optional function on desktop before 1.3 232 if (kGL_GrGLStandard != fStandard || 233 (glVer >= GR_GL_VER(1,3)) || 234 fExtensions.has("GL_ARB_texture_compression")) { 235 if (nullptr == fFunctions.fCompressedTexImage2D 236#if 0 237 || nullptr == fFunctions.fCompressedTexSubImage2D 238#endif 239 ) { 240 RETURN_FALSE_INTERFACE 241 } 242 } 243 244 // part of desktop GL, but not ES 245 if (kGL_GrGLStandard == fStandard && 246 (nullptr == fFunctions.fGetTexLevelParameteriv || 247 nullptr == fFunctions.fDrawBuffer || 248 nullptr == fFunctions.fReadBuffer)) { 249 RETURN_FALSE_INTERFACE 250 } 251 252 // GL_EXT_texture_storage is part of desktop 4.2 253 // There is a desktop ARB extension and an ES+desktop EXT extension 254 if (kGL_GrGLStandard == fStandard) { 255 if (glVer >= GR_GL_VER(4,2) || 256 fExtensions.has("GL_ARB_texture_storage") || 257 fExtensions.has("GL_EXT_texture_storage")) { 258 if (nullptr == fFunctions.fTexStorage2D) { 259 RETURN_FALSE_INTERFACE 260 } 261 } 262 } else if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_texture_storage")) { 263 if (nullptr == fFunctions.fTexStorage2D) { 264 RETURN_FALSE_INTERFACE 265 } 266 } 267 268 // glTextureBarrier is part of desktop 4.5. There are also ARB and NV extensions. 269 if (kGL_GrGLStandard == fStandard) { 270 if (glVer >= GR_GL_VER(4,5) || 271 fExtensions.has("GL_ARB_texture_barrier") || 272 fExtensions.has("GL_NV_texture_barrier")) { 273 if (nullptr == fFunctions.fTextureBarrier) { 274 RETURN_FALSE_INTERFACE 275 } 276 } 277 } else if (fExtensions.has("GL_NV_texture_barrier")) { 278 if (nullptr == fFunctions.fTextureBarrier) { 279 RETURN_FALSE_INTERFACE 280 } 281 } 282 283 if (fExtensions.has("GL_KHR_blend_equation_advanced") || 284 fExtensions.has("GL_NV_blend_equation_advanced")) { 285 if (nullptr == fFunctions.fBlendBarrier) { 286 RETURN_FALSE_INTERFACE 287 } 288 } 289 290 if (fExtensions.has("GL_EXT_discard_framebuffer")) { 291 if (nullptr == fFunctions.fDiscardFramebuffer) { 292 RETURN_FALSE_INTERFACE 293 } 294 } 295 296 // FBO MSAA 297 if (kGL_GrGLStandard == fStandard) { 298 // GL 3.0 and the ARB extension have multisample + blit 299 if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_ARB_framebuffer_object")) { 300 if (nullptr == fFunctions.fRenderbufferStorageMultisample || 301 nullptr == fFunctions.fBlitFramebuffer) { 302 RETURN_FALSE_INTERFACE 303 } 304 } else { 305 if (fExtensions.has("GL_EXT_framebuffer_blit") && 306 nullptr == fFunctions.fBlitFramebuffer) { 307 RETURN_FALSE_INTERFACE 308 } 309 if (fExtensions.has("GL_EXT_framebuffer_multisample") && 310 nullptr == fFunctions.fRenderbufferStorageMultisample) { 311 RETURN_FALSE_INTERFACE 312 } 313 } 314 } else { 315 if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_CHROMIUM_framebuffer_multisample")) { 316 if (nullptr == fFunctions.fRenderbufferStorageMultisample || 317 nullptr == fFunctions.fBlitFramebuffer) { 318 RETURN_FALSE_INTERFACE 319 } 320 } else { 321 if (fExtensions.has("GL_ANGLE_framebuffer_multisample") && 322 nullptr == fFunctions.fRenderbufferStorageMultisample) { 323 RETURN_FALSE_INTERFACE 324 } 325 if (fExtensions.has("GL_ANGLE_framebuffer_blit") && 326 nullptr == fFunctions.fBlitFramebuffer) { 327 RETURN_FALSE_INTERFACE 328 } 329 } 330 if (fExtensions.has("GL_APPLE_framebuffer_multisample")) { 331 if (nullptr == fFunctions.fRenderbufferStorageMultisampleES2APPLE || 332 nullptr == fFunctions.fResolveMultisampleFramebuffer) { 333 RETURN_FALSE_INTERFACE 334 } 335 } 336 if (fExtensions.has("GL_IMG_multisampled_render_to_texture") || 337 fExtensions.has("GL_EXT_multisampled_render_to_texture")) { 338 if (nullptr == fFunctions.fRenderbufferStorageMultisampleES2EXT || 339 nullptr == fFunctions.fFramebufferTexture2DMultisample) { 340 RETURN_FALSE_INTERFACE 341 } 342 } 343 } 344 345 // On ES buffer mapping is an extension. On Desktop 346 // buffer mapping was part of original VBO extension 347 // which we require. 348 if (kGL_GrGLStandard == fStandard || fExtensions.has("GL_OES_mapbuffer")) { 349 if (nullptr == fFunctions.fMapBuffer || 350 nullptr == fFunctions.fUnmapBuffer) { 351 RETURN_FALSE_INTERFACE 352 } 353 } 354 355 // Dual source blending 356 if (kGL_GrGLStandard == fStandard) { 357 if (glVer >= GR_GL_VER(3,3) || fExtensions.has("GL_ARB_blend_func_extended")) { 358 if (nullptr == fFunctions.fBindFragDataLocationIndexed) { 359 RETURN_FALSE_INTERFACE 360 } 361 } 362 } else { 363 if (glVer >= GR_GL_VER(3,0) && fExtensions.has("GL_EXT_blend_func_extended")) { 364 if (nullptr == fFunctions.fBindFragDataLocation || 365 nullptr == fFunctions.fBindFragDataLocationIndexed) { 366 RETURN_FALSE_INTERFACE 367 } 368 } 369 } 370 371 372 // glGetStringi was added in version 3.0 of both desktop and ES. 373 if (glVer >= GR_GL_VER(3, 0)) { 374 if (nullptr == fFunctions.fGetStringi) { 375 RETURN_FALSE_INTERFACE 376 } 377 } 378 379 // glVertexAttribIPointer was added in version 3.0 of both desktop and ES. 380 if (glVer >= GR_GL_VER(3, 0)) { 381 if (NULL == fFunctions.fVertexAttribIPointer) { 382 RETURN_FALSE_INTERFACE 383 } 384 } 385 386 if (kGL_GrGLStandard == fStandard) { 387 if (glVer >= GR_GL_VER(3,1)) { 388 if (nullptr == fFunctions.fTexBuffer) { 389 RETURN_FALSE_INTERFACE; 390 } 391 } 392 if (glVer >= GR_GL_VER(4,3)) { 393 if (nullptr == fFunctions.fTexBufferRange) { 394 RETURN_FALSE_INTERFACE; 395 } 396 } 397 } else { 398 if (glVer >= GR_GL_VER(3,2) || fExtensions.has("GL_OES_texture_buffer") || 399 fExtensions.has("GL_EXT_texture_buffer")) { 400 if (nullptr == fFunctions.fTexBuffer || 401 nullptr == fFunctions.fTexBufferRange) { 402 RETURN_FALSE_INTERFACE; 403 } 404 } 405 } 406 407 if (kGL_GrGLStandard == fStandard) { 408 if (glVer >= GR_GL_VER(3, 0) || fExtensions.has("GL_ARB_vertex_array_object")) { 409 if (nullptr == fFunctions.fBindVertexArray || 410 nullptr == fFunctions.fDeleteVertexArrays || 411 nullptr == fFunctions.fGenVertexArrays) { 412 RETURN_FALSE_INTERFACE 413 } 414 } 415 } else { 416 if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_OES_vertex_array_object")) { 417 if (nullptr == fFunctions.fBindVertexArray || 418 nullptr == fFunctions.fDeleteVertexArrays || 419 nullptr == fFunctions.fGenVertexArrays) { 420 RETURN_FALSE_INTERFACE 421 } 422 } 423 } 424 425 if (fExtensions.has("GL_EXT_debug_marker")) { 426 if (nullptr == fFunctions.fInsertEventMarker || 427 nullptr == fFunctions.fPushGroupMarker || 428 nullptr == fFunctions.fPopGroupMarker) { 429 RETURN_FALSE_INTERFACE 430 } 431 } 432 433 if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,3)) || 434 fExtensions.has("GL_ARB_invalidate_subdata")) { 435 if (nullptr == fFunctions.fInvalidateBufferData || 436 nullptr == fFunctions.fInvalidateBufferSubData || 437 nullptr == fFunctions.fInvalidateFramebuffer || 438 nullptr == fFunctions.fInvalidateSubFramebuffer || 439 nullptr == fFunctions.fInvalidateTexImage || 440 nullptr == fFunctions.fInvalidateTexSubImage) { 441 RETURN_FALSE_INTERFACE; 442 } 443 } else if (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,0)) { 444 // ES 3.0 adds the framebuffer functions but not the others. 445 if (nullptr == fFunctions.fInvalidateFramebuffer || 446 nullptr == fFunctions.fInvalidateSubFramebuffer) { 447 RETURN_FALSE_INTERFACE; 448 } 449 } 450 451 if (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_CHROMIUM_map_sub")) { 452 if (nullptr == fFunctions.fMapBufferSubData || 453 nullptr == fFunctions.fMapTexSubImage2D || 454 nullptr == fFunctions.fUnmapBufferSubData || 455 nullptr == fFunctions.fUnmapTexSubImage2D) { 456 RETURN_FALSE_INTERFACE; 457 } 458 } 459 460 // These functions are added to the 3.0 version of both GLES and GL. 461 if (glVer >= GR_GL_VER(3,0) || 462 (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_EXT_map_buffer_range")) || 463 (kGL_GrGLStandard == fStandard && fExtensions.has("GL_ARB_map_buffer_range"))) { 464 if (nullptr == fFunctions.fMapBufferRange || 465 nullptr == fFunctions.fFlushMappedBufferRange) { 466 RETURN_FALSE_INTERFACE; 467 } 468 } 469 470 if ((kGL_GrGLStandard == fStandard && 471 (glVer >= GR_GL_VER(3,2) || fExtensions.has("GL_ARB_texture_multisample"))) || 472 (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,1))) { 473 if (NULL == fFunctions.fGetMultisamplefv) { 474 RETURN_FALSE_INTERFACE 475 } 476 } 477 478 if ((kGL_GrGLStandard == fStandard && 479 (glVer >= GR_GL_VER(4,3) || fExtensions.has("GL_ARB_program_interface_query"))) || 480 (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,1))) { 481 if (nullptr == fFunctions.fGetProgramResourceLocation) { 482 RETURN_FALSE_INTERFACE 483 } 484 } 485 486 if (kGLES_GrGLStandard == fStandard || glVer >= GR_GL_VER(4,1) || 487 fExtensions.has("GL_ARB_ES2_compatibility")) { 488 if (nullptr == fFunctions.fGetShaderPrecisionFormat) { 489 RETURN_FALSE_INTERFACE 490 } 491 } 492 493 if (fExtensions.has("GL_NV_path_rendering") || fExtensions.has("GL_CHROMIUM_path_rendering")) { 494 if (nullptr == fFunctions.fMatrixLoadf || 495 nullptr == fFunctions.fMatrixLoadIdentity || 496 nullptr == fFunctions.fPathCommands || 497 nullptr == fFunctions.fPathParameteri || 498 nullptr == fFunctions.fPathParameterf || 499 nullptr == fFunctions.fGenPaths || 500 nullptr == fFunctions.fDeletePaths || 501 nullptr == fFunctions.fIsPath || 502 nullptr == fFunctions.fPathStencilFunc || 503 nullptr == fFunctions.fStencilFillPath || 504 nullptr == fFunctions.fStencilStrokePath || 505 nullptr == fFunctions.fStencilFillPathInstanced || 506 nullptr == fFunctions.fStencilStrokePathInstanced || 507 nullptr == fFunctions.fCoverFillPath || 508 nullptr == fFunctions.fCoverStrokePath || 509 nullptr == fFunctions.fCoverFillPathInstanced || 510 nullptr == fFunctions.fCoverStrokePathInstanced 511#if 0 512 // List of functions that Skia uses, but which have been added since the initial release 513 // of NV_path_rendering driver. We do not want to fail interface validation due to 514 // missing features, we will just not use the extension. 515 // Update this list -> update GrGLCaps::hasPathRenderingSupport too. 516 || nullptr == fFunctions.fStencilThenCoverFillPath || 517 nullptr == fFunctions.fStencilThenCoverStrokePath || 518 nullptr == fFunctions.fStencilThenCoverFillPathInstanced || 519 nullptr == fFunctions.fStencilThenCoverStrokePathInstanced || 520 nullptr == fFunctions.fProgramPathFragmentInputGen 521#endif 522 ) { 523 RETURN_FALSE_INTERFACE 524 } 525 if (fExtensions.has("GL_CHROMIUM_path_rendering")) { 526 if (nullptr == fFunctions.fBindFragmentInputLocation) { 527 RETURN_FALSE_INTERFACE 528 } 529 } 530 } 531 532 if (fExtensions.has("GL_EXT_raster_multisample")) { 533 if (nullptr == fFunctions.fRasterSamples) { 534 RETURN_FALSE_INTERFACE 535 } 536 } 537 538 if (fExtensions.has("GL_NV_framebuffer_mixed_samples") || 539 fExtensions.has("GL_CHROMIUM_framebuffer_mixed_samples")) { 540 if (nullptr == fFunctions.fCoverageModulation) { 541 RETURN_FALSE_INTERFACE 542 } 543 } 544 545 if (kGL_GrGLStandard == fStandard) { 546 if (glVer >= GR_GL_VER(3,1) || 547 fExtensions.has("GL_EXT_draw_instanced") || fExtensions.has("GL_ARB_draw_instanced")) { 548 if (nullptr == fFunctions.fDrawArraysInstanced || 549 nullptr == fFunctions.fDrawElementsInstanced) { 550 RETURN_FALSE_INTERFACE 551 } 552 } 553 } else if (kGLES_GrGLStandard == fStandard) { 554 if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_draw_instanced")) { 555 if (nullptr == fFunctions.fDrawArraysInstanced || 556 nullptr == fFunctions.fDrawElementsInstanced) { 557 RETURN_FALSE_INTERFACE 558 } 559 } 560 } 561 562 if (kGL_GrGLStandard == fStandard) { 563 if (glVer >= GR_GL_VER(3,2) || fExtensions.has("GL_ARB_instanced_arrays")) { 564 if (nullptr == fFunctions.fVertexAttribDivisor) { 565 RETURN_FALSE_INTERFACE 566 } 567 } 568 } else if (kGLES_GrGLStandard == fStandard) { 569 if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_instanced_arrays")) { 570 if (nullptr == fFunctions.fVertexAttribDivisor) { 571 RETURN_FALSE_INTERFACE 572 } 573 } 574 } 575 576 if ((kGL_GrGLStandard == fStandard && 577 (glVer >= GR_GL_VER(4,0) || fExtensions.has("GL_ARB_draw_indirect"))) || 578 (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,1))) { 579 if (NULL == fFunctions.fDrawArraysIndirect || 580 NULL == fFunctions.fDrawElementsIndirect) { 581 RETURN_FALSE_INTERFACE 582 } 583 } 584 585 if ((kGL_GrGLStandard == fStandard && 586 (glVer >= GR_GL_VER(4,3) || fExtensions.has("GL_ARB_multi_draw_indirect"))) || 587 (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_EXT_multi_draw_indirect"))) { 588 if (NULL == fFunctions.fMultiDrawArraysIndirect || 589 NULL == fFunctions.fMultiDrawElementsIndirect) { 590 RETURN_FALSE_INTERFACE 591 } 592 } 593 594 if (fExtensions.has("GL_NV_bindless_texture")) { 595 if (nullptr == fFunctions.fGetTextureHandle || 596 nullptr == fFunctions.fGetTextureSamplerHandle || 597 nullptr == fFunctions.fMakeTextureHandleResident || 598 nullptr == fFunctions.fMakeTextureHandleNonResident || 599 nullptr == fFunctions.fGetImageHandle || 600 nullptr == fFunctions.fMakeImageHandleResident || 601 nullptr == fFunctions.fMakeImageHandleNonResident || 602 nullptr == fFunctions.fIsTextureHandleResident || 603 nullptr == fFunctions.fIsImageHandleResident || 604 nullptr == fFunctions.fUniformHandleui64 || 605 nullptr == fFunctions.fUniformHandleui64v || 606 nullptr == fFunctions.fProgramUniformHandleui64 || 607 nullptr == fFunctions.fProgramUniformHandleui64v) { 608 RETURN_FALSE_INTERFACE 609 } 610 } 611 612 if (kGL_GrGLStandard == fStandard && fExtensions.has("GL_EXT_direct_state_access")) { 613 if (nullptr == fFunctions.fTextureParameteri || 614 nullptr == fFunctions.fTextureParameteriv || 615 nullptr == fFunctions.fTextureParameterf || 616 nullptr == fFunctions.fTextureParameterfv || 617 nullptr == fFunctions.fTextureImage1D || 618 nullptr == fFunctions.fTextureImage2D || 619 nullptr == fFunctions.fTextureSubImage1D || 620 nullptr == fFunctions.fTextureSubImage2D || 621 nullptr == fFunctions.fCopyTextureImage1D || 622 nullptr == fFunctions.fCopyTextureImage2D || 623 nullptr == fFunctions.fCopyTextureSubImage1D || 624 nullptr == fFunctions.fCopyTextureSubImage2D || 625 nullptr == fFunctions.fGetTextureImage || 626 nullptr == fFunctions.fGetTextureParameterfv || 627 nullptr == fFunctions.fGetTextureParameteriv || 628 nullptr == fFunctions.fGetTextureLevelParameterfv || 629 nullptr == fFunctions.fGetTextureLevelParameteriv) { 630 RETURN_FALSE_INTERFACE 631 } 632 if (glVer >= GR_GL_VER(1,2)) { 633 if (nullptr == fFunctions.fTextureImage3D || 634 nullptr == fFunctions.fTextureSubImage3D || 635 nullptr == fFunctions.fCopyTextureSubImage3D || 636 nullptr == fFunctions.fCompressedTextureImage3D || 637 nullptr == fFunctions.fCompressedTextureImage2D || 638 nullptr == fFunctions.fCompressedTextureImage1D || 639 nullptr == fFunctions.fCompressedTextureSubImage3D || 640 nullptr == fFunctions.fCompressedTextureSubImage2D || 641 nullptr == fFunctions.fCompressedTextureSubImage1D || 642 nullptr == fFunctions.fGetCompressedTextureImage) { 643 RETURN_FALSE_INTERFACE 644 } 645 } 646 if (glVer >= GR_GL_VER(1,5)) { 647 if (nullptr == fFunctions.fNamedBufferData || 648 nullptr == fFunctions.fNamedBufferSubData || 649 nullptr == fFunctions.fMapNamedBuffer || 650 nullptr == fFunctions.fUnmapNamedBuffer || 651 nullptr == fFunctions.fGetNamedBufferParameteriv || 652 nullptr == fFunctions.fGetNamedBufferPointerv || 653 nullptr == fFunctions.fGetNamedBufferSubData) { 654 RETURN_FALSE_INTERFACE 655 } 656 } 657 if (glVer >= GR_GL_VER(2,0)) { 658 if (nullptr == fFunctions.fProgramUniform1f || 659 nullptr == fFunctions.fProgramUniform2f || 660 nullptr == fFunctions.fProgramUniform3f || 661 nullptr == fFunctions.fProgramUniform4f || 662 nullptr == fFunctions.fProgramUniform1i || 663 nullptr == fFunctions.fProgramUniform2i || 664 nullptr == fFunctions.fProgramUniform3i || 665 nullptr == fFunctions.fProgramUniform4i || 666 nullptr == fFunctions.fProgramUniform1fv || 667 nullptr == fFunctions.fProgramUniform2fv || 668 nullptr == fFunctions.fProgramUniform3fv || 669 nullptr == fFunctions.fProgramUniform4fv || 670 nullptr == fFunctions.fProgramUniform1iv || 671 nullptr == fFunctions.fProgramUniform2iv || 672 nullptr == fFunctions.fProgramUniform3iv || 673 nullptr == fFunctions.fProgramUniform4iv || 674 nullptr == fFunctions.fProgramUniformMatrix2fv || 675 nullptr == fFunctions.fProgramUniformMatrix3fv || 676 nullptr == fFunctions.fProgramUniformMatrix4fv) { 677 RETURN_FALSE_INTERFACE 678 } 679 } 680 if (glVer >= GR_GL_VER(2,1)) { 681 if (nullptr == fFunctions.fProgramUniformMatrix2x3fv || 682 nullptr == fFunctions.fProgramUniformMatrix3x2fv || 683 nullptr == fFunctions.fProgramUniformMatrix2x4fv || 684 nullptr == fFunctions.fProgramUniformMatrix4x2fv || 685 nullptr == fFunctions.fProgramUniformMatrix3x4fv || 686 nullptr == fFunctions.fProgramUniformMatrix4x3fv) { 687 RETURN_FALSE_INTERFACE 688 } 689 } 690 if (glVer >= GR_GL_VER(3,0)) { 691 if (nullptr == fFunctions.fNamedRenderbufferStorage || 692 nullptr == fFunctions.fGetNamedRenderbufferParameteriv || 693 nullptr == fFunctions.fNamedRenderbufferStorageMultisample || 694 nullptr == fFunctions.fCheckNamedFramebufferStatus || 695 nullptr == fFunctions.fNamedFramebufferTexture1D || 696 nullptr == fFunctions.fNamedFramebufferTexture2D || 697 nullptr == fFunctions.fNamedFramebufferTexture3D || 698 nullptr == fFunctions.fNamedFramebufferRenderbuffer || 699 nullptr == fFunctions.fGetNamedFramebufferAttachmentParameteriv || 700 nullptr == fFunctions.fGenerateTextureMipmap || 701 nullptr == fFunctions.fFramebufferDrawBuffer || 702 nullptr == fFunctions.fFramebufferDrawBuffers || 703 nullptr == fFunctions.fFramebufferReadBuffer || 704 nullptr == fFunctions.fGetFramebufferParameteriv || 705 nullptr == fFunctions.fNamedCopyBufferSubData || 706 nullptr == fFunctions.fVertexArrayVertexOffset || 707 nullptr == fFunctions.fVertexArrayColorOffset || 708 nullptr == fFunctions.fVertexArrayEdgeFlagOffset || 709 nullptr == fFunctions.fVertexArrayIndexOffset || 710 nullptr == fFunctions.fVertexArrayNormalOffset || 711 nullptr == fFunctions.fVertexArrayTexCoordOffset || 712 nullptr == fFunctions.fVertexArrayMultiTexCoordOffset || 713 nullptr == fFunctions.fVertexArrayFogCoordOffset || 714 nullptr == fFunctions.fVertexArraySecondaryColorOffset || 715 nullptr == fFunctions.fVertexArrayVertexAttribOffset || 716 nullptr == fFunctions.fVertexArrayVertexAttribIOffset || 717 nullptr == fFunctions.fEnableVertexArray || 718 nullptr == fFunctions.fDisableVertexArray || 719 nullptr == fFunctions.fEnableVertexArrayAttrib || 720 nullptr == fFunctions.fDisableVertexArrayAttrib || 721 nullptr == fFunctions.fGetVertexArrayIntegerv || 722 nullptr == fFunctions.fGetVertexArrayPointerv || 723 nullptr == fFunctions.fGetVertexArrayIntegeri_v || 724 nullptr == fFunctions.fGetVertexArrayPointeri_v || 725 nullptr == fFunctions.fMapNamedBufferRange || 726 nullptr == fFunctions.fFlushMappedNamedBufferRange) { 727 RETURN_FALSE_INTERFACE 728 } 729 } 730 if (glVer >= GR_GL_VER(3,1)) { 731 if (nullptr == fFunctions.fTextureBuffer) { 732 RETURN_FALSE_INTERFACE; 733 } 734 } 735 } 736 737 if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,3)) || 738 fExtensions.has("GL_KHR_debug")) { 739 if (nullptr == fFunctions.fDebugMessageControl || 740 nullptr == fFunctions.fDebugMessageInsert || 741 nullptr == fFunctions.fDebugMessageCallback || 742 nullptr == fFunctions.fGetDebugMessageLog || 743 nullptr == fFunctions.fPushDebugGroup || 744 nullptr == fFunctions.fPopDebugGroup || 745 nullptr == fFunctions.fObjectLabel) { 746 RETURN_FALSE_INTERFACE 747 } 748 } 749 750 if (fExtensions.has("GL_EXT_window_rectangles")) { 751 if (nullptr == fFunctions.fWindowRectangles) { 752 RETURN_FALSE_INTERFACE 753 } 754 } 755 756 if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,0)) || 757 fExtensions.has("GL_ARB_sample_shading")) { 758 if (nullptr == fFunctions.fMinSampleShading) { 759 RETURN_FALSE_INTERFACE 760 } 761 } else if (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_OES_sample_shading")) { 762 if (nullptr == fFunctions.fMinSampleShading) { 763 RETURN_FALSE_INTERFACE 764 } 765 } 766 767 if (kGL_GrGLStandard == fStandard) { 768 if (glVer >= GR_GL_VER(3, 2) || fExtensions.has("GL_ARB_sync")) { 769 if (nullptr == fFunctions.fFenceSync || 770 nullptr == fFunctions.fClientWaitSync || 771 nullptr == fFunctions.fWaitSync || 772 nullptr == fFunctions.fDeleteSync) { 773 RETURN_FALSE_INTERFACE 774 } 775 } 776 } else if (kGLES_GrGLStandard == fStandard) { 777 if (glVer >= GR_GL_VER(3, 0)) { 778 if (nullptr == fFunctions.fFenceSync || 779 nullptr == fFunctions.fClientWaitSync || 780 nullptr == fFunctions.fWaitSync || 781 nullptr == fFunctions.fDeleteSync) { 782 RETURN_FALSE_INTERFACE 783 } 784 } 785 } 786 787 if (fExtensions.has("EGL_KHR_image") || fExtensions.has("EGL_KHR_image_base")) { 788 if (nullptr == fFunctions.fEGLCreateImage || 789 nullptr == fFunctions.fEGLDestroyImage) { 790 RETURN_FALSE_INTERFACE 791 } 792 } 793 794 if (kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(2,0)) { 795 if (nullptr == fFunctions.fDrawRangeElements) { 796 RETURN_FALSE_INTERFACE; 797 } 798 } else if (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,0)) { 799 if (nullptr == fFunctions.fDrawRangeElements) { 800 RETURN_FALSE_INTERFACE; 801 } 802 } 803 804 if (kGL_GrGLStandard == fStandard) { 805 if (glVer >= GR_GL_VER(4,2) || fExtensions.has("GL_ARB_shader_image_load_store")) { 806 if (nullptr == fFunctions.fBindImageTexture || 807 nullptr == fFunctions.fMemoryBarrier) { 808 RETURN_FALSE_INTERFACE; 809 } 810 } 811 if (glVer >= GR_GL_VER(4,5) || fExtensions.has("GL_ARB_ES3_1_compatibility")) { 812 if (nullptr == fFunctions.fMemoryBarrierByRegion) { 813 RETURN_FALSE_INTERFACE; 814 } 815 } 816 } else if (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,1)) { 817 if (nullptr == fFunctions.fBindImageTexture || 818 nullptr == fFunctions.fMemoryBarrier || 819 nullptr == fFunctions.fMemoryBarrierByRegion) { 820 RETURN_FALSE_INTERFACE; 821 } 822 } 823 824 return true; 825} 826