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