}
void
+_clutter_backend_ensure_context_internal (ClutterBackend *backend,
+ ClutterStage *stage)
+{
+ ClutterBackendClass *klass = CLUTTER_BACKEND_GET_CLASS (backend);
+ if (G_LIKELY (klass->ensure_context))
+ klass->ensure_context (backend, stage);
+}
+
+void
_clutter_backend_ensure_context (ClutterBackend *backend,
ClutterStage *stage)
{
static ClutterStage *current_context_stage = NULL;
- ClutterBackendClass *klass;
g_return_if_fail (CLUTTER_IS_BACKEND (backend));
g_return_if_fail (CLUTTER_IS_STAGE (stage));
new_stage);
}
- klass = CLUTTER_BACKEND_GET_CLASS (backend);
- if (G_LIKELY (klass->ensure_context))
- klass->ensure_context (backend, new_stage);
+ _clutter_backend_ensure_context_internal (backend, new_stage);
/* XXX: Until Cogl becomes fully responsible for backend windows
* Clutter need to manually keep it informed of the current window size
*/
if (is_realized)
{
- CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
- clutter_stage_ensure_current (CLUTTER_STAGE (self));
+ GError *error = NULL;
+ ClutterBackend *backend = clutter_get_default_backend ();
+
+ /* We want to select the context without calling
+ clutter_backend_ensure_context so that it doesn't call any
+ Cogl functions. Otherwise it would create the Cogl context
+ before we get a chance to check whether the GL version is
+ valid */
+ _clutter_backend_ensure_context_internal (backend, CLUTTER_STAGE (self));
+
+ /* Make sure Cogl can support the driver */
+ if (!_cogl_check_driver_valid (&error))
+ {
+ g_warning ("The GL driver is not supported: %s",
+ error->message);
+ g_clear_error (&error);
+ CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
+ }
+ else
+ CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
}
else
CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
#include "cogl-internal.h"
#include "cogl-context.h"
+#define COGL_CHECK_GL_VERSION(driver_major, driver_minor, \
+ target_major, target_minor) \
+ ((driver_major) > (target_major) || \
+ ((driver_major) == (target_major) && (driver_minor) >= (target_minor)))
+
typedef struct _CoglGLSymbolTableEntry
{
const char *name;
}
#endif
+static gboolean
+_cogl_get_gl_version (int *major_out, int *minor_out)
+{
+ const char *version_string, *major_end, *minor_end;
+ int major = 0, minor = 0;
+
+ /* Get the OpenGL version number */
+ if ((version_string = (const char *) glGetString (GL_VERSION)) == NULL)
+ return FALSE;
+
+ /* Extract the major number */
+ for (major_end = version_string; *major_end >= '0'
+ && *major_end <= '9'; major_end++)
+ major = (major * 10) + *major_end - '0';
+ /* If there were no digits or the major number isn't followed by a
+ dot then it is invalid */
+ if (major_end == version_string || *major_end != '.')
+ return FALSE;
+
+ /* Extract the minor number */
+ for (minor_end = major_end + 1; *minor_end >= '0'
+ && *minor_end <= '9'; minor_end++)
+ minor = (minor * 10) + *minor_end - '0';
+ /* If there were no digits or there is an unexpected character then
+ it is invalid */
+ if (minor_end == major_end + 1
+ || (*minor_end && *minor_end != ' ' && *minor_end != '.'))
+ return FALSE;
+
+ *major_out = major;
+ *minor_out = minor;
+
+ return TRUE;
+}
+
+gboolean
+_cogl_check_driver_valid (GError **error)
+{
+ int major, minor;
+
+ if (!_cogl_get_gl_version (&major, &minor))
+ {
+ g_set_error (error,
+ COGL_DRIVER_ERROR,
+ COGL_DRIVER_ERROR_UNKNOWN_VERSION,
+ "The OpenGL version could not be determined");
+ return FALSE;
+ }
+
+ /* OpenGL 1.2 is required */
+ if (!COGL_CHECK_GL_VERSION (major, minor, 1, 2))
+ {
+ g_set_error (error,
+ COGL_DRIVER_ERROR,
+ COGL_DRIVER_ERROR_INVALID_VERSION,
+ "The OpenGL version of your driver (%i.%i) "
+ "is not compatible with Cogl",
+ major, minor);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
void
_cogl_features_init (void)
{
gboolean fbo_ARB = FALSE;
gboolean fbo_EXT = FALSE;
const char *suffix;
+ int gl_major = 0, gl_minor = 0;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
+ _cogl_get_gl_version (&gl_major, &gl_minor);
+
flags = COGL_FEATURE_TEXTURE_READ_PIXELS;
gl_extensions = (const gchar*) glGetString (GL_EXTENSIONS);
cogl_get_proc_address ("glBlendColor");
/* Available in 1.4 */
- ctx->drv.pf_glBlendFuncSeparate =
- (COGL_PFNGLBLENDFUNCSEPARATEPROC)
- cogl_get_proc_address ("glBlendFuncSeparate");
+ if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 1, 4))
+ ctx->drv.pf_glBlendFuncSeparate =
+ (COGL_PFNGLBLENDFUNCSEPARATEPROC)
+ cogl_get_proc_address ("glBlendFuncSeparate");
/* Available in 2.0 */
- ctx->drv.pf_glBlendEquationSeparate =
- (COGL_PFNGLBLENDEQUATIONSEPARATEPROC)
- cogl_get_proc_address ("glBlendEquationSeparate");
+ if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0))
+ ctx->drv.pf_glBlendEquationSeparate =
+ (COGL_PFNGLBLENDEQUATIONSEPARATEPROC)
+ cogl_get_proc_address ("glBlendEquationSeparate");
/* Cache features */
ctx->feature_flags = flags;
ctx->features_cached = TRUE;
}
-