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