Add a GL 3 driver

This adds a new CoglDriver for GL 3 called COGL_DRIVER_GL3. When
requested, the GLX, EGL and SDL2 winsyss will set the necessary
attributes to request a forward-compatible core profile 3.1 context.
That means it will have no deprecated features.

To simplify the explosion of checks for specific combinations of
context->driver, many of these conditionals have now been replaced
with private feature flags that are checked instead. The GL and GLES
drivers now initialise these private feature flags depending on which
driver is used.

The fixed function backends now explicitly check whether the fixed
function private feature is available which means the GL3 driver will
fall back to always using the GLSL progend. Since Rob's latest patches
the GLSL progend no longer uses any fixed function API anyway so it
should just work.

The driver is currently lower priority than COGL_DRIVER_GL so it will
not be used unless it is specificly requested. We may want to change
this priority at some point because apparently Mesa can make some
memory savings if a core profile context is used.

In GL 3, getting the combined extensions string with glGetString is
deprecated so this patch changes it to use glGetStringi to build up an
array of extensions instead. _cogl_context_get_gl_extensions now
returns this array instead of trying to return a const string. The
caller is expected to free the array.

Some issues with this patch:

• GL 3 does not support GL_ALPHA format textures. We should probably
  make this a feature flag or something. Cogl uses this to render text
  which currently just throws a GL error and breaks so it's pretty
  important to do something about this before considering the GL3
  driver to be stable.

• GL 3 doesn't support client side vertex buffers. This probably
  doesn't matter because CoglBuffer won't normally use malloc'd
  buffers if VBOs are available, but it might but worth making
  malloc'd buffers a private feature and forcing it not to use them.

• GL 3 doesn't support the default vertex array object. This patch
  just makes it create and bind a single non-default vertex array
  object which gets used just like the normal default object. Ideally
  it would be good to use vertex array objects properly and attach
  them to a CoglPrimitive to cache the state.

Reviewed-by: Robert Bragg <robert@linux.intel.com>

(cherry picked from commit 66c9db993595b3a22e63f4c201ea468bc9b88cb6)
This commit is contained in:
Neil Roberts 2012-09-26 20:32:36 +01:00 committed by Robert Bragg
parent 1abf0ed55e
commit 2616ae0fa9
43 changed files with 478 additions and 229 deletions

View File

@ -342,7 +342,7 @@ emit_vertex_buffer_geometry (CoglPangoDisplayListNode *node)
2 /* n_attributes */); 2 /* n_attributes */);
#ifdef CLUTTER_COGL_HAS_GL #ifdef CLUTTER_COGL_HAS_GL
if (ctx->driver == COGL_DRIVER_GL) if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_QUADS))
cogl_primitive_set_mode (prim, GL_QUADS); cogl_primitive_set_mode (prim, GL_QUADS);
else else
#endif #endif

View File

