LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/gpu/gl - GrGLInterface.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 551 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13