blob: 7e557da4f5f98853ccf7a1ac5f7b269ef10c9894 [file] [log] [blame]
twiz@google.com59a190b2011-03-14 21:23:01 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * 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.
twiz@google.com59a190b2011-03-14 21:23:01 +00006 */
7
8
tomhudson@google.com6bf38b52012-02-14 15:11:59 +00009#include "gl/GrGLInterface.h"
bsalomon@google.com1744f972013-02-26 21:46:32 +000010#include "gl/GrGLExtensions.h"
11#include "gl/GrGLUtil.h"
twiz@google.com59a190b2011-03-14 21:23:01 +000012
13#include <stdio.h>
14
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +000015SK_DEFINE_INST_COUNT(GrGLInterface)
16
bsalomon@google.com56bfc5a2011-09-01 13:28:16 +000017#if GR_GL_PER_GL_FUNC_CALLBACK
18namespace {
19void GrGLDefaultInterfaceCallback(const GrGLInterface*) {}
20}
21#endif
22
bsalomon@google.com0b77d682011-08-19 13:28:54 +000023GrGLInterface::GrGLInterface() {
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000024 fBindingsExported = kNone_GrGLBinding;
bsalomon@google.com0b77d682011-08-19 13:28:54 +000025
bsalomon@google.com56bfc5a2011-09-01 13:28:16 +000026#if GR_GL_PER_GL_FUNC_CALLBACK
27 fCallback = GrGLDefaultInterfaceCallback;
28 fCallbackData = 0;
29#endif
bsalomon@google.com0b77d682011-08-19 13:28:54 +000030}
31
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000032bool GrGLInterface::validate(GrGLBinding binding) const {
bsalomon@google.com0b77d682011-08-19 13:28:54 +000033
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000034 // kNone must be 0 so that the check we're about to do can never succeed if
35 // binding == kNone.
36 GR_STATIC_ASSERT(kNone_GrGLBinding == 0);
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000037
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000038 if (0 == (binding & fBindingsExported)) {
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000039 return false;
40 }
skia.committer@gmail.com12eea2b2013-02-27 07:10:10 +000041
bsalomon@google.com1744f972013-02-26 21:46:32 +000042 GrGLExtensions extensions;
43 if (!extensions.init(binding, this)) {
44 return false;
45 }
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000046
47 // functions that are always required
48 if (NULL == fActiveTexture ||
49 NULL == fAttachShader ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000050 NULL == fBindAttribLocation ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000051 NULL == fBindBuffer ||
52 NULL == fBindTexture ||
53 NULL == fBlendFunc ||
robertphillips@google.come7884302012-04-18 14:39:58 +000054 NULL == fBlendColor || // -> GL >= 1.4, ES >= 2.0 or extension
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000055 NULL == fBufferData ||
56 NULL == fBufferSubData ||
57 NULL == fClear ||
58 NULL == fClearColor ||
59 NULL == fClearStencil ||
60 NULL == fColorMask ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000061 NULL == fCompileShader ||
commit-bot@chromium.org98168bb2013-04-11 22:00:34 +000062 NULL == fCopyTexSubImage2D ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000063 NULL == fCreateProgram ||
64 NULL == fCreateShader ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000065 NULL == fCullFace ||
66 NULL == fDeleteBuffers ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000067 NULL == fDeleteProgram ||
68 NULL == fDeleteShader ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000069 NULL == fDeleteTextures ||
70 NULL == fDepthMask ||
71 NULL == fDisable ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000072 NULL == fDisableVertexAttribArray ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000073 NULL == fDrawArrays ||
74 NULL == fDrawElements ||
75 NULL == fEnable ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000076 NULL == fEnableVertexAttribArray ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000077 NULL == fFrontFace ||
78 NULL == fGenBuffers ||
79 NULL == fGenTextures ||
80 NULL == fGetBufferParameteriv ||
commit-bot@chromium.orgcffff792013-07-26 16:36:04 +000081#ifndef SKIA_IGNORE_GPU_MIPMAPS
82 NULL == fGenerateMipmap ||
83#endif
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000084 NULL == fGetError ||
85 NULL == fGetIntegerv ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000086 NULL == fGetProgramInfoLog ||
87 NULL == fGetProgramiv ||
88 NULL == fGetShaderInfoLog ||
89 NULL == fGetShaderiv ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000090 NULL == fGetString ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000091 NULL == fGetUniformLocation ||
92 NULL == fLinkProgram ||
commit-bot@chromium.org941df4f2013-08-20 20:54:08 +000093 NULL == fLineWidth ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000094 NULL == fPixelStorei ||
95 NULL == fReadPixels ||
96 NULL == fScissor ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000097 NULL == fShaderSource ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000098 NULL == fStencilFunc ||
99 NULL == fStencilMask ||
100 NULL == fStencilOp ||
101 NULL == fTexImage2D ||
102 NULL == fTexParameteri ||
bsalomon@google.com4d063de2012-05-31 17:59:23 +0000103 NULL == fTexParameteriv ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000104 NULL == fTexSubImage2D ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000105 NULL == fUniform1f ||
106 NULL == fUniform1i ||
107 NULL == fUniform1fv ||
108 NULL == fUniform1iv ||
109 NULL == fUniform2f ||
110 NULL == fUniform2i ||
111 NULL == fUniform2fv ||
112 NULL == fUniform2iv ||
113 NULL == fUniform3f ||
114 NULL == fUniform3i ||
115 NULL == fUniform3fv ||
116 NULL == fUniform3iv ||
117 NULL == fUniform4f ||
118 NULL == fUniform4i ||
119 NULL == fUniform4fv ||
120 NULL == fUniform4iv ||
121 NULL == fUniformMatrix2fv ||
122 NULL == fUniformMatrix3fv ||
123 NULL == fUniformMatrix4fv ||
124 NULL == fUseProgram ||
125 NULL == fVertexAttrib4fv ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000126 NULL == fVertexAttribPointer ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000127 NULL == fViewport ||
128 NULL == fBindFramebuffer ||
129 NULL == fBindRenderbuffer ||
130 NULL == fCheckFramebufferStatus ||
131 NULL == fDeleteFramebuffers ||
132 NULL == fDeleteRenderbuffers ||
bsalomon@google.com373a6632011-10-19 20:43:20 +0000133 NULL == fFinish ||
134 NULL == fFlush ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000135 NULL == fFramebufferRenderbuffer ||
136 NULL == fFramebufferTexture2D ||
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000137 NULL == fGetFramebufferAttachmentParameteriv ||
138 NULL == fGetRenderbufferParameteriv ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000139 NULL == fGenFramebuffers ||
140 NULL == fGenRenderbuffers ||
141 NULL == fRenderbufferStorage) {
142 return false;
143 }
144
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000145 GrGLVersion glVer = GrGLGetVersion(this);
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000146
bsalomon@google.comf714d512013-08-30 18:25:21 +0000147 bool isCoreProfile = false;
148 if (kDesktop_GrGLBinding == binding && glVer >= GR_GL_VER(3,2)) {
149 GrGLint profileMask;
150 GR_GL_GetIntegerv(this, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
151 isCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT);
152 }
153
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000154 // Now check that baseline ES/Desktop fns not covered above are present
155 // and that we have fn pointers for any advertised extensions that we will
156 // try to use.
157
158 // these functions are part of ES2, we assume they are available
159 // On the desktop we assume they are available if the extension
160 // is present or GL version is high enough.
bsalomon@google.com791816a2013-08-15 18:54:39 +0000161 if (kES_GrGLBinding == binding) {
robertphillips@google.come7884302012-04-18 14:39:58 +0000162 if (NULL == fStencilFuncSeparate ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000163 NULL == fStencilMaskSeparate ||
164 NULL == fStencilOpSeparate) {
165 return false;
166 }
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000167 } else if (kDesktop_GrGLBinding == binding) {
robertphillips@google.come7884302012-04-18 14:39:58 +0000168
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000169 if (glVer >= GR_GL_VER(2,0)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000170 if (NULL == fStencilFuncSeparate ||
171 NULL == fStencilMaskSeparate ||
172 NULL == fStencilOpSeparate) {
173 return false;
174 }
175 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000176 if (glVer >= GR_GL_VER(3,0) && NULL == fBindFragDataLocation) {
bsalomon@google.combc5cf512011-09-21 16:21:07 +0000177 return false;
178 }
bsalomon@google.com1744f972013-02-26 21:46:32 +0000179 if (glVer >= GR_GL_VER(2,0) || extensions.has("GL_ARB_draw_buffers")) {
bsalomon@google.comd32c5f52011-08-02 19:29:03 +0000180 if (NULL == fDrawBuffers) {
181 return false;
182 }
183 }
robertphillips@google.come7884302012-04-18 14:39:58 +0000184
bsalomon@google.com1744f972013-02-26 21:46:32 +0000185 if (glVer >= GR_GL_VER(1,5) || extensions.has("GL_ARB_occlusion_query")) {
bsalomon@google.com373a6632011-10-19 20:43:20 +0000186 if (NULL == fGenQueries ||
187 NULL == fDeleteQueries ||
188 NULL == fBeginQuery ||
189 NULL == fEndQuery ||
190 NULL == fGetQueryiv ||
191 NULL == fGetQueryObjectiv ||
192 NULL == fGetQueryObjectuiv) {
193 return false;
194 }
195 }
196 if (glVer >= GR_GL_VER(3,3) ||
bsalomon@google.com1744f972013-02-26 21:46:32 +0000197 extensions.has("GL_ARB_timer_query") ||
198 extensions.has("GL_EXT_timer_query")) {
bsalomon@google.com373a6632011-10-19 20:43:20 +0000199 if (NULL == fGetQueryObjecti64v ||
200 NULL == fGetQueryObjectui64v) {
201 return false;
202 }
203 }
bsalomon@google.com1744f972013-02-26 21:46:32 +0000204 if (glVer >= GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) {
bsalomon@google.com373a6632011-10-19 20:43:20 +0000205 if (NULL == fQueryCounter) {
206 return false;
207 }
208 }
commit-bot@chromium.org46fbfe02013-08-30 15:52:12 +0000209 if (!isCoreProfile) {
210 if (NULL == fClientActiveTexture ||
211 NULL == fDisableClientState ||
212 NULL == fEnableClientState ||
213 NULL == fLoadIdentity ||
214 NULL == fLoadMatrixf ||
215 NULL == fMatrixMode ||
216 NULL == fTexGenf ||
217 NULL == fTexGenfv ||
218 NULL == fTexGeni ||
219 NULL == fVertexPointer) {
220 return false;
221 }
bsalomon@google.comfe11cb62012-06-06 15:17:54 +0000222 }
bsalomon@google.com1744f972013-02-26 21:46:32 +0000223 if (false && extensions.has("GL_NV_path_rendering")) {
bsalomon@google.comfe11cb62012-06-06 15:17:54 +0000224 if (NULL == fPathCommands ||
225 NULL == fPathCoords ||
226 NULL == fPathSubCommands ||
227 NULL == fPathSubCoords ||
228 NULL == fPathString ||
229 NULL == fPathGlyphs ||
230 NULL == fPathGlyphRange ||
231 NULL == fWeightPaths ||
232 NULL == fCopyPath ||
233 NULL == fInterpolatePaths ||
234 NULL == fTransformPath ||
235 NULL == fPathParameteriv ||
236 NULL == fPathParameteri ||
237 NULL == fPathParameterfv ||
238 NULL == fPathParameterf ||
239 NULL == fPathDashArray ||
240 NULL == fGenPaths ||
241 NULL == fDeletePaths ||
242 NULL == fIsPath ||
243 NULL == fPathStencilFunc ||
244 NULL == fPathStencilDepthOffset ||
245 NULL == fStencilFillPath ||
246 NULL == fStencilStrokePath ||
247 NULL == fStencilFillPathInstanced ||
248 NULL == fStencilStrokePathInstanced ||
249 NULL == fPathCoverDepthFunc ||
250 NULL == fPathColorGen ||
251 NULL == fPathTexGen ||
252 NULL == fPathFogGen ||
253 NULL == fCoverFillPath ||
254 NULL == fCoverStrokePath ||
255 NULL == fCoverFillPathInstanced ||
256 NULL == fCoverStrokePathInstanced ||
257 NULL == fGetPathParameteriv ||
258 NULL == fGetPathParameterfv ||
259 NULL == fGetPathCommands ||
260 NULL == fGetPathCoords ||
261 NULL == fGetPathDashArray ||
262 NULL == fGetPathMetrics ||
263 NULL == fGetPathMetricRange ||
264 NULL == fGetPathSpacing ||
265 NULL == fGetPathColorGeniv ||
266 NULL == fGetPathColorGenfv ||
267 NULL == fGetPathTexGeniv ||
268 NULL == fGetPathTexGenfv ||
269 NULL == fIsPointInFillPath ||
270 NULL == fIsPointInStrokePath ||
271 NULL == fGetPathLength ||
272 NULL == fPointAlongPath) {
273 return false;
274 }
275 }
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000276 }
277
278 // optional function on desktop before 1.3
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000279 if (kDesktop_GrGLBinding != binding ||
bsalomon@google.com1744f972013-02-26 21:46:32 +0000280 (glVer >= GR_GL_VER(1,3)) ||
281 extensions.has("GL_ARB_texture_compression")) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000282 if (NULL == fCompressedTexImage2D) {
283 return false;
284 }
285 }
286
bsalomon@google.comd32c5f52011-08-02 19:29:03 +0000287 // part of desktop GL, but not ES
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000288 if (kDesktop_GrGLBinding == binding &&
commit-bot@chromium.org941df4f2013-08-20 20:54:08 +0000289 (NULL == fGetTexLevelParameteriv ||
bsalomon@google.comc49d66b2011-08-03 14:22:30 +0000290 NULL == fDrawBuffer ||
291 NULL == fReadBuffer)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000292 return false;
293 }
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000294
bsalomon@google.com280e99f2012-01-05 16:17:38 +0000295 // GL_EXT_texture_storage is part of desktop 4.2
296 // There is a desktop ARB extension and an ES+desktop EXT extension
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000297 if (kDesktop_GrGLBinding == binding) {
bsalomon@google.combaa9ea12012-01-06 19:05:43 +0000298 if (glVer >= GR_GL_VER(4,2) ||
bsalomon@google.com1744f972013-02-26 21:46:32 +0000299 extensions.has("GL_ARB_texture_storage") ||
300 extensions.has("GL_EXT_texture_storage")) {
bsalomon@google.combaa9ea12012-01-06 19:05:43 +0000301 if (NULL == fTexStorage2D) {
302 return false;
303 }
304 }
commit-bot@chromium.org7a434a22013-08-21 14:01:56 +0000305 } else if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_EXT_texture_storage")) {
bsalomon@google.combaa9ea12012-01-06 19:05:43 +0000306 if (NULL == fTexStorage2D) {
307 return false;
308 }
bsalomon@google.com280e99f2012-01-05 16:17:38 +0000309 }
310
robertphillips@google.coma6ffb582013-04-29 16:50:17 +0000311 if (extensions.has("GL_EXT_discard_framebuffer")) {
312// FIXME: Remove this once Chromium is updated to provide this function
313#if 0
314 if (NULL == fDiscardFramebuffer) {
315 return false;
316 }
317#endif
318 }
319
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000320 // FBO MSAA
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000321 if (kDesktop_GrGLBinding == binding) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000322 // GL 3.0 and the ARB extension have multisample + blit
bsalomon@google.com1744f972013-02-26 21:46:32 +0000323 if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object")) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000324 if (NULL == fRenderbufferStorageMultisample ||
325 NULL == fBlitFramebuffer) {
326 return false;
327 }
328 } else {
bsalomon@google.com1744f972013-02-26 21:46:32 +0000329 if (extensions.has("GL_EXT_framebuffer_blit") &&
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000330 NULL == fBlitFramebuffer) {
331 return false;
332 }
bsalomon@google.com1744f972013-02-26 21:46:32 +0000333 if (extensions.has("GL_EXT_framebuffer_multisample") &&
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000334 NULL == fRenderbufferStorageMultisample) {
335 return false;
336 }
337 }
338 } else {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000339#if GR_GL_IGNORE_ES3_MSAA
bsalomon@google.com1744f972013-02-26 21:46:32 +0000340 if (extensions.has("GL_CHROMIUM_framebuffer_multisample")) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000341 if (NULL == fRenderbufferStorageMultisample ||
342 NULL == fBlitFramebuffer) {
343 return false;
344 }
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000345 } else if (extensions.has("GL_APPLE_framebuffer_multisample")) {
346 if (NULL == fRenderbufferStorageMultisample ||
347 NULL == fResolveMultisampleFramebuffer) {
348 return false;
349 }
350 } else if (extensions.has("GL_IMG_multisampled_render_to_texture") ||
351 extensions.has("GL_EXT_multisampled_render_to_texture")) {
352 if (NULL == fRenderbufferStorageMultisample ||
353 NULL == fFramebufferTexture2DMultisample) {
354 return false;
355 }
356 }
357#else
358 if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_CHROMIUM_framebuffer_multisample")) {
359 if (NULL == fRenderbufferStorageMultisample ||
360 NULL == fBlitFramebuffer) {
361 return false;
362 }
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000363 }
bsalomon@google.com1744f972013-02-26 21:46:32 +0000364 if (extensions.has("GL_APPLE_framebuffer_multisample")) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000365 if (NULL == fRenderbufferStorageMultisampleES2APPLE ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000366 NULL == fResolveMultisampleFramebuffer) {
367 return false;
368 }
369 }
bsalomon@google.com347c3822013-05-01 20:10:01 +0000370 if (extensions.has("GL_IMG_multisampled_render_to_texture") ||
371 extensions.has("GL_EXT_multisampled_render_to_texture")) {
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000372 if (NULL == fRenderbufferStorageMultisampleES2EXT ||
bsalomon@google.comf3a60c02013-03-19 19:06:09 +0000373 NULL == fFramebufferTexture2DMultisample) {
374 return false;
375 }
376 }
commit-bot@chromium.orga8e5a062013-09-05 23:44:09 +0000377#endif
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000378 }
379
380 // On ES buffer mapping is an extension. On Desktop
381 // buffer mapping was part of original VBO extension
382 // which we require.
bsalomon@google.com1744f972013-02-26 21:46:32 +0000383 if (kDesktop_GrGLBinding == binding || extensions.has("GL_OES_mapbuffer")) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000384 if (NULL == fMapBuffer ||
385 NULL == fUnmapBuffer) {
386 return false;
387 }
388 }
389
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000390 // Dual source blending
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000391 if (kDesktop_GrGLBinding == binding &&
bsalomon@google.com1744f972013-02-26 21:46:32 +0000392 (glVer >= GR_GL_VER(3,3) || extensions.has("GL_ARB_blend_func_extended"))) {
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000393 if (NULL == fBindFragDataLocationIndexed) {
394 return false;
395 }
396 }
skia.committer@gmail.com12eea2b2013-02-27 07:10:10 +0000397
commit-bot@chromium.org726e6212013-08-23 20:55:46 +0000398 // glGetStringi was added in version 3.0 of both desktop and ES.
399 if (glVer >= GR_GL_VER(3, 0)) {
bsalomon@google.com1744f972013-02-26 21:46:32 +0000400 if (NULL == fGetStringi) {
401 return false;
402 }
403 }
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000404
bsalomon@google.comecd84842013-03-01 15:36:02 +0000405 if (kDesktop_GrGLBinding == binding) {
406 if (glVer >= GR_GL_VER(3, 0) || extensions.has("GL_ARB_vertex_array_object")) {
407 if (NULL == fBindVertexArray ||
408 NULL == fDeleteVertexArrays ||
409 NULL == fGenVertexArrays) {
410 return false;
411 }
412 }
413 } else {
commit-bot@chromium.org2276c012013-08-16 15:53:33 +0000414 if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_OES_vertex_array_object")) {
bsalomon@google.comecd84842013-03-01 15:36:02 +0000415 if (NULL == fBindVertexArray ||
416 NULL == fDeleteVertexArrays ||
417 NULL == fGenVertexArrays) {
418 return false;
419 }
420 }
bsalomon@google.comecd84842013-03-01 15:36:02 +0000421 }
422
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000423 return true;
424}