blob: 61020bc2e37a1eefaa3b36d158e8378e28d30b1f [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
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +000014SK_DEFINE_INST_COUNT(GrGLInterface)
15
bsalomon@google.com56bfc5a2011-09-01 13:28:16 +000016#if GR_GL_PER_GL_FUNC_CALLBACK
17namespace {
18void GrGLDefaultInterfaceCallback(const GrGLInterface*) {}
19}
20#endif
21
bsalomon@google.com0b77d682011-08-19 13:28:54 +000022GrGLInterface::GrGLInterface() {
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000023 fBindingsExported = kNone_GrGLBinding;
bsalomon@google.com0b77d682011-08-19 13:28:54 +000024
bsalomon@google.com56bfc5a2011-09-01 13:28:16 +000025#if GR_GL_PER_GL_FUNC_CALLBACK
26 fCallback = GrGLDefaultInterfaceCallback;
27 fCallbackData = 0;
28#endif
bsalomon@google.com0b77d682011-08-19 13:28:54 +000029}
30
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000031bool GrGLInterface::validate(GrGLBinding binding) const {
bsalomon@google.com0b77d682011-08-19 13:28:54 +000032
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000033 // kNone must be 0 so that the check we're about to do can never succeed if
34 // binding == kNone.
35 GR_STATIC_ASSERT(kNone_GrGLBinding == 0);
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000036
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000037 if (0 == (binding & fBindingsExported)) {
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000038 return false;
39 }
40
41 // functions that are always required
42 if (NULL == fActiveTexture ||
43 NULL == fAttachShader ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000044 NULL == fBindAttribLocation ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000045 NULL == fBindBuffer ||
46 NULL == fBindTexture ||
47 NULL == fBlendFunc ||
robertphillips@google.come7884302012-04-18 14:39:58 +000048 NULL == fBlendColor || // -> GL >= 1.4, ES >= 2.0 or extension
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000049 NULL == fBufferData ||
50 NULL == fBufferSubData ||
51 NULL == fClear ||
52 NULL == fClearColor ||
53 NULL == fClearStencil ||
54 NULL == fColorMask ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000055 NULL == fCompileShader ||
56 NULL == fCreateProgram ||
57 NULL == fCreateShader ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000058 NULL == fCullFace ||
59 NULL == fDeleteBuffers ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000060 NULL == fDeleteProgram ||
61 NULL == fDeleteShader ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000062 NULL == fDeleteTextures ||
63 NULL == fDepthMask ||
64 NULL == fDisable ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000065 NULL == fDisableVertexAttribArray ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000066 NULL == fDrawArrays ||
67 NULL == fDrawElements ||
68 NULL == fEnable ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000069 NULL == fEnableVertexAttribArray ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000070 NULL == fFrontFace ||
71 NULL == fGenBuffers ||
72 NULL == fGenTextures ||
73 NULL == fGetBufferParameteriv ||
74 NULL == fGetError ||
75 NULL == fGetIntegerv ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000076 NULL == fGetProgramInfoLog ||
77 NULL == fGetProgramiv ||
78 NULL == fGetShaderInfoLog ||
79 NULL == fGetShaderiv ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000080 NULL == fGetString ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000081 NULL == fGetUniformLocation ||
82 NULL == fLinkProgram ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000083 NULL == fPixelStorei ||
84 NULL == fReadPixels ||
85 NULL == fScissor ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000086 NULL == fShaderSource ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000087 NULL == fStencilFunc ||
88 NULL == fStencilMask ||
89 NULL == fStencilOp ||
90 NULL == fTexImage2D ||
91 NULL == fTexParameteri ||
bsalomon@google.com4d063de2012-05-31 17:59:23 +000092 NULL == fTexParameteriv ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +000093 NULL == fTexSubImage2D ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +000094 NULL == fUniform1f ||
95 NULL == fUniform1i ||
96 NULL == fUniform1fv ||
97 NULL == fUniform1iv ||
98 NULL == fUniform2f ||
99 NULL == fUniform2i ||
100 NULL == fUniform2fv ||
101 NULL == fUniform2iv ||
102 NULL == fUniform3f ||
103 NULL == fUniform3i ||
104 NULL == fUniform3fv ||
105 NULL == fUniform3iv ||
106 NULL == fUniform4f ||
107 NULL == fUniform4i ||
108 NULL == fUniform4fv ||
109 NULL == fUniform4iv ||
110 NULL == fUniformMatrix2fv ||
111 NULL == fUniformMatrix3fv ||
112 NULL == fUniformMatrix4fv ||
113 NULL == fUseProgram ||
114 NULL == fVertexAttrib4fv ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000115 NULL == fVertexAttribPointer ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000116 NULL == fViewport ||
117 NULL == fBindFramebuffer ||
118 NULL == fBindRenderbuffer ||
119 NULL == fCheckFramebufferStatus ||
120 NULL == fDeleteFramebuffers ||
121 NULL == fDeleteRenderbuffers ||
bsalomon@google.com373a6632011-10-19 20:43:20 +0000122 NULL == fFinish ||
123 NULL == fFlush ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000124 NULL == fFramebufferRenderbuffer ||
125 NULL == fFramebufferTexture2D ||
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000126 NULL == fGetFramebufferAttachmentParameteriv ||
127 NULL == fGetRenderbufferParameteriv ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000128 NULL == fGenFramebuffers ||
129 NULL == fGenRenderbuffers ||
130 NULL == fRenderbufferStorage) {
131 return false;
132 }
133
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000134 const char* ext;
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000135 GrGLVersion glVer = GrGLGetVersion(this);
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000136 ext = (const char*)fGetString(GR_GL_EXTENSIONS);
137
138 // Now check that baseline ES/Desktop fns not covered above are present
139 // and that we have fn pointers for any advertised extensions that we will
140 // try to use.
141
142 // these functions are part of ES2, we assume they are available
143 // On the desktop we assume they are available if the extension
144 // is present or GL version is high enough.
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000145 if (kES2_GrGLBinding == binding) {
robertphillips@google.come7884302012-04-18 14:39:58 +0000146 if (NULL == fStencilFuncSeparate ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000147 NULL == fStencilMaskSeparate ||
148 NULL == fStencilOpSeparate) {
149 return false;
150 }
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000151 } else if (kDesktop_GrGLBinding == binding) {
robertphillips@google.come7884302012-04-18 14:39:58 +0000152
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000153 if (glVer >= GR_GL_VER(2,0)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000154 if (NULL == fStencilFuncSeparate ||
155 NULL == fStencilMaskSeparate ||
156 NULL == fStencilOpSeparate) {
157 return false;
158 }
159 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000160 if (glVer >= GR_GL_VER(3,0) && NULL == fBindFragDataLocation) {
bsalomon@google.combc5cf512011-09-21 16:21:07 +0000161 return false;
162 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000163 if (glVer >= GR_GL_VER(2,0) ||
164 GrGLHasExtensionFromString("GL_ARB_draw_buffers", ext)) {
bsalomon@google.comd32c5f52011-08-02 19:29:03 +0000165 if (NULL == fDrawBuffers) {
166 return false;
167 }
168 }
robertphillips@google.come7884302012-04-18 14:39:58 +0000169
bsalomon@google.com373a6632011-10-19 20:43:20 +0000170 if (glVer >= GR_GL_VER(1,5) ||
171 GrGLHasExtensionFromString("GL_ARB_occlusion_query", ext)) {
172 if (NULL == fGenQueries ||
173 NULL == fDeleteQueries ||
174 NULL == fBeginQuery ||
175 NULL == fEndQuery ||
176 NULL == fGetQueryiv ||
177 NULL == fGetQueryObjectiv ||
178 NULL == fGetQueryObjectuiv) {
179 return false;
180 }
181 }
182 if (glVer >= GR_GL_VER(3,3) ||
183 GrGLHasExtensionFromString("GL_ARB_timer_query", ext) ||
184 GrGLHasExtensionFromString("GL_EXT_timer_query", ext)) {
185 if (NULL == fGetQueryObjecti64v ||
186 NULL == fGetQueryObjectui64v) {
187 return false;
188 }
189 }
190 if (glVer >= GR_GL_VER(3,3) ||
191 GrGLHasExtensionFromString("GL_ARB_timer_query", ext)) {
192 if (NULL == fQueryCounter) {
193 return false;
194 }
195 }
bsalomon@google.comfe11cb62012-06-06 15:17:54 +0000196 // The below two blocks are checks for functions used with
197 // GL_NV_path_rendering. We're not enforcing that they be non-NULL
198 // because they aren't actually called at this time.
199 if (false &&
bsalomon@google.comd4340e22012-06-06 15:38:52 +0000200 (NULL == fMatrixMode ||
201 NULL == fLoadIdentity ||
202 NULL == fLoadMatrixf)) {
bsalomon@google.comfe11cb62012-06-06 15:17:54 +0000203 return false;
204 }
205 if (false && GrGLHasExtensionFromString("GL_NV_path_rendering", ext)) {
206 if (NULL == fPathCommands ||
207 NULL == fPathCoords ||
208 NULL == fPathSubCommands ||
209 NULL == fPathSubCoords ||
210 NULL == fPathString ||
211 NULL == fPathGlyphs ||
212 NULL == fPathGlyphRange ||
213 NULL == fWeightPaths ||
214 NULL == fCopyPath ||
215 NULL == fInterpolatePaths ||
216 NULL == fTransformPath ||
217 NULL == fPathParameteriv ||
218 NULL == fPathParameteri ||
219 NULL == fPathParameterfv ||
220 NULL == fPathParameterf ||
221 NULL == fPathDashArray ||
222 NULL == fGenPaths ||
223 NULL == fDeletePaths ||
224 NULL == fIsPath ||
225 NULL == fPathStencilFunc ||
226 NULL == fPathStencilDepthOffset ||
227 NULL == fStencilFillPath ||
228 NULL == fStencilStrokePath ||
229 NULL == fStencilFillPathInstanced ||
230 NULL == fStencilStrokePathInstanced ||
231 NULL == fPathCoverDepthFunc ||
232 NULL == fPathColorGen ||
233 NULL == fPathTexGen ||
234 NULL == fPathFogGen ||
235 NULL == fCoverFillPath ||
236 NULL == fCoverStrokePath ||
237 NULL == fCoverFillPathInstanced ||
238 NULL == fCoverStrokePathInstanced ||
239 NULL == fGetPathParameteriv ||
240 NULL == fGetPathParameterfv ||
241 NULL == fGetPathCommands ||
242 NULL == fGetPathCoords ||
243 NULL == fGetPathDashArray ||
244 NULL == fGetPathMetrics ||
245 NULL == fGetPathMetricRange ||
246 NULL == fGetPathSpacing ||
247 NULL == fGetPathColorGeniv ||
248 NULL == fGetPathColorGenfv ||
249 NULL == fGetPathTexGeniv ||
250 NULL == fGetPathTexGenfv ||
251 NULL == fIsPointInFillPath ||
252 NULL == fIsPointInStrokePath ||
253 NULL == fGetPathLength ||
254 NULL == fPointAlongPath) {
255 return false;
256 }
257 }
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000258 }
259
260 // optional function on desktop before 1.3
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000261 if (kDesktop_GrGLBinding != binding ||
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000262 (glVer >= GR_GL_VER(1,3) ||
263 GrGLHasExtensionFromString("GL_ARB_texture_compression", ext))) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000264 if (NULL == fCompressedTexImage2D) {
265 return false;
266 }
267 }
268
bsalomon@google.comd32c5f52011-08-02 19:29:03 +0000269 // part of desktop GL, but not ES
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000270 if (kDesktop_GrGLBinding == binding &&
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000271 (NULL == fLineWidth ||
bsalomon@google.comd32c5f52011-08-02 19:29:03 +0000272 NULL == fGetTexLevelParameteriv ||
bsalomon@google.comc49d66b2011-08-03 14:22:30 +0000273 NULL == fDrawBuffer ||
274 NULL == fReadBuffer)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000275 return false;
276 }
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000277
bsalomon@google.com280e99f2012-01-05 16:17:38 +0000278 // GL_EXT_texture_storage is part of desktop 4.2
279 // There is a desktop ARB extension and an ES+desktop EXT extension
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000280 if (kDesktop_GrGLBinding == binding) {
bsalomon@google.combaa9ea12012-01-06 19:05:43 +0000281 if (glVer >= GR_GL_VER(4,2) ||
282 GrGLHasExtensionFromString("GL_ARB_texture_storage", ext) ||
283 GrGLHasExtensionFromString("GL_EXT_texture_storage", ext)) {
284 if (NULL == fTexStorage2D) {
285 return false;
286 }
287 }
288 } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", ext)) {
289 if (NULL == fTexStorage2D) {
290 return false;
291 }
bsalomon@google.com280e99f2012-01-05 16:17:38 +0000292 }
293
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000294 // FBO MSAA
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000295 if (kDesktop_GrGLBinding == binding) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000296 // GL 3.0 and the ARB extension have multisample + blit
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000297 if (glVer >= GR_GL_VER(3,0) || GrGLHasExtensionFromString("GL_ARB_framebuffer_object", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000298 if (NULL == fRenderbufferStorageMultisample ||
299 NULL == fBlitFramebuffer) {
300 return false;
301 }
302 } else {
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000303 if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit", ext) &&
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000304 NULL == fBlitFramebuffer) {
305 return false;
306 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000307 if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", ext) &&
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000308 NULL == fRenderbufferStorageMultisample) {
309 return false;
310 }
311 }
312 } else {
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000313 if (GrGLHasExtensionFromString("GL_CHROMIUM_framebuffer_multisample", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000314 if (NULL == fRenderbufferStorageMultisample ||
315 NULL == fBlitFramebuffer) {
316 return false;
317 }
318 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000319 if (GrGLHasExtensionFromString("GL_APPLE_framebuffer_multisample", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000320 if (NULL == fRenderbufferStorageMultisample ||
321 NULL == fResolveMultisampleFramebuffer) {
322 return false;
323 }
324 }
325 }
326
327 // On ES buffer mapping is an extension. On Desktop
328 // buffer mapping was part of original VBO extension
329 // which we require.
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000330 if (kDesktop_GrGLBinding == binding ||
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000331 GrGLHasExtensionFromString("GL_OES_mapbuffer", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000332 if (NULL == fMapBuffer ||
333 NULL == fUnmapBuffer) {
334 return false;
335 }
336 }
337
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000338 // Dual source blending
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000339 if (kDesktop_GrGLBinding == binding &&
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000340 (glVer >= GR_GL_VER(3,3) ||
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000341 GrGLHasExtensionFromString("GL_ARB_blend_func_extended", ext))) {
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000342 if (NULL == fBindFragDataLocationIndexed) {
343 return false;
344 }
345 }
346
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000347 return true;
348}