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 15 GrGLInterface::GrGLInterface() { 16 fStandard = kNone_GrGLStandard; 17 } 18 19 #ifdef SK_DEBUG 20 static int kIsDebug = 1; 21 #else 22 static int kIsDebug = 0; 23 #endif 24 25 #define RETURN_FALSE_INTERFACE \ 26 if (kIsDebug) { SkDebugf("%s:%d GrGLInterface::validate() failed.\n", __FILE__, __LINE__); } \ 27 return false; 28 29 bool GrGLInterface::validate() const { 30 31 if (kNone_GrGLStandard == fStandard) { 32 RETURN_FALSE_INTERFACE 33 } 34 35 if (!fExtensions.isInitialized()) { 36 RETURN_FALSE_INTERFACE 37 } 38 39 // functions that are always required 40 if (!fFunctions.fActiveTexture || 41 !fFunctions.fAttachShader || 42 !fFunctions.fBindAttribLocation || 43 !fFunctions.fBindBuffer || 44 !fFunctions.fBindTexture || 45 !fFunctions.fBlendColor || // -> GL >= 1.4 or extension, ES >= 2.0 46 !fFunctions.fBlendEquation || // -> GL >= 1.4 or extension, ES >= 2.0 47 !fFunctions.fBlendFunc || 48 !fFunctions.fBufferData || 49 !fFunctions.fBufferSubData || 50 !fFunctions.fClear || 51 !fFunctions.fClearColor || 52 !fFunctions.fClearStencil || 53 !fFunctions.fColorMask || 54 !fFunctions.fCompileShader || 55 !fFunctions.fCompressedTexImage2D || 56 !fFunctions.fCompressedTexSubImage2D || 57 !fFunctions.fCopyTexSubImage2D || 58 !fFunctions.fCreateProgram || 59 !fFunctions.fCreateShader || 60 !fFunctions.fCullFace || 61 !fFunctions.fDeleteBuffers || 62 !fFunctions.fDeleteProgram || 63 !fFunctions.fDeleteShader || 64 !fFunctions.fDeleteTextures || 65 !fFunctions.fDepthMask || 66 !fFunctions.fDisable || 67 !fFunctions.fDisableVertexAttribArray || 68 !fFunctions.fDrawArrays || 69 !fFunctions.fDrawElements || 70 !fFunctions.fEnable || 71 !fFunctions.fEnableVertexAttribArray || 72 !fFunctions.fFrontFace || 73 !fFunctions.fGenBuffers || 74 !fFunctions.fGenTextures || 75 !fFunctions.fGetBufferParameteriv || 76 !fFunctions.fGenerateMipmap || 77 !fFunctions.fGetError || 78 !fFunctions.fGetIntegerv || 79 !fFunctions.fGetProgramInfoLog || 80 !fFunctions.fGetProgramiv || 81 !fFunctions.fGetShaderInfoLog || 82 !fFunctions.fGetShaderiv || 83 !fFunctions.fGetString || 84 !fFunctions.fGetUniformLocation || 85 !fFunctions.fIsTexture || 86 !fFunctions.fLinkProgram || 87 !fFunctions.fLineWidth || 88 !fFunctions.fPixelStorei || 89 !fFunctions.fReadPixels || 90 !fFunctions.fScissor || 91 !fFunctions.fShaderSource || 92 !fFunctions.fStencilFunc || 93 !fFunctions.fStencilFuncSeparate || 94 !fFunctions.fStencilMask || 95 !fFunctions.fStencilMaskSeparate || 96 !fFunctions.fStencilOp || 97 !fFunctions.fStencilOpSeparate || 98 !fFunctions.fTexImage2D || 99 !fFunctions.fTexParameteri || 100 !fFunctions.fTexParameteriv || 101 !fFunctions.fTexSubImage2D || 102 !fFunctions.fUniform1f || 103 !fFunctions.fUniform1i || 104 !fFunctions.fUniform1fv || 105 !fFunctions.fUniform1iv || 106 !fFunctions.fUniform2f || 107 !fFunctions.fUniform2i || 108 !fFunctions.fUniform2fv || 109 !fFunctions.fUniform2iv || 110 !fFunctions.fUniform3f || 111 !fFunctions.fUniform3i || 112 !fFunctions.fUniform3fv || 113 !fFunctions.fUniform3iv || 114 !fFunctions.fUniform4f || 115 !fFunctions.fUniform4i || 116 !fFunctions.fUniform4fv || 117 !fFunctions.fUniform4iv || 118 !fFunctions.fUniformMatrix2fv || 119 !fFunctions.fUniformMatrix3fv || 120 !fFunctions.fUniformMatrix4fv || 121 !fFunctions.fUseProgram || 122 !fFunctions.fVertexAttrib1f || 123 !fFunctions.fVertexAttrib2fv || 124 !fFunctions.fVertexAttrib3fv || 125 !fFunctions.fVertexAttrib4fv || 126 !fFunctions.fVertexAttribPointer || 127 !fFunctions.fViewport || 128 !fFunctions.fBindFramebuffer || 129 !fFunctions.fBindRenderbuffer || 130 !fFunctions.fCheckFramebufferStatus || 131 !fFunctions.fDeleteFramebuffers || 132 !fFunctions.fDeleteRenderbuffers || 133 !fFunctions.fFinish || 134 !fFunctions.fFlush || 135 !fFunctions.fFramebufferRenderbuffer || 136 !fFunctions.fFramebufferTexture2D || 137 !fFunctions.fGetFramebufferAttachmentParameteriv || 138 !fFunctions.fGetRenderbufferParameteriv || 139 !fFunctions.fGenFramebuffers || 140 !fFunctions.fGenRenderbuffers || 141 !fFunctions.fRenderbufferStorage) { 142 RETURN_FALSE_INTERFACE 143 } 144 145 GrGLVersion glVer = GrGLGetVersion(this); 146 if (GR_GL_INVALID_VER == glVer) { 147 RETURN_FALSE_INTERFACE 148 } 149 150 // Now check that baseline ES/Desktop fns not covered above are present 151 // and that we have fn pointers for any advertised fExtensions that we will 152 // try to use. 153 154 // these functions are part of ES2, we assume they are available 155 // On the desktop we assume they are available if the extension 156 // is present or GL version is high enough. 157 if (kGL_GrGLStandard == fStandard) { 158 if (glVer >= GR_GL_VER(3,0) && !fFunctions.fBindFragDataLocation) { 159 RETURN_FALSE_INTERFACE 160 } 161 162 if (glVer >= GR_GL_VER(3,3) || 163 fExtensions.has("GL_ARB_timer_query") || 164 fExtensions.has("GL_EXT_timer_query")) { 165 if (!fFunctions.fGetQueryObjecti64v || 166 !fFunctions.fGetQueryObjectui64v) { 167 RETURN_FALSE_INTERFACE 168 } 169 } 170 if (glVer >= GR_GL_VER(3,3) || fExtensions.has("GL_ARB_timer_query")) { 171 if (!fFunctions.fQueryCounter) { 172 RETURN_FALSE_INTERFACE 173 } 174 } 175 } 176 177 // part of desktop GL, but not ES 178 if (kGL_GrGLStandard == fStandard && 179 (!fFunctions.fDrawBuffer || 180 !fFunctions.fPolygonMode)) { 181 RETURN_FALSE_INTERFACE 182 } 183 184 // ES 3.0 (or ES 2.0 extended) has glDrawBuffers but not glDrawBuffer 185 if (kGL_GrGLStandard == fStandard || glVer >= GR_GL_VER(3,0)) { 186 if (!fFunctions.fDrawBuffers) { 187 RETURN_FALSE_INTERFACE 188 } 189 } 190 191 if (kGL_GrGLStandard == fStandard || glVer >= GR_GL_VER(3,0)) { 192 if (!fFunctions.fReadBuffer) { 193 RETURN_FALSE_INTERFACE 194 } 195 } 196 197 // glGetTexLevelParameteriv was added to ES in 3.1. 198 if (kGL_GrGLStandard == fStandard || glVer >= GR_GL_VER(3,1)) { 199 if (!fFunctions.fGetTexLevelParameteriv) { 200 RETURN_FALSE_INTERFACE 201 } 202 } 203 204 // GL_EXT_texture_storage is part of desktop 4.2 205 // There is a desktop ARB extension and an ES+desktop EXT extension 206 if (kGL_GrGLStandard == fStandard) { 207 if (glVer >= GR_GL_VER(4,2) || 208 fExtensions.has("GL_ARB_texture_storage") || 209 fExtensions.has("GL_EXT_texture_storage")) { 210 if (!fFunctions.fTexStorage2D) { 211 RETURN_FALSE_INTERFACE 212 } 213 } 214 } else if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_texture_storage")) { 215 if (!fFunctions.fTexStorage2D) { 216 RETURN_FALSE_INTERFACE 217 } 218 } 219 220 // glTextureBarrier is part of desktop 4.5. There are also ARB and NV extensions. 221 if (kGL_GrGLStandard == fStandard) { 222 if (glVer >= GR_GL_VER(4,5) || 223 fExtensions.has("GL_ARB_texture_barrier") || 224 fExtensions.has("GL_NV_texture_barrier")) { 225 if (!fFunctions.fTextureBarrier) { 226 RETURN_FALSE_INTERFACE 227 } 228 } 229 } else if (fExtensions.has("GL_NV_texture_barrier")) { 230 if (!fFunctions.fTextureBarrier) { 231 RETURN_FALSE_INTERFACE 232 } 233 } 234 235 if (fExtensions.has("GL_KHR_blend_equation_advanced") || 236 fExtensions.has("GL_NV_blend_equation_advanced")) { 237 if (!fFunctions.fBlendBarrier) { 238 RETURN_FALSE_INTERFACE 239 } 240 } 241 242 if (fExtensions.has("GL_EXT_discard_framebuffer")) { 243 if (!fFunctions.fDiscardFramebuffer) { 244 RETURN_FALSE_INTERFACE 245 } 246 } 247 248 // Required since OpenGL 1.5 and ES 3.0 or with GL_EXT_occlusion_query_boolean 249 if (kGL_GrGLStandard == fStandard || glVer >= GR_GL_VER(3,0) || 250 fExtensions.has("GL_EXT_occlusion_query_boolean")) { 251 #if 0 // Not yet added to chrome's bindings. 252 if (!fFunctions.fGenQueries || 253 !fFunctions.fDeleteQueries || 254 !fFunctions.fBeginQuery || 255 !fFunctions.fEndQuery || 256 !fFunctions.fGetQueryiv || 257 !fFunctions.fGetQueryObjectuiv) { 258 RETURN_FALSE_INTERFACE 259 } 260 #endif 261 } 262 // glGetQueryObjectiv doesn't exist in ES. 263 if (kGL_GrGLStandard == fStandard && !fFunctions.fGetQueryObjectiv) { 264 RETURN_FALSE_INTERFACE 265 } 266 267 // FBO MSAA 268 if (kGL_GrGLStandard == fStandard) { 269 // GL 3.0 and the ARB extension have multisample + blit 270 if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_ARB_framebuffer_object")) { 271 if (!fFunctions.fRenderbufferStorageMultisample || 272 !fFunctions.fBlitFramebuffer) { 273 RETURN_FALSE_INTERFACE 274 } 275 } else { 276 if (fExtensions.has("GL_EXT_framebuffer_blit") && 277 !fFunctions.fBlitFramebuffer) { 278 RETURN_FALSE_INTERFACE 279 } 280 if (fExtensions.has("GL_EXT_framebuffer_multisample") && 281 !fFunctions.fRenderbufferStorageMultisample) { 282 RETURN_FALSE_INTERFACE 283 } 284 } 285 } else { 286 if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_CHROMIUM_framebuffer_multisample")) { 287 if (!fFunctions.fRenderbufferStorageMultisample || 288 !fFunctions.fBlitFramebuffer) { 289 RETURN_FALSE_INTERFACE 290 } 291 } else { 292 if (fExtensions.has("GL_ANGLE_framebuffer_multisample") && 293 !fFunctions.fRenderbufferStorageMultisample) { 294 RETURN_FALSE_INTERFACE 295 } 296 if (fExtensions.has("GL_ANGLE_framebuffer_blit") && 297 !fFunctions.fBlitFramebuffer) { 298 RETURN_FALSE_INTERFACE 299 } 300 } 301 if (fExtensions.has("GL_APPLE_framebuffer_multisample")) { 302 if (!fFunctions.fRenderbufferStorageMultisampleES2APPLE || 303 !fFunctions.fResolveMultisampleFramebuffer) { 304 RETURN_FALSE_INTERFACE 305 } 306 } 307 if (fExtensions.has("GL_IMG_multisampled_render_to_texture") || 308 fExtensions.has("GL_EXT_multisampled_render_to_texture")) { 309 if (!fFunctions.fRenderbufferStorageMultisampleES2EXT || 310 !fFunctions.fFramebufferTexture2DMultisample) { 311 RETURN_FALSE_INTERFACE 312 } 313 } 314 } 315 316 // On ES buffer mapping is an extension. On Desktop 317 // buffer mapping was part of original VBO extension 318 // which we require. 319 if (kGL_GrGLStandard == fStandard || fExtensions.has("GL_OES_mapbuffer")) { 320 if (!fFunctions.fMapBuffer || 321 !fFunctions.fUnmapBuffer) { 322 RETURN_FALSE_INTERFACE 323 } 324 } 325 326 // Dual source blending 327 if (kGL_GrGLStandard == fStandard) { 328 if (glVer >= GR_GL_VER(3,3) || fExtensions.has("GL_ARB_blend_func_extended")) { 329 if (!fFunctions.fBindFragDataLocationIndexed) { 330 RETURN_FALSE_INTERFACE 331 } 332 } 333 } else { 334 if (glVer >= GR_GL_VER(3,0) && fExtensions.has("GL_EXT_blend_func_extended")) { 335 if (!fFunctions.fBindFragDataLocation || 336 !fFunctions.fBindFragDataLocationIndexed) { 337 RETURN_FALSE_INTERFACE 338 } 339 } 340 } 341 342 343 // glGetStringi was added in version 3.0 of both desktop and ES. 344 if (glVer >= GR_GL_VER(3, 0)) { 345 if (!fFunctions.fGetStringi) { 346 RETURN_FALSE_INTERFACE 347 } 348 } 349 350 // glVertexAttribIPointer was added in version 3.0 of both desktop and ES. 351 if (glVer >= GR_GL_VER(3, 0)) { 352 if (!fFunctions.fVertexAttribIPointer) { 353 RETURN_FALSE_INTERFACE 354 } 355 } 356 357 if (kGL_GrGLStandard == fStandard) { 358 if (glVer >= GR_GL_VER(3,1)) { 359 if (!fFunctions.fTexBuffer) { 360 RETURN_FALSE_INTERFACE; 361 } 362 } 363 if (glVer >= GR_GL_VER(4,3)) { 364 if (!fFunctions.fTexBufferRange) { 365 RETURN_FALSE_INTERFACE; 366 } 367 } 368 } else { 369 if (glVer >= GR_GL_VER(3,2) || fExtensions.has("GL_OES_texture_buffer") || 370 fExtensions.has("GL_EXT_texture_buffer")) { 371 if (!fFunctions.fTexBuffer || 372 !fFunctions.fTexBufferRange) { 373 RETURN_FALSE_INTERFACE; 374 } 375 } 376 } 377 378 if (kGL_GrGLStandard == fStandard) { 379 if (glVer >= GR_GL_VER(3, 0) || fExtensions.has("GL_ARB_vertex_array_object")) { 380 if (!fFunctions.fBindVertexArray || 381 !fFunctions.fDeleteVertexArrays || 382 !fFunctions.fGenVertexArrays) { 383 RETURN_FALSE_INTERFACE 384 } 385 } 386 } else { 387 if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_OES_vertex_array_object")) { 388 if (!fFunctions.fBindVertexArray || 389 !fFunctions.fDeleteVertexArrays || 390 !fFunctions.fGenVertexArrays) { 391 RETURN_FALSE_INTERFACE 392 } 393 } 394 } 395 396 if (fExtensions.has("GL_EXT_debug_marker")) { 397 if (!fFunctions.fInsertEventMarker || 398 !fFunctions.fPushGroupMarker || 399 !fFunctions.fPopGroupMarker) { 400 RETURN_FALSE_INTERFACE 401 } 402 } 403 404 if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,3)) || 405 fExtensions.has("GL_ARB_invalidate_subdata")) { 406 if (!fFunctions.fInvalidateBufferData || 407 !fFunctions.fInvalidateBufferSubData || 408 !fFunctions.fInvalidateFramebuffer || 409 !fFunctions.fInvalidateSubFramebuffer || 410 !fFunctions.fInvalidateTexImage || 411 !fFunctions.fInvalidateTexSubImage) { 412 RETURN_FALSE_INTERFACE; 413 } 414 } else if (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,0)) { 415 // ES 3.0 adds the framebuffer functions but not the others. 416 if (!fFunctions.fInvalidateFramebuffer || 417 !fFunctions.fInvalidateSubFramebuffer) { 418 RETURN_FALSE_INTERFACE; 419 } 420 } 421 422 if (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_CHROMIUM_map_sub")) { 423 if (!fFunctions.fMapBufferSubData || 424 !fFunctions.fMapTexSubImage2D || 425 !fFunctions.fUnmapBufferSubData || 426 !fFunctions.fUnmapTexSubImage2D) { 427 RETURN_FALSE_INTERFACE; 428 } 429 } 430 431 // These functions are added to the 3.0 version of both GLES and GL. 432 if (glVer >= GR_GL_VER(3,0) || 433 (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_EXT_map_buffer_range")) || 434 (kGL_GrGLStandard == fStandard && fExtensions.has("GL_ARB_map_buffer_range"))) { 435 if (!fFunctions.fMapBufferRange || 436 !fFunctions.fFlushMappedBufferRange) { 437 RETURN_FALSE_INTERFACE; 438 } 439 } 440 441 if ((kGL_GrGLStandard == fStandard && 442 (glVer >= GR_GL_VER(3,2) || fExtensions.has("GL_ARB_texture_multisample"))) || 443 (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,1))) { 444 if (!fFunctions.fGetMultisamplefv) { 445 RETURN_FALSE_INTERFACE 446 } 447 } 448 449 if ((kGL_GrGLStandard == fStandard && 450 (glVer >= GR_GL_VER(4,3) || fExtensions.has("GL_ARB_program_interface_query"))) || 451 (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,1))) { 452 if (!fFunctions.fGetProgramResourceLocation) { 453 RETURN_FALSE_INTERFACE 454 } 455 } 456 457 if (kGLES_GrGLStandard == fStandard || glVer >= GR_GL_VER(4,1) || 458 fExtensions.has("GL_ARB_ES2_compatibility")) { 459 if (!fFunctions.fGetShaderPrecisionFormat) { 460 RETURN_FALSE_INTERFACE 461 } 462 } 463 464 if (fExtensions.has("GL_NV_path_rendering") || fExtensions.has("GL_CHROMIUM_path_rendering")) { 465 if (!fFunctions.fMatrixLoadf || 466 !fFunctions.fMatrixLoadIdentity || 467 !fFunctions.fPathCommands || 468 !fFunctions.fPathParameteri || 469 !fFunctions.fPathParameterf || 470 !fFunctions.fGenPaths || 471 !fFunctions.fDeletePaths || 472 !fFunctions.fIsPath || 473 !fFunctions.fPathStencilFunc || 474 !fFunctions.fStencilFillPath || 475 !fFunctions.fStencilStrokePath || 476 !fFunctions.fStencilFillPathInstanced || 477 !fFunctions.fStencilStrokePathInstanced || 478 !fFunctions.fCoverFillPath || 479 !fFunctions.fCoverStrokePath || 480 !fFunctions.fCoverFillPathInstanced || 481 !fFunctions.fCoverStrokePathInstanced 482 #if 0 483 // List of functions that Skia uses, but which have been added since the initial release 484 // of NV_path_rendering driver. We do not want to fail interface validation due to 485 // missing features, we will just not use the extension. 486 // Update this list -> update GrGLCaps::hasPathRenderingSupport too. 487 || !fFunctions.fStencilThenCoverFillPath || 488 !fFunctions.fStencilThenCoverStrokePath || 489 !fFunctions.fStencilThenCoverFillPathInstanced || 490 !fFunctions.fStencilThenCoverStrokePathInstanced || 491 !fFunctions.fProgramPathFragmentInputGen 492 #endif 493 ) { 494 RETURN_FALSE_INTERFACE 495 } 496 if (fExtensions.has("GL_CHROMIUM_path_rendering")) { 497 if (!fFunctions.fBindFragmentInputLocation) { 498 RETURN_FALSE_INTERFACE 499 } 500 } 501 } 502 503 if (fExtensions.has("GL_EXT_raster_multisample")) { 504 if (!fFunctions.fRasterSamples) { 505 RETURN_FALSE_INTERFACE 506 } 507 } 508 509 if (fExtensions.has("GL_NV_framebuffer_mixed_samples") || 510 fExtensions.has("GL_CHROMIUM_framebuffer_mixed_samples")) { 511 if (!fFunctions.fCoverageModulation) { 512 RETURN_FALSE_INTERFACE 513 } 514 } 515 516 if (kGL_GrGLStandard == fStandard) { 517 if (glVer >= GR_GL_VER(3,1) || 518 fExtensions.has("GL_EXT_draw_instanced") || fExtensions.has("GL_ARB_draw_instanced")) { 519 if (!fFunctions.fDrawArraysInstanced || 520 !fFunctions.fDrawElementsInstanced) { 521 RETURN_FALSE_INTERFACE 522 } 523 } 524 } else if (kGLES_GrGLStandard == fStandard) { 525 if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_draw_instanced")) { 526 if (!fFunctions.fDrawArraysInstanced || 527 !fFunctions.fDrawElementsInstanced) { 528 RETURN_FALSE_INTERFACE 529 } 530 } 531 } 532 533 if (kGL_GrGLStandard == fStandard) { 534 if (glVer >= GR_GL_VER(3,2) || fExtensions.has("GL_ARB_instanced_arrays")) { 535 if (!fFunctions.fVertexAttribDivisor) { 536 RETURN_FALSE_INTERFACE 537 } 538 } 539 } else if (kGLES_GrGLStandard == fStandard) { 540 if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_instanced_arrays")) { 541 if (!fFunctions.fVertexAttribDivisor) { 542 RETURN_FALSE_INTERFACE 543 } 544 } 545 } 546 547 if ((kGL_GrGLStandard == fStandard && 548 (glVer >= GR_GL_VER(4,0) || fExtensions.has("GL_ARB_draw_indirect"))) || 549 (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,1))) { 550 if (!fFunctions.fDrawArraysIndirect || 551 !fFunctions.fDrawElementsIndirect) { 552 RETURN_FALSE_INTERFACE 553 } 554 } 555 556 if ((kGL_GrGLStandard == fStandard && 557 (glVer >= GR_GL_VER(4,3) || fExtensions.has("GL_ARB_multi_draw_indirect"))) || 558 (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_EXT_multi_draw_indirect"))) { 559 if (!fFunctions.fMultiDrawArraysIndirect || 560 !fFunctions.fMultiDrawElementsIndirect) { 561 RETURN_FALSE_INTERFACE 562 } 563 } 564 565 if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,3)) || 566 fExtensions.has("GL_KHR_debug")) { 567 if (!fFunctions.fDebugMessageControl || 568 !fFunctions.fDebugMessageInsert || 569 !fFunctions.fDebugMessageCallback || 570 !fFunctions.fGetDebugMessageLog || 571 !fFunctions.fPushDebugGroup || 572 !fFunctions.fPopDebugGroup || 573 !fFunctions.fObjectLabel) { 574 RETURN_FALSE_INTERFACE 575 } 576 } 577 578 if (fExtensions.has("GL_EXT_window_rectangles")) { 579 if (!fFunctions.fWindowRectangles) { 580 RETURN_FALSE_INTERFACE 581 } 582 } 583 584 if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,0)) || 585 fExtensions.has("GL_ARB_sample_shading")) { 586 if (!fFunctions.fMinSampleShading) { 587 RETURN_FALSE_INTERFACE 588 } 589 } else if (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_OES_sample_shading")) { 590 if (!fFunctions.fMinSampleShading) { 591 RETURN_FALSE_INTERFACE 592 } 593 } 594 595 if (kGL_GrGLStandard == fStandard) { 596 if (glVer >= GR_GL_VER(3, 2) || fExtensions.has("GL_ARB_sync")) { 597 if (!fFunctions.fFenceSync || 598 !fFunctions.fIsSync || 599 !fFunctions.fClientWaitSync || 600 !fFunctions.fWaitSync || 601 !fFunctions.fDeleteSync) { 602 RETURN_FALSE_INTERFACE 603 } 604 } 605 } else if (kGLES_GrGLStandard == fStandard) { 606 if (glVer >= GR_GL_VER(3, 0) || fExtensions.has("GL_APPLE_sync")) { 607 if (!fFunctions.fFenceSync || 608 !fFunctions.fIsSync || 609 !fFunctions.fClientWaitSync || 610 !fFunctions.fWaitSync || 611 !fFunctions.fDeleteSync) { 612 RETURN_FALSE_INTERFACE 613 } 614 } 615 } 616 617 if (fExtensions.has("EGL_KHR_image") || fExtensions.has("EGL_KHR_image_base")) { 618 if (!fFunctions.fEGLCreateImage || 619 !fFunctions.fEGLDestroyImage) { 620 RETURN_FALSE_INTERFACE 621 } 622 } 623 624 // glDrawRangeElements was added to ES in 3.0. 625 if (kGL_GrGLStandard == fStandard || glVer >= GR_GL_VER(3,0)) { 626 if (!fFunctions.fDrawRangeElements) { 627 RETURN_FALSE_INTERFACE; 628 } 629 } 630 631 // getInternalformativ was added in GL 4.2, ES 3.0, and with extension ARB_internalformat_query 632 if ((kGL_GrGLStandard == fStandard && 633 (glVer >= GR_GL_VER(4,2) || fExtensions.has("GL_ARB_internalformat_query"))) || 634 (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,0))) { 635 if (!fFunctions.fGetInternalformativ) { 636 RETURN_FALSE_INTERFACE; 637 } 638 } 639 640 if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,1)) || 641 (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,0))) { 642 if (!fFunctions.fGetProgramBinary || 643 !fFunctions.fProgramBinary || 644 !fFunctions.fProgramParameteri) { 645 RETURN_FALSE_INTERFACE; 646 } 647 } 648 649 return true; 650 } 651