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