@ -216,12 +216,8 @@ validate_blend_statements (CoglBlendStringStatement *statements,
_COGL_GET_CONTEXT (ctx, 0); _COGL_GET_CONTEXT (ctx, 0);
if (ctx->driver == COGL_DRIVER_GL) if (n_statements == 2 &&
{ !ctx->glBlendEquationSeparate &&
if (n_statements == 2)
{
/* glBlendEquationSeperate is GL 2.0 only */
if (!ctx->glBlendEquationSeparate &&
statements[0].function->type != statements[1].function->type) statements[0].function->type != statements[1].function->type)
{ {
error_string = "Separate blend functions for the RGB an A " error_string = "Separate blend functions for the RGB an A "
@ -229,18 +225,6 @@ validate_blend_statements (CoglBlendStringStatement *statements,
detail = COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR; detail = COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR;
goto error; goto error;
} }
}
}
else if (ctx->driver == COGL_DRIVER_GLES1)
{
if (n_statements != 1)
{
error_string = "Separate blend functions for the RGB an A "
"channels isn't supported by the GLES 1";
detail = COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR;
goto error;
}
}
for (i = 0; i < n_statements; i++) for (i = 0; i < n_statements; i++)
for (j = 0; j < statements[i].function->argc; j++) for (j = 0; j < statements[i].function->argc; j++)
@ -262,12 +246,13 @@ validate_blend_statements (CoglBlendStringStatement *statements,
goto error; goto error;
} }
if (ctx->driver == COGL_DRIVER_GLES1 && if (!(ctx->private_feature_flags &
COGL_PRIVATE_FEATURE_BLEND_CONSTANT) &&
arg->factor.is_color && arg->factor.is_color &&
(arg->factor.source.info->type == (arg->factor.source.info->type ==
COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT)) COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT))
{ {
error_string = "GLES Doesn't support constant blend factors"; error_string = "Driver doesn't support constant blend factors";
detail = COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR; detail = COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR;
goto error; goto error;
} }

View File

@ -29,6 +29,7 @@
#endif #endif
#include <glib.h> #include <glib.h>
#include <string.h>
#include "cogl-util.h" #include "cogl-util.h"
#include "cogl-types.h" #include "cogl-types.h"
@ -46,7 +47,26 @@
CoglBool CoglBool
cogl_clutter_check_extension (const char *name, const char *ext) cogl_clutter_check_extension (const char *name, const char *ext)
{ {
return _cogl_check_extension (name, ext); char *end;
int name_len, n;
if (name == NULL || ext == NULL)
return FALSE;
end = (char*)(ext + strlen(ext));
name_len = strlen(name);
while (ext < end)
{
n = strcspn(ext, " ");
if ((name_len == n) && (!strncmp(name, ext, n)))
return TRUE;
ext += (n + 1);
}
return FALSE;
} }
CoglBool CoglBool

View File

@ -356,7 +356,15 @@ void
_cogl_context_set_current_modelview_entry (CoglContext *context, _cogl_context_set_current_modelview_entry (CoglContext *context,
CoglMatrixEntry *entry); CoglMatrixEntry *entry);
const char * /*
* _cogl_context_get_gl_extensions:
* @context: A CoglContext
*
* Return value: a NULL-terminated array of strings representing the
* supported extensions by the current driver. This array is owned
* by the caller and should be freed with g_strfreev().
*/
char **
_cogl_context_get_gl_extensions (CoglContext *context); _cogl_context_get_gl_extensions (CoglContext *context);
const char * const char *

View File

@ -261,9 +261,7 @@ cogl_context_new (CoglDisplay *display,
context->texture_units = context->texture_units =
g_array_new (FALSE, FALSE, sizeof (CoglTextureUnit)); g_array_new (FALSE, FALSE, sizeof (CoglTextureUnit));
if (context->driver == COGL_DRIVER_GL || if ((context->private_feature_flags & COGL_PRIVATE_FEATURE_ANY_GL))
context->driver == COGL_DRIVER_GLES1 ||
context->driver == COGL_DRIVER_GLES2)
{ {
/* See cogl-pipeline.c for more details about why we leave texture unit 1 /* See cogl-pipeline.c for more details about why we leave texture unit 1
* active by default... */ * active by default... */
@ -368,8 +366,7 @@ cogl_context_new (CoglDisplay *display,
context->blit_texture_pipeline = NULL; context->blit_texture_pipeline = NULL;
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES) #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
if (context->driver == COGL_DRIVER_GL || if ((context->private_feature_flags & COGL_PRIVATE_FEATURE_ALPHA_TEST))
context->driver == COGL_DRIVER_GLES1)
/* The default for GL_ALPHA_TEST is to always pass which is equivalent to /* The default for GL_ALPHA_TEST is to always pass which is equivalent to
* the test being disabled therefore we assume that for all drivers there * the test being disabled therefore we assume that for all drivers there
* will be no performance impact if we always leave the test enabled which * will be no performance impact if we always leave the test enabled which
@ -379,6 +376,22 @@ cogl_context_new (CoglDisplay *display,
GE (context, glEnable (GL_ALPHA_TEST)); GE (context, glEnable (GL_ALPHA_TEST));
#endif #endif
#if defined (HAVE_COGL_GL)
if ((context->driver == COGL_DRIVER_GL3))
{
GLuint vertex_array;
/* In a forward compatible context, GL 3 doesn't support rendering
* using the default vertex array object. Cogl doesn't use vertex
* array objects yet so for now we just create a dummy array
* object that we will use as our own default object. Eventually
* it could be good to attach the vertex array objects to
* CoglPrimitives */
context->glGenVertexArrays (1, &vertex_array);
context->glBindVertexArray (vertex_array);
}
#endif
context->current_modelview_entry = NULL; context->current_modelview_entry = NULL;
context->current_projection_entry = NULL; context->current_projection_entry = NULL;
_cogl_matrix_entry_identity_init (&context->identity_entry); _cogl_matrix_entry_identity_init (&context->identity_entry);
@ -430,13 +443,13 @@ cogl_context_new (CoglDisplay *display,
context->buffer_map_fallback_in_use = FALSE; context->buffer_map_fallback_in_use = FALSE;
/* As far as I can tell, GL_POINT_SPRITE doesn't have any effect /* As far as I can tell, GL_POINT_SPRITE doesn't have any effect
unless GL_COORD_REPLACE is enabled for an individual unless GL_COORD_REPLACE is enabled for an individual layer.
layer. Therefore it seems like it should be ok to just leave it Therefore it seems like it should be ok to just leave it enabled
enabled all the time instead of having to have a set property on all the time instead of having to have a set property on each
each pipeline to track whether any layers have point sprite pipeline to track whether any layers have point sprite coords
coords enabled. We don't need to do this for GLES2 because point enabled. We don't need to do this for GL3 or GLES2 because point
sprites are handled using a builtin varying in the shader. */ sprites are handled using a builtin varying in the shader. */
if (context->driver != COGL_DRIVER_GLES2 && if ((context->private_feature_flags & COGL_PRIVATE_FEATURE_FIXED_FUNCTION) &&
cogl_has_feature (context, COGL_FEATURE_ID_POINT_SPRITE)) cogl_has_feature (context, COGL_FEATURE_ID_POINT_SPRITE))
GE (context, glEnable (GL_POINT_SPRITE)); GE (context, glEnable (GL_POINT_SPRITE));
@ -610,38 +623,45 @@ _cogl_context_set_current_modelview_entry (CoglContext *context,
context->current_modelview_entry = entry; context->current_modelview_entry = entry;
} }
const char * char **
_cogl_context_get_gl_extensions (CoglContext *context) _cogl_context_get_gl_extensions (CoglContext *context)
{ {
const char *env_disabled_extensions; const char *env_disabled_extensions;
char **ret;
/* In GL 3, querying GL_EXTENSIONS is deprecated so we have to build
* the array using glGetStringi instead */
if (context->driver == COGL_DRIVER_GL3)
{
int num_extensions, i;
context->glGetIntegerv (GL_NUM_EXTENSIONS, &num_extensions);
ret = g_malloc (sizeof (char *) * (num_extensions + 1));
for (i = 0; i < num_extensions; i++)
{
const char *ext =
(const char *) context->glGetStringi (GL_EXTENSIONS, i);
ret[i] = g_strdup (ext);
}
ret[num_extensions] = NULL;
}
else
{
const char *all_extensions =
(const char *) context->glGetString (GL_EXTENSIONS);
ret = g_strsplit (all_extensions, " ", 0 /* max tokens */);
}
if ((env_disabled_extensions = g_getenv ("COGL_DISABLE_GL_EXTENSIONS")) if ((env_disabled_extensions = g_getenv ("COGL_DISABLE_GL_EXTENSIONS"))
|| _cogl_config_disable_gl_extensions) || _cogl_config_disable_gl_extensions)
{ {
static CoglUserDataKey extensions_key;
const char *enabled_extensions;
char **split_enabled_extensions;
char **split_env_disabled_extensions; char **split_env_disabled_extensions;
char **split_conf_disabled_extensions; char **split_conf_disabled_extensions;
char **e; char **src, **dst;
GString *result;
/* We need to return a const string so we'll attach the results
* to the CoglContext to avoid leaking the generated string.
* This string is only used rarely so we are using
* cogl_object_set_user_data instead of adding an explicit
* member to CoglContext to avoid making the struct bigger */
enabled_extensions =
cogl_object_get_user_data (COGL_OBJECT (context), &extensions_key);
if (enabled_extensions)
return enabled_extensions;
enabled_extensions = (const char *) context->glGetString (GL_EXTENSIONS);
split_enabled_extensions = g_strsplit (enabled_extensions,
" ",
0 /* no max tokens */);
if (env_disabled_extensions) if (env_disabled_extensions)
split_env_disabled_extensions = split_env_disabled_extensions =
@ -659,46 +679,38 @@ _cogl_context_get_gl_extensions (CoglContext *context)
else else
split_conf_disabled_extensions = NULL; split_conf_disabled_extensions = NULL;
result = g_string_new (NULL); for (dst = ret, src = ret;
*src;
for (e = split_enabled_extensions; *e; e++) src++)
{ {
char **d; char **d;
if (split_env_disabled_extensions) if (split_env_disabled_extensions)
for (d = split_env_disabled_extensions; *d; d++) for (d = split_env_disabled_extensions; *d; d++)
if (!strcmp (*e, *d)) if (!strcmp (*src, *d))
goto disabled; goto disabled;
if (split_conf_disabled_extensions) if (split_conf_disabled_extensions)
for (d = split_conf_disabled_extensions; *d; d++) for (d = split_conf_disabled_extensions; *d; d++)
if (!strcmp (*e, *d)) if (!strcmp (*src, *d))
goto disabled; goto disabled;
if (result->len > 0) *(dst++) = *src;
g_string_append_c (result, ' '); continue;
g_string_append (result, *e);
disabled: disabled:
g_free (*src);
continue; continue;
} }
enabled_extensions = g_string_free (result, FALSE); *dst = NULL;
g_strfreev (split_enabled_extensions);
if (split_env_disabled_extensions) if (split_env_disabled_extensions)
g_strfreev (split_env_disabled_extensions); g_strfreev (split_env_disabled_extensions);
if (split_conf_disabled_extensions) if (split_conf_disabled_extensions)
g_strfreev (split_conf_disabled_extensions); g_strfreev (split_conf_disabled_extensions);
cogl_object_set_user_data (COGL_OBJECT (context),
&extensions_key,
(void *) enabled_extensions,
(CoglUserDataDestroyCallback) g_free);
return enabled_extensions;
} }
else
return (const char *) context->glGetString (GL_EXTENSIONS); return ret;
} }
const char * const char *

View File

@ -31,6 +31,7 @@
#include "cogl-feature-private.h" #include "cogl-feature-private.h"
#include "cogl-renderer-private.h" #include "cogl-renderer-private.h"
#include "cogl-private.h"
CoglBool CoglBool
_cogl_feature_check (CoglRenderer *renderer, _cogl_feature_check (CoglRenderer *renderer,
@ -39,7 +40,7 @@ _cogl_feature_check (CoglRenderer *renderer,
int gl_major, int gl_major,
int gl_minor, int gl_minor,
CoglDriver driver, CoglDriver driver,
const char *extensions_string, char * const *extensions,
void *function_table) void *function_table)
{ {
@ -49,7 +50,8 @@ _cogl_feature_check (CoglRenderer *renderer,
/* First check whether the functions should be directly provided by /* First check whether the functions should be directly provided by
GL */ GL */
if ((driver == COGL_DRIVER_GL && if (((driver == COGL_DRIVER_GL ||
driver == COGL_DRIVER_GL3) &&
COGL_CHECK_GL_VERSION (gl_major, gl_minor, COGL_CHECK_GL_VERSION (gl_major, gl_minor,
data->min_gl_major, data->min_gl_minor)) || data->min_gl_major, data->min_gl_minor)) ||
(driver == COGL_DRIVER_GLES1 && (driver == COGL_DRIVER_GLES1 &&
@ -97,7 +99,7 @@ _cogl_feature_check (CoglRenderer *renderer,
g_string_append_c (full_extension_name, '_'); g_string_append_c (full_extension_name, '_');
g_string_append (full_extension_name, extension); g_string_append (full_extension_name, extension);
if (_cogl_check_extension (full_extension_name->str, if (_cogl_check_extension (full_extension_name->str,
extensions_string)) extensions))
break; break;
} }
@ -192,7 +194,7 @@ void
_cogl_feature_check_ext_functions (CoglContext *context, _cogl_feature_check_ext_functions (CoglContext *context,
int gl_major, int gl_major,
int gl_minor, int gl_minor,
const char *gl_extensions) char * const *gl_extensions)
{ {
int i; int i;

View File

@ -87,13 +87,13 @@ _cogl_feature_check (CoglRenderer *renderer,
int gl_major, int gl_major,
int gl_minor, int gl_minor,
CoglDriver driver, CoglDriver driver,
const char *extensions_string, char * const *extensions,
void *function_table); void *function_table);
void void
_cogl_feature_check_ext_functions (CoglContext *context, _cogl_feature_check_ext_functions (CoglContext *context,
int gl_major, int gl_major,
int gl_minor, int gl_minor,
const char *gl_extensions); char * const *gl_extensions);
#endif /* __COGL_FEATURE_PRIVATE_H */ #endif /* __COGL_FEATURE_PRIVATE_H */

View File

@ -1556,7 +1556,8 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
GL_RGBA/GL_UNSIGNED_BYTE and convert if necessary. We also need GL_RGBA/GL_UNSIGNED_BYTE and convert if necessary. We also need
to use this intermediate buffer if the rowstride has padding to use this intermediate buffer if the rowstride has padding
because GLES does not support setting GL_ROW_LENGTH */ because GLES does not support setting GL_ROW_LENGTH */
if ((ctx->driver != COGL_DRIVER_GL && if ((!(ctx->private_feature_flags &
COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT) &&
(gl_format != GL_RGBA || gl_type != GL_UNSIGNED_BYTE || (gl_format != GL_RGBA || gl_type != GL_UNSIGNED_BYTE ||
cogl_bitmap_get_rowstride (bitmap) != 4 * width)) || cogl_bitmap_get_rowstride (bitmap) != 4 * width)) ||
(required_format & ~COGL_PREMULT_BIT) != (format & ~COGL_PREMULT_BIT)) (required_format & ~COGL_PREMULT_BIT) != (format & ~COGL_PREMULT_BIT))
@ -1567,7 +1568,8 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
uint8_t *tmp_data; uint8_t *tmp_data;
int succeeded; int succeeded;
if (ctx->driver == COGL_DRIVER_GL) if ((ctx->private_feature_flags &
COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT))
read_format = required_format; read_format = required_format;
else else
{ {

View File

@ -104,7 +104,17 @@ typedef enum
COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL = 1L<<8, COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL = 1L<<8,
COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888 = 1L<<9, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888 = 1L<<9,
COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE = 1L<<10, COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE = 1L<<10,
COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS = 1L<<11 COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS = 1L<<11,
COGL_PRIVATE_FEATURE_FIXED_FUNCTION = 1L<<12,
COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT = 1L<<13,
COGL_PRIVATE_FEATURE_ANY_GL = 1L<<14,
COGL_PRIVATE_FEATURE_ALPHA_TEST = 1L<<15,
COGL_PRIVATE_FEATURE_FORMAT_CONVERSION = 1L<<16,
COGL_PRIVATE_FEATURE_QUADS = 1L<<17,
COGL_PRIVATE_FEATURE_BLEND_CONSTANT = 1L<<18,
COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS = 1L<<19,
COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM = 1L<<20,
COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS = 1L<<21
} CoglPrivateFeatureFlags; } CoglPrivateFeatureFlags;
/* Sometimes when evaluating pipelines, either during comparisons or /* Sometimes when evaluating pipelines, either during comparisons or
@ -115,9 +125,6 @@ typedef enum _CoglPipelineEvalFlags
COGL_PIPELINE_EVAL_FLAG_NONE = 0 COGL_PIPELINE_EVAL_FLAG_NONE = 0
} CoglPipelineEvalFlags; } CoglPipelineEvalFlags;
CoglBool
_cogl_check_extension (const char *name, const char *ext);
uint32_t uint32_t
_cogl_driver_error_quark (void); _cogl_driver_error_quark (void);

View File

@ -303,7 +303,7 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
draw_flags |= COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE; draw_flags |= COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE;
#ifdef HAVE_COGL_GL #ifdef HAVE_COGL_GL
if (ctx->driver == COGL_DRIVER_GL) if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_QUADS))
{ {
/* XXX: it's rather evil that we sneak in the GL_QUADS enum here... */ /* XXX: it's rather evil that we sneak in the GL_QUADS enum here... */
_cogl_framebuffer_draw_attributes (framebuffer, _cogl_framebuffer_draw_attributes (framebuffer,
@ -615,7 +615,7 @@ _cogl_journal_flush_vbo_offsets_and_entries (CoglJournalEntry *batch_start,
4, 4,
COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE);
if (ctx->driver != COGL_DRIVER_GL) if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_QUADS))
state->indices = cogl_get_rectangle_indices (ctx, batch_len); state->indices = cogl_get_rectangle_indices (ctx, batch_len);
/* We only create new Attributes when the stride within the /* We only create new Attributes when the stride within the

View File

@ -795,8 +795,7 @@ _cogl_matrix_flush_to_gl_builtin (CoglContext *ctx,
CoglMatrix *matrix, CoglMatrix *matrix,
CoglMatrixMode mode) CoglMatrixMode mode)
{ {
g_assert (ctx->driver == COGL_DRIVER_GL || g_assert ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_FIXED_FUNCTION));
ctx->driver == COGL_DRIVER_GLES1);
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES) #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
if (ctx->flushed_matrix_mode != mode) if (ctx->flushed_matrix_mode != mode)
@ -836,8 +835,7 @@ _cogl_matrix_entry_flush_to_gl_builtins (CoglContext *ctx,
CoglFramebuffer *framebuffer, CoglFramebuffer *framebuffer,
CoglBool disable_flip) CoglBool disable_flip)
{ {
g_assert (ctx->driver == COGL_DRIVER_GL || g_assert ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_FIXED_FUNCTION));
ctx->driver == COGL_DRIVER_GLES1);
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES) #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
{ {

View File

@ -1037,7 +1037,7 @@ cogl_pipeline_set_blend_constant (CoglPipeline *pipeline,
_COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));
if (ctx->driver == COGL_DRIVER_GLES1) if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_BLEND_CONSTANT))
return; return;
#if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL) #if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL)

View File

@ -2824,8 +2824,10 @@ _cogl_pipeline_get_layer_state_for_fragment_codegen (CoglContext *context)
COGL_PIPELINE_LAYER_STATE_UNIT | COGL_PIPELINE_LAYER_STATE_UNIT |
COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS); COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS);
if (context->driver == COGL_DRIVER_GL || /* If the driver supports GLSL then we might be using gl_PointCoord
context->driver == COGL_DRIVER_GLES2) * to implement the sprite coords. In that case the generated code
* depends on the point sprite state */
if (cogl_has_feature (context, COGL_FEATURE_ID_GLSL))
state |= COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS; state |= COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS;
return state; return state;
@ -2838,7 +2840,7 @@ _cogl_pipeline_get_state_for_fragment_codegen (CoglContext *context)
COGL_PIPELINE_STATE_USER_SHADER | COGL_PIPELINE_STATE_USER_SHADER |
COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS); COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS);
if (context->driver == COGL_DRIVER_GLES2) if (!(context->private_feature_flags & COGL_PRIVATE_FEATURE_ALPHA_TEST))
state |= COGL_PIPELINE_STATE_ALPHA_FUNC; state |= COGL_PIPELINE_STATE_ALPHA_FUNC;
return state; return state;

View File

@ -31,7 +31,7 @@
G_BEGIN_DECLS G_BEGIN_DECLS
CoglBool CoglBool
_cogl_check_extension (const char *name, const char *ext); _cogl_check_extension (const char *name, char * const *ext);
void void
_cogl_clear (const CoglColor *color, unsigned long buffers); _cogl_clear (const CoglColor *color, unsigned long buffers);

View File

@ -286,6 +286,15 @@ _cogl_renderer_choose_driver (CoglRenderer *renderer,
libgl_name = COGL_GL_LIBNAME; libgl_name = COGL_GL_LIBNAME;
goto found; goto found;
} }
if (renderer->driver_override == COGL_DRIVER_GL3 ||
(renderer->driver_override == COGL_DRIVER_ANY &&
(driver_name == NULL || !g_ascii_strcasecmp (driver_name, "gl3"))))
{
renderer->driver = COGL_DRIVER_GL3;
libgl_name = COGL_GL_LIBNAME;
goto found;
}
#endif #endif
#ifdef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES2
@ -340,6 +349,7 @@ found:
#ifndef HAVE_DIRECTLY_LINKED_GL_LIBRARY #ifndef HAVE_DIRECTLY_LINKED_GL_LIBRARY
if (renderer->driver == COGL_DRIVER_GL || if (renderer->driver == COGL_DRIVER_GL ||
renderer->driver == COGL_DRIVER_GL3 ||
renderer->driver == COGL_DRIVER_GLES1 || renderer->driver == COGL_DRIVER_GLES1 ||
renderer->driver == COGL_DRIVER_GLES2) renderer->driver == COGL_DRIVER_GLES2)
{ {
@ -362,6 +372,7 @@ found:
{ {
#ifdef HAVE_COGL_GL #ifdef HAVE_COGL_GL
case COGL_DRIVER_GL: case COGL_DRIVER_GL:
case COGL_DRIVER_GL3:
renderer->driver_vtable = &_cogl_driver_gl; renderer->driver_vtable = &_cogl_driver_gl;
renderer->texture_driver = &_cogl_texture_driver_gl; renderer->texture_driver = &_cogl_texture_driver_gl;
break; break;
@ -579,7 +590,7 @@ cogl_renderer_get_n_fragment_texture_units (CoglRenderer *renderer)
_COGL_GET_CONTEXT (ctx, 0); _COGL_GET_CONTEXT (ctx, 0);
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES2) #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES2)
if (ctx->driver == COGL_DRIVER_GL || ctx->driver == COGL_DRIVER_GLES2) if (cogl_has_feature (ctx, COGL_FEATURE_ID_GLSL))
GE (ctx, glGetIntegerv (GL_MAX_TEXTURE_IMAGE_UNITS, &n)); GE (ctx, glGetIntegerv (GL_MAX_TEXTURE_IMAGE_UNITS, &n));
#endif #endif

View File

@ -330,6 +330,7 @@ cogl_renderer_remove_constraint (CoglRenderer *renderer,
* @COGL_DRIVER_ANY: Implies no preference for which driver is used * @COGL_DRIVER_ANY: Implies no preference for which driver is used
* @COGL_DRIVER_NOP: A No-Op driver. * @COGL_DRIVER_NOP: A No-Op driver.
* @COGL_DRIVER_GL: An OpenGL driver. * @COGL_DRIVER_GL: An OpenGL driver.
* @COGL_DRIVER_GL3: An OpenGL driver using the core GL 3.1 profile
* @COGL_DRIVER_GLES1: An OpenGL ES 1.1 driver. * @COGL_DRIVER_GLES1: An OpenGL ES 1.1 driver.
* @COGL_DRIVER_GLES2: An OpenGL ES 2.0 driver. * @COGL_DRIVER_GLES2: An OpenGL ES 2.0 driver.
* *
@ -344,6 +345,7 @@ typedef enum
COGL_DRIVER_ANY, COGL_DRIVER_ANY,
COGL_DRIVER_NOP, COGL_DRIVER_NOP,
COGL_DRIVER_GL, COGL_DRIVER_GL,
COGL_DRIVER_GL3,
COGL_DRIVER_GLES1, COGL_DRIVER_GLES1,
COGL_DRIVER_GLES2 COGL_DRIVER_GLES2
} CoglDriver; } CoglDriver;

View File

@ -239,7 +239,8 @@ _cogl_shader_compile_real (CoglHandle handle,
shader->gl_handle = ctx->glCreateShader (gl_type); shader->gl_handle = ctx->glCreateShader (gl_type);
if (ctx->driver == COGL_DRIVER_GL && if ((ctx->driver == COGL_DRIVER_GL ||
ctx->driver == COGL_DRIVER_GL3 ) &&
ctx->glsl_major == 1 && ctx->glsl_major == 1 &&
ctx->glsl_minor >= 2) ctx->glsl_minor >= 2)
{ {

View File

@ -206,7 +206,7 @@ _cogl_texture_prepare_for_upload (CoglBitmap *src_bmp,
limited number of formats so we must convert using the Cogl limited number of formats so we must convert using the Cogl
bitmap code instead */ bitmap code instead */
if (ctx->driver == COGL_DRIVER_GL) if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_FORMAT_CONVERSION))
{ {
/* If the source format does not have the same premult flag as the /* If the source format does not have the same premult flag as the
dst format then we need to copy and convert it */ dst format then we need to copy and convert it */

View File

@ -51,6 +51,7 @@
#include "cogl1-context.h" #include "cogl1-context.h"
#include "cogl-offscreen.h" #include "cogl-offscreen.h"
#include "cogl-attribute-gl-private.h" #include "cogl-attribute-gl-private.h"
#include "cogl-clutter.h"
#ifdef COGL_GL_DEBUG #ifdef COGL_GL_DEBUG
/* GL error to string conversion */ /* GL error to string conversion */
@ -99,26 +100,13 @@ cogl_get_proc_address (const char* name)
} }
CoglBool CoglBool
_cogl_check_extension (const char *name, const gchar *ext) _cogl_check_extension (const char *name, char * const *ext)
{ {
char *end; while (*ext)
int name_len, n; if (!strcmp (name, *ext))
if (name == NULL || ext == NULL)
return FALSE;
end = (char*)(ext + strlen(ext));
name_len = strlen(name);
while (ext < end)
{
n = strcspn(ext, " ");
if ((name_len == n) && (!strncmp(name, ext, n)))
return TRUE; return TRUE;
ext += (n + 1); else
} ext++;
return FALSE; return FALSE;
} }
@ -127,7 +115,7 @@ _cogl_check_extension (const char *name, const gchar *ext)
CoglBool CoglBool
cogl_check_extension (const char *name, const char *ext) cogl_check_extension (const char *name, const char *ext)
{ {
return _cogl_check_extension (name, ext); return cogl_clutter_check_extension (name, ext);
} }
/* XXX: it's expected that we'll deprecated this with /* XXX: it's expected that we'll deprecated this with

View File

@ -54,8 +54,8 @@ toggle_builtin_attribute_enabled_cb (int bit_num, void *user_data)
ForeachChangedBitState *state = user_data; ForeachChangedBitState *state = user_data;
CoglContext *context = state->context; CoglContext *context = state->context;
_COGL_RETURN_VAL_IF_FAIL (context->driver == COGL_DRIVER_GL || _COGL_RETURN_VAL_IF_FAIL ((context->private_feature_flags &
context->driver == COGL_DRIVER_GLES1, COGL_PRIVATE_FEATURE_FIXED_FUNCTION),
FALSE); FALSE);
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES) #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
@ -91,8 +91,8 @@ toggle_texcood_attribute_enabled_cb (int bit_num, void *user_data)
ForeachChangedBitState *state = user_data; ForeachChangedBitState *state = user_data;
CoglContext *context = state->context; CoglContext *context = state->context;
_COGL_RETURN_VAL_IF_FAIL (context->driver == COGL_DRIVER_GL || _COGL_RETURN_VAL_IF_FAIL ((context->private_feature_flags &
context->driver == COGL_DRIVER_GLES1, COGL_PRIVATE_FEATURE_FIXED_FUNCTION),
FALSE); FALSE);
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES) #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)

View File

@ -122,6 +122,7 @@ set_clip_plane (CoglFramebuffer *framebuffer,
break; break;
case COGL_DRIVER_GL: case COGL_DRIVER_GL:
case COGL_DRIVER_GL3:
planed[0] = planef[0]; planed[0] = planef[0];
planed[1] = planef[1]; planed[1] = planef[1];
planed[2] = planef[2]; planed[2] = planef[2];

View File

@ -896,8 +896,8 @@ _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
return; return;
#ifdef HAVE_COGL_GL #ifdef HAVE_COGL_GL
if (ctx->driver == COGL_DRIVER_GL && if ((ctx->private_feature_flags &
cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN) && COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS) &&
framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN) framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN)
{ {
GLenum attachment, pname; GLenum attachment, pname;

View File

@ -913,10 +913,10 @@ _cogl_pipeline_fragend_glsl_add_layer (CoglPipeline *pipeline,
return TRUE; return TRUE;
} }
/* GLES2 doesn't have alpha testing so we need to implement it in the /* GLES2 and GL3 don't have alpha testing so we need to implement it
shader */ in the shader */
#ifdef HAVE_COGL_GLES2 #if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL)
static void static void
add_alpha_test_snippet (CoglPipeline *pipeline, add_alpha_test_snippet (CoglPipeline *pipeline,
@ -1046,8 +1046,8 @@ _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline,
g_string_append (shader_state->source, g_string_append (shader_state->source,
" cogl_color_out = cogl_color_in;\n"); " cogl_color_out = cogl_color_in;\n");
#ifdef HAVE_COGL_GLES2 #if defined(HAVE_COGL_GLES2) || defined (HAVE_COGL_GL)
if (ctx->driver == COGL_DRIVER_GLES2) if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_ALPHA_TEST))
add_alpha_test_snippet (pipeline, shader_state); add_alpha_test_snippet (pipeline, shader_state);
#endif #endif
@ -1072,10 +1072,9 @@ _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline,
source_strings[1] = shader_state->source->str; source_strings[1] = shader_state->source->str;
if (shader_state->ref_point_coord && if (shader_state->ref_point_coord &&
ctx->driver == COGL_DRIVER_GL) (ctx->driver == COGL_DRIVER_GL ||
{ ctx->driver == COGL_DRIVER_GL3))
version_string = "#version 120\n"; version_string = "#version 120\n";
}
else else
version_string = NULL; version_string = NULL;

View File

@ -452,7 +452,7 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state (
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* On GLES2 we'll flush the color later */ /* On GLES2 we'll flush the color later */
if (ctx->driver != COGL_DRIVER_GLES2 && if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_FIXED_FUNCTION) &&
!skip_gl_color) !skip_gl_color)
{ {
if ((pipelines_difference & COGL_PIPELINE_STATE_COLOR) || if ((pipelines_difference & COGL_PIPELINE_STATE_COLOR) ||
@ -531,7 +531,7 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state (
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES) #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
if (ctx->driver != COGL_DRIVER_GLES2) if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_ALPHA_TEST))
{ {
/* Under GLES2 the alpha function is implemented as part of the /* Under GLES2 the alpha function is implemented as part of the
fragment shader */ fragment shader */
@ -675,7 +675,8 @@ get_max_activateable_texture_units (void)
int i; int i;
#ifdef HAVE_COGL_GL #ifdef HAVE_COGL_GL
if (ctx->driver == COGL_DRIVER_GL) if (ctx->driver == COGL_DRIVER_GL ||
ctx->driver == COGL_DRIVER_GL3)
{ {
/* GL_MAX_TEXTURE_COORDS is provided for both GLSL and ARBfp. It /* GL_MAX_TEXTURE_COORDS is provided for both GLSL and ARBfp. It
defines the number of texture coordinates that can be defines the number of texture coordinates that can be
@ -856,7 +857,7 @@ flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data)
* glsl progend. * glsl progend.
*/ */
#if defined (HAVE_COGL_GLES) || defined (HAVE_COGL_GL) #if defined (HAVE_COGL_GLES) || defined (HAVE_COGL_GL)
if (ctx->driver != COGL_DRIVER_GLES2 && if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_FIXED_FUNCTION) &&
(layers_difference & COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS)) (layers_difference & COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS))
{ {
CoglPipelineState change = COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS; CoglPipelineState change = COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS;

View File

@ -48,7 +48,7 @@ _cogl_pipeline_progend_fixed_start (CoglPipeline *pipeline)
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_FIXED))) if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_FIXED)))
return FALSE; return FALSE;
if (ctx->driver == COGL_DRIVER_GLES2) if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_FIXED_FUNCTION))
return FALSE; return FALSE;
/* Vertex snippets are only supported in the GLSL fragend */ /* Vertex snippets are only supported in the GLSL fragend */

View File

@ -261,7 +261,8 @@ _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline,
"cogl_generated_source ()\n" "cogl_generated_source ()\n"
"{\n"); "{\n");
if (ctx->driver == COGL_DRIVER_GLES2) if (!(ctx->private_feature_flags &
COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM))
/* There is no builtin uniform for the pointsize on GLES2 so we need /* There is no builtin uniform for the pointsize on GLES2 so we need
to copy it from the custom uniform in the vertex shader */ to copy it from the custom uniform in the vertex shader */
g_string_append (shader_state->source, g_string_append (shader_state->source,
@ -460,7 +461,8 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline,
shader_state->gl_shader = shader; shader_state->gl_shader = shader;
} }
if (ctx->driver == COGL_DRIVER_GL && if ((ctx->private_feature_flags &
COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM) &&
(pipelines_difference & COGL_PIPELINE_STATE_POINT_SIZE)) (pipelines_difference & COGL_PIPELINE_STATE_POINT_SIZE))
{ {
CoglPipeline *authority = CoglPipeline *authority =

View File

@ -323,7 +323,8 @@ cogl_texture_2d_new_from_foreign (CoglContext *ctx,
(only level 0 we are interested in) */ (only level 0 we are interested in) */
#if HAVE_COGL_GL #if HAVE_COGL_GL
if (ctx->driver == COGL_DRIVER_GL) if ((ctx->private_feature_flags &
COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS))
{ {
GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_2D, 0,
GL_TEXTURE_COMPRESSED, GL_TEXTURE_COMPRESSED,

View File

@ -291,10 +291,10 @@ _cogl_get_gl_version (CoglContext *ctx,
static CoglBool static CoglBool
check_gl_version (CoglContext *ctx, check_gl_version (CoglContext *ctx,
char **gl_extensions,
CoglError **error) CoglError **error)
{ {
int major, minor; int major, minor;
const char *gl_extensions;
if (!_cogl_get_gl_version (ctx, &major, &minor)) if (!_cogl_get_gl_version (ctx, &major, &minor))
{ {
@ -309,8 +309,6 @@ check_gl_version (CoglContext *ctx,
if (COGL_CHECK_GL_VERSION (major, minor, 1, 3)) if (COGL_CHECK_GL_VERSION (major, minor, 1, 3))
return TRUE; return TRUE;
gl_extensions = _cogl_context_get_gl_extensions (ctx);
/* OpenGL 1.2 is only supported if we have the multitexturing /* OpenGL 1.2 is only supported if we have the multitexturing
extension */ extension */
if (!_cogl_check_extension ("GL_ARB_multitexture", gl_extensions)) if (!_cogl_check_extension ("GL_ARB_multitexture", gl_extensions))
@ -344,22 +342,36 @@ _cogl_driver_update_features (CoglContext *ctx,
{ {
CoglPrivateFeatureFlags private_flags = 0; CoglPrivateFeatureFlags private_flags = 0;
CoglFeatureFlags flags = 0; CoglFeatureFlags flags = 0;
const char *gl_extensions; char **gl_extensions;
int max_clip_planes = 0; int max_clip_planes = 0;
int num_stencil_bits = 0; int num_stencil_bits = 0;
int gl_major = 0, gl_minor = 0; int gl_major = 0, gl_minor = 0;
/* We have to special case getting the pointer to the glGetString /* We have to special case getting the pointer to the glGetString*
function because we need to use it to determine what functions we functions because we need to use them to determine what functions
can expect */ we can expect */
ctx->glGetString = ctx->glGetString =
(void *) _cogl_renderer_get_proc_address (ctx->display->renderer, (void *) _cogl_renderer_get_proc_address (ctx->display->renderer,
"glGetString", "glGetString",
TRUE); TRUE);
ctx->glGetStringi =
(void *) _cogl_renderer_get_proc_address (ctx->display->renderer,
"glGetStringi",
TRUE);
ctx->glGetIntegerv =
(void *) _cogl_renderer_get_proc_address (ctx->display->renderer,
"glGetIntegerv",
TRUE);
if (!check_gl_version (ctx, error)) gl_extensions = _cogl_context_get_gl_extensions (ctx);
if (!check_gl_version (ctx, gl_extensions, error))
return FALSE; return FALSE;
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WINSYS)))
{
char *all_extensions = g_strjoinv (" ", gl_extensions);
COGL_NOTE (WINSYS, COGL_NOTE (WINSYS,
"Checking features\n" "Checking features\n"
" GL_VENDOR: %s\n" " GL_VENDOR: %s\n"
@ -369,7 +381,10 @@ _cogl_driver_update_features (CoglContext *ctx,
ctx->glGetString (GL_VENDOR), ctx->glGetString (GL_VENDOR),
ctx->glGetString (GL_RENDERER), ctx->glGetString (GL_RENDERER),
_cogl_context_get_gl_version (ctx), _cogl_context_get_gl_version (ctx),
_cogl_context_get_gl_extensions (ctx)); all_extensions);
g_free (all_extensions);
}
_cogl_get_gl_version (ctx, &gl_major, &gl_minor); _cogl_get_gl_version (ctx, &gl_major, &gl_minor);
@ -395,8 +410,6 @@ _cogl_driver_update_features (CoglContext *ctx,
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 1, 4)) if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 1, 4))
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_MIRRORED_REPEAT, TRUE); COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_MIRRORED_REPEAT, TRUE);
gl_extensions = _cogl_context_get_gl_extensions (ctx);
_cogl_feature_check_ext_functions (ctx, _cogl_feature_check_ext_functions (ctx,
gl_major, gl_major,
gl_minor, gl_minor,
@ -434,6 +447,7 @@ _cogl_driver_update_features (CoglContext *ctx,
{ {
flags |= COGL_FEATURE_OFFSCREEN; flags |= COGL_FEATURE_OFFSCREEN;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_OFFSCREEN, TRUE); COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_OFFSCREEN, TRUE);
private_flags |= COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS;
} }
if (ctx->glBlitFramebuffer) if (ctx->glBlitFramebuffer)
@ -457,6 +471,10 @@ _cogl_driver_update_features (CoglContext *ctx,
_cogl_check_extension ("GL_EXT_pixel_buffer_object", gl_extensions)) _cogl_check_extension ("GL_EXT_pixel_buffer_object", gl_extensions))
private_flags |= COGL_PRIVATE_FEATURE_PBOS; private_flags |= COGL_PRIVATE_FEATURE_PBOS;
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 1, 4) ||
_cogl_check_extension ("GL_EXT_blend_color", gl_extensions))
private_flags |= COGL_PRIVATE_FEATURE_BLEND_CONSTANT;
if (ctx->glGenPrograms) if (ctx->glGenPrograms)
{ {
flags |= COGL_FEATURE_SHADERS_ARBFP; flags |= COGL_FEATURE_SHADERS_ARBFP;
@ -546,10 +564,25 @@ _cogl_driver_update_features (CoglContext *ctx,
if (ctx->glGenSamplers) if (ctx->glGenSamplers)
private_flags |= COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS; private_flags |= COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS;
if (ctx->driver == COGL_DRIVER_GL)
/* Features which are not available in GL 3 */
private_flags |= (COGL_PRIVATE_FEATURE_FIXED_FUNCTION |
COGL_PRIVATE_FEATURE_ALPHA_TEST |
COGL_PRIVATE_FEATURE_QUADS);
private_flags |= (COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT |
COGL_PRIVATE_FEATURE_ANY_GL |
COGL_PRIVATE_FEATURE_FORMAT_CONVERSION |
COGL_PRIVATE_FEATURE_BLEND_CONSTANT |
COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM |
COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS);
/* Cache features */ /* Cache features */
ctx->private_feature_flags |= private_flags; ctx->private_feature_flags |= private_flags;
ctx->feature_flags |= flags; ctx->feature_flags |= flags;
g_strfreev (gl_extensions);
return TRUE; return TRUE;
} }

View File

@ -51,7 +51,7 @@ _cogl_pipeline_progend_fixed_arbfp_start (CoglPipeline *pipeline)
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_FIXED))) if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_FIXED)))
return FALSE; return FALSE;
if (ctx->driver == COGL_DRIVER_GLES2) if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_FIXED_FUNCTION))
return FALSE; return FALSE;
/* Vertex snippets are only supported in the GLSL fragend */ /* Vertex snippets are only supported in the GLSL fragend */

View File

@ -192,7 +192,7 @@ _cogl_driver_update_features (CoglContext *context,
{ {
CoglPrivateFeatureFlags private_flags = 0; CoglPrivateFeatureFlags private_flags = 0;
CoglFeatureFlags flags = 0; CoglFeatureFlags flags = 0;
const char *gl_extensions; char **gl_extensions;
int num_stencil_bits = 0; int num_stencil_bits = 0;
/* We have to special case getting the pointer to the glGetString /* We have to special case getting the pointer to the glGetString
@ -203,6 +203,12 @@ _cogl_driver_update_features (CoglContext *context,
"glGetString", "glGetString",
TRUE); TRUE);
gl_extensions = _cogl_context_get_gl_extensions (context);
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WINSYS)))
{
char *all_extensions = g_strjoinv (" ", gl_extensions);
COGL_NOTE (WINSYS, COGL_NOTE (WINSYS,
"Checking features\n" "Checking features\n"
" GL_VENDOR: %s\n" " GL_VENDOR: %s\n"
@ -212,14 +218,15 @@ _cogl_driver_update_features (CoglContext *context,
context->glGetString (GL_VENDOR), context->glGetString (GL_VENDOR),
context->glGetString (GL_RENDERER), context->glGetString (GL_RENDERER),
_cogl_context_get_gl_version (context), _cogl_context_get_gl_version (context),
_cogl_context_get_gl_extensions (context)); all_extensions);
_cogl_gpu_info_init (context, &context->gpu); g_free (all_extensions);
}
context->glsl_major = 1; context->glsl_major = 1;
context->glsl_minor = 0; context->glsl_minor = 0;
gl_extensions = _cogl_context_get_gl_extensions (context); _cogl_gpu_info_init (context, &context->gpu);
_cogl_feature_check_ext_functions (context, _cogl_feature_check_ext_functions (context,
-1 /* GL major version */, -1 /* GL major version */,
@ -255,9 +262,16 @@ _cogl_driver_update_features (CoglContext *context,
COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_DEPTH_RANGE, TRUE); COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_DEPTH_RANGE, TRUE);
COGL_FLAGS_SET (context->features, COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_MIRRORED_REPEAT, TRUE); COGL_FEATURE_ID_MIRRORED_REPEAT, TRUE);
}
private_flags |= COGL_PRIVATE_FEATURE_VBOS; private_flags |= COGL_PRIVATE_FEATURE_BLEND_CONSTANT;
}
else if (context->driver == COGL_DRIVER_GLES1)
private_flags |= (COGL_PRIVATE_FEATURE_FIXED_FUNCTION |
COGL_PRIVATE_FEATURE_ALPHA_TEST |
COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM);
private_flags |= (COGL_PRIVATE_FEATURE_VBOS |
COGL_PRIVATE_FEATURE_ANY_GL);
/* Both GLES 1.1 and GLES 2.0 support point sprites in core */ /* Both GLES 1.1 and GLES 2.0 support point sprites in core */
flags |= COGL_FEATURE_POINT_SPRITE; flags |= COGL_FEATURE_POINT_SPRITE;
@ -341,6 +355,8 @@ _cogl_driver_update_features (CoglContext *context,
context->private_feature_flags |= private_flags; context->private_feature_flags |= private_flags;
context->feature_flags |= flags; context->feature_flags |= flags;
g_strfreev (gl_extensions);
return TRUE; return TRUE;
} }

View File

@ -128,7 +128,7 @@ COGL_EXT_END ()
COGL_EXT_BEGIN (offscreen_blit, 255, 255, COGL_EXT_BEGIN (offscreen_blit, 3, 0,
0, /* not in either GLES */ 0, /* not in either GLES */
"EXT\0ANGLE\0", "EXT\0ANGLE\0",
"framebuffer_blit\0") "framebuffer_blit\0")
@ -211,7 +211,7 @@ COGL_EXT_FUNCTION (void, glFramebufferTexture2DMultisampleIMG,
GLsizei samples)) GLsizei samples))
COGL_EXT_END () COGL_EXT_END ()
COGL_EXT_BEGIN (ARB_sampler_objects, 255, 255, COGL_EXT_BEGIN (ARB_sampler_objects, 3, 3,
0, /* not in either GLES */ 0, /* not in either GLES */
"ARB:\0", "ARB:\0",
"sampler_objects\0") "sampler_objects\0")
@ -264,3 +264,25 @@ COGL_EXT_FUNCTION (void, glGetAttachedObjects,
GLsizei* count, GLsizei* count,
GLuint* shaders)) GLuint* shaders))
COGL_EXT_END () COGL_EXT_END ()
COGL_EXT_BEGIN (only_gl3, 3, 0,
0, /* not in either GLES */
"\0",
"\0")
COGL_EXT_FUNCTION (const GLubyte *, glGetStringi,
(GLenum name, GLuint index))
COGL_EXT_END ()
COGL_EXT_BEGIN (vertex_array_object, 3, 0,
0, /* not in either GLES */
"ARB\0OES\0",
"vertex_array_object\0")
COGL_EXT_FUNCTION (void, glBindVertexArray,
(GLuint array))
COGL_EXT_FUNCTION (void, glDeleteVertexArrays,
(GLsizei n,
const GLuint *arrays))
COGL_EXT_FUNCTION (void, glGenVertexArrays,
(GLsizei n,
GLuint *arrays))
COGL_EXT_END ()

