blob: abd4366701e18d7f1185b1d591c744459eebdf28 [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.com9c1f1ac2012-05-07 17:09:37 +000010#include "GrGLUtil.h"
twiz@google.com59a190b2011-03-14 21:23:01 +000011
12#include <stdio.h>
13
bsalomon@google.com56bfc5a2011-09-01 13:28:16 +000014#if GR_GL_PER_GL_FUNC_CALLBACK
15namespace {
16void GrGLDefaultInterfaceCallback(const GrGLInterface*) {}
17}
18#endif
19
bsalomon@google.com0b77d682011-08-19 13:28:54 +000020GrGLInterface::GrGLInterface() {
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000021 fBindingsExported = kNone_GrGLBinding;
bsalomon@google.com0b77d682011-08-19 13:28:54 +000022
bsalomon@google.com56bfc5a2011-09-01 13:28:16 +000023#if GR_GL_PER_GL_FUNC_CALLBACK
24 fCallback = GrGLDefaultInterfaceCallback;
25 fCallbackData = 0;
26#endif
bsalomon@google.com0b77d682011-08-19 13:28:54 +000027}
28
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000029bool GrGLInterface::validate(GrGLBinding binding) const {
bsalomon@google.com0b77d682011-08-19 13:28:54 +000030
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000031 // kNone must be 0 so that the check we're about to do can never succeed if
32 // binding == kNone.
33 GR_STATIC_ASSERT(kNone_GrGLBinding == 0);
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000034
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000035 if (0 == (binding & fBindingsExported)) {
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000036 return false;
37 }
38
39 // functions that are always required
40 if (NULL == fActiveTexture ||
41 NULL == fAttachShader ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000042 NULL == fBindAttribLocation ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000043 NULL == fBindBuffer ||
44 NULL == fBindTexture ||
45 NULL == fBlendFunc ||
robertphillips@google.come7884302012-04-18 14:39:58 +000046 NULL == fBlendColor || // -> GL >= 1.4, ES >= 2.0 or extension
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000047 NULL == fBufferData ||
48 NULL == fBufferSubData ||
49 NULL == fClear ||
50 NULL == fClearColor ||
51 NULL == fClearStencil ||
52 NULL == fColorMask ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000053 NULL == fCompileShader ||
54 NULL == fCreateProgram ||
55 NULL == fCreateShader ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000056 NULL == fCullFace ||
57 NULL == fDeleteBuffers ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000058 NULL == fDeleteProgram ||
59 NULL == fDeleteShader ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000060 NULL == fDeleteTextures ||
61 NULL == fDepthMask ||
62 NULL == fDisable ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000063 NULL == fDisableVertexAttribArray ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000064 NULL == fDrawArrays ||
65 NULL == fDrawElements ||
66 NULL == fEnable ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000067 NULL == fEnableVertexAttribArray ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000068 NULL == fFrontFace ||
69 NULL == fGenBuffers ||
70 NULL == fGenTextures ||
71 NULL == fGetBufferParameteriv ||
72 NULL == fGetError ||
73 NULL == fGetIntegerv ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000074 NULL == fGetProgramInfoLog ||
75 NULL == fGetProgramiv ||
76 NULL == fGetShaderInfoLog ||
77 NULL == fGetShaderiv ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000078 NULL == fGetString ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000079 NULL == fGetUniformLocation ||
80 NULL == fLinkProgram ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000081 NULL == fPixelStorei ||
82 NULL == fReadPixels ||
83 NULL == fScissor ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000084 NULL == fShaderSource ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000085 NULL == fStencilFunc ||
86 NULL == fStencilMask ||
87 NULL == fStencilOp ||
88 NULL == fTexImage2D ||
89 NULL == fTexParameteri ||
bsalomon@google.com4d063de2012-05-31 17:59:23 +000090 NULL == fTexParameteriv ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000091 NULL == fTexSubImage2D ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000092 NULL == fUniform1f ||
93 NULL == fUniform1i ||
94 NULL == fUniform1fv ||
95 NULL == fUniform1iv ||
96 NULL == fUniform2f ||
97 NULL == fUniform2i ||
98 NULL == fUniform2fv ||
99 NULL == fUniform2iv ||
100 NULL == fUniform3f ||
101 NULL == fUniform3i ||
102 NULL == fUniform3fv ||
103 NULL == fUniform3iv ||
104 NULL == fUniform4f ||
105 NULL == fUniform4i ||
106 NULL == fUniform4fv ||
107 NULL == fUniform4iv ||
108 NULL == fUniformMatrix2fv ||
109 NULL == fUniformMatrix3fv ||
110 NULL == fUniformMatrix4fv ||
111 NULL == fUseProgram ||
112 NULL == fVertexAttrib4fv ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000113 NULL == fVertexAttribPointer ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000114 NULL == fViewport ||
115 NULL == fBindFramebuffer ||
116 NULL == fBindRenderbuffer ||
117 NULL == fCheckFramebufferStatus ||
118 NULL == fDeleteFramebuffers ||
119 NULL == fDeleteRenderbuffers ||
bsalomon@google.com373a6632011-10-19 20:43:20 +0000120 NULL == fFinish ||
121 NULL == fFlush ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000122 NULL == fFramebufferRenderbuffer ||
123 NULL == fFramebufferTexture2D ||
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000124 NULL == fGetFramebufferAttachmentParameteriv ||
125 NULL == fGetRenderbufferParameteriv ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000126 NULL == fGenFramebuffers ||
127 NULL == fGenRenderbuffers ||
128 NULL == fRenderbufferStorage) {
129 return false;
130 }
131
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000132 const char* ext;
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000133 GrGLVersion glVer = GrGLGetVersion(this);
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000134 ext = (const char*)fGetString(GR_GL_EXTENSIONS);
135
136 // Now check that baseline ES/Desktop fns not covered above are present
137 // and that we have fn pointers for any advertised extensions that we will
138 // try to use.
139
140 // these functions are part of ES2, we assume they are available
141 // On the desktop we assume they are available if the extension
142 // is present or GL version is high enough.
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000143 if (kES2_GrGLBinding == binding) {
robertphillips@google.come7884302012-04-18 14:39:58 +0000144 if (NULL == fStencilFuncSeparate ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000145 NULL == fStencilMaskSeparate ||
146 NULL == fStencilOpSeparate) {
147 return false;
148 }
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000149 } else if (kDesktop_GrGLBinding == binding) {
robertphillips@google.come7884302012-04-18 14:39:58 +0000150
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000151 if (glVer >= GR_GL_VER(2,0)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000152 if (NULL == fStencilFuncSeparate ||
153 NULL == fStencilMaskSeparate ||
154 NULL == fStencilOpSeparate) {
155 return false;
156 }
157 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000158 if (glVer >= GR_GL_VER(3,0) && NULL == fBindFragDataLocation) {
bsalomon@google.combc5cf512011-09-21 16:21:07 +0000159 return false;
160 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000161 if (glVer >= GR_GL_VER(2,0) ||
162 GrGLHasExtensionFromString("GL_ARB_draw_buffers", ext)) {
bsalomon@google.comd32c5f52011-08-02 19:29:03 +0000163 if (NULL == fDrawBuffers) {
164 return false;
165 }
166 }
robertphillips@google.come7884302012-04-18 14:39:58 +0000167
bsalomon@google.com373a6632011-10-19 20:43:20 +0000168 if (glVer >= GR_GL_VER(1,5) ||
169 GrGLHasExtensionFromString("GL_ARB_occlusion_query", ext)) {
170 if (NULL == fGenQueries ||
171 NULL == fDeleteQueries ||
172 NULL == fBeginQuery ||
173 NULL == fEndQuery ||
174 NULL == fGetQueryiv ||
175 NULL == fGetQueryObjectiv ||
176 NULL == fGetQueryObjectuiv) {
177 return false;
178 }
179 }
180 if (glVer >= GR_GL_VER(3,3) ||
181 GrGLHasExtensionFromString("GL_ARB_timer_query", ext) ||
182 GrGLHasExtensionFromString("GL_EXT_timer_query", ext)) {
183 if (NULL == fGetQueryObjecti64v ||
184 NULL == fGetQueryObjectui64v) {
185 return false;
186 }
187 }
188 if (glVer >= GR_GL_VER(3,3) ||
189 GrGLHasExtensionFromString("GL_ARB_timer_query", ext)) {
190 if (NULL == fQueryCounter) {
191 return false;
192 }
193 }
bsalomon@google.comfe11cb62012-06-06 15:17:54 +0000194 // The below two blocks are checks for functions used with
195 // GL_NV_path_rendering. We're not enforcing that they be non-NULL
196 // because they aren't actually called at this time.
197 if (false &&
bsalomon@google.comd4340e22012-06-06 15:38:52 +0000198 (NULL == fMatrixMode ||
199 NULL == fLoadIdentity ||
200 NULL == fLoadMatrixf)) {
bsalomon@google.comfe11cb62012-06-06 15:17:54 +0000201 return false;
202 }
203 if (false && GrGLHasExtensionFromString("GL_NV_path_rendering", ext)) {
204 if (NULL == fPathCommands ||
205 NULL == fPathCoords ||
206 NULL == fPathSubCommands ||
207 NULL == fPathSubCoords ||
208 NULL == fPathString ||
209 NULL == fPathGlyphs ||
210 NULL == fPathGlyphRange ||
211 NULL == fWeightPaths ||
212 NULL == fCopyPath ||
213 NULL == fInterpolatePaths ||
214 NULL == fTransformPath ||
215 NULL == fPathParameteriv ||
216 NULL == fPathParameteri ||
217 NULL == fPathParameterfv ||
218 NULL == fPathParameterf ||
219 NULL == fPathDashArray ||
220 NULL == fGenPaths ||
221 NULL == fDeletePaths ||
222 NULL == fIsPath ||
223 NULL == fPathStencilFunc ||
224 NULL == fPathStencilDepthOffset ||
225 NULL == fStencilFillPath ||
226 NULL == fStencilStrokePath ||
227 NULL == fStencilFillPathInstanced ||
228 NULL == fStencilStrokePathInstanced ||
229 NULL == fPathCoverDepthFunc ||
230 NULL == fPathColorGen ||
231 NULL == fPathTexGen ||
232 NULL == fPathFogGen ||
233 NULL == fCoverFillPath ||
234 NULL == fCoverStrokePath ||
235 NULL == fCoverFillPathInstanced ||
236 NULL == fCoverStrokePathInstanced ||
237 NULL == fGetPathParameteriv ||
238 NULL == fGetPathParameterfv ||
239 NULL == fGetPathCommands ||
240 NULL == fGetPathCoords ||
241 NULL == fGetPathDashArray ||
242 NULL == fGetPathMetrics ||
243 NULL == fGetPathMetricRange ||
244 NULL == fGetPathSpacing ||
245 NULL == fGetPathColorGeniv ||
246 NULL == fGetPathColorGenfv ||
247 NULL == fGetPathTexGeniv ||
248 NULL == fGetPathTexGenfv ||
249 NULL == fIsPointInFillPath ||
250 NULL == fIsPointInStrokePath ||
251 NULL == fGetPathLength ||
252 NULL == fPointAlongPath) {
253 return false;
254 }
255 }
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000256 }
257
258 // optional function on desktop before 1.3
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000259 if (kDesktop_GrGLBinding != binding ||
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000260 (glVer >= GR_GL_VER(1,3) ||
261 GrGLHasExtensionFromString("GL_ARB_texture_compression", ext))) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000262 if (NULL == fCompressedTexImage2D) {
263 return false;
264 }
265 }
266
bsalomon@google.comd32c5f52011-08-02 19:29:03 +0000267 // part of desktop GL, but not ES
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000268 if (kDesktop_GrGLBinding == binding &&
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000269 (NULL == fLineWidth ||
bsalomon@google.comd32c5f52011-08-02 19:29:03 +0000270 NULL == fGetTexLevelParameteriv ||
bsalomon@google.comc49d66b2011-08-03 14:22:30 +0000271 NULL == fDrawBuffer ||
272 NULL == fReadBuffer)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000273 return false;
274 }
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000275
bsalomon@google.com280e99f2012-01-05 16:17:38 +0000276 // GL_EXT_texture_storage is part of desktop 4.2
277 // There is a desktop ARB extension and an ES+desktop EXT extension
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000278 if (kDesktop_GrGLBinding == binding) {
bsalomon@google.combaa9ea12012-01-06 19:05:43 +0000279 if (glVer >= GR_GL_VER(4,2) ||
280 GrGLHasExtensionFromString("GL_ARB_texture_storage", ext) ||
281 GrGLHasExtensionFromString("GL_EXT_texture_storage", ext)) {
282 if (NULL == fTexStorage2D) {
283 return false;
284 }
285 }
286 } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", ext)) {
287 if (NULL == fTexStorage2D) {
288 return false;
289 }
bsalomon@google.com280e99f2012-01-05 16:17:38 +0000290 }
291
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000292 // FBO MSAA
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000293 if (kDesktop_GrGLBinding == binding) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000294 // GL 3.0 and the ARB extension have multisample + blit
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000295 if (glVer >= GR_GL_VER(3,0) || GrGLHasExtensionFromString("GL_ARB_framebuffer_object", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000296 if (NULL == fRenderbufferStorageMultisample ||
297 NULL == fBlitFramebuffer) {
298 return false;
299 }
300 } else {
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000301 if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit", ext) &&
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000302 NULL == fBlitFramebuffer) {
303 return false;
304 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000305 if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", ext) &&
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000306 NULL == fRenderbufferStorageMultisample) {
307 return false;
308 }
309 }
310 } else {
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000311 if (GrGLHasExtensionFromString("GL_CHROMIUM_framebuffer_multisample", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000312 if (NULL == fRenderbufferStorageMultisample ||
313 NULL == fBlitFramebuffer) {
314 return false;
315 }
316 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000317 if (GrGLHasExtensionFromString("GL_APPLE_framebuffer_multisample", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000318 if (NULL == fRenderbufferStorageMultisample ||
319 NULL == fResolveMultisampleFramebuffer) {
320 return false;
321 }
322 }
323 }
324
325 // On ES buffer mapping is an extension. On Desktop
326 // buffer mapping was part of original VBO extension
327 // which we require.
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000328 if (kDesktop_GrGLBinding == binding ||
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000329 GrGLHasExtensionFromString("GL_OES_mapbuffer", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000330 if (NULL == fMapBuffer ||
331 NULL == fUnmapBuffer) {
332 return false;
333 }
334 }
335
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000336 // Dual source blending
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000337 if (kDesktop_GrGLBinding == binding &&
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000338 (glVer >= GR_GL_VER(3,3) ||
339 GrGLHasExtensionFromString("GL_ARB_blend_func_extended", ext))) {
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000340 if (NULL == fBindFragDataLocationIndexed) {
341 return false;
342 }
343 }
344
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000345 return true;
346}
347