Validate that the GL version is >= 1.2
There is a new internal Cogl function called _cogl_check_driver_valid which looks at the value of the GL_VERSION string to determine whether the driver is supported. Clutter now calls this after the stage is realized. If it fails then the stage is marked as unrealized and a warning is shown. _cogl_features_init now also checks the version number before getting the function pointers for glBlendFuncSeparate and glBlendEquationSeparate. It is not safe to just check for the presence of the functions because some drivers may define the function without fully implementing the spec. The GLES version of _cogl_check_driver_valid just always returns TRUE because there are no version requirements yet. Eventually the function could also check for mandatory extensions if there were any. http://bugzilla.openedhand.com/show_bug.cgi?id=1875
This commit is contained in:
parent
d309272901
commit
a50907848f
@ -942,3 +942,8 @@ _cogl_get_clip_state (void)
|
|||||||
return _cogl_draw_buffer_get_clip_state (draw_buffer);
|
return _cogl_draw_buffer_get_clip_state (draw_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GQuark
|
||||||
|
_cogl_driver_error_quark (void)
|
||||||
|
{
|
||||||
|
return g_quark_from_static_string ("cogl-driver-error-quark");
|
||||||
|
}
|
||||||
|
@ -969,8 +969,17 @@ void cogl_flush_gl_state (int flags);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* private */
|
/* private */
|
||||||
|
#define COGL_DRIVER_ERROR (_cogl_driver_error_quark ())
|
||||||
|
|
||||||
|
typedef enum { /*< prefix=COGL_DRIVER_ERROR >*/
|
||||||
|
COGL_DRIVER_ERROR_UNKNOWN_VERSION,
|
||||||
|
COGL_DRIVER_ERROR_INVALID_VERSION
|
||||||
|
} CoglDriverError;
|
||||||
|
|
||||||
void _cogl_set_indirect_context (gboolean indirect);
|
void _cogl_set_indirect_context (gboolean indirect);
|
||||||
void _cogl_set_viewport (int x, int y, int width, int height);
|
void _cogl_set_viewport (int x, int y, int width, int height);
|
||||||
|
gboolean _cogl_check_driver_valid (GError **error);
|
||||||
|
GQuark _cogl_driver_error_quark (void);
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_onscreen_clutter_backend_set_size (int width, int height);
|
_cogl_onscreen_clutter_backend_set_size (int width, int height);
|
||||||
|
@ -32,6 +32,11 @@
|
|||||||
#include "cogl-internal.h"
|
#include "cogl-internal.h"
|
||||||
#include "cogl-context.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
|
typedef struct _CoglGLSymbolTableEntry
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -109,6 +114,70 @@ really_enable_npot (void)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
void
|
||||||
_cogl_features_init (void)
|
_cogl_features_init (void)
|
||||||
{
|
{
|
||||||
@ -119,9 +188,12 @@ _cogl_features_init (void)
|
|||||||
gboolean fbo_ARB = FALSE;
|
gboolean fbo_ARB = FALSE;
|
||||||
gboolean fbo_EXT = FALSE;
|
gboolean fbo_EXT = FALSE;
|
||||||
const char *suffix;
|
const char *suffix;
|
||||||
|
int gl_major = 0, gl_minor = 0;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
|
_cogl_get_gl_version (&gl_major, &gl_minor);
|
||||||
|
|
||||||
flags = COGL_FEATURE_TEXTURE_READ_PIXELS;
|
flags = COGL_FEATURE_TEXTURE_READ_PIXELS;
|
||||||
|
|
||||||
gl_extensions = (const gchar*) glGetString (GL_EXTENSIONS);
|
gl_extensions = (const gchar*) glGetString (GL_EXTENSIONS);
|
||||||
@ -427,11 +499,13 @@ _cogl_features_init (void)
|
|||||||
cogl_get_proc_address ("glBlendColor");
|
cogl_get_proc_address ("glBlendColor");
|
||||||
|
|
||||||
/* Available in 1.4 */
|
/* Available in 1.4 */
|
||||||
|
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 1, 4))
|
||||||
ctx->drv.pf_glBlendFuncSeparate =
|
ctx->drv.pf_glBlendFuncSeparate =
|
||||||
(COGL_PFNGLBLENDFUNCSEPARATEPROC)
|
(COGL_PFNGLBLENDFUNCSEPARATEPROC)
|
||||||
cogl_get_proc_address ("glBlendFuncSeparate");
|
cogl_get_proc_address ("glBlendFuncSeparate");
|
||||||
|
|
||||||
/* Available in 2.0 */
|
/* Available in 2.0 */
|
||||||
|
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0))
|
||||||
ctx->drv.pf_glBlendEquationSeparate =
|
ctx->drv.pf_glBlendEquationSeparate =
|
||||||
(COGL_PFNGLBLENDEQUATIONSEPARATEPROC)
|
(COGL_PFNGLBLENDEQUATIONSEPARATEPROC)
|
||||||
cogl_get_proc_address ("glBlendEquationSeparate");
|
cogl_get_proc_address ("glBlendEquationSeparate");
|
||||||
@ -440,4 +514,3 @@ _cogl_features_init (void)
|
|||||||
ctx->feature_flags = flags;
|
ctx->feature_flags = flags;
|
||||||
ctx->features_cached = TRUE;
|
ctx->features_cached = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +82,12 @@ _cogl_resolve_gl_symbols (CoglGLSymbolTableEntry *symbol_table,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_check_driver_valid (GError **error)
|
||||||
|
{
|
||||||
|
/* The GLES backend doesn't have any particular version requirements */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_features_init (void)
|
_cogl_features_init (void)
|
||||||
|
Loading…
Reference in New Issue
Block a user