4 * An object oriented GL/GLES Abstraction/Utility Layer
6 * Copyright (C) 2007,2008,2009 Intel Corporation.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
30 #include "cogl-private.h"
31 #include "cogl-internal.h"
32 #include "cogl-context-private.h"
33 #include "cogl-feature-private.h"
34 #include "cogl-renderer-private.h"
37 _cogl_get_gl_version (int *major_out, int *minor_out)
39 const char *version_string, *major_end, *minor_end;
40 int major = 0, minor = 0;
42 _COGL_GET_CONTEXT (ctx, FALSE);
44 /* Get the OpenGL version number */
45 if ((version_string = (const char *) ctx->glGetString (GL_VERSION)) == NULL)
48 /* Extract the major number */
49 for (major_end = version_string; *major_end >= '0'
50 && *major_end <= '9'; major_end++)
51 major = (major * 10) + *major_end - '0';
52 /* If there were no digits or the major number isn't followed by a
53 dot then it is invalid */
54 if (major_end == version_string || *major_end != '.')
57 /* Extract the minor number */
58 for (minor_end = major_end + 1; *minor_end >= '0'
59 && *minor_end <= '9'; minor_end++)
60 minor = (minor * 10) + *minor_end - '0';
61 /* If there were no digits or there is an unexpected character then
63 if (minor_end == major_end + 1
64 || (*minor_end && *minor_end != ' ' && *minor_end != '.'))
74 check_gl_version (CoglContext *ctx,
78 const char *gl_extensions;
80 if (!_cogl_get_gl_version (&major, &minor))
84 COGL_DRIVER_ERROR_UNKNOWN_VERSION,
85 "The OpenGL version could not be determined");
89 /* GL 1.3 supports all of the required functionality in core */
90 if (COGL_CHECK_GL_VERSION (major, minor, 1, 3))
93 gl_extensions = (const char*) ctx->glGetString (GL_EXTENSIONS);
95 /* OpenGL 1.2 is only supported if we have the multitexturing
97 if (!_cogl_check_extension ("GL_ARB_multitexture", gl_extensions))
101 COGL_DRIVER_ERROR_INVALID_VERSION,
102 "The OpenGL driver is missing "
103 "the GL_ARB_multitexture extension");
107 /* OpenGL 1.2 is required */
108 if (!COGL_CHECK_GL_VERSION (major, minor, 1, 2))
112 COGL_DRIVER_ERROR_INVALID_VERSION,
113 "The OpenGL version of your driver (%i.%i) "
114 "is not compatible with Cogl",
123 _cogl_gl_update_features (CoglContext *context,
126 CoglPrivateFeatureFlags private_flags = 0;
127 CoglFeatureFlags flags = 0;
128 const char *gl_extensions;
129 int max_clip_planes = 0;
130 int num_stencil_bits = 0;
131 int gl_major = 0, gl_minor = 0;
133 _COGL_GET_CONTEXT (ctx, FALSE);
135 /* We have to special case getting the pointer to the glGetString
136 function because we need to use it to determine what functions we
138 context->glGetString =
139 (void *) _cogl_renderer_get_proc_address (context->display->renderer,
142 if (!check_gl_version (context, error))
146 "Checking features\n"
150 " GL_EXTENSIONS: %s",
151 ctx->glGetString (GL_VENDOR),
152 ctx->glGetString (GL_RENDERER),
153 ctx->glGetString (GL_VERSION),
154 ctx->glGetString (GL_EXTENSIONS));
156 _cogl_get_gl_version (&gl_major, &gl_minor);
158 flags = (COGL_FEATURE_TEXTURE_READ_PIXELS
159 | COGL_FEATURE_UNSIGNED_INT_INDICES
160 | COGL_FEATURE_DEPTH_RANGE);
161 COGL_FLAGS_SET (ctx->features,
162 COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE);
163 COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_DEPTH_RANGE, TRUE);
165 if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 1, 4))
166 COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_MIRRORED_REPEAT, TRUE);
168 gl_extensions = (const char *)ctx->glGetString (GL_EXTENSIONS);
170 _cogl_feature_check_ext_functions (context,
175 if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0) ||
176 _cogl_check_extension ("GL_ARB_texture_non_power_of_two", gl_extensions))
178 flags |= COGL_FEATURE_TEXTURE_NPOT
179 | COGL_FEATURE_TEXTURE_NPOT_BASIC
180 | COGL_FEATURE_TEXTURE_NPOT_MIPMAP
181 | COGL_FEATURE_TEXTURE_NPOT_REPEAT;
182 COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_NPOT, TRUE);
183 COGL_FLAGS_SET (ctx->features,
184 COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE);
185 COGL_FLAGS_SET (ctx->features,
186 COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP, TRUE);
187 COGL_FLAGS_SET (ctx->features,
188 COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT, TRUE);
191 if (_cogl_check_extension ("GL_MESA_pack_invert", gl_extensions))
192 private_flags |= COGL_PRIVATE_FEATURE_MESA_PACK_INVERT;
194 GE( ctx, glGetIntegerv (GL_STENCIL_BITS, &num_stencil_bits) );
195 /* We need at least three stencil bits to combine clips */
196 if (num_stencil_bits > 2)
197 private_flags |= COGL_PRIVATE_FEATURE_STENCIL_BUFFER;
199 GE( ctx, glGetIntegerv (GL_MAX_CLIP_PLANES, &max_clip_planes) );
200 if (max_clip_planes >= 4)
201 private_flags |= COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES;
203 if (context->glGenRenderbuffers)
205 flags |= COGL_FEATURE_OFFSCREEN;
206 COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_OFFSCREEN, TRUE);
209 if (context->glBlitFramebuffer)
210 private_flags |= COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT;
212 if (context->glRenderbufferStorageMultisampleIMG)
214 flags |= COGL_FEATURE_OFFSCREEN_MULTISAMPLE;
215 COGL_FLAGS_SET (ctx->features,
216 COGL_FEATURE_ID_OFFSCREEN_MULTISAMPLE, TRUE);
219 if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 1) ||
220 _cogl_check_extension ("GL_EXT_pixel_buffer_object", gl_extensions))
221 private_flags |= COGL_PRIVATE_FEATURE_PBOS;
223 if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0) ||
224 _cogl_check_extension ("GL_ARB_point_sprite", gl_extensions))
226 flags |= COGL_FEATURE_POINT_SPRITE;
227 COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_POINT_SPRITE, TRUE);
230 if (context->glGenPrograms)
232 flags |= COGL_FEATURE_SHADERS_ARBFP;
233 COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_ARBFP, TRUE);
236 if (context->glCreateProgram)
238 flags |= COGL_FEATURE_SHADERS_GLSL;
239 COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_GLSL, TRUE);
242 if (context->glGenBuffers)
244 private_flags |= COGL_PRIVATE_FEATURE_VBOS;
245 flags |= (COGL_FEATURE_MAP_BUFFER_FOR_READ |
246 COGL_FEATURE_MAP_BUFFER_FOR_WRITE);
247 COGL_FLAGS_SET (ctx->features,
248 COGL_FEATURE_ID_MAP_BUFFER_FOR_READ, TRUE);
249 COGL_FLAGS_SET (ctx->features,
250 COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, TRUE);
253 if (_cogl_check_extension ("GL_ARB_texture_rectangle", gl_extensions))
255 flags |= COGL_FEATURE_TEXTURE_RECTANGLE;
256 COGL_FLAGS_SET (ctx->features,
257 COGL_FEATURE_ID_TEXTURE_RECTANGLE, TRUE);
260 if (context->glTexImage3D)
262 flags |= COGL_FEATURE_TEXTURE_3D;
263 COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_3D, TRUE);
266 if (context->glEGLImageTargetTexture2D)
267 private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE;
269 if (_cogl_check_extension ("GL_EXT_packed_depth_stencil", gl_extensions))
270 private_flags |= COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL;
273 context->private_feature_flags |= private_flags;
274 context->feature_flags |= flags;