View File

@ -50,11 +50,11 @@
*/ */
COGL_EXT_BEGIN (only_in_both_gles, COGL_EXT_BEGIN (only_in_both_gles,
255, 255, 4, 1,
COGL_EXT_IN_GLES | COGL_EXT_IN_GLES |
COGL_EXT_IN_GLES2, COGL_EXT_IN_GLES2,
"\0", "ARB\0",
"\0") "ES2_compatibility\0")
COGL_EXT_FUNCTION (void, glDepthRangef, COGL_EXT_FUNCTION (void, glDepthRangef,
(GLfloat near_val, GLfloat far_val)) (GLfloat near_val, GLfloat far_val))
COGL_EXT_FUNCTION (void, glClearDepthf, COGL_EXT_FUNCTION (void, glClearDepthf,

View File

@ -50,7 +50,7 @@
*/ */
COGL_EXT_BEGIN (offscreen, COGL_EXT_BEGIN (offscreen,
255, 255, 3, 0,
COGL_EXT_IN_GLES2, COGL_EXT_IN_GLES2,
/* for some reason the ARB version of this /* for some reason the ARB version of this
extension doesn't have an ARB suffix for the extension doesn't have an ARB suffix for the
@ -146,10 +146,10 @@ COGL_EXT_FUNCTION (void, glBlendEquationSeparate,
COGL_EXT_END () COGL_EXT_END ()
COGL_EXT_BEGIN (gles2_only_api, COGL_EXT_BEGIN (gles2_only_api,
255, 255, 4, 1,
COGL_EXT_IN_GLES2, COGL_EXT_IN_GLES2,
"\0", "ARB:\0",
"\0") "ES2_compatibility\0")
COGL_EXT_FUNCTION (void, glReleaseShaderCompiler, (void)) COGL_EXT_FUNCTION (void, glReleaseShaderCompiler, (void))
COGL_EXT_FUNCTION (void, glGetShaderPrecisionFormat, COGL_EXT_FUNCTION (void, glGetShaderPrecisionFormat,
(GLenum shadertype, (GLenum shadertype,

View File

@ -87,4 +87,11 @@ COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglUnbindWaylandDisplay,
(EGLDisplay dpy, (EGLDisplay dpy,
struct wl_display *wayland_display)) struct wl_display *wayland_display))
COGL_WINSYS_FEATURE_END () COGL_WINSYS_FEATURE_END ()
COGL_WINSYS_FEATURE_BEGIN (create_context,
"KHR\0",
"create_context\0",
COGL_EGL_WINSYS_FEATURE_CREATE_CONTEXT)
COGL_WINSYS_FEATURE_END ()
#endif #endif

View File

@ -68,7 +68,8 @@ typedef enum _CoglEGLWinsysFeature
{ {
COGL_EGL_WINSYS_FEATURE_SWAP_REGION =1L<<0, COGL_EGL_WINSYS_FEATURE_SWAP_REGION =1L<<0,
COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP =1L<<1, COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP =1L<<1,
COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_WAYLAND_BUFFER =1L<<2 COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_WAYLAND_BUFFER =1L<<2,
COGL_EGL_WINSYS_FEATURE_CREATE_CONTEXT =1L<<3
} CoglEGLWinsysFeature; } CoglEGLWinsysFeature;
typedef struct _CoglRendererEGL typedef struct _CoglRendererEGL

View File

@ -148,9 +148,11 @@ check_egl_extensions (CoglRenderer *renderer)
{ {
CoglRendererEGL *egl_renderer = renderer->winsys; CoglRendererEGL *egl_renderer = renderer->winsys;
const char *egl_extensions; const char *egl_extensions;
char **split_extensions;
int i; int i;
egl_extensions = eglQueryString (egl_renderer->edpy, EGL_EXTENSIONS); egl_extensions = eglQueryString (egl_renderer->edpy, EGL_EXTENSIONS);
split_extensions = g_strsplit (egl_extensions, " ", 0 /* max_tokens */);
COGL_NOTE (WINSYS, " EGL Extensions: %s", egl_extensions); COGL_NOTE (WINSYS, " EGL Extensions: %s", egl_extensions);
@ -159,12 +161,14 @@ check_egl_extensions (CoglRenderer *renderer)
if (_cogl_feature_check (renderer, if (_cogl_feature_check (renderer,
"EGL", winsys_feature_data + i, 0, 0, "EGL", winsys_feature_data + i, 0, 0,
COGL_DRIVER_GL, /* the driver isn't used */ COGL_DRIVER_GL, /* the driver isn't used */
egl_extensions, split_extensions,
egl_renderer)) egl_renderer))
{ {
egl_renderer->private_features |= egl_renderer->private_features |=
winsys_feature_data[i].feature_flags_private; winsys_feature_data[i].feature_flags_private;
} }
g_strfreev (split_extensions);
} }
CoglBool CoglBool
@ -234,7 +238,8 @@ egl_attributes_from_framebuffer_config (CoglDisplay *display,
attributes[i++] = EGL_DONT_CARE; attributes[i++] = EGL_DONT_CARE;
attributes[i++] = EGL_RENDERABLE_TYPE; attributes[i++] = EGL_RENDERABLE_TYPE;
attributes[i++] = (renderer->driver == COGL_DRIVER_GL ? attributes[i++] = ((renderer->driver == COGL_DRIVER_GL ||
renderer->driver == COGL_DRIVER_GL3) ?
EGL_OPENGL_BIT : EGL_OPENGL_BIT :
renderer->driver == COGL_DRIVER_GLES1 ? renderer->driver == COGL_DRIVER_GLES1 ?
EGL_OPENGL_ES_BIT : EGL_OPENGL_ES_BIT :
@ -314,24 +319,16 @@ try_create_context (CoglDisplay *display,
EGLConfig config; EGLConfig config;
EGLint config_count = 0; EGLint config_count = 0;
EGLBoolean status; EGLBoolean status;
EGLint attribs[3]; EGLint attribs[9];
EGLint cfg_attribs[MAX_EGL_CONFIG_ATTRIBS]; EGLint cfg_attribs[MAX_EGL_CONFIG_ATTRIBS];
const char *error_message; const char *error_message;
_COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context == NULL, TRUE); _COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context == NULL, TRUE);
if (renderer->driver == COGL_DRIVER_GL) if (renderer->driver == COGL_DRIVER_GL ||
renderer->driver == COGL_DRIVER_GL3)
eglBindAPI (EGL_OPENGL_API); eglBindAPI (EGL_OPENGL_API);
if (display->renderer->driver == COGL_DRIVER_GLES2)
{
attribs[0] = EGL_CONTEXT_CLIENT_VERSION;
attribs[1] = 2;
attribs[2] = EGL_NONE;
}
else
attribs[0] = EGL_NONE;
egl_attributes_from_framebuffer_config (display, egl_attributes_from_framebuffer_config (display,
&display->onscreen_template->config, &display->onscreen_template->config,
cfg_attribs); cfg_attribs);
@ -350,10 +347,40 @@ try_create_context (CoglDisplay *display,
egl_display->egl_config = config; egl_display->egl_config = config;
if (display->renderer->driver == COGL_DRIVER_GL3)
{
if (!(egl_renderer->private_features &
COGL_EGL_WINSYS_FEATURE_CREATE_CONTEXT))
{
error_message = "Driver does not support GL 3 contexts";
goto fail;
}
/* Try to get a core profile 3.1 context with no deprecated features */
attribs[0] = EGL_CONTEXT_MAJOR_VERSION_KHR;
attribs[1] = 3;
attribs[2] = EGL_CONTEXT_MINOR_VERSION_KHR;
attribs[3] = 1;
attribs[4] = EGL_CONTEXT_FLAGS_KHR;
attribs[5] = EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
attribs[6] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
attribs[7] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
attribs[8] = EGL_NONE;
}
else if (display->renderer->driver == COGL_DRIVER_GLES2)
{
attribs[0] = EGL_CONTEXT_CLIENT_VERSION;
attribs[1] = 2;
attribs[2] = EGL_NONE;
}
else
attribs[0] = EGL_NONE;
egl_display->egl_context = eglCreateContext (edpy, egl_display->egl_context = eglCreateContext (edpy,
config, config,
EGL_NO_CONTEXT, EGL_NO_CONTEXT,
attribs); attribs);
if (egl_display->egl_context == EGL_NO_CONTEXT) if (egl_display->egl_context == EGL_NO_CONTEXT)
{ {
error_message = "Unable to create a suitable EGL context"; error_message = "Unable to create a suitable EGL context";

View File

@ -111,3 +111,17 @@ COGL_WINSYS_FEATURE_BEGIN (swap_event,
0, 0,
COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT) COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT)
COGL_WINSYS_FEATURE_END () COGL_WINSYS_FEATURE_END ()
COGL_WINSYS_FEATURE_BEGIN (create_context,
"ARB\0",
"create_context",
0,
0,
0)
COGL_WINSYS_FEATURE_FUNCTION (GLXContext, glXCreateContextAttribs,
(Display *dpy,
GLXFBConfig config,
GLXContext share_context,
Bool direct,
const int *attrib_list))
COGL_WINSYS_FEATURE_END ()

View File

@ -331,7 +331,8 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
if (!_cogl_xlib_renderer_connect (renderer, error)) if (!_cogl_xlib_renderer_connect (renderer, error))
goto error; goto error;
if (renderer->driver != COGL_DRIVER_GL) if (renderer->driver != COGL_DRIVER_GL &&
renderer->driver != COGL_DRIVER_GL3)
{ {
_cogl_set_error (error, COGL_WINSYS_ERROR, _cogl_set_error (error, COGL_WINSYS_ERROR,
COGL_WINSYS_ERROR_INIT, COGL_WINSYS_ERROR_INIT,
@ -394,6 +395,7 @@ update_winsys_features (CoglContext *context, CoglError **error)
_cogl_xlib_renderer_get_data (context->display->renderer); _cogl_xlib_renderer_get_data (context->display->renderer);
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
const char *glx_extensions; const char *glx_extensions;
char **split_extensions;
int default_screen; int default_screen;
int i; int i;
@ -418,11 +420,13 @@ update_winsys_features (CoglContext *context, CoglError **error)
COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN, COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN,
TRUE); TRUE);
split_extensions = g_strsplit (glx_extensions, " ", 0 /* max_tokens */);
for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++) for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++)
if (_cogl_feature_check (context->display->renderer, if (_cogl_feature_check (context->display->renderer,
"GLX", winsys_feature_data + i, 0, 0, "GLX", winsys_feature_data + i, 0, 0,
COGL_DRIVER_GL, /* the driver isn't used */ COGL_DRIVER_GL, /* the driver isn't used */
glx_extensions, split_extensions,
glx_renderer)) glx_renderer))
{ {
context->feature_flags |= winsys_feature_data[i].feature_flags; context->feature_flags |= winsys_feature_data[i].feature_flags;
@ -432,6 +436,8 @@ update_winsys_features (CoglContext *context, CoglError **error)
TRUE); TRUE);
} }
g_strfreev (split_extensions);
/* Note: the GLX_SGI_video_sync spec explicitly states this extension /* Note: the GLX_SGI_video_sync spec explicitly states this extension
* only works for direct contexts. */ * only works for direct contexts. */
if (!glx_renderer->is_direct) if (!glx_renderer->is_direct)
@ -607,6 +613,36 @@ done:
return ret; return ret;
} }
static GLXContext
create_gl3_context (CoglDisplay *display,
GLXFBConfig fb_config)
{
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (display->renderer);
CoglGLXRenderer *glx_renderer = display->renderer->winsys;
/* We want a core profile 3.1 context with no deprecated features */
static const int attrib_list[] =
{
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 1,
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
None
};
/* Make sure that the display supports the GLX_ARB_create_context
extension */
if (glx_renderer->pf_glXCreateContextAttribs == NULL)
return NULL;
return glx_renderer->pf_glXCreateContextAttribs (xlib_renderer->xdpy,
fb_config,
NULL /* share_context */,
True, /* direct */
attrib_list);
}
static CoglBool static CoglBool
create_context (CoglDisplay *display, CoglError **error) create_context (CoglDisplay *display, CoglError **error)
{ {
@ -644,12 +680,16 @@ create_context (CoglDisplay *display, CoglError **error)
COGL_NOTE (WINSYS, "Creating GLX Context (display: %p)", COGL_NOTE (WINSYS, "Creating GLX Context (display: %p)",
xlib_renderer->xdpy); xlib_renderer->xdpy);
if (display->renderer->driver == COGL_DRIVER_GL3)
glx_display->glx_context = create_gl3_context (display, config);
else
glx_display->glx_context = glx_display->glx_context =
glx_renderer->glXCreateNewContext (xlib_renderer->xdpy, glx_renderer->glXCreateNewContext (xlib_renderer->xdpy,
config, config,
GLX_RGBA_TYPE, GLX_RGBA_TYPE,
NULL, NULL,
True); True);
if (glx_display->glx_context == NULL) if (glx_display->glx_context == NULL)
{ {
_cogl_set_error (error, COGL_WINSYS_ERROR, _cogl_set_error (error, COGL_WINSYS_ERROR,

View File

@ -162,6 +162,12 @@ _cogl_winsys_display_setup (CoglDisplay *display,
sdl_display->video_mode_flags = SDL_OPENGL; sdl_display->video_mode_flags = SDL_OPENGL;
break; break;
case COGL_DRIVER_GL3:
_cogl_set_error (error, COGL_WINSYS_ERROR,
COGL_WINSYS_ERROR_INIT,
"The SDL winsys does not support GL 3");
goto error;
#ifdef COGL_HAS_SDL_GLES_SUPPORT #ifdef COGL_HAS_SDL_GLES_SUPPORT
case COGL_DRIVER_GLES2: case COGL_DRIVER_GLES2:
sdl_display->video_mode_flags = SDL_OPENGLES; sdl_display->video_mode_flags = SDL_OPENGLES;

View File

@ -157,6 +157,8 @@ _cogl_winsys_display_setup (CoglDisplay *display,
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 1); SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 1);
else if (display->renderer->driver == COGL_DRIVER_GLES2) else if (display->renderer->driver == COGL_DRIVER_GLES2)
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2);
else if (display->renderer->driver == COGL_DRIVER_GL3)
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 3);
/* Create a dummy 1x1 window that never gets display so that we can /* Create a dummy 1x1 window that never gets display so that we can
* create a GL context */ * create a GL context */
@ -195,6 +197,7 @@ _cogl_winsys_display_setup (CoglDisplay *display,
switch (display->renderer->driver) switch (display->renderer->driver)
{ {
case COGL_DRIVER_GL: case COGL_DRIVER_GL:
case COGL_DRIVER_GL3:
/* The first character of the version string will be a digit if /* The first character of the version string will be a digit if
* it's normal GL */ * it's normal GL */
if (!g_ascii_isdigit (gl_version[0])) if (!g_ascii_isdigit (gl_version[0]))
@ -204,6 +207,29 @@ _cogl_winsys_display_setup (CoglDisplay *display,
"The GL driver was requested but SDL is using GLES"); "The GL driver was requested but SDL is using GLES");
goto error; goto error;
} }
if (gl_version[0] >= '3')
{
if (display->renderer->driver == COGL_DRIVER_GL)
{
_cogl_set_error (error, COGL_WINSYS_ERROR,
COGL_WINSYS_ERROR_INIT,
"The GL driver was requested but SDL is using "
"GL %c", gl_version[0]);
goto error;
}
}
else
{
if (display->renderer->driver == COGL_DRIVER_GL3)
{
_cogl_set_error (error, COGL_WINSYS_ERROR,
COGL_WINSYS_ERROR_INIT,
"The GL3 driver was requested but SDL is using "
"GL %c", gl_version[0]);
goto error;
}
}
break; break;
case COGL_DRIVER_GLES2: case COGL_DRIVER_GLES2:

View File

@ -579,9 +579,14 @@ get_wgl_extensions_string (HDC dc)
GL_EXT_SWAP_CONTROL so if the extension to get the list of WGL GL_EXT_SWAP_CONTROL so if the extension to get the list of WGL
extensions isn't supported then we can at least fake it to extensions isn't supported then we can at least fake it to
support the swap control extension */ support the swap control extension */
if (_cogl_check_extension ("WGL_EXT_swap_control", {
_cogl_context_get_gl_extensions (ctx))) char **extensions = _cogl_context_get_gl_extensions (ctx);
CoglBool have_ext = _cogl_check_extension ("WGL_EXT_swap_control",
extensions);
g_strfreev (extensions);
if (have_ext)
return "WGL_EXT_swap_control"; return "WGL_EXT_swap_control";
}
return NULL; return NULL;
} }
@ -612,13 +617,15 @@ update_winsys_features (CoglContext *context, CoglError **error)
if (wgl_extensions) if (wgl_extensions)
{ {
char **split_extensions = g_strsplit (wgl_extensions);
COGL_NOTE (WINSYS, " WGL Extensions: %s", wgl_extensions); COGL_NOTE (WINSYS, " WGL Extensions: %s", wgl_extensions);
for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++) for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++)
if (_cogl_feature_check (context->display->renderer, if (_cogl_feature_check (context->display->renderer,
"WGL", winsys_feature_data + i, 0, 0, "WGL", winsys_feature_data + i, 0, 0,
COGL_DRIVER_GL, COGL_DRIVER_GL,
wgl_extensions, split_extensions,
wgl_renderer)) wgl_renderer))
{ {
context->feature_flags |= winsys_feature_data[i].feature_flags; context->feature_flags |= winsys_feature_data[i].feature_flags;
@ -627,6 +634,8 @@ update_winsys_features (CoglContext *context, CoglError **error)
winsys_feature_data[i].winsys_feature, winsys_feature_data[i].winsys_feature,
TRUE); TRUE);
} }
g_strfreev (split_extensions);
} }
return TRUE; return TRUE;

