blob: 360e84e263abcf47f0b5bdb2e85018a40668ef64 [file] [log] [blame]
bsalomon@google.com42ab7ea2011-01-19 17:19:40 +00001/*
2 Copyright 2010 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#include "GrGLConfig.h"
18#include <stdio.h>
19
20bool has_gl_extension(const char* ext) {
21 const char* glstr = (const char*) glGetString(GL_EXTENSIONS);
22
23 int extLength = strlen(ext);
24
25 while (true) {
26 int n = strcspn(glstr, " ");
27 if (n == extLength && 0 == strncmp(ext, glstr, n)) {
28 return true;
29 }
30 if (0 == glstr[n]) {
31 return false;
32 }
33 glstr += n+1;
34 }
35}
36
37void gl_version(int* major, int* minor) {
38 const char* v = (const char*) glGetString(GL_VERSION);
39 if (NULL == v) {
40 GrAssert(0);
41 *major = 0;
42 *minor = 0;
43 return;
44 }
45#if GR_SUPPORT_GLDESKTOP
46 int n = sscanf(v, "%d.%d", major, minor);
47 if (n != 2) {
48 GrAssert(0);
49 *major = 0;
50 *minor = 0;
51 return;
52 }
53#else
54 char profile[2];
55 int n = sscanf(v, "OpenGL ES-%c%c %d.%d", profile, profile+1, major, minor);
56 bool ok = 4 == n;
57 if (!ok) {
58 int n = sscanf(v, "OpenGL ES %d.%d", major, minor);
59 ok = 2 == n;
60 }
61 if (!ok) {
62 GrAssert(0);
63 *major = 0;
64 *minor = 0;
65 return;
66 }
67#endif
68}
69
70#if defined(GR_GL_PROC_ADDRESS_HEADER)
71 #include GR_GL_PROC_ADDRESS_HEADER
72#endif
73
74typedef void (*glProc)(void);
75
76#define GET_PROC(EXT_STRUCT, PROC_NAME) \
77 *((glProc*) &(EXT_STRUCT-> PROC_NAME)) = (glProc) GR_GL_PROC_ADDRESS((gl ## PROC_NAME)); \
78 GrAssert(NULL != EXT_STRUCT-> PROC_NAME)
79
80#define GET_SUFFIX_PROC(EXT_STRUCT, PROC_NAME, SUFFIX) \
81 *((glProc*) &(EXT_STRUCT-> PROC_NAME)) = (glProc) GR_GL_PROC_ADDRESS((gl ## PROC_NAME ## SUFFIX)); \
82 GrAssert(NULL != EXT_STRUCT-> PROC_NAME)
83
84extern void GrGLInitExtensions(GrGLExts* exts) {
85 exts->GenFramebuffers = NULL;
86 exts->BindFramebuffer = NULL;
87 exts->FramebufferTexture2D = NULL;
88 exts->CheckFramebufferStatus = NULL;
89 exts->DeleteFramebuffers = NULL;
90 exts->RenderbufferStorage = NULL;
91 exts->GenRenderbuffers = NULL;
92 exts->DeleteRenderbuffers = NULL;
93 exts->FramebufferRenderbuffer = NULL;
94 exts->BindRenderbuffer = NULL;
95 exts->RenderbufferStorageMultisample = NULL;
96 exts->BlitFramebuffer = NULL;
97 exts->ResolveMultisampleFramebuffer = NULL;
98 exts->FramebufferTexture2DMultisample = NULL;
99 exts->MapBuffer = NULL;
100 exts->UnmapBuffer = NULL;
101
102 GLint major, minor;
103 gl_version(&major, &minor);
bsalomon@google.com42ab7ea2011-01-19 17:19:40 +0000104
105 bool fboFound = false;
reed@google.combf858b72011-01-19 19:04:04 +0000106#if GR_SUPPORT_GLDESKTOP
reed@google.comc9218432011-01-25 19:05:12 +0000107 #if defined(GL_VERSION_3_0) && GL_VERSION_3_0
bsalomon@google.com42ab7ea2011-01-19 17:19:40 +0000108 if (!fboFound && major >= 3) { // all of ARB_fbo is in 3.x
109 exts->GenFramebuffers = glGenFramebuffers;
110 exts->BindFramebuffer = glBindFramebuffer;
111 exts->FramebufferTexture2D = glFramebufferTexture2D;
112 exts->CheckFramebufferStatus = glCheckFramebufferStatus;
113 exts->DeleteFramebuffers = glDeleteFramebuffers;
114 exts->RenderbufferStorage = glRenderbufferStorage;
115 exts->GenRenderbuffers = glGenRenderbuffers;
116 exts->DeleteRenderbuffers = glDeleteRenderbuffers;
117 exts->FramebufferRenderbuffer = glFramebufferRenderbuffer;
118 exts->BindRenderbuffer = glBindRenderbuffer;
119 exts->RenderbufferStorageMultisample = glRenderbufferStorageMultisample;
120 exts->BlitFramebuffer = glBlitFramebuffer;
121 fboFound = true;
122 }
123 #endif
124 #if GL_ARB_framebuffer_object
125 if (!fboFound && has_gl_extension("GL_ARB_framebuffer_object")) {
126 // GL_ARB_framebuffer_object doesn't use ARB suffix.
127 GET_PROC(exts, GenFramebuffers);
128 GET_PROC(exts, BindFramebuffer);
129 GET_PROC(exts, FramebufferTexture2D);
130 GET_PROC(exts, CheckFramebufferStatus);
131 GET_PROC(exts, DeleteFramebuffers);
132 GET_PROC(exts, RenderbufferStorage);
133 GET_PROC(exts, GenRenderbuffers);
134 GET_PROC(exts, DeleteRenderbuffers);
135 GET_PROC(exts, FramebufferRenderbuffer);
136 GET_PROC(exts, BindRenderbuffer);
137 GET_PROC(exts, RenderbufferStorageMultisample);
138 GET_PROC(exts, BlitFramebuffer);
139 fboFound = true;
140 }
141 #endif
142 // Mac doesn't declare prototypes for EXT FBO extensions
143 #if GL_EXT_framebuffer_object && !GR_MAC_BUILD
144 if (!fboFound && has_gl_extension("GL_EXT_framebuffer_object")) {
145 GET_SUFFIX_PROC(exts, GenFramebuffers, EXT);
146 GET_SUFFIX_PROC(exts, BindFramebuffer, EXT);
147 GET_SUFFIX_PROC(exts, FramebufferTexture2D, EXT);
148 GET_SUFFIX_PROC(exts, CheckFramebufferStatus, EXT);
149 GET_SUFFIX_PROC(exts, DeleteFramebuffers, EXT);
150 GET_SUFFIX_PROC(exts, RenderbufferStorage, EXT);
151 GET_SUFFIX_PROC(exts, GenRenderbuffers, EXT);
152 GET_SUFFIX_PROC(exts, DeleteRenderbuffers, EXT);
153 GET_SUFFIX_PROC(exts, FramebufferRenderbuffer, EXT);
154 GET_SUFFIX_PROC(exts, BindRenderbuffer, EXT);
155 fboFound = true;
156 // check for fbo ms and fbo blit
157 #if GL_EXT_framebuffer_multisample
158 if (has_gl_extension("GL_EXT_framebuffer_multisample")) {
159 GET_SUFFIX_PROC(exts, RenderbufferStorageMultisample, EXT);
160 }
161 #endif
162 #if GL_EXT_framebuffer_blit
163 if (has_gl_extension("GL_EXT_framebuffer_blit")) {
164 GET_SUFFIX_PROC(exts, BlitFramebuffer, EXT);
165 }
166 #endif
167 }
168 #endif
169 if (!fboFound) {
170 // we require some form of FBO
171 GrAssert(!"No FBOs supported?");
172 }
173 // we assume we have at least GL 1.5 or higher (VBOs introduced in 1.5)
174 exts->MapBuffer = glMapBuffer;
175 exts->UnmapBuffer = glUnmapBuffer;
176#else // !GR_SUPPORT_GLDESKTOP
bsalomon@google.com42ab7ea2011-01-19 17:19:40 +0000177 #if GR_SUPPORT_GLES2
178 if (!fboFound && major >= 2) {// ES 2.0 supports FBO
179 exts->GenFramebuffers = glGenFramebuffers;
180 exts->BindFramebuffer = glBindFramebuffer;
181 exts->FramebufferTexture2D = glFramebufferTexture2D;
182 exts->CheckFramebufferStatus = glCheckFramebufferStatus;
183 exts->DeleteFramebuffers = glDeleteFramebuffers;
184 exts->RenderbufferStorage = glRenderbufferStorage;
185 exts->GenRenderbuffers = glGenRenderbuffers;
186 exts->DeleteRenderbuffers = glDeleteRenderbuffers;
187 exts->FramebufferRenderbuffer = glFramebufferRenderbuffer;
188 exts->BindRenderbuffer = glBindRenderbuffer;
189 fboFound = true;
190 }
191 #endif
reed@google.combf858b72011-01-19 19:04:04 +0000192 #if GL_OES_framebuffer_object
bsalomon@google.com42ab7ea2011-01-19 17:19:40 +0000193 if (!fboFound && has_gl_extension("GL_OES_framebuffer_object")) {
194 GET_SUFFIX_PROC(exts, GenFramebuffers, OES);
195 GET_SUFFIX_PROC(exts, BindFramebuffer, OES);
196 GET_SUFFIX_PROC(exts, FramebufferTexture2D, OES);
197 GET_SUFFIX_PROC(exts, CheckFramebufferStatus, OES);
198 GET_SUFFIX_PROC(exts, DeleteFramebuffers, OES);
199 GET_SUFFIX_PROC(exts, RenderbufferStorage, OES);
200 GET_SUFFIX_PROC(exts, GenRenderbuffers, OES);
201 GET_SUFFIX_PROC(exts, DeleteRenderbuffers, OES);
202 GET_SUFFIX_PROC(exts, FramebufferRenderbuffer, OES);
203 GET_SUFFIX_PROC(exts, BindRenderbuffer, OES);
204 }
205 #endif
206
207 if (!fboFound) {
208 // we require some form of FBO
209 GrAssert(!"No FBOs supported?");
210 }
211
212 #if GL_APPLE_framebuffer_multisample
213 if (has_gl_extension("GL_APPLE_framebuffer_multisample")) {
214 GET_SUFFIX_PROC(exts, ResolveMultisampleFramebuffer, APPLE);
215 }
216 #endif
217
218 #if GL_IMG_multisampled_render_to_texture
219 if (has_gl_extension("GL_IMG_multisampled_render_to_texture")) {
220 GET_SUFFIX_PROC(exts, FramebufferTexture2DMultisample, IMG);
221 }
222 #endif
223
224 #if GL_OES_mapbuffer
225 if (has_gl_extension("GL_OES_mapbuffer")) {
226 GET_SUFFIX_PROC(exts, MapBuffer, OES);
227 GET_SUFFIX_PROC(exts, UnmapBuffer, OES);
228 }
229 #endif
230#endif // !GR_SUPPORT_GLDESKTOP
231}
232
reed@google.combf858b72011-01-19 19:04:04 +0000233
234///////////////////////////////////////////////////////////////////////////////
235
236void GrGLCheckErr(const char* location, const char* call) {
237 uint32_t err = glGetError();
238 if (GL_NO_ERROR != err) {
239 GrPrintf("---- glGetError %x", err);
240 if (NULL != location) {
241 GrPrintf(" at\n\t%s", location);
242 }
243 if (NULL != call) {
244 GrPrintf("\n\t\t%s", call);
245 }
246 GrPrintf("\n");
247 }
248}
249
250///////////////////////////////////////////////////////////////////////////////
251
252bool gPrintGL = true;
253
254
bsalomon@google.com42ab7ea2011-01-19 17:19:40 +0000255