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