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