blob: 8be0f2bf13a37ece19a1a56c9bd691a3fd6bc46a [file] [log] [blame]
twiz@google.com59a190b2011-03-14 21:23:01 +00001/*
2 Copyright 2011 Google Inc.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17
18#include "GrGLInterface.h"
19#include "GrTypes.h"
20
twiz@google.com0f31ca72011-03-18 17:38:11 +000021#include "GrGLPlatformIncludes.h"
twiz@google.com59a190b2011-03-14 21:23:01 +000022#include <stdio.h>
23
twiz@google.com0f31ca72011-03-18 17:38:11 +000024#if defined(GR_GL_PLATFORM_HEADER_SUPPORT)
25 #include GR_GL_PLATFORM_HEADER_SUPPORT
26#endif
27
28#if defined(GR_GL_PLATFORM_HEADER)
29 #include GR_GL_PLATFORM_HEADER
30#endif
31
32#if defined(GR_GL_PLATFORM_HEADER_EXT)
33 #include GR_GL_PLATFORM_HEADER_EXT
34#endif
35
36#if defined(GR_GL_PLATFORM_HEADER2)
37 #include GR_GL_PLATFORM_HEADER2
38#endif
39
40#if defined(GR_GL_PLATFORM_HEADER_EXT2)
41 #include GR_GL_PLATFORM_HEADER_EXT2
42#endif
43
twiz@google.com59a190b2011-03-14 21:23:01 +000044#if defined(GR_GL_PROC_ADDRESS_HEADER)
45 #include GR_GL_PROC_ADDRESS_HEADER
46#endif
47
48#if !defined(GR_GL_PROC_ADDRESS)
49 #error "Must define GR_GL_PROC_ADDRESS"
50#endif
51
52#define GR_GL_GET_PROC(PROC_NAME) \
53 glBindings->f##PROC_NAME = \
54 reinterpret_cast<GrGLInterface::GrGL##PROC_NAME##Proc>( \
55 GR_GL_PROC_ADDRESS(gl##PROC_NAME)); \
56 GrAssert(NULL != glBindings->f##PROC_NAME && \
57 "Missing GL binding: " #PROC_NAME);
58
59#define GR_GL_GET_PROC_SUFFIX(PROC_NAME, SUFFIX) \
60 glBindings->f##PROC_NAME = \
61 reinterpret_cast<GrGLInterface::GrGL##PROC_NAME##Proc>( \
62 GR_GL_PROC_ADDRESS(gl##PROC_NAME##SUFFIX)); \
63 GrAssert(NULL != glBindings->f##PROC_NAME && \
64 "Missing GL binding: " #PROC_NAME);
65
66#define GR_GL_GET_PROC_SYMBOL(PROC_NAME) \
67 glBindings->f##PROC_NAME = reinterpret_cast<GrGLInterface::GrGL##PROC_NAME##Proc>(gl##PROC_NAME);
68
69namespace {
70
71void gl_version_from_string(int* major, int* minor,
72 const char* versionString) {
73 if (NULL == versionString) {
74 GrAssert(0);
75 *major = 0;
76 *minor = 0;
77 return;
78 }
twiz@google.com0f31ca72011-03-18 17:38:11 +000079
twiz@google.com59a190b2011-03-14 21:23:01 +000080 int n = sscanf(versionString, "%d.%d", major, minor);
twiz@google.com0f31ca72011-03-18 17:38:11 +000081 if (2 == n) {
82 return;
twiz@google.com59a190b2011-03-14 21:23:01 +000083 }
twiz@google.com0f31ca72011-03-18 17:38:11 +000084
twiz@google.com59a190b2011-03-14 21:23:01 +000085 char profile[2];
twiz@google.com0f31ca72011-03-18 17:38:11 +000086 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
87 major, minor);
twiz@google.com59a190b2011-03-14 21:23:01 +000088 bool ok = 4 == n;
89 if (!ok) {
twiz@google.com0f31ca72011-03-18 17:38:11 +000090 n = sscanf(versionString, "OpenGL ES %d.%d", major, minor);
twiz@google.com59a190b2011-03-14 21:23:01 +000091 ok = 2 == n;
92 }
twiz@google.com0f31ca72011-03-18 17:38:11 +000093
twiz@google.com59a190b2011-03-14 21:23:01 +000094 if (!ok) {
95 GrAssert(0);
96 *major = 0;
97 *minor = 0;
98 return;
99 }
twiz@google.com59a190b2011-03-14 21:23:01 +0000100}
101
102bool has_gl_extension_from_string(const char* ext,
103 const char* extensionString) {
104 int extLength = strlen(ext);
105
106 while (true) {
107 int n = strcspn(extensionString, " ");
108 if (n == extLength && 0 == strncmp(ext, extensionString, n)) {
109 return true;
110 }
111 if (0 == extensionString[n]) {
112 return false;
113 }
114 extensionString += n+1;
115 }
116
117 return false;
118}
119
120GrGLInterface* gGLInterface = NULL;
121
122void InitializeGLInterfaceExtensions(GrGLInterface* glBindings) {
123 int major, minor;
124 const char* versionString = reinterpret_cast<const char*>(
125 glBindings->fGetString(GL_VERSION));
126 const char* extensionString = reinterpret_cast<const char*>(
127 glBindings->fGetString(GL_EXTENSIONS));
128 gl_version_from_string(&major, &minor, versionString);
129
130 bool fboFound = false;
131#if GR_SUPPORT_GLDESKTOP
132 if (major >= 3 || has_gl_extension_from_string("GL_ARB_framebuffer_object",
133 extensionString)) {
134 // GL_ARB_framebuffer_object doesn't use ARB suffix.
135 GR_GL_GET_PROC(GenFramebuffers);
136 GR_GL_GET_PROC(BindFramebuffer);
137 GR_GL_GET_PROC(FramebufferTexture2D);
138 GR_GL_GET_PROC(CheckFramebufferStatus);
139 GR_GL_GET_PROC(DeleteFramebuffers);
140 GR_GL_GET_PROC(RenderbufferStorage);
141 GR_GL_GET_PROC(GenRenderbuffers);
142 GR_GL_GET_PROC(DeleteRenderbuffers);
143 GR_GL_GET_PROC(FramebufferRenderbuffer);
144 GR_GL_GET_PROC(BindRenderbuffer);
145 GR_GL_GET_PROC(RenderbufferStorageMultisample);
146 GR_GL_GET_PROC(BlitFramebuffer);
147 fboFound = true;
148 }
149
senorblanco@chromium.org9d18b782011-03-28 20:47:09 +0000150 #if GL_EXT_framebuffer_object
twiz@google.com59a190b2011-03-14 21:23:01 +0000151 if (!fboFound &&
152 has_gl_extension_from_string("GL_EXT_framebuffer_object",
153 extensionString)) {
154 GR_GL_GET_PROC_SUFFIX(GenFramebuffers, EXT);
155 GR_GL_GET_PROC_SUFFIX(BindFramebuffer, EXT);
156 GR_GL_GET_PROC_SUFFIX(FramebufferTexture2D, EXT);
157 GR_GL_GET_PROC_SUFFIX(CheckFramebufferStatus, EXT);
158 GR_GL_GET_PROC_SUFFIX(DeleteFramebuffers, EXT);
159 GR_GL_GET_PROC_SUFFIX(RenderbufferStorage, EXT);
160 GR_GL_GET_PROC_SUFFIX(GenRenderbuffers, EXT);
161 GR_GL_GET_PROC_SUFFIX(DeleteRenderbuffers, EXT);
162 GR_GL_GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT);
163 GR_GL_GET_PROC_SUFFIX(BindRenderbuffer, EXT);
164 fboFound = true;
165
166 if (has_gl_extension_from_string("GL_EXT_framebuffer_multisample",
167 extensionString)) {
168 GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
169 }
170 if (has_gl_extension_from_string("GL_EXT_framebuffer_blit",
171 extensionString)) {
172 GR_GL_GET_PROC_SUFFIX(BlitFramebuffer, EXT);
173 }
174 }
175 #endif
176
177 // we assume we have at least GL 1.5 or higher (VBOs introduced in 1.5)
178 GrAssert((major == 1 && minor >= 5) || major >=2);
179 GR_GL_GET_PROC(MapBuffer);
180 GR_GL_GET_PROC(UnmapBuffer);
181#else // !GR_SUPPORT_GLDESKTOP
182 #if GR_SUPPORT_GLES2
183 if (!fboFound && major >= 2) {// ES 2.0 supports FBO
184 GR_GL_GET_PROC(GenFramebuffers);
185 GR_GL_GET_PROC(BindFramebuffer);
186 GR_GL_GET_PROC(FramebufferTexture2D);
187 GR_GL_GET_PROC(CheckFramebufferStatus);
188 GR_GL_GET_PROC(DeleteFramebuffers);
189 GR_GL_GET_PROC(RenderbufferStorage);
190 GR_GL_GET_PROC(GenRenderbuffers);
191 GR_GL_GET_PROC(DeleteRenderbuffers);
192 GR_GL_GET_PROC(FramebufferRenderbuffer);
193 GR_GL_GET_PROC(BindRenderbuffer);
194 fboFound = true;
195 }
196 #endif
197
twiz@google.com0f31ca72011-03-18 17:38:11 +0000198 #if GL_OES_framebuffer_object
twiz@google.com59a190b2011-03-14 21:23:01 +0000199 if (!fboFound &&
200 has_gl_extension_from_string("GL_OES_framebuffer_object",
201 extensionString)) {
202 GR_GL_GET_PROC_SUFFIX(GenFramebuffers, OES);
203 GR_GL_GET_PROC_SUFFIX(BindFramebuffer, OES);
204 GR_GL_GET_PROC_SUFFIX(FramebufferTexture2D, OES);
205 GR_GL_GET_PROC_SUFFIX(CheckFramebufferStatus, OES);
206 GR_GL_GET_PROC_SUFFIX(DeleteFramebuffers, OES);
207 GR_GL_GET_PROC_SUFFIX(RenderbufferStorage, OES);
208 GR_GL_GET_PROC_SUFFIX(GenRenderbuffers, OES);
209 GR_GL_GET_PROC_SUFFIX(DeleteRenderbuffers, OES);
210 GR_GL_GET_PROC_SUFFIX(FramebufferRenderbuffer, OES);
211 GR_GL_GET_PROC_SUFFIX(BindRenderbuffer, OES);
212 fboFound = true;
213 }
214 #endif
bsalomon@google.coma9ecdad2011-03-23 13:50:34 +0000215 bool msaaFound = false;
216 // Chrome advertises the equivalent of GL_EXT_framebuffer_blit plus
217 // GL_EXT_framebuffer_multisample as GL_CHROMIUM_framebuffer_multisample
218 // The EXT suffixes are used on the functions, however.
219 #if GL_EXT_framebuffer_multisample
220 if (!msaaFound &&
221 has_gl_extension_from_string("GL_CHROMIUM_framebuffer_multisample",
twiz@google.com59a190b2011-03-14 21:23:01 +0000222 extensionString)) {
bsalomon@google.coma9ecdad2011-03-23 13:50:34 +0000223 GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
224 GR_GL_GET_PROC_SUFFIX(BlitFramebuffer, EXT);
225 msaaFound = true;
226 }
227 #endif
228 #if GL_APPLE_framebuffer_multisample
229 if (!msaaFound &&
230 has_gl_extension_from_string("GL_APPLE_framebuffer_multisample",
231 extensionString)) {
232 GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisample, APPLE);
twiz@google.com59a190b2011-03-14 21:23:01 +0000233 GR_GL_GET_PROC_SUFFIX(ResolveMultisampleFramebuffer, APPLE);
bsalomon@google.coma9ecdad2011-03-23 13:50:34 +0000234 msaaFound = true;
twiz@google.com59a190b2011-03-14 21:23:01 +0000235 }
236 #endif
237
twiz@google.com59a190b2011-03-14 21:23:01 +0000238 #if GL_OES_mapbuffer
239 if (has_gl_extension_from_string("GL_OES_mapbuffer", extensionString)) {
240 GR_GL_GET_PROC_SUFFIX(MapBuffer, OES);
241 GR_GL_GET_PROC_SUFFIX(UnmapBuffer, OES);
242 }
243 #endif
244#endif // !GR_SUPPORT_GLDESKTOP
245
246 if (!fboFound) {
247 // we require some form of FBO
248 GrAssert(!"No FBOs supported?");
249 }
250}
251
252void GrGLInitializeGLInterface(GrGLInterface* glBindings) {
253 Gr_bzero(glBindings, sizeof(GrGLInterface));
254
twiz@google.comb65e0cb2011-03-18 20:41:44 +0000255 // Indicate the type of the exported GL functions based on macros
256 // pulled in from the platform includes.
257#if GR_SUPPORT_GLDESKTOP
258 glBindings->fBindingsExported = kDesktop_GrGLBinding;
259#endif
260
261#if GR_SUPPORT_GLES1 && !GR_SUPPORT_GLES2
262 glBindings->fBindingsExported = kES1_GrGLBinding;
263#endif
264
265#if GR_SUPPORT_GLES2
266 glBindings->fBindingsExported = kES2_GrGLBinding;
267#endif
268
twiz@google.comdc008e12011-03-15 16:12:21 +0000269#if GR_SUPPORT_GLDESKTOP || GR_SUPPORT_GLES1
twiz@google.com59a190b2011-03-14 21:23:01 +0000270 // These entry points only exist on desktop GL implementations.
271 GR_GL_GET_PROC_SYMBOL(Color4ub);
272 GR_GL_GET_PROC_SYMBOL(ColorPointer);
273 GR_GL_GET_PROC_SYMBOL(DisableClientState);
274 GR_GL_GET_PROC_SYMBOL(EnableClientState);
275 GR_GL_GET_PROC_SYMBOL(LoadMatrixf);
276 GR_GL_GET_PROC_SYMBOL(MatrixMode);
277 GR_GL_GET_PROC_SYMBOL(PointSize);
278 GR_GL_GET_PROC_SYMBOL(ShadeModel);
279 GR_GL_GET_PROC_SYMBOL(TexCoordPointer);
280 GR_GL_GET_PROC_SYMBOL(TexEnvi);
281 GR_GL_GET_PROC_SYMBOL(VertexPointer);
282 GR_GL_GET_PROC(ClientActiveTexture);
283#endif
284
285 // The following gl entry points are part of GL 1.1, and will always be
286 // exported as symbols.
287 // Note that on windows, the wglGetProcAddress call will fail to retrieve
288 // these entry points.
289 GR_GL_GET_PROC_SYMBOL(BlendFunc);
290 GR_GL_GET_PROC_SYMBOL(Clear);
291 GR_GL_GET_PROC_SYMBOL(ClearColor);
292 GR_GL_GET_PROC_SYMBOL(ClearStencil);
293 GR_GL_GET_PROC_SYMBOL(ColorMask);
294 GR_GL_GET_PROC_SYMBOL(CullFace);
295 GR_GL_GET_PROC_SYMBOL(DeleteTextures);
296 GR_GL_GET_PROC_SYMBOL(DepthMask);
297 GR_GL_GET_PROC_SYMBOL(Disable);
298 GR_GL_GET_PROC_SYMBOL(DrawArrays);
299 GR_GL_GET_PROC_SYMBOL(DrawElements);
300 GR_GL_GET_PROC_SYMBOL(Enable);
301 GR_GL_GET_PROC_SYMBOL(FrontFace);
302 GR_GL_GET_PROC_SYMBOL(GenTextures);
303 GR_GL_GET_PROC_SYMBOL(GetError);
304 GR_GL_GET_PROC_SYMBOL(GetIntegerv);
305 GR_GL_GET_PROC_SYMBOL(GetString);
306 GR_GL_GET_PROC_SYMBOL(LineWidth);
307 GR_GL_GET_PROC_SYMBOL(PixelStorei);
308 GR_GL_GET_PROC_SYMBOL(ReadPixels);
309 GR_GL_GET_PROC_SYMBOL(Scissor);
310 GR_GL_GET_PROC_SYMBOL(StencilFunc);
311 GR_GL_GET_PROC_SYMBOL(StencilMask);
312 GR_GL_GET_PROC_SYMBOL(StencilOp);
313 GR_GL_GET_PROC_SYMBOL(TexImage2D);
314 GR_GL_GET_PROC_SYMBOL(TexParameteri);
315 GR_GL_GET_PROC_SYMBOL(TexSubImage2D);
316 GR_GL_GET_PROC_SYMBOL(Viewport);
317
318 // Capture the remaining entry points as gl extensions.
319 GR_GL_GET_PROC(ActiveTexture);
320 GR_GL_GET_PROC(AttachShader);
321 GR_GL_GET_PROC(BindAttribLocation);
322 GR_GL_GET_PROC(BindBuffer);
323 GR_GL_GET_PROC(BindTexture);
bsalomon@google.com080773c2011-03-15 19:09:25 +0000324 GR_GL_GET_PROC(BlendColor);
twiz@google.com59a190b2011-03-14 21:23:01 +0000325 GR_GL_GET_PROC(BufferData);
326 GR_GL_GET_PROC(BufferSubData);
327 GR_GL_GET_PROC(CompileShader);
328 GR_GL_GET_PROC(CompressedTexImage2D);
329 GR_GL_GET_PROC(CreateProgram);
330 GR_GL_GET_PROC(CreateShader);
331 GR_GL_GET_PROC(DeleteBuffers);
332 GR_GL_GET_PROC(DeleteProgram);
333 GR_GL_GET_PROC(DeleteShader);
334 GR_GL_GET_PROC(DisableVertexAttribArray);
335 GR_GL_GET_PROC(EnableVertexAttribArray);
336 GR_GL_GET_PROC(GenBuffers);
337 GR_GL_GET_PROC(GetBufferParameteriv);
338 GR_GL_GET_PROC(GetProgramInfoLog);
339 GR_GL_GET_PROC(GetProgramiv);
340 GR_GL_GET_PROC(GetShaderInfoLog);
341 GR_GL_GET_PROC(GetShaderiv);
342 GR_GL_GET_PROC(GetUniformLocation);
343 GR_GL_GET_PROC(LinkProgram);
344 GR_GL_GET_PROC(ShaderSource);
345 GR_GL_GET_PROC(StencilFuncSeparate);
346 GR_GL_GET_PROC(StencilMaskSeparate);
347 GR_GL_GET_PROC(StencilOpSeparate);
348 GR_GL_GET_PROC(Uniform1fv);
349 GR_GL_GET_PROC(Uniform1i);
350 GR_GL_GET_PROC(Uniform4fv);
351 GR_GL_GET_PROC(UniformMatrix3fv);
352 GR_GL_GET_PROC(UseProgram);
353 GR_GL_GET_PROC(VertexAttrib4fv);
354 GR_GL_GET_PROC(VertexAttribPointer);
355
356 InitializeGLInterfaceExtensions(glBindings);
357}
358
359} // unnamed namespace
360
bsalomon@google.com91826102011-03-21 19:51:57 +0000361GR_API void GrGLSetGLInterface(GrGLInterface* gl_interface) {
twiz@google.com59a190b2011-03-14 21:23:01 +0000362 gGLInterface = gl_interface;
363}
364
bsalomon@google.com91826102011-03-21 19:51:57 +0000365GR_API GrGLInterface* GrGLGetGLInterface() {
twiz@google.com59a190b2011-03-14 21:23:01 +0000366 return gGLInterface;
367}
368
369void GrGLSetDefaultGLInterface() {
370 static GrGLInterface gDefaultInterface;
371 static bool gDefaultInitialized = false;
372 GrAssert(!gDefaultInitialized);
373
374 if (!gDefaultInitialized) {
375 GrGLInitializeGLInterface(&gDefaultInterface);
376 GrGLSetGLInterface(&gDefaultInterface);
377 }
378}
379
380bool has_gl_extension(const char* ext) {
381 const char* glstr = reinterpret_cast<const char*>(
382 GrGLGetGLInterface()->fGetString(GL_EXTENSIONS));
383
384 return has_gl_extension_from_string(ext, glstr);
385}
386
387void gl_version(int* major, int* minor) {
388 const char* v = reinterpret_cast<const char*>(
389 GrGLGetGLInterface()->fGetString(GL_VERSION));
390 gl_version_from_string(major, minor, v);
391}