1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/gpu/gl/GrGLInterface.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,488 @@ 1.4 +/* 1.5 + * Copyright 2011 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 + 1.12 +#include "gl/GrGLInterface.h" 1.13 +#include "gl/GrGLExtensions.h" 1.14 +#include "gl/GrGLUtil.h" 1.15 + 1.16 +#include <stdio.h> 1.17 + 1.18 +#if GR_GL_PER_GL_FUNC_CALLBACK 1.19 +namespace { 1.20 +void GrGLDefaultInterfaceCallback(const GrGLInterface*) {} 1.21 +} 1.22 +#endif 1.23 + 1.24 +const GrGLInterface* GrGLInterfaceAddTestDebugMarker(const GrGLInterface* interface, 1.25 + GrGLInsertEventMarkerProc insertEventMarkerFn, 1.26 + GrGLPushGroupMarkerProc pushGroupMarkerFn, 1.27 + GrGLPopGroupMarkerProc popGroupMarkerFn) { 1.28 + GrGLInterface* newInterface = GrGLInterface::NewClone(interface); 1.29 + 1.30 + if (!newInterface->fExtensions.has("GL_EXT_debug_marker")) { 1.31 + newInterface->fExtensions.add("GL_EXT_debug_marker"); 1.32 + } 1.33 + 1.34 + newInterface->fFunctions.fInsertEventMarker = insertEventMarkerFn; 1.35 + newInterface->fFunctions.fPushGroupMarker = pushGroupMarkerFn; 1.36 + newInterface->fFunctions.fPopGroupMarker = popGroupMarkerFn; 1.37 + 1.38 + return newInterface; 1.39 +} 1.40 + 1.41 +const GrGLInterface* GrGLInterfaceRemoveNVPR(const GrGLInterface* interface) { 1.42 + GrGLInterface* newInterface = GrGLInterface::NewClone(interface); 1.43 + 1.44 + newInterface->fExtensions.remove("GL_NV_path_rendering"); 1.45 + 1.46 + newInterface->fFunctions.fPathCommands = NULL; 1.47 + newInterface->fFunctions.fPathCoords = NULL; 1.48 + newInterface->fFunctions.fPathSubCommands = NULL; 1.49 + newInterface->fFunctions.fPathSubCoords = NULL; 1.50 + newInterface->fFunctions.fPathString = NULL; 1.51 + newInterface->fFunctions.fPathGlyphs = NULL; 1.52 + newInterface->fFunctions.fPathGlyphRange = NULL; 1.53 + newInterface->fFunctions.fWeightPaths = NULL; 1.54 + newInterface->fFunctions.fCopyPath = NULL; 1.55 + newInterface->fFunctions.fInterpolatePaths = NULL; 1.56 + newInterface->fFunctions.fTransformPath = NULL; 1.57 + newInterface->fFunctions.fPathParameteriv = NULL; 1.58 + newInterface->fFunctions.fPathParameteri = NULL; 1.59 + newInterface->fFunctions.fPathParameterfv = NULL; 1.60 + newInterface->fFunctions.fPathParameterf = NULL; 1.61 + newInterface->fFunctions.fPathDashArray = NULL; 1.62 + newInterface->fFunctions.fGenPaths = NULL; 1.63 + newInterface->fFunctions.fDeletePaths = NULL; 1.64 + newInterface->fFunctions.fIsPath = NULL; 1.65 + newInterface->fFunctions.fPathStencilFunc = NULL; 1.66 + newInterface->fFunctions.fPathStencilDepthOffset = NULL; 1.67 + newInterface->fFunctions.fStencilFillPath = NULL; 1.68 + newInterface->fFunctions.fStencilStrokePath = NULL; 1.69 + newInterface->fFunctions.fStencilFillPathInstanced = NULL; 1.70 + newInterface->fFunctions.fStencilStrokePathInstanced = NULL; 1.71 + newInterface->fFunctions.fPathCoverDepthFunc = NULL; 1.72 + newInterface->fFunctions.fPathColorGen = NULL; 1.73 + newInterface->fFunctions.fPathTexGen = NULL; 1.74 + newInterface->fFunctions.fPathFogGen = NULL; 1.75 + newInterface->fFunctions.fCoverFillPath = NULL; 1.76 + newInterface->fFunctions.fCoverStrokePath = NULL; 1.77 + newInterface->fFunctions.fCoverFillPathInstanced = NULL; 1.78 + newInterface->fFunctions.fCoverStrokePathInstanced = NULL; 1.79 + newInterface->fFunctions.fGetPathParameteriv = NULL; 1.80 + newInterface->fFunctions.fGetPathParameterfv = NULL; 1.81 + newInterface->fFunctions.fGetPathCommands = NULL; 1.82 + newInterface->fFunctions.fGetPathCoords = NULL; 1.83 + newInterface->fFunctions.fGetPathDashArray = NULL; 1.84 + newInterface->fFunctions.fGetPathMetrics = NULL; 1.85 + newInterface->fFunctions.fGetPathMetricRange = NULL; 1.86 + newInterface->fFunctions.fGetPathSpacing = NULL; 1.87 + newInterface->fFunctions.fGetPathColorGeniv = NULL; 1.88 + newInterface->fFunctions.fGetPathColorGenfv = NULL; 1.89 + newInterface->fFunctions.fGetPathTexGeniv = NULL; 1.90 + newInterface->fFunctions.fGetPathTexGenfv = NULL; 1.91 + newInterface->fFunctions.fIsPointInFillPath = NULL; 1.92 + newInterface->fFunctions.fIsPointInStrokePath = NULL; 1.93 + newInterface->fFunctions.fGetPathLength = NULL; 1.94 + newInterface->fFunctions.fPointAlongPath = NULL; 1.95 + 1.96 + return newInterface; 1.97 +} 1.98 + 1.99 +GrGLInterface::GrGLInterface() { 1.100 + fStandard = kNone_GrGLStandard; 1.101 + 1.102 +#if GR_GL_PER_GL_FUNC_CALLBACK 1.103 + fCallback = GrGLDefaultInterfaceCallback; 1.104 + fCallbackData = 0; 1.105 +#endif 1.106 +} 1.107 + 1.108 +GrGLInterface* GrGLInterface::NewClone(const GrGLInterface* interface) { 1.109 + SkASSERT(NULL != interface); 1.110 + 1.111 + GrGLInterface* clone = SkNEW(GrGLInterface); 1.112 + clone->fStandard = interface->fStandard; 1.113 + clone->fExtensions = interface->fExtensions; 1.114 + clone->fFunctions = interface->fFunctions; 1.115 +#if GR_GL_PER_GL_FUNC_CALLBACK 1.116 + clone->fCallback = interface->fCallback; 1.117 + clone->fCallbackData = interface->fCallbackData; 1.118 +#endif 1.119 + return clone; 1.120 +} 1.121 + 1.122 +bool GrGLInterface::validate() const { 1.123 + 1.124 + if (kNone_GrGLStandard == fStandard) { 1.125 + return false; 1.126 + } 1.127 + 1.128 + if (!fExtensions.isInitialized()) { 1.129 + return false; 1.130 + } 1.131 + 1.132 + // functions that are always required 1.133 + if (NULL == fFunctions.fActiveTexture || 1.134 + NULL == fFunctions.fAttachShader || 1.135 + NULL == fFunctions.fBindAttribLocation || 1.136 + NULL == fFunctions.fBindBuffer || 1.137 + NULL == fFunctions.fBindTexture || 1.138 + NULL == fFunctions.fBlendFunc || 1.139 + NULL == fFunctions.fBlendColor || // -> GL >= 1.4, ES >= 2.0 or extension 1.140 + NULL == fFunctions.fBufferData || 1.141 + NULL == fFunctions.fBufferSubData || 1.142 + NULL == fFunctions.fClear || 1.143 + NULL == fFunctions.fClearColor || 1.144 + NULL == fFunctions.fClearStencil || 1.145 + NULL == fFunctions.fColorMask || 1.146 + NULL == fFunctions.fCompileShader || 1.147 + NULL == fFunctions.fCopyTexSubImage2D || 1.148 + NULL == fFunctions.fCreateProgram || 1.149 + NULL == fFunctions.fCreateShader || 1.150 + NULL == fFunctions.fCullFace || 1.151 + NULL == fFunctions.fDeleteBuffers || 1.152 + NULL == fFunctions.fDeleteProgram || 1.153 + NULL == fFunctions.fDeleteShader || 1.154 + NULL == fFunctions.fDeleteTextures || 1.155 + NULL == fFunctions.fDepthMask || 1.156 + NULL == fFunctions.fDisable || 1.157 + NULL == fFunctions.fDisableVertexAttribArray || 1.158 + NULL == fFunctions.fDrawArrays || 1.159 + NULL == fFunctions.fDrawElements || 1.160 + NULL == fFunctions.fEnable || 1.161 + NULL == fFunctions.fEnableVertexAttribArray || 1.162 + NULL == fFunctions.fFrontFace || 1.163 + NULL == fFunctions.fGenBuffers || 1.164 + NULL == fFunctions.fGenTextures || 1.165 + NULL == fFunctions.fGetBufferParameteriv || 1.166 + NULL == fFunctions.fGenerateMipmap || 1.167 + NULL == fFunctions.fGetError || 1.168 + NULL == fFunctions.fGetIntegerv || 1.169 + NULL == fFunctions.fGetProgramInfoLog || 1.170 + NULL == fFunctions.fGetProgramiv || 1.171 + NULL == fFunctions.fGetShaderInfoLog || 1.172 + NULL == fFunctions.fGetShaderiv || 1.173 + NULL == fFunctions.fGetString || 1.174 + NULL == fFunctions.fGetUniformLocation || 1.175 + NULL == fFunctions.fLinkProgram || 1.176 + NULL == fFunctions.fLineWidth || 1.177 + NULL == fFunctions.fPixelStorei || 1.178 + NULL == fFunctions.fReadPixels || 1.179 + NULL == fFunctions.fScissor || 1.180 + NULL == fFunctions.fShaderSource || 1.181 + NULL == fFunctions.fStencilFunc || 1.182 + NULL == fFunctions.fStencilMask || 1.183 + NULL == fFunctions.fStencilOp || 1.184 + NULL == fFunctions.fTexImage2D || 1.185 + NULL == fFunctions.fTexParameteri || 1.186 + NULL == fFunctions.fTexParameteriv || 1.187 + NULL == fFunctions.fTexSubImage2D || 1.188 + NULL == fFunctions.fUniform1f || 1.189 + NULL == fFunctions.fUniform1i || 1.190 + NULL == fFunctions.fUniform1fv || 1.191 + NULL == fFunctions.fUniform1iv || 1.192 + NULL == fFunctions.fUniform2f || 1.193 + NULL == fFunctions.fUniform2i || 1.194 + NULL == fFunctions.fUniform2fv || 1.195 + NULL == fFunctions.fUniform2iv || 1.196 + NULL == fFunctions.fUniform3f || 1.197 + NULL == fFunctions.fUniform3i || 1.198 + NULL == fFunctions.fUniform3fv || 1.199 + NULL == fFunctions.fUniform3iv || 1.200 + NULL == fFunctions.fUniform4f || 1.201 + NULL == fFunctions.fUniform4i || 1.202 + NULL == fFunctions.fUniform4fv || 1.203 + NULL == fFunctions.fUniform4iv || 1.204 + NULL == fFunctions.fUniformMatrix2fv || 1.205 + NULL == fFunctions.fUniformMatrix3fv || 1.206 + NULL == fFunctions.fUniformMatrix4fv || 1.207 + NULL == fFunctions.fUseProgram || 1.208 + NULL == fFunctions.fVertexAttrib4fv || 1.209 + NULL == fFunctions.fVertexAttribPointer || 1.210 + NULL == fFunctions.fViewport || 1.211 + NULL == fFunctions.fBindFramebuffer || 1.212 + NULL == fFunctions.fBindRenderbuffer || 1.213 + NULL == fFunctions.fCheckFramebufferStatus || 1.214 + NULL == fFunctions.fDeleteFramebuffers || 1.215 + NULL == fFunctions.fDeleteRenderbuffers || 1.216 + NULL == fFunctions.fFinish || 1.217 + NULL == fFunctions.fFlush || 1.218 + NULL == fFunctions.fFramebufferRenderbuffer || 1.219 + NULL == fFunctions.fFramebufferTexture2D || 1.220 + NULL == fFunctions.fGetFramebufferAttachmentParameteriv || 1.221 + NULL == fFunctions.fGetRenderbufferParameteriv || 1.222 + NULL == fFunctions.fGenFramebuffers || 1.223 + NULL == fFunctions.fGenRenderbuffers || 1.224 + NULL == fFunctions.fRenderbufferStorage) { 1.225 + return false; 1.226 + } 1.227 + 1.228 + GrGLVersion glVer = GrGLGetVersion(this); 1.229 + 1.230 + bool isCoreProfile = false; 1.231 + if (kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,2)) { 1.232 + GrGLint profileMask; 1.233 + GR_GL_GetIntegerv(this, GR_GL_CONTEXT_PROFILE_MASK, &profileMask); 1.234 + isCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT); 1.235 + } 1.236 + 1.237 + // Now check that baseline ES/Desktop fns not covered above are present 1.238 + // and that we have fn pointers for any advertised fExtensions that we will 1.239 + // try to use. 1.240 + 1.241 + // these functions are part of ES2, we assume they are available 1.242 + // On the desktop we assume they are available if the extension 1.243 + // is present or GL version is high enough. 1.244 + if (kGLES_GrGLStandard == fStandard) { 1.245 + if (NULL == fFunctions.fStencilFuncSeparate || 1.246 + NULL == fFunctions.fStencilMaskSeparate || 1.247 + NULL == fFunctions.fStencilOpSeparate) { 1.248 + return false; 1.249 + } 1.250 + } else if (kGL_GrGLStandard == fStandard) { 1.251 + 1.252 + if (glVer >= GR_GL_VER(2,0)) { 1.253 + if (NULL == fFunctions.fStencilFuncSeparate || 1.254 + NULL == fFunctions.fStencilMaskSeparate || 1.255 + NULL == fFunctions.fStencilOpSeparate) { 1.256 + return false; 1.257 + } 1.258 + } 1.259 + if (glVer >= GR_GL_VER(3,0) && NULL == fFunctions.fBindFragDataLocation) { 1.260 + return false; 1.261 + } 1.262 + if (glVer >= GR_GL_VER(2,0) || fExtensions.has("GL_ARB_draw_buffers")) { 1.263 + if (NULL == fFunctions.fDrawBuffers) { 1.264 + return false; 1.265 + } 1.266 + } 1.267 + 1.268 + if (glVer >= GR_GL_VER(1,5) || fExtensions.has("GL_ARB_occlusion_query")) { 1.269 + if (NULL == fFunctions.fGenQueries || 1.270 + NULL == fFunctions.fDeleteQueries || 1.271 + NULL == fFunctions.fBeginQuery || 1.272 + NULL == fFunctions.fEndQuery || 1.273 + NULL == fFunctions.fGetQueryiv || 1.274 + NULL == fFunctions.fGetQueryObjectiv || 1.275 + NULL == fFunctions.fGetQueryObjectuiv) { 1.276 + return false; 1.277 + } 1.278 + } 1.279 + if (glVer >= GR_GL_VER(3,3) || 1.280 + fExtensions.has("GL_ARB_timer_query") || 1.281 + fExtensions.has("GL_EXT_timer_query")) { 1.282 + if (NULL == fFunctions.fGetQueryObjecti64v || 1.283 + NULL == fFunctions.fGetQueryObjectui64v) { 1.284 + return false; 1.285 + } 1.286 + } 1.287 + if (glVer >= GR_GL_VER(3,3) || fExtensions.has("GL_ARB_timer_query")) { 1.288 + if (NULL == fFunctions.fQueryCounter) { 1.289 + return false; 1.290 + } 1.291 + } 1.292 + if (!isCoreProfile) { 1.293 + if (NULL == fFunctions.fLoadIdentity || 1.294 + NULL == fFunctions.fLoadMatrixf || 1.295 + NULL == fFunctions.fMatrixMode || 1.296 + NULL == fFunctions.fTexGenfv || 1.297 + NULL == fFunctions.fTexGeni) { 1.298 + return false; 1.299 + } 1.300 + } 1.301 + if (fExtensions.has("GL_NV_path_rendering")) { 1.302 + if (NULL == fFunctions.fPathCommands || 1.303 + NULL == fFunctions.fPathCoords || 1.304 + NULL == fFunctions.fPathSubCommands || 1.305 + NULL == fFunctions.fPathSubCoords || 1.306 + NULL == fFunctions.fPathString || 1.307 + NULL == fFunctions.fPathGlyphs || 1.308 + NULL == fFunctions.fPathGlyphRange || 1.309 + NULL == fFunctions.fWeightPaths || 1.310 + NULL == fFunctions.fCopyPath || 1.311 + NULL == fFunctions.fInterpolatePaths || 1.312 + NULL == fFunctions.fTransformPath || 1.313 + NULL == fFunctions.fPathParameteriv || 1.314 + NULL == fFunctions.fPathParameteri || 1.315 + NULL == fFunctions.fPathParameterfv || 1.316 + NULL == fFunctions.fPathParameterf || 1.317 + NULL == fFunctions.fPathDashArray || 1.318 + NULL == fFunctions.fGenPaths || 1.319 + NULL == fFunctions.fDeletePaths || 1.320 + NULL == fFunctions.fIsPath || 1.321 + NULL == fFunctions.fPathStencilFunc || 1.322 + NULL == fFunctions.fPathStencilDepthOffset || 1.323 + NULL == fFunctions.fStencilFillPath || 1.324 + NULL == fFunctions.fStencilStrokePath || 1.325 + NULL == fFunctions.fStencilFillPathInstanced || 1.326 + NULL == fFunctions.fStencilStrokePathInstanced || 1.327 + NULL == fFunctions.fPathCoverDepthFunc || 1.328 + NULL == fFunctions.fPathColorGen || 1.329 + NULL == fFunctions.fPathTexGen || 1.330 + NULL == fFunctions.fPathFogGen || 1.331 + NULL == fFunctions.fCoverFillPath || 1.332 + NULL == fFunctions.fCoverStrokePath || 1.333 + NULL == fFunctions.fCoverFillPathInstanced || 1.334 + NULL == fFunctions.fCoverStrokePathInstanced || 1.335 + NULL == fFunctions.fGetPathParameteriv || 1.336 + NULL == fFunctions.fGetPathParameterfv || 1.337 + NULL == fFunctions.fGetPathCommands || 1.338 + NULL == fFunctions.fGetPathCoords || 1.339 + NULL == fFunctions.fGetPathDashArray || 1.340 + NULL == fFunctions.fGetPathMetrics || 1.341 + NULL == fFunctions.fGetPathMetricRange || 1.342 + NULL == fFunctions.fGetPathSpacing || 1.343 + NULL == fFunctions.fGetPathColorGeniv || 1.344 + NULL == fFunctions.fGetPathColorGenfv || 1.345 + NULL == fFunctions.fGetPathTexGeniv || 1.346 + NULL == fFunctions.fGetPathTexGenfv || 1.347 + NULL == fFunctions.fIsPointInFillPath || 1.348 + NULL == fFunctions.fIsPointInStrokePath || 1.349 + NULL == fFunctions.fGetPathLength || 1.350 + NULL == fFunctions.fPointAlongPath) { 1.351 + return false; 1.352 + } 1.353 + } 1.354 + } 1.355 + 1.356 + // optional function on desktop before 1.3 1.357 + if (kGL_GrGLStandard != fStandard || 1.358 + (glVer >= GR_GL_VER(1,3)) || 1.359 + fExtensions.has("GL_ARB_texture_compression")) { 1.360 + if (NULL == fFunctions.fCompressedTexImage2D) { 1.361 + return false; 1.362 + } 1.363 + } 1.364 + 1.365 + // part of desktop GL, but not ES 1.366 + if (kGL_GrGLStandard == fStandard && 1.367 + (NULL == fFunctions.fGetTexLevelParameteriv || 1.368 + NULL == fFunctions.fDrawBuffer || 1.369 + NULL == fFunctions.fReadBuffer)) { 1.370 + return false; 1.371 + } 1.372 + 1.373 + // GL_EXT_texture_storage is part of desktop 4.2 1.374 + // There is a desktop ARB extension and an ES+desktop EXT extension 1.375 + if (kGL_GrGLStandard == fStandard) { 1.376 + if (glVer >= GR_GL_VER(4,2) || 1.377 + fExtensions.has("GL_ARB_texture_storage") || 1.378 + fExtensions.has("GL_EXT_texture_storage")) { 1.379 + if (NULL == fFunctions.fTexStorage2D) { 1.380 + return false; 1.381 + } 1.382 + } 1.383 + } else if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_texture_storage")) { 1.384 + if (NULL == fFunctions.fTexStorage2D) { 1.385 + return false; 1.386 + } 1.387 + } 1.388 + 1.389 + if (fExtensions.has("GL_EXT_discard_framebuffer")) { 1.390 +// FIXME: Remove this once Chromium is updated to provide this function 1.391 +#if 0 1.392 + if (NULL == fFunctions.fDiscardFramebuffer) { 1.393 + return false; 1.394 + } 1.395 +#endif 1.396 + } 1.397 + 1.398 + // FBO MSAA 1.399 + if (kGL_GrGLStandard == fStandard) { 1.400 + // GL 3.0 and the ARB extension have multisample + blit 1.401 + if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_ARB_framebuffer_object")) { 1.402 + if (NULL == fFunctions.fRenderbufferStorageMultisample || 1.403 + NULL == fFunctions.fBlitFramebuffer) { 1.404 + return false; 1.405 + } 1.406 + } else { 1.407 + if (fExtensions.has("GL_EXT_framebuffer_blit") && 1.408 + NULL == fFunctions.fBlitFramebuffer) { 1.409 + return false; 1.410 + } 1.411 + if (fExtensions.has("GL_EXT_framebuffer_multisample") && 1.412 + NULL == fFunctions.fRenderbufferStorageMultisample) { 1.413 + return false; 1.414 + } 1.415 + } 1.416 + } else { 1.417 + if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_CHROMIUM_framebuffer_multisample")) { 1.418 + if (NULL == fFunctions.fRenderbufferStorageMultisample || 1.419 + NULL == fFunctions.fBlitFramebuffer) { 1.420 + return false; 1.421 + } 1.422 + } 1.423 + if (fExtensions.has("GL_APPLE_framebuffer_multisample")) { 1.424 + if (NULL == fFunctions.fRenderbufferStorageMultisampleES2APPLE || 1.425 + NULL == fFunctions.fResolveMultisampleFramebuffer) { 1.426 + return false; 1.427 + } 1.428 + } 1.429 + if (fExtensions.has("GL_IMG_multisampled_render_to_texture") || 1.430 + fExtensions.has("GL_EXT_multisampled_render_to_texture")) { 1.431 + if (NULL == fFunctions.fRenderbufferStorageMultisampleES2EXT || 1.432 + NULL == fFunctions.fFramebufferTexture2DMultisample) { 1.433 + return false; 1.434 + } 1.435 + } 1.436 + } 1.437 + 1.438 + // On ES buffer mapping is an extension. On Desktop 1.439 + // buffer mapping was part of original VBO extension 1.440 + // which we require. 1.441 + if (kGL_GrGLStandard == fStandard || fExtensions.has("GL_OES_mapbuffer")) { 1.442 + if (NULL == fFunctions.fMapBuffer || 1.443 + NULL == fFunctions.fUnmapBuffer) { 1.444 + return false; 1.445 + } 1.446 + } 1.447 + 1.448 + // Dual source blending 1.449 + if (kGL_GrGLStandard == fStandard && 1.450 + (glVer >= GR_GL_VER(3,3) || fExtensions.has("GL_ARB_blend_func_extended"))) { 1.451 + if (NULL == fFunctions.fBindFragDataLocationIndexed) { 1.452 + return false; 1.453 + } 1.454 + } 1.455 + 1.456 + // glGetStringi was added in version 3.0 of both desktop and ES. 1.457 + if (glVer >= GR_GL_VER(3, 0)) { 1.458 + if (NULL == fFunctions.fGetStringi) { 1.459 + return false; 1.460 + } 1.461 + } 1.462 + 1.463 + if (kGL_GrGLStandard == fStandard) { 1.464 + if (glVer >= GR_GL_VER(3, 0) || fExtensions.has("GL_ARB_vertex_array_object")) { 1.465 + if (NULL == fFunctions.fBindVertexArray || 1.466 + NULL == fFunctions.fDeleteVertexArrays || 1.467 + NULL == fFunctions.fGenVertexArrays) { 1.468 + return false; 1.469 + } 1.470 + } 1.471 + } else { 1.472 + if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_OES_vertex_array_object")) { 1.473 + if (NULL == fFunctions.fBindVertexArray || 1.474 + NULL == fFunctions.fDeleteVertexArrays || 1.475 + NULL == fFunctions.fGenVertexArrays) { 1.476 + return false; 1.477 + } 1.478 + } 1.479 + } 1.480 + 1.481 +#if 0 1.482 + if (fExtensions.has("GL_EXT_debug_marker")) { 1.483 + if (NULL == fFunctions.fInsertEventMarker || 1.484 + NULL == fFunctions.fPushGroupMarker || 1.485 + NULL == fFunctions.fPopGroupMarker) { 1.486 + return false; 1.487 + } 1.488 + } 1.489 +#endif 1.490 + return true; 1.491 +}