blob: 702b057e3eb92284d5b4e685b7147514dbd12b37 [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
150 #if GL_EXT_framebuffer_object && !GR_MAC_BUILD
151 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
215
216 #if GL_APPLE_framebuffer_multisample
217 if (has_gl_extension_from_string("GL_APPLE_framebuffer_multisample",
218 extensionString)) {
219 GR_GL_GET_PROC_SUFFIX(ResolveMultisampleFramebuffer, APPLE);
220 }
221 #endif
222
twiz@google.com59a190b2011-03-14 21:23:01 +0000223 #if GL_OES_mapbuffer
224 if (has_gl_extension_from_string("GL_OES_mapbuffer", extensionString)) {
225 GR_GL_GET_PROC_SUFFIX(MapBuffer, OES);
226 GR_GL_GET_PROC_SUFFIX(UnmapBuffer, OES);
227 }
228 #endif
229#endif // !GR_SUPPORT_GLDESKTOP
230
231 if (!fboFound) {
232 // we require some form of FBO
233 GrAssert(!"No FBOs supported?");
234 }
235}
236
237void GrGLInitializeGLInterface(GrGLInterface* glBindings) {
238 Gr_bzero(glBindings, sizeof(GrGLInterface));
239
twiz@google.comb65e0cb2011-03-18 20:41:44 +0000240 // Indicate the type of the exported GL functions based on macros
241 // pulled in from the platform includes.
242#if GR_SUPPORT_GLDESKTOP
243 glBindings->fBindingsExported = kDesktop_GrGLBinding;
244#endif
245
246#if GR_SUPPORT_GLES1 && !GR_SUPPORT_GLES2
247 glBindings->fBindingsExported = kES1_GrGLBinding;
248#endif
249
250#if GR_SUPPORT_GLES2
251 glBindings->fBindingsExported = kES2_GrGLBinding;
252#endif
253
twiz@google.comdc008e12011-03-15 16:12:21 +0000254#if GR_SUPPORT_GLDESKTOP || GR_SUPPORT_GLES1
twiz@google.com59a190b2011-03-14 21:23:01 +0000255 // These entry points only exist on desktop GL implementations.
256 GR_GL_GET_PROC_SYMBOL(Color4ub);
257 GR_GL_GET_PROC_SYMBOL(ColorPointer);
258 GR_GL_GET_PROC_SYMBOL(DisableClientState);
259 GR_GL_GET_PROC_SYMBOL(EnableClientState);
260 GR_GL_GET_PROC_SYMBOL(LoadMatrixf);
261 GR_GL_GET_PROC_SYMBOL(MatrixMode);
262 GR_GL_GET_PROC_SYMBOL(PointSize);
263 GR_GL_GET_PROC_SYMBOL(ShadeModel);
264 GR_GL_GET_PROC_SYMBOL(TexCoordPointer);
265 GR_GL_GET_PROC_SYMBOL(TexEnvi);
266 GR_GL_GET_PROC_SYMBOL(VertexPointer);
267 GR_GL_GET_PROC(ClientActiveTexture);
268#endif
269
270 // The following gl entry points are part of GL 1.1, and will always be
271 // exported as symbols.
272 // Note that on windows, the wglGetProcAddress call will fail to retrieve
273 // these entry points.
274 GR_GL_GET_PROC_SYMBOL(BlendFunc);
275 GR_GL_GET_PROC_SYMBOL(Clear);
276 GR_GL_GET_PROC_SYMBOL(ClearColor);
277 GR_GL_GET_PROC_SYMBOL(ClearStencil);
278 GR_GL_GET_PROC_SYMBOL(ColorMask);
279 GR_GL_GET_PROC_SYMBOL(CullFace);
280 GR_GL_GET_PROC_SYMBOL(DeleteTextures);
281 GR_GL_GET_PROC_SYMBOL(DepthMask);
282 GR_GL_GET_PROC_SYMBOL(Disable);
283 GR_GL_GET_PROC_SYMBOL(DrawArrays);
284 GR_GL_GET_PROC_SYMBOL(DrawElements);
285 GR_GL_GET_PROC_SYMBOL(Enable);
286 GR_GL_GET_PROC_SYMBOL(FrontFace);
287 GR_GL_GET_PROC_SYMBOL(GenTextures);
288 GR_GL_GET_PROC_SYMBOL(GetError);
289 GR_GL_GET_PROC_SYMBOL(GetIntegerv);
290 GR_GL_GET_PROC_SYMBOL(GetString);
291 GR_GL_GET_PROC_SYMBOL(LineWidth);
292 GR_GL_GET_PROC_SYMBOL(PixelStorei);
293 GR_GL_GET_PROC_SYMBOL(ReadPixels);
294 GR_GL_GET_PROC_SYMBOL(Scissor);
295 GR_GL_GET_PROC_SYMBOL(StencilFunc);
296 GR_GL_GET_PROC_SYMBOL(StencilMask);
297 GR_GL_GET_PROC_SYMBOL(StencilOp);
298 GR_GL_GET_PROC_SYMBOL(TexImage2D);
299 GR_GL_GET_PROC_SYMBOL(TexParameteri);
300 GR_GL_GET_PROC_SYMBOL(TexSubImage2D);
301 GR_GL_GET_PROC_SYMBOL(Viewport);
302
303 // Capture the remaining entry points as gl extensions.
304 GR_GL_GET_PROC(ActiveTexture);
305 GR_GL_GET_PROC(AttachShader);
306 GR_GL_GET_PROC(BindAttribLocation);
307 GR_GL_GET_PROC(BindBuffer);
308 GR_GL_GET_PROC(BindTexture);
bsalomon@google.com080773c2011-03-15 19:09:25 +0000309 GR_GL_GET_PROC(BlendColor);
twiz@google.com59a190b2011-03-14 21:23:01 +0000310 GR_GL_GET_PROC(BufferData);
311 GR_GL_GET_PROC(BufferSubData);
312 GR_GL_GET_PROC(CompileShader);
313 GR_GL_GET_PROC(CompressedTexImage2D);
314 GR_GL_GET_PROC(CreateProgram);
315 GR_GL_GET_PROC(CreateShader);
316 GR_GL_GET_PROC(DeleteBuffers);
317 GR_GL_GET_PROC(DeleteProgram);
318 GR_GL_GET_PROC(DeleteShader);
319 GR_GL_GET_PROC(DisableVertexAttribArray);
320 GR_GL_GET_PROC(EnableVertexAttribArray);
321 GR_GL_GET_PROC(GenBuffers);
322 GR_GL_GET_PROC(GetBufferParameteriv);
323 GR_GL_GET_PROC(GetProgramInfoLog);
324 GR_GL_GET_PROC(GetProgramiv);
325 GR_GL_GET_PROC(GetShaderInfoLog);
326 GR_GL_GET_PROC(GetShaderiv);
327 GR_GL_GET_PROC(GetUniformLocation);
328 GR_GL_GET_PROC(LinkProgram);
329 GR_GL_GET_PROC(ShaderSource);
330 GR_GL_GET_PROC(StencilFuncSeparate);
331 GR_GL_GET_PROC(StencilMaskSeparate);
332 GR_GL_GET_PROC(StencilOpSeparate);
333 GR_GL_GET_PROC(Uniform1fv);
334 GR_GL_GET_PROC(Uniform1i);
335 GR_GL_GET_PROC(Uniform4fv);
336 GR_GL_GET_PROC(UniformMatrix3fv);
337 GR_GL_GET_PROC(UseProgram);
338 GR_GL_GET_PROC(VertexAttrib4fv);
339 GR_GL_GET_PROC(VertexAttribPointer);
340
341 InitializeGLInterfaceExtensions(glBindings);
342}
343
344} // unnamed namespace
345
bsalomon@google.com91826102011-03-21 19:51:57 +0000346GR_API void GrGLSetGLInterface(GrGLInterface* gl_interface) {
twiz@google.com59a190b2011-03-14 21:23:01 +0000347 gGLInterface = gl_interface;
348}
349
bsalomon@google.com91826102011-03-21 19:51:57 +0000350GR_API GrGLInterface* GrGLGetGLInterface() {
twiz@google.com59a190b2011-03-14 21:23:01 +0000351 return gGLInterface;
352}
353
354void GrGLSetDefaultGLInterface() {
355 static GrGLInterface gDefaultInterface;
356 static bool gDefaultInitialized = false;
357 GrAssert(!gDefaultInitialized);
358
359 if (!gDefaultInitialized) {
360 GrGLInitializeGLInterface(&gDefaultInterface);
361 GrGLSetGLInterface(&gDefaultInterface);
362 }
363}
364
365bool has_gl_extension(const char* ext) {
366 const char* glstr = reinterpret_cast<const char*>(
367 GrGLGetGLInterface()->fGetString(GL_EXTENSIONS));
368
369 return has_gl_extension_from_string(ext, glstr);
370}
371
372void gl_version(int* major, int* minor) {
373 const char* v = reinterpret_cast<const char*>(
374 GrGLGetGLInterface()->fGetString(GL_VERSION));
375 gl_version_from_string(major, minor, v);
376}