View File

@ -67,8 +67,8 @@ TITLE_FORMAT="%35s"
printf $TITLE_FORMAT "Test" printf $TITLE_FORMAT "Test"
if test $HAVE_GL -eq 1; then if test $HAVE_GL -eq 1; then
GL_FORMAT=" %6s %8s %7s %6s" GL_FORMAT=" %6s %8s %7s %6s %6s"
printf "$GL_FORMAT" "GL+FF" "GL+ARBFP" "GL+GLSL" "GL-NPT" printf "$GL_FORMAT" "GL+FF" "GL+ARBFP" "GL+GLSL" "GL-NPT" "GL3"
fi fi
if test $HAVE_GLES2 -eq 1; then if test $HAVE_GLES2 -eq 1; then
GLES2_FORMAT=" %6s %7s" GLES2_FORMAT=" %6s %7s"
@ -101,6 +101,10 @@ do
export COGL_DRIVER=gl export COGL_DRIVER=gl
export COGL_DEBUG=disable-npot-textures export COGL_DEBUG=disable-npot-textures
run_test $test gl_npot run_test $test gl_npot
export COGL_DRIVER=gl3
export COGL_DEBUG=
run_test $test gl3
fi fi
if test $HAVE_GLES2 -eq 1; then if test $HAVE_GLES2 -eq 1; then
@ -119,7 +123,8 @@ do
"`get_status $gl_ff_result`" \ "`get_status $gl_ff_result`" \
"`get_status $gl_arbfp_result`" \ "`get_status $gl_arbfp_result`" \
"`get_status $gl_glsl_result`" \ "`get_status $gl_glsl_result`" \
"`get_status $gl_npot_result`" "`get_status $gl_npot_result`" \
"`get_status $gl3_result`"
fi fi
if test $HAVE_GLES2 -eq 1; then if test $HAVE_GLES2 -eq 1; then
printf "$GLES2_FORMAT" \ printf "$GLES2_FORMAT" \

View File

@ -53,7 +53,8 @@ test_utils_init (TestFlags flags)
renderer = cogl_display_get_renderer (display); renderer = cogl_display_get_renderer (display);
if (flags & TEST_REQUIREMENT_GL && if (flags & TEST_REQUIREMENT_GL &&
cogl_renderer_get_driver (renderer) != COGL_DRIVER_GL) cogl_renderer_get_driver (renderer) != COGL_DRIVER_GL &&
cogl_renderer_get_driver (renderer) != COGL_DRIVER_GL3)
{ {
missing_requirement = TRUE; missing_requirement = TRUE;
} }