Dynamically load the GL or GLES library

The GL or GLES library is now dynamically loaded by the CoglRenderer
so that it can choose between GL, GLES1 and GLES2 at runtime. The
library is loaded by the renderer because it needs to be done before
calling eglInitialize. There is a new environment variable called
COGL_DRIVER to choose between gl, gles1 or gles2.

The #ifdefs for HAVE_COGL_GL, HAVE_COGL_GLES and HAVE_COGL_GLES2 have
been changed so that they don't assume the ifdefs are mutually
exclusive. They haven't been removed entirely so that it's possible to
compile the GLES backends without the the enums from the GL headers.

When using GLX the winsys additionally dynamically loads libGL because
that also contains the GLX API. It can't be linked in directly because
that would probably conflict with the GLES API if the EGL is
selected. When compiling with EGL support the library links directly
to libEGL because it doesn't contain any GL API so it shouldn't have
any conflicts.

When building for WGL or OSX Cogl still directly links against the GL
API so there is a #define in config.h so that Cogl won't try to dlopen
the library.

Cogl-pango previously had a #ifdef to detect when the GL backend is
used so that it can sneakily pass GL_QUADS to
cogl_vertex_buffer_draw. This is now changed so that it queries the
CoglContext for the backend. However to get this to work Cogl now
needs to export the _cogl_context_get_default symbol and cogl-pango
needs some extra -I flags to so that it can include
cogl-context-private.h
This commit is contained in:
Neil Roberts 2011-07-07 20:44:56 +01:00
parent 5f181973a6
commit b2e735ff7f
48 changed files with 1556 additions and 1110 deletions

View File

@ -40,6 +40,8 @@ INCLUDES = \
-DG_DISABLE_SINGLE_INCLUDES \ -DG_DISABLE_SINGLE_INCLUDES \
-DCLUTTER_COMPILATION \ -DCLUTTER_COMPILATION \
-DG_LOG_DOMAIN=\"CoglPango\" \ -DG_LOG_DOMAIN=\"CoglPango\" \
-I$(top_srcdir)/cogl \
-I$(top_srcdir)/cogl/winsys \
-I$(top_srcdir) \ -I$(top_srcdir) \
-I$(top_builddir) -I$(top_builddir)

View File

@ -30,6 +30,7 @@
#include <string.h> #include <string.h>
#include "cogl-pango-display-list.h" #include "cogl-pango-display-list.h"
#include "cogl/cogl-context-private.h"
typedef enum typedef enum
{ {
@ -265,6 +266,8 @@ emit_rectangles_through_journal (CoglPangoDisplayListNode *node)
static void static void
emit_vertex_buffer_geometry (CoglPangoDisplayListNode *node) emit_vertex_buffer_geometry (CoglPangoDisplayListNode *node)
{ {
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* It's expensive to go through the Cogl journal for large runs /* It's expensive to go through the Cogl journal for large runs
* of text in part because the journal transforms the quads in software * of text in part because the journal transforms the quads in software
* to avoid changing the modelview matrix. So for larger runs of text * to avoid changing the modelview matrix. So for larger runs of text
@ -293,29 +296,27 @@ emit_vertex_buffer_geometry (CoglPangoDisplayListNode *node)
node->d.texture.vertex_buffer = vb; node->d.texture.vertex_buffer = vb;
} }
#ifdef CLUTTER_COGL_HAS_GL #ifdef CLUTTER_COGL_HAS_GL
if (ctx->driver == COGL_DRIVER_GL)
cogl_vertex_buffer_draw (node->d.texture.vertex_buffer,
GL_QUADS,
0, node->d.texture.verts->len);
else
#endif
{
/* GLES doesn't support GL_QUADS so instead we use a VBO with
indexed vertices to generate GL_TRIANGLES from the quads */
cogl_vertex_buffer_draw (node->d.texture.vertex_buffer, int n_indices = node->d.texture.verts->len / 4 * 6;
GL_QUADS, CoglHandle indices_vbo
0, node->d.texture.verts->len); = cogl_vertex_buffer_indices_get_for_quads (n_indices);
#else /* CLUTTER_COGL_HAS_GL */ cogl_vertex_buffer_draw_elements (node->d.texture.vertex_buffer,
{ COGL_VERTICES_MODE_TRIANGLES,
/* GLES doesn't support GL_QUADS so instead we use a VBO with indices_vbo,
indexed vertices to generate GL_TRIANGLES from the quads */ 0, node->d.texture.verts->len - 1,
0, n_indices);
int n_indices = node->d.texture.verts->len / 4 * 6; }
CoglHandle indices_vbo
= cogl_vertex_buffer_indices_get_for_quads (n_indices);
cogl_vertex_buffer_draw_elements (node->d.texture.vertex_buffer,
COGL_VERTICES_MODE_TRIANGLES,
indices_vbo,
0, node->d.texture.verts->len - 1,
0, n_indices);
}
#endif /* CLUTTER_COGL_HAS_GL */
} }
static void static void

View File

@ -28,6 +28,9 @@ AM_CPPFLAGS = \
-DG_DISABLE_DEPRECATED \ -DG_DISABLE_DEPRECATED \
-DG_LOG_DOMAIN=\"Cogl\" \ -DG_LOG_DOMAIN=\"Cogl\" \
-DCLUTTER_COMPILATION \ -DCLUTTER_COMPILATION \
-DCOGL_GL_LIBNAME=\"$(COGL_GL_LIBNAME)\" \
-DCOGL_GLES1_LIBNAME=\"$(COGL_GLES1_LIBNAME)\" \
-DCOGL_GLES2_LIBNAME=\"$(COGL_GLES2_LIBNAME)\" \
$(NULL) $(NULL)
AM_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) $(MAINTAINER_CFLAGS) AM_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) $(MAINTAINER_CFLAGS)
@ -102,20 +105,19 @@ cogl_experimental_h = \
# driver sources # driver sources
cogl_driver_sources = cogl_driver_sources =
if COGL_DRIVER_GL if COGL_DRIVER_GL_SUPPORTED
cogl_driver_sources += \ cogl_driver_sources += \
$(srcdir)/driver/gl/cogl-gl.c \ $(srcdir)/driver/gl/cogl-gl.c \
$(srcdir)/driver/gl/cogl-texture-driver-gl.c \ $(srcdir)/driver/gl/cogl-texture-driver-gl.c \
$(NULL) $(NULL)
endif endif
if COGL_DRIVER_GLES if COGL_DRIVER_GLES_SUPPORTED
cogl_driver_sources += \ cogl_driver_sources += \
$(srcdir)/driver/gles/cogl-gles.c \ $(srcdir)/driver/gles/cogl-gles.c \
$(srcdir)/driver/gles/cogl-texture-driver-gles.c \ $(srcdir)/driver/gles/cogl-texture-driver-gles.c \
$(NULL) $(NULL)
endif
endif # COGL_DRIVER_GLES
# winsys sources, common to all backends # winsys sources, common to all backends
cogl_winsys_common_sources = \ cogl_winsys_common_sources = \
@ -387,7 +389,7 @@ libcogl_la_LDFLAGS = \
-no-undefined \ -no-undefined \
-version-info @COGL_LT_CURRENT@:@COGL_LT_REVISION@:@COGL_LT_AGE@ \ -version-info @COGL_LT_CURRENT@:@COGL_LT_REVISION@:@COGL_LT_AGE@ \
-export-dynamic \ -export-dynamic \
-export-symbols-regex "^(cogl|_cogl_debug_flags|_cogl_atlas_new|_cogl_atlas_add_reorganize_callback|_cogl_atlas_reserve_space|_cogl_callback|_cogl_util_get_eye_planes_for_screen_poly|_cogl_atlas_texture_remove_reorganize_callback|_cogl_atlas_texture_add_reorganize_callback|_cogl_texture_foreach_sub_texture_in_region|_cogl_atlas_texture_new_with_size|_cogl_profile_trace_message).*" -export-symbols-regex "^(cogl|_cogl_debug_flags|_cogl_atlas_new|_cogl_atlas_add_reorganize_callback|_cogl_atlas_reserve_space|_cogl_callback|_cogl_util_get_eye_planes_for_screen_poly|_cogl_atlas_texture_remove_reorganize_callback|_cogl_atlas_texture_add_reorganize_callback|_cogl_texture_foreach_sub_texture_in_region|_cogl_atlas_texture_new_with_size|_cogl_profile_trace_message|_cogl_context_get_default).*"
libcogl_la_SOURCES = $(cogl_sources_c) libcogl_la_SOURCES = $(cogl_sources_c)
nodist_libcogl_la_SOURCES = $(BUILT_SOURCES) nodist_libcogl_la_SOURCES = $(BUILT_SOURCES)

View File

@ -47,26 +47,11 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#if ! defined (HAVE_COGL_GL)
/* GLES doesn't have glDrawRangeElements, so we simply pretend it does
* but that it makes no use of the start, end constraints: */
#define glDrawRangeElements(mode, start, end, count, type, indices) \
glDrawElements (mode, count, type, indices)
/* This isn't defined in the GLES headers */ /* This isn't defined in the GLES headers */
#ifndef GL_UNSIGNED_INT #ifndef GL_UNSIGNED_INT
#define GL_UNSIGNED_INT 0x1405 #define GL_UNSIGNED_INT 0x1405
#endif #endif
#ifdef HAVE_COGL_GLES2
#define MAY_HAVE_PROGRAMABLE_GL
#endif /* HAVE_COGL_GLES2 */
#endif
static void _cogl_attribute_free (CoglAttribute *attribute); static void _cogl_attribute_free (CoglAttribute *attribute);
COGL_OBJECT_DEFINE (Attribute, attribute); COGL_OBJECT_DEFINE (Attribute, attribute);
@ -412,23 +397,24 @@ toggle_enabled_cb (int bit_num, void *user_data)
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
#ifdef HAVE_COGL_GLES2 if (ctx->driver == COGL_DRIVER_GLES2)
{
if (enabled) if (enabled)
GE( ctx, glEnableVertexAttribArray (bit_num) ); GE( ctx, glEnableVertexAttribArray (bit_num) );
else
GE( ctx, glDisableVertexAttribArray (bit_num) );
}
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
else else
GE( ctx, glDisableVertexAttribArray (bit_num) ); {
GE( ctx, glClientActiveTexture (GL_TEXTURE0 + bit_num) );
#else /* HAVE_COGL_GLES2 */ if (enabled)
GE( ctx, glEnableClientState (GL_TEXTURE_COORD_ARRAY) );
GE( ctx, glClientActiveTexture (GL_TEXTURE0 + bit_num) ); else
GE( ctx, glDisableClientState (GL_TEXTURE_COORD_ARRAY) );
if (enabled) }
GE( ctx, glEnableClientState (GL_TEXTURE_COORD_ARRAY) ); #endif
else
GE( ctx, glDisableClientState (GL_TEXTURE_COORD_ARRAY) );
#endif /* HAVE_COGL_GLES2 */
} }
static void static void
@ -460,9 +446,7 @@ enable_gl_state (CoglDrawFlags flags,
{ {
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
int i; int i;
#ifdef MAY_HAVE_PROGRAMABLE_GL
GLuint generic_index = 0; GLuint generic_index = 0;
#endif
unsigned long enable_flags = 0; unsigned long enable_flags = 0;
gboolean skip_gl_color = FALSE; gboolean skip_gl_color = FALSE;
CoglPipeline *source; CoglPipeline *source;
@ -591,134 +575,144 @@ enable_gl_state (CoglDrawFlags flags,
{ {
case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY: case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
#ifdef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
attrib_location =
_cogl_pipeline_progend_glsl_get_color_attribute (source);
if (attrib_location != -1)
{ {
GE( ctx, attrib_location =
glVertexAttribPointer (attrib_location, _cogl_pipeline_progend_glsl_get_color_attribute (source);
attribute->n_components, if (attrib_location != -1)
attribute->type, {
TRUE, /* normalize */ GE( ctx,
attribute->stride, glVertexAttribPointer (attrib_location,
base + attribute->offset) ); attribute->n_components,
attribute->type,
TRUE, /* normalize */
attribute->stride,
base + attribute->offset) );
_cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE); _cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE);
}
} }
else
#else
enable_flags |= COGL_ENABLE_COLOR_ARRAY;
/* GE (ctx, glEnableClientState (GL_COLOR_ARRAY)); */
GE (ctx, glColorPointer (attribute->n_components,
attribute->type,
attribute->stride,
base + attribute->offset));
#endif #endif
{
enable_flags |= COGL_ENABLE_COLOR_ARRAY;
/* GE (ctx, glEnableClientState (GL_COLOR_ARRAY)); */
GE (ctx, glColorPointer (attribute->n_components,
attribute->type,
attribute->stride,
base + attribute->offset));
}
break; break;
case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY: case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
#ifdef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
attrib_location =
_cogl_pipeline_progend_glsl_get_normal_attribute (source);
if (attrib_location != -1)
{ {
GE( ctx, attrib_location =
glVertexAttribPointer (attrib_location, _cogl_pipeline_progend_glsl_get_normal_attribute (source);
attribute->n_components, if (attrib_location != -1)
attribute->type, {
TRUE, /* normalize */ GE( ctx,
attribute->stride, glVertexAttribPointer (attrib_location,
base + attribute->offset) ); attribute->n_components,
_cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE); attribute->type,
TRUE, /* normalize */
attribute->stride,
base + attribute->offset) );
_cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE);
}
} }
#else
/* FIXME: go through cogl cache to enable normal array */
GE (ctx, glEnableClientState (GL_NORMAL_ARRAY));
GE (ctx, glNormalPointer (attribute->type,
attribute->stride,
base + attribute->offset));
#endif #endif
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
if (ctx->driver != COGL_DRIVER_GLES2)
{
/* FIXME: go through cogl cache to enable normal array */
GE (ctx, glEnableClientState (GL_NORMAL_ARRAY));
GE (ctx, glNormalPointer (attribute->type,
attribute->stride,
base + attribute->offset));
}
#endif
break; break;
case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY: case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
#ifdef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
attrib_location = _cogl_pipeline_progend_glsl_get_tex_coord_attribute
(source, attribute->texture_unit);
if (attrib_location != -1)
{ {
GE( ctx, attrib_location =
glVertexAttribPointer (attrib_location, _cogl_pipeline_progend_glsl_get_tex_coord_attribute
attribute->n_components, (source, attribute->texture_unit);
attribute->type, if (attrib_location != -1)
FALSE, /* normalize */ {
attribute->stride, GE( ctx,
base + attribute->offset) ); glVertexAttribPointer (attrib_location,
_cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE); attribute->n_components,
attribute->type,
FALSE, /* normalize */
attribute->stride,
base + attribute->offset) );
_cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE);
}
} }
#else else
GE (ctx, glClientActiveTexture (GL_TEXTURE0 +
attribute->texture_unit));
GE (ctx, glTexCoordPointer (attribute->n_components,
attribute->type,
attribute->stride,
base + attribute->offset));
_cogl_bitmask_set (&ctx->temp_bitmask,
attribute->texture_unit, TRUE);
#endif #endif
{
GE (ctx, glClientActiveTexture (GL_TEXTURE0 +
attribute->texture_unit));
GE (ctx, glTexCoordPointer (attribute->n_components,
attribute->type,
attribute->stride,
base + attribute->offset));
_cogl_bitmask_set (&ctx->temp_bitmask,
attribute->texture_unit, TRUE);
}
break; break;
case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY: case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
#ifdef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
attrib_location =
_cogl_pipeline_progend_glsl_get_position_attribute (source);
if (attrib_location != -1)
{ {
GE( ctx, attrib_location =
glVertexAttribPointer (attrib_location, _cogl_pipeline_progend_glsl_get_position_attribute (source);
attribute->n_components, if (attrib_location != -1)
attribute->type, {
FALSE, /* normalize */ GE( ctx,
attribute->stride, glVertexAttribPointer (attrib_location,
base + attribute->offset) ); attribute->n_components,
_cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE); attribute->type,
FALSE, /* normalize */
attribute->stride,
base + attribute->offset) );
_cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE);
}
} }
else
#else
enable_flags |= COGL_ENABLE_VERTEX_ARRAY;
/* GE (ctx, glEnableClientState (GL_VERTEX_ARRAY)); */
GE (ctx, glVertexPointer (attribute->n_components,
attribute->type,
attribute->stride,
base + attribute->offset));
#endif #endif
{
enable_flags |= COGL_ENABLE_VERTEX_ARRAY;
/* GE (ctx, glEnableClientState (GL_VERTEX_ARRAY)); */
GE (ctx, glVertexPointer (attribute->n_components,
attribute->type,
attribute->stride,
base + attribute->offset));
}
break; break;
case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY: case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY:
{ if (ctx->driver != COGL_DRIVER_GLES1)
#ifdef MAY_HAVE_PROGRAMABLE_GL {
/* FIXME: go through cogl cache to enable generic array. */ /* FIXME: go through cogl cache to enable generic array. */
/* FIXME: this is going to end up just using the builtins /* FIXME: this is going to end up just using the builtins
on GLES 2 */ on GLES 2 */
GE (ctx, glEnableVertexAttribArray (generic_index++)); GE (ctx, glEnableVertexAttribArray (generic_index++));
GE (ctx, glVertexAttribPointer (generic_index, GE (ctx, glVertexAttribPointer (generic_index,
attribute->n_components, attribute->n_components,
attribute->type, attribute->type,
attribute->normalized, attribute->normalized,
attribute->stride, attribute->stride,
base + attribute->offset)); base + attribute->offset));
#endif }
}
break; break;
default: default:
g_warning ("Unrecognised attribute type 0x%08x", attribute->type); g_warning ("Unrecognised attribute type 0x%08x", attribute->type);
@ -752,9 +746,7 @@ disable_gl_state (CoglAttribute **attributes,
int n_attributes, int n_attributes,
CoglPipeline *source) CoglPipeline *source)
{ {
#ifdef MAY_HAVE_PROGRAMABLE_GL
GLuint generic_index = 0; GLuint generic_index = 0;
#endif
int i; int i;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -773,8 +765,9 @@ disable_gl_state (CoglAttribute **attributes,
break; break;
case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY: case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
/* FIXME: go through cogl cache to enable normal array */ /* FIXME: go through cogl cache to enable normal array */
#ifndef HAVE_COGL_GLES2 #if defined(HAVE_COGL_GLES) || defined(HAVE_COGL_GL)
GE (ctx, glDisableClientState (GL_NORMAL_ARRAY)); if (ctx->driver != COGL_DRIVER_GLES2)
GE (ctx, glDisableClientState (GL_NORMAL_ARRAY));
#endif #endif
break; break;
case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY: case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
@ -788,10 +781,9 @@ disable_gl_state (CoglAttribute **attributes,
/* GE (ctx, glDisableClientState (GL_VERTEX_ARRAY)); */ /* GE (ctx, glDisableClientState (GL_VERTEX_ARRAY)); */
break; break;
case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY: case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY:
#ifdef MAY_HAVE_PROGRAMABLE_GL if (ctx->driver != COGL_DRIVER_GLES1)
/* FIXME: go through cogl cache to enable generic array */ /* FIXME: go through cogl cache to enable generic array */
GE (ctx, glDisableVertexAttribArray (generic_index++)); GE (ctx, glDisableVertexAttribArray (generic_index++));
#endif
break; break;
default: default:
g_warning ("Unrecognised attribute type 0x%08x", attribute->type); g_warning ("Unrecognised attribute type 0x%08x", attribute->type);

View File

@ -214,32 +214,33 @@ validate_blend_statements (CoglBlendStringStatement *statements,
const char *error_string; const char *error_string;
CoglBlendStringError detail = COGL_BLEND_STRING_ERROR_INVALID_ERROR; CoglBlendStringError detail = COGL_BLEND_STRING_ERROR_INVALID_ERROR;
#ifdef HAVE_COGL_GL
_COGL_GET_CONTEXT (ctx, 0); _COGL_GET_CONTEXT (ctx, 0);
#endif
#ifdef HAVE_COGL_GL if (ctx->driver == COGL_DRIVER_GL)
if (n_statements == 2)
{ {
/* glBlendEquationSeperate is GL 2.0 only */ if (n_statements == 2)
if (!ctx->glBlendEquationSeparate && {
statements[0].function->type != statements[1].function->type) /* glBlendEquationSeperate is GL 2.0 only */
if (!ctx->glBlendEquationSeparate &&
statements[0].function->type != statements[1].function->type)
{
error_string = "Separate blend functions for the RGB an A "
"channels isn't supported by the driver";
detail = COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR;
goto error;
}
}
}
else if (ctx->driver == COGL_DRIVER_GLES1)
{
if (n_statements != 1)
{ {
error_string = "Separate blend functions for the RGB an A " error_string = "Separate blend functions for the RGB an A "
"channels isn't supported by the driver"; "channels isn't supported by the GLES 1";
detail = COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR; detail = COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR;
goto error; goto error;
} }
} }
#elif defined(HAVE_COGL_GLES)
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;
}
#endif
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++)
@ -261,15 +262,15 @@ validate_blend_statements (CoglBlendStringStatement *statements,
goto error; goto error;
} }
#ifdef HAVE_COGL_GLES if (ctx->driver == COGL_DRIVER_GLES1 &&
if (arg->factor.is_color && arg->factor.is_color &&
arg->factor.source.info->type == COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT) (arg->factor.source.info->type ==
COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT))
{ {
error_string = "GLES Doesn't support constant blend factors"; error_string = "GLES 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;
} }
#endif
} }
return TRUE; return TRUE;

View File

@ -316,33 +316,25 @@ _cogl_buffer_access_to_gl_enum (CoglBufferAccess access)
return GL_READ_ONLY; return GL_READ_ONLY;
} }
/* OpenGL ES 1.1 and 2 only know about STATIC_DRAW and DYNAMIC_DRAW */
#if defined (COGL_HAS_GLES)
GLenum
_cogl_buffer_hints_to_gl_enum (CoglBufferUsageHint usage_hint,
CoglBufferUpdateHint update_hint)
{
/* usage hint is always TEXTURE for now */
if (update_hint == COGL_BUFFER_UPDATE_HINT_STATIC)
return GL_STATIC_DRAW;
return GL_DYNAMIC_DRAW;
}
#else
GLenum GLenum
_cogl_buffer_hints_to_gl_enum (CoglBufferUsageHint usage_hint, _cogl_buffer_hints_to_gl_enum (CoglBufferUsageHint usage_hint,
CoglBufferUpdateHint update_hint) CoglBufferUpdateHint update_hint)
{ {
_COGL_GET_CONTEXT (ctx, 0);
/* usage hint is always TEXTURE for now */ /* usage hint is always TEXTURE for now */
if (update_hint == COGL_BUFFER_UPDATE_HINT_STATIC) if (update_hint == COGL_BUFFER_UPDATE_HINT_STATIC)
return GL_STATIC_DRAW; return GL_STATIC_DRAW;
if (update_hint == COGL_BUFFER_UPDATE_HINT_DYNAMIC) if (update_hint == COGL_BUFFER_UPDATE_HINT_DYNAMIC)
return GL_DYNAMIC_DRAW; return GL_DYNAMIC_DRAW;
/* OpenGL ES 1.1 and 2 only know about STATIC_DRAW and DYNAMIC_DRAW */
#ifdef HAVE_COGL_GL
if (update_hint == COGL_BUFFER_UPDATE_HINT_STREAM) if (update_hint == COGL_BUFFER_UPDATE_HINT_STREAM)
return GL_STREAM_DRAW; return GL_STREAM_DRAW;
#endif
return GL_STATIC_DRAW; return GL_STATIC_DRAW;
} }
#endif
void * void *
_cogl_buffer_bind (CoglBuffer *buffer, CoglBufferBindTarget target) _cogl_buffer_bind (CoglBuffer *buffer, CoglBufferBindTarget target)

View File

@ -71,11 +71,8 @@ set_clip_plane (GLint plane_num,
const float *vertex_a, const float *vertex_a,
const float *vertex_b) const float *vertex_b)
{ {
#if defined (HAVE_COGL_GLES2) || defined (HAVE_COGL_GLES) GLfloat planef[4];
GLfloat plane[4]; double planed[4];
#else
GLdouble plane[4];
#endif
GLfloat angle; GLfloat angle;
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
CoglMatrixStack *modelview_stack = CoglMatrixStack *modelview_stack =
@ -110,17 +107,29 @@ set_clip_plane (GLint plane_num,
_cogl_matrix_stack_flush_to_gl (modelview_stack, COGL_MATRIX_MODELVIEW); _cogl_matrix_stack_flush_to_gl (modelview_stack, COGL_MATRIX_MODELVIEW);
plane[0] = 0; planef[0] = 0;
plane[1] = -1.0; planef[1] = -1.0;
plane[2] = 0; planef[2] = 0;
plane[3] = vertex_a[1]; planef[3] = vertex_a[1];
#if defined (HAVE_COGL_GLES2)
g_assert_not_reached (); switch (ctx->driver)
#elif defined (HAVE_COGL_GLES) {
GE( ctx, glClipPlanef (plane_num, plane) ); default:
#else g_assert_not_reached ();
GE( ctx, glClipPlane (plane_num, plane) ); break;
#endif
case COGL_DRIVER_GLES1:
GE( ctx, glClipPlanef (plane_num, planef) );
break;
case COGL_DRIVER_GL:
planed[0] = planef[0];
planed[1] = planef[1];
planed[2] = planef[2];
planed[3] = planef[3];
GE( ctx, glClipPlane (plane_num, planed) );
break;
}
_cogl_matrix_stack_pop (modelview_stack); _cogl_matrix_stack_pop (modelview_stack);
} }

View File

@ -56,6 +56,8 @@ struct _CoglContext
CoglDisplay *display; CoglDisplay *display;
CoglDriver driver;
/* vtable for the texture driver functions */ /* vtable for the texture driver functions */
const CoglTextureDriver *texture_driver; const CoglTextureDriver *texture_driver;
@ -86,10 +88,8 @@ struct _CoglContext
API. We keep track of the matrix stack that Cogl is trying to API. We keep track of the matrix stack that Cogl is trying to
flush so we can flush it later after the program is generated. A flush so we can flush it later after the program is generated. A
reference is taken on the stacks. */ reference is taken on the stacks. */
#ifdef HAVE_COGL_GLES2
CoglMatrixStack *flushed_modelview_stack; CoglMatrixStack *flushed_modelview_stack;
CoglMatrixStack *flushed_projection_stack; CoglMatrixStack *flushed_projection_stack;
#endif /* HAVE_COGL_GLES2 */
GArray *texture_units; GArray *texture_units;
int active_texture_unit; int active_texture_unit;
@ -287,6 +287,18 @@ _cogl_context_get_default ();
const CoglWinsysVtable * const CoglWinsysVtable *
_cogl_context_get_winsys (CoglContext *context); _cogl_context_get_winsys (CoglContext *context);
/* Check whether the current GL context is supported by Cogl */
gboolean
_cogl_context_check_gl_version (CoglContext *context,
GError **error);
/* Query the GL extensions and lookup the corresponding function
* pointers. Theoretically the list of extensions can change for
* different GL contexts so it is the winsys backend's responsiblity
* to know when to re-query the GL extensions. */
void
_cogl_context_update_features (CoglContext *context);
/* Obtains the context and returns retval if NULL */ /* Obtains the context and returns retval if NULL */
#define _COGL_GET_CONTEXT(ctxvar, retval) \ #define _COGL_GET_CONTEXT(ctxvar, retval) \
CoglContext *ctxvar = _cogl_context_get_default (); \ CoglContext *ctxvar = _cogl_context_get_default (); \

View File

@ -54,8 +54,12 @@
#define GL_POINT_SPRITE 0x8861 #define GL_POINT_SPRITE 0x8861
#endif #endif
#ifdef HAVE_COGL_GL
extern const CoglTextureDriver _cogl_texture_driver_gl; extern const CoglTextureDriver _cogl_texture_driver_gl;
#endif
#if defined (HAVE_COGL_GLES) || defined (HAVE_COGL_GLES2)
extern const CoglTextureDriver _cogl_texture_driver_gles; extern const CoglTextureDriver _cogl_texture_driver_gles;
#endif
static void _cogl_context_free (CoglContext *context); static void _cogl_context_free (CoglContext *context);
@ -168,6 +172,11 @@ cogl_context_new (CoglDisplay *display,
context->display = display; context->display = display;
/* This is duplicated data, but it's much more convenient to have
the driver attached to the context and the value is accessed a
lot throughout Cogl */
context->driver = display->renderer->driver;
winsys = _cogl_context_get_winsys (context); winsys = _cogl_context_get_winsys (context);
if (!winsys->context_init (context, error)) if (!winsys->context_init (context, error))
{ {
@ -176,12 +185,25 @@ cogl_context_new (CoglDisplay *display,
return NULL; return NULL;
} }
switch (context->driver)
{
#ifdef HAVE_COGL_GL #ifdef HAVE_COGL_GL
context->texture_driver = &_cogl_texture_driver_gl; case COGL_DRIVER_GL:
#else context->texture_driver = &_cogl_texture_driver_gl;
context->texture_driver = &_cogl_texture_driver_gles; break;
#endif #endif
#if defined (HAVE_COGL_GLES) || defined (HAVE_COGL_GLES2)
case COGL_DRIVER_GLES1:
case COGL_DRIVER_GLES2:
context->texture_driver = &_cogl_texture_driver_gles;
break;
#endif
default:
g_assert_not_reached ();
}
/* Initialise the driver specific state */ /* Initialise the driver specific state */
_cogl_init_feature_overrides (context); _cogl_init_feature_overrides (context);
@ -308,14 +330,15 @@ cogl_context_new (CoglDisplay *display,
context->texture_download_pipeline = COGL_INVALID_HANDLE; context->texture_download_pipeline = COGL_INVALID_HANDLE;
context->blit_texture_pipeline = COGL_INVALID_HANDLE; context->blit_texture_pipeline = COGL_INVALID_HANDLE;
#ifndef HAVE_COGL_GLES2 #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
/* The default for GL_ALPHA_TEST is to always pass which is equivalent to if (context->driver != COGL_DRIVER_GLES2)
* the test being disabled therefore we assume that for all drivers there /* The default for GL_ALPHA_TEST is to always pass which is equivalent to
* will be no performance impact if we always leave the test enabled which * the test being disabled therefore we assume that for all drivers there
* makes things a bit simpler for us. Under GLES2 the alpha test is * will be no performance impact if we always leave the test enabled which
* implemented in the fragment shader so there is no enable for it * makes things a bit simpler for us. Under GLES2 the alpha test is
*/ * implemented in the fragment shader so there is no enable for it
GE (context, glEnable (GL_ALPHA_TEST)); */
GE (context, glEnable (GL_ALPHA_TEST));
#endif #endif
#ifdef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES2
@ -361,10 +384,9 @@ cogl_context_new (CoglDisplay *display,
each pipeline to track whether any layers have point sprite each pipeline to track whether any layers have point sprite
coords enabled. We don't need to do this for GLES2 because point coords enabled. We don't need to do this for GLES2 because point
sprites are handled using a builtin varying in the shader. */ sprites are handled using a builtin varying in the shader. */
#ifndef HAVE_COGL_GLES2 if (_context->driver != COGL_DRIVER_GLES2 &&
if (cogl_features_available (COGL_FEATURE_POINT_SPRITE)) cogl_features_available (COGL_FEATURE_POINT_SPRITE))
GE (context, glEnable (GL_POINT_SPRITE)); GE (context, glEnable (GL_POINT_SPRITE));
#endif
return _cogl_context_object_new (context); return _cogl_context_object_new (context);
} }
@ -499,3 +521,37 @@ cogl_context_egl_get_egl_display (CoglContext *context)
} }
#endif #endif
gboolean
_cogl_context_check_gl_version (CoglContext *context,
GError **error)
{
#ifdef HAVE_COGL_GL
if (context->driver == COGL_DRIVER_GL)
return _cogl_gl_check_gl_version (context, error);
#endif
#if defined(HAVE_COGL_GLES) || defined(HAVE_COGL_GLES2)
return _cogl_gles_check_gl_version (context, error);
#endif
g_assert_not_reached ();
}
void
_cogl_context_update_features (CoglContext *context)
{
#ifdef HAVE_COGL_GL
if (context->driver == COGL_DRIVER_GL)
{
_cogl_gl_update_features (context);
return;
}
#endif
#if defined(HAVE_COGL_GLES) || defined(HAVE_COGL_GLES2)
_cogl_gles_update_features (context);
return;
#endif
g_assert_not_reached ();
}

View File

@ -29,6 +29,7 @@
#include "cogl-display.h" #include "cogl-display.h"
#include "cogl-renderer.h" #include "cogl-renderer.h"
#include "cogl-onscreen-template.h" #include "cogl-onscreen-template.h"
#include "cogl-internal.h"
#if COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT #if COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT
#include <wayland-server.h> #include <wayland-server.h>
#endif #endif

View File

@ -28,9 +28,12 @@
#include "config.h" #include "config.h"
#endif #endif
#include <string.h>
#include "cogl.h" #include "cogl.h"
#include "cogl-private.h" #include "cogl-private.h"
#include "cogl-object.h" #include "cogl-object.h"
#include "cogl-internal.h"
#include "cogl-display-private.h" #include "cogl-display-private.h"
#include "cogl-renderer-private.h" #include "cogl-renderer-private.h"

View File

@ -563,19 +563,6 @@ COGL_EXT_FUNCTION (GLboolean, glUnmapBuffer,
(GLenum target)) (GLenum target))
COGL_EXT_END () COGL_EXT_END ()
COGL_EXT_BEGIN (draw_range_elements, 1, 2,
0, /* not in either GLES */
"\0",
"\0")
COGL_EXT_FUNCTION (void, glDrawRangeElements,
(GLenum mode,
GLuint start,
GLuint end,
GLsizei count,
GLenum type,
const GLvoid *indices))
COGL_EXT_END ()
COGL_EXT_BEGIN (blending, 1, 2, COGL_EXT_BEGIN (blending, 1, 2,
COGL_EXT_IN_GLES2, COGL_EXT_IN_GLES2,
"\0", "\0",

View File

@ -38,7 +38,7 @@ _cogl_feature_check (const CoglWinsysVtable *winsys,
const CoglFeatureData *data, const CoglFeatureData *data,
int gl_major, int gl_major,
int gl_minor, int gl_minor,
CoglExtGlesAvailability gles_version, CoglDriver driver,
const char *extensions_string, const char *extensions_string,
void *function_table) void *function_table)
@ -48,9 +48,13 @@ _cogl_feature_check (const CoglWinsysVtable *winsys,
/* First check whether the functions should be directly provided by /* First check whether the functions should be directly provided by
GL */ GL */
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, if ((driver == COGL_DRIVER_GL &&
data->min_gl_major, data->min_gl_minor) || COGL_CHECK_GL_VERSION (gl_major, gl_minor,
(gles_version & data->gles_availability)) data->min_gl_major, data->min_gl_minor)) ||
(driver == COGL_DRIVER_GLES1 &&
(data->gles_availability & COGL_EXT_IN_GLES)) ||
(driver == COGL_DRIVER_GLES2 &&
(data->gles_availability & COGL_EXT_IN_GLES2)))
suffix = ""; suffix = "";
else else
{ {
@ -180,15 +184,14 @@ 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, const char *gl_extensions)
CoglExtGlesAvailability gles_version)
{ {
int i; int i;
for (i = 0; i < G_N_ELEMENTS (cogl_feature_ext_functions_data); i++) for (i = 0; i < G_N_ELEMENTS (cogl_feature_ext_functions_data); i++)
_cogl_feature_check (_cogl_context_get_winsys (context), _cogl_feature_check (_cogl_context_get_winsys (context),
"GL", cogl_feature_ext_functions_data + i, "GL", cogl_feature_ext_functions_data + i,
gl_major, gl_minor, gles_version, gl_major, gl_minor, context->driver,
gl_extensions, gl_extensions,
context); context);
} }

View File

@ -86,7 +86,7 @@ _cogl_feature_check (const CoglWinsysVtable *winsys,
const CoglFeatureData *data, const CoglFeatureData *data,
int gl_major, int gl_major,
int gl_minor, int gl_minor,
CoglExtGlesAvailability gles_version, CoglDriver driver,
const char *extensions_string, const char *extensions_string,
void *function_table); void *function_table);
@ -94,7 +94,6 @@ 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, const char *gl_extensions);
CoglExtGlesAvailability gles_version);
#endif /* __COGL_FEATURE_PRIVATE_H */ #endif /* __COGL_FEATURE_PRIVATE_H */

View File

@ -615,8 +615,9 @@ _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
return; return;
#ifdef HAVE_COGL_GL #ifdef HAVE_COGL_GL
if (cogl_features_available (COGL_FEATURE_OFFSCREEN) if (ctx->driver == COGL_DRIVER_GL &&
&& framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN) cogl_features_available (COGL_FEATURE_OFFSCREEN) &&
framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN)
{ {
GLenum attachment, pname; GLenum attachment, pname;
@ -812,6 +813,8 @@ _cogl_offscreen_new_to_texture_full (CoglHandle texhandle,
CoglFramebufferTryFBOData data; CoglFramebufferTryFBOData data;
gboolean fbo_created; gboolean fbo_created;
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
if (!cogl_features_available (COGL_FEATURE_OFFSCREEN)) if (!cogl_features_available (COGL_FEATURE_OFFSCREEN))
return COGL_INVALID_HANDLE; return COGL_INVALID_HANDLE;
@ -866,7 +869,8 @@ _cogl_offscreen_new_to_texture_full (CoglHandle texhandle,
if ((have_working_flags && if ((have_working_flags &&
try_creating_fbo (offscreen, flags, &data)) || try_creating_fbo (offscreen, flags, &data)) ||
#ifdef HAVE_COGL_GL #ifdef HAVE_COGL_GL
try_creating_fbo (offscreen, flags = _TRY_DEPTH_STENCIL, &data) || (ctx->driver == COGL_DRIVER_GL &&
try_creating_fbo (offscreen, flags = _TRY_DEPTH_STENCIL, &data)) ||
#endif #endif
try_creating_fbo (offscreen, flags = _TRY_DEPTH | _TRY_STENCIL, try_creating_fbo (offscreen, flags = _TRY_DEPTH | _TRY_STENCIL,
&data) || &data) ||

View File

@ -25,6 +25,7 @@
#ifndef __COGL_RENDERER_GLX_PRIVATE_H #ifndef __COGL_RENDERER_GLX_PRIVATE_H
#define __COGL_RENDERER_GLX_PRIVATE_H #define __COGL_RENDERER_GLX_PRIVATE_H
#include <gmodule.h>
#include "cogl-object-private.h" #include "cogl-object-private.h"
#include "cogl-xlib-renderer-private.h" #include "cogl-xlib-renderer-private.h"
@ -43,6 +44,56 @@ typedef struct _CoglGLXRenderer
/* Vblank stuff */ /* Vblank stuff */
int dri_fd; int dri_fd;
/* GModule pointing to libGL which we use to get glX functions out of */
GModule *libgl_module;
/* Function pointers for core GLX functionality. We can't just link
against these directly because we need to conditionally load
libGL when we are using GLX so that it won't conflict with a GLES
library if we are using EGL + GLES */
void
(* glXDestroyContext) (Display *dpy, GLXContext ctx);
void
(* glXSwapBuffers) (Display *dpy, GLXDrawable drawable);
Bool
(* glXQueryExtension) (Display *dpy, int *errorb, int *event);
const char *
(* glXQueryExtensionsString) (Display *dpy, int screen);
Bool
(* glXQueryVersion) (Display *dpy, int *maj, int *min);
Bool
(* glXIsDirect) (Display *dpy, GLXContext ctx);
int
(* glXGetFBConfigAttrib) (Display *dpy, GLXFBConfig config,
int attribute, int *value);
GLXWindow
(* glXCreateWindow) (Display *dpy, GLXFBConfig config,
Window win, const int *attribList);
void
(* glXDestroyWindow) (Display *dpy, GLXWindow window);
GLXPixmap
(* glXCreatePixmap) (Display *dpy, GLXFBConfig config,
Pixmap pixmap, const int *attribList);
void
(* glXDestroyPixmap) (Display *dpy, GLXPixmap pixmap);
GLXContext
(* glXCreateNewContext) (Display *dpy, GLXFBConfig config,
int renderType, GLXContext shareList,
Bool direct);
Bool
(* glXMakeContextCurrent) (Display *dpy, GLXDrawable draw,
GLXDrawable read, GLXContext ctx);
void
(* glXSelectEvent) (Display *dpy, GLXDrawable drawable,
unsigned long mask);
GLXFBConfig *
(* glXGetFBConfigs) (Display *dpy, int screen, int *nelements);
GLXFBConfig *
(* glXChooseFBConfig) (Display *dpy, int screen,
const int *attrib_list, int *nelements);
XVisualInfo *
(* glXGetVisualFromFBConfig) (Display *dpy, GLXFBConfig config);
/* Function pointers for GLX specific extensions */ /* Function pointers for GLX specific extensions */
#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f) #define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f)

View File

@ -123,9 +123,18 @@ _cogl_transform_point (const CoglMatrix *matrix_mv,
typedef enum { /*< prefix=COGL_DRIVER_ERROR >*/ typedef enum { /*< prefix=COGL_DRIVER_ERROR >*/
COGL_DRIVER_ERROR_UNKNOWN_VERSION, COGL_DRIVER_ERROR_UNKNOWN_VERSION,
COGL_DRIVER_ERROR_INVALID_VERSION COGL_DRIVER_ERROR_INVALID_VERSION,
COGL_DRIVER_ERROR_NO_SUITABLE_DRIVER_FOUND,
COGL_DRIVER_ERROR_FAILED_TO_LOAD_LIBRARY
} CoglDriverError; } CoglDriverError;
typedef enum
{
COGL_DRIVER_GL,
COGL_DRIVER_GLES1,
COGL_DRIVER_GLES2
} CoglDriver;
typedef enum typedef enum
{ {
COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE = 1L<<0, COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE = 1L<<0,

View File

@ -102,10 +102,10 @@ typedef struct _CoglJournalFlushState
gsize stride; gsize stride;
size_t array_offset; size_t array_offset;
GLuint current_vertex; GLuint current_vertex;
#ifndef HAVE_COGL_GL
CoglIndices *indices; CoglIndices *indices;
gsize indices_type_size; gsize indices_type_size;
#endif
CoglMatrixStack *modelview_stack; CoglMatrixStack *modelview_stack;
CoglMatrixStack *projection_stack; CoglMatrixStack *projection_stack;
@ -301,35 +301,38 @@ _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)
/* XXX: it's rather evil that we sneak in the GL_QUADS enum here... */
_cogl_draw_attributes (GL_QUADS,
state->current_vertex, batch_len * 4,
attributes,
state->attributes->len,
draw_flags);
#else /* HAVE_COGL_GL */
if (batch_len > 1)
{ {
_cogl_draw_indexed_attributes (COGL_VERTICES_MODE_TRIANGLES, /* XXX: it's rather evil that we sneak in the GL_QUADS enum here... */
state->current_vertex * 6 / 4, _cogl_draw_attributes (GL_QUADS,
batch_len * 6, state->current_vertex, batch_len * 4,
state->indices,
attributes,
state->attributes->len,
draw_flags);
}
else
{
_cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLE_FAN,
state->current_vertex, 4,
attributes, attributes,
state->attributes->len, state->attributes->len,
draw_flags); draw_flags);
} }
#endif else
#endif /* HAVE_COGL_GL */
{
if (batch_len > 1)
{
_cogl_draw_indexed_attributes (COGL_VERTICES_MODE_TRIANGLES,
state->current_vertex * 6 / 4,
batch_len * 6,
state->indices,
attributes,
state->attributes->len,
draw_flags);
}
else
{
_cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLE_FAN,
state->current_vertex, 4,
attributes,
state->attributes->len,
draw_flags);
}
}
/* DEBUGGING CODE XXX: This path will cause all rectangles to be /* DEBUGGING CODE XXX: This path will cause all rectangles to be
* drawn with a coloured outline. Each batch will be rendered with * drawn with a coloured outline. Each batch will be rendered with
@ -619,9 +622,8 @@ _cogl_journal_flush_vbo_offsets_and_entries (CoglJournalEntry *batch_start,
4, 4,
COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE);
#ifndef HAVE_COGL_GL if (ctx->driver != COGL_DRIVER_GL)
state->indices = cogl_get_rectangle_indices (batch_len); state->indices = cogl_get_rectangle_indices (batch_len);
#endif
/* We only create new Attributes when the stride within the /* We only create new Attributes when the stride within the
* AttributeBuffer changes. (due to a change in the number of pipeline * AttributeBuffer changes. (due to a change in the number of pipeline

View File

@ -393,7 +393,7 @@ _cogl_matrix_stack_set (CoglMatrixStack *stack,
stack->age++; stack->age++;
} }
#ifndef HAVE_COGL_GLES2 #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
static void static void
flush_to_fixed_api_gl (gboolean is_identity, flush_to_fixed_api_gl (gboolean is_identity,
@ -417,7 +417,7 @@ flush_to_fixed_api_gl (gboolean is_identity,
} }
} }
#endif /* HAVE_COGL_GLES2 */ #endif
void void
_cogl_matrix_stack_prepare_for_flush (CoglMatrixStack *stack, _cogl_matrix_stack_prepare_for_flush (CoglMatrixStack *stack,
@ -462,72 +462,74 @@ _cogl_matrix_stack_flush_to_gl (CoglMatrixStack *stack,
state = _cogl_matrix_stack_top (stack); state = _cogl_matrix_stack_top (stack);
#ifdef HAVE_COGL_GLES2 if (ctx->driver == COGL_DRIVER_GLES2)
/* Under GLES2 we need to flush the matrices differently because
they are stored in uniforms attached to the program instead of
the global GL context state. At this point we can't be sure that
the right program will be generated so instead we'll just store a
reference to the matrix stack that is intended to be flushed and
update the uniform once the program is ready. */
switch (mode)
{ {
case COGL_MATRIX_MODELVIEW: /* Under GLES2 we need to flush the matrices differently because
cogl_object_ref (stack); they are stored in uniforms attached to the program instead of
if (ctx->flushed_modelview_stack) the global GL context state. At this point we can't be sure that
cogl_object_unref (ctx->flushed_modelview_stack); the right program will be generated so instead we'll just store a
ctx->flushed_modelview_stack = stack; reference to the matrix stack that is intended to be flushed and
break; update the uniform once the program is ready. */
case COGL_MATRIX_PROJECTION:
cogl_object_ref (stack);
if (ctx->flushed_projection_stack)
cogl_object_unref (ctx->flushed_projection_stack);
ctx->flushed_projection_stack = stack;
break;
case COGL_MATRIX_TEXTURE:
/* This shouldn't happen because the texture matrices are
handled by the GLSL pipeline backend */
g_assert_not_reached ();
break;
}
#else /* HAVE_COGL_GLES2 */
if (stack->flushed_state == state)
return;
if (ctx->flushed_matrix_mode != mode)
{
GLenum gl_mode = 0;
switch (mode) switch (mode)
{ {
case COGL_MATRIX_MODELVIEW: case COGL_MATRIX_MODELVIEW:
gl_mode = GL_MODELVIEW; cogl_object_ref (stack);
if (ctx->flushed_modelview_stack)
cogl_object_unref (ctx->flushed_modelview_stack);
ctx->flushed_modelview_stack = stack;
break; break;
case COGL_MATRIX_PROJECTION: case COGL_MATRIX_PROJECTION:
gl_mode = GL_PROJECTION; cogl_object_ref (stack);
if (ctx->flushed_projection_stack)
cogl_object_unref (ctx->flushed_projection_stack);
ctx->flushed_projection_stack = stack;
break; break;
case COGL_MATRIX_TEXTURE: case COGL_MATRIX_TEXTURE:
gl_mode = GL_TEXTURE; /* This shouldn't happen because the texture matrices are
handled by the GLSL pipeline backend */
g_assert_not_reached ();
break; break;
} }
GE (ctx, glMatrixMode (gl_mode));
ctx->flushed_matrix_mode = mode;
} }
_cogl_matrix_stack_prepare_for_flush (stack, #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
mode, else
flush_to_fixed_api_gl, {
stack); if (stack->flushed_state == state)
return;
#endif /* HAVE_COGL_GLES2 */ if (ctx->flushed_matrix_mode != mode)
{
GLenum gl_mode = 0;
switch (mode)
{
case COGL_MATRIX_MODELVIEW:
gl_mode = GL_MODELVIEW;
break;
case COGL_MATRIX_PROJECTION:
gl_mode = GL_PROJECTION;
break;
case COGL_MATRIX_TEXTURE:
gl_mode = GL_TEXTURE;
break;
}
GE (ctx, glMatrixMode (gl_mode));
ctx->flushed_matrix_mode = mode;
}
_cogl_matrix_stack_prepare_for_flush (stack,
mode,
flush_to_fixed_api_gl,
stack);
}
#endif
stack->flushed_state = state; stack->flushed_state = state;
} }

View File

@ -225,9 +225,9 @@ _cogl_pipeline_fragend_arbfp_start (CoglPipeline *pipeline,
*/ */
authority = _cogl_pipeline_find_equivalent_parent authority = _cogl_pipeline_find_equivalent_parent
(pipeline, (pipeline,
COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN & _cogl_pipeline_get_state_for_fragment_codegen (ctx) &
~COGL_PIPELINE_STATE_LAYERS, ~COGL_PIPELINE_STATE_LAYERS,
COGL_PIPELINE_LAYER_STATE_AFFECTS_FRAGMENT_CODEGEN); _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx));
authority_priv = get_arbfp_priv (authority); authority_priv = get_arbfp_priv (authority);
if (authority_priv && if (authority_priv &&
authority_priv->arbfp_program_state) authority_priv->arbfp_program_state)
@ -318,12 +318,18 @@ _cogl_pipeline_fragend_arbfp_start (CoglPipeline *pipeline,
unsigned int unsigned int
_cogl_pipeline_fragend_arbfp_hash (const void *data) _cogl_pipeline_fragend_arbfp_hash (const void *data)
{ {
unsigned long fragment_state = unsigned int fragment_state;
COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN; unsigned int layer_fragment_state;
unsigned long layer_fragment_state =
COGL_PIPELINE_LAYER_STATE_AFFECTS_FRAGMENT_CODEGEN; _COGL_GET_CONTEXT (ctx, 0);
fragment_state =
_cogl_pipeline_get_state_for_fragment_codegen (ctx);
layer_fragment_state =
_cogl_pipeline_get_layer_state_for_fragment_codegen (ctx);
return _cogl_pipeline_hash ((CoglPipeline *)data, return _cogl_pipeline_hash ((CoglPipeline *)data,
fragment_state, layer_fragment_state, fragment_state, layer_fragment_state,
0); 0);
} }
@ -331,10 +337,15 @@ _cogl_pipeline_fragend_arbfp_hash (const void *data)
gboolean gboolean
_cogl_pipeline_fragend_arbfp_equal (const void *a, const void *b) _cogl_pipeline_fragend_arbfp_equal (const void *a, const void *b)
{ {
unsigned long fragment_state = unsigned int fragment_state;
COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN; unsigned int layer_fragment_state;
unsigned long layer_fragment_state =
COGL_PIPELINE_LAYER_STATE_AFFECTS_FRAGMENT_CODEGEN; _COGL_GET_CONTEXT (ctx, 0);
fragment_state =
_cogl_pipeline_get_state_for_fragment_codegen (ctx);
layer_fragment_state =
_cogl_pipeline_get_layer_state_for_fragment_codegen (ctx);
return _cogl_pipeline_equal ((CoglPipeline *)a, (CoglPipeline *)b, return _cogl_pipeline_equal ((CoglPipeline *)a, (CoglPipeline *)b,
fragment_state, layer_fragment_state, fragment_state, layer_fragment_state,
@ -344,12 +355,9 @@ _cogl_pipeline_fragend_arbfp_equal (const void *a, const void *b)
static const char * static const char *
gl_target_to_arbfp_string (GLenum gl_target) gl_target_to_arbfp_string (GLenum gl_target)
{ {
#ifndef HAVE_COGL_GLES2
if (gl_target == GL_TEXTURE_1D) if (gl_target == GL_TEXTURE_1D)
return "1D"; return "1D";
else else if (gl_target == GL_TEXTURE_2D)
#endif
if (gl_target == GL_TEXTURE_2D)
return "2D"; return "2D";
#ifdef GL_ARB_texture_rectangle #ifdef GL_ARB_texture_rectangle
else if (gl_target == GL_TEXTURE_RECTANGLE_ARB) else if (gl_target == GL_TEXTURE_RECTANGLE_ARB)
@ -1028,7 +1036,9 @@ _cogl_pipeline_fragend_arbfp_pipeline_pre_change_notify (
CoglPipelineState change, CoglPipelineState change,
const CoglColor *new_color) const CoglColor *new_color)
{ {
if ((change & COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN)) _COGL_GET_CONTEXT (ctx, NO_RETVAL);
if ((change & _cogl_pipeline_get_state_for_fragment_codegen (ctx)))
dirty_arbfp_program_state (pipeline); dirty_arbfp_program_state (pipeline);
} }
@ -1047,10 +1057,13 @@ _cogl_pipeline_fragend_arbfp_layer_pre_change_notify (
CoglPipelineLayerState change) CoglPipelineLayerState change)
{ {
CoglPipelineFragendARBfpPrivate *priv = get_arbfp_priv (owner); CoglPipelineFragendARBfpPrivate *priv = get_arbfp_priv (owner);
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (!priv) if (!priv)
return; return;
if ((change & COGL_PIPELINE_LAYER_STATE_AFFECTS_FRAGMENT_CODEGEN)) if ((change & _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx)))
{ {
dirty_arbfp_program_state (owner); dirty_arbfp_program_state (owner);
return; return;

View File

@ -92,9 +92,14 @@ _cogl_pipeline_fragend_fixed_start (CoglPipeline *pipeline,
{ {
CoglHandle user_program; CoglHandle user_program;
_COGL_GET_CONTEXT (ctx, FALSE);
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)
return FALSE;
/* If there is a user program with a fragment shader then the /* If there is a user program with a fragment shader then the
appropriate backend for that language should handle it. We can appropriate backend for that language should handle it. We can
still use the fixed fragment backend if the program only contains still use the fixed fragment backend if the program only contains
@ -319,20 +324,19 @@ _cogl_pipeline_fragend_fixed_end (CoglPipeline *pipeline,
GE (ctx, glFogfv (GL_FOG_COLOR, fogColor)); GE (ctx, glFogfv (GL_FOG_COLOR, fogColor));
#if HAVE_COGL_GLES if (ctx->driver == COGL_DRIVER_GLES1)
switch (fog_state->mode) switch (fog_state->mode)
{ {
case COGL_FOG_MODE_LINEAR: case COGL_FOG_MODE_LINEAR:
gl_mode = GL_LINEAR; gl_mode = GL_LINEAR;
break; break;
case COGL_FOG_MODE_EXPONENTIAL: case COGL_FOG_MODE_EXPONENTIAL:
gl_mode = GL_EXP; gl_mode = GL_EXP;
break; break;
case COGL_FOG_MODE_EXPONENTIAL_SQUARED: case COGL_FOG_MODE_EXPONENTIAL_SQUARED:
gl_mode = GL_EXP2; gl_mode = GL_EXP2;
break; break;
} }
#endif
/* TODO: support other modes for GLES2 */ /* TODO: support other modes for GLES2 */
/* NB: GLES doesn't have glFogi */ /* NB: GLES doesn't have glFogi */

View File

@ -227,9 +227,9 @@ _cogl_pipeline_fragend_glsl_start (CoglPipeline *pipeline,
*/ */
authority = _cogl_pipeline_find_equivalent_parent authority = _cogl_pipeline_find_equivalent_parent
(pipeline, (pipeline,
COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN & _cogl_pipeline_get_state_for_fragment_codegen (ctx) &
~COGL_PIPELINE_STATE_LAYERS, ~COGL_PIPELINE_STATE_LAYERS,
COGL_PIPELINE_LAYER_STATE_AFFECTS_FRAGMENT_CODEGEN); _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx));
authority_priv = get_glsl_priv (authority); authority_priv = get_glsl_priv (authority);
if (!authority_priv) if (!authority_priv)
@ -339,6 +339,8 @@ add_texture_lookup (GlslShaderState *glsl_shader_state,
int unit_index = _cogl_pipeline_layer_get_unit_index (layer); int unit_index = _cogl_pipeline_layer_get_unit_index (layer);
const char *target_string, *tex_coord_swizzle; const char *target_string, *tex_coord_swizzle;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_TEXTURING))) if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_TEXTURING)))
{ {
g_string_append (glsl_shader_state->source, g_string_append (glsl_shader_state->source,
@ -362,7 +364,7 @@ add_texture_lookup (GlslShaderState *glsl_shader_state,
cogl_texture_get_gl_texture (texture, NULL, &gl_target); cogl_texture_get_gl_texture (texture, NULL, &gl_target);
switch (gl_target) switch (gl_target)
{ {
#ifndef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GL
case GL_TEXTURE_1D: case GL_TEXTURE_1D:
target_string = "1D"; target_string = "1D";
tex_coord_swizzle = "s"; tex_coord_swizzle = "s";
@ -413,14 +415,13 @@ add_texture_lookup (GlslShaderState *glsl_shader_state,
supports the gl_PointCoord variable, it requires GLSL 1.2 which supports the gl_PointCoord variable, it requires GLSL 1.2 which
would mean we would have to declare the GLSL version and check would mean we would have to declare the GLSL version and check
for it */ for it */
#ifdef HAVE_COGL_GLES2 if (ctx->driver == COGL_DRIVER_GLES2 &&
if (cogl_pipeline_get_layer_point_sprite_coords_enabled (pipeline, cogl_pipeline_get_layer_point_sprite_coords_enabled (pipeline,
layer->index)) layer->index))
g_string_append_printf (glsl_shader_state->source, g_string_append_printf (glsl_shader_state->source,
"gl_PointCoord.%s", "gl_PointCoord.%s",
tex_coord_swizzle); tex_coord_swizzle);
else else
#endif
g_string_append_printf (glsl_shader_state->source, g_string_append_printf (glsl_shader_state->source,
"cogl_tex_coord_in[%d].%s", "cogl_tex_coord_in[%d].%s",
unit_index, tex_coord_swizzle); unit_index, tex_coord_swizzle);
@ -782,7 +783,8 @@ _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline,
COGL_COUNTER_INC (_cogl_uprof_context, fragend_glsl_compile_counter); COGL_COUNTER_INC (_cogl_uprof_context, fragend_glsl_compile_counter);
#ifdef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES2
add_alpha_test_snippet (pipeline, glsl_shader_state); if (ctx->driver == COGL_DRIVER_GLES2)
add_alpha_test_snippet (pipeline, glsl_shader_state);
#endif #endif
g_string_append (glsl_shader_state->source, "}\n"); g_string_append (glsl_shader_state->source, "}\n");
@ -833,7 +835,9 @@ _cogl_pipeline_fragend_glsl_pre_change_notify (CoglPipeline *pipeline,
CoglPipelineState change, CoglPipelineState change,
const CoglColor *new_color) const CoglColor *new_color)
{ {
if ((change & COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN)) _COGL_GET_CONTEXT (ctx, NO_RETVAL);
if ((change & _cogl_pipeline_get_state_for_fragment_codegen (ctx)))
dirty_glsl_shader_state (pipeline); dirty_glsl_shader_state (pipeline);
} }
@ -853,11 +857,13 @@ _cogl_pipeline_fragend_glsl_layer_pre_change_notify (
{ {
CoglPipelineFragendGlslPrivate *priv; CoglPipelineFragendGlslPrivate *priv;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
priv = get_glsl_priv (owner); priv = get_glsl_priv (owner);
if (!priv) if (!priv)
return; return;
if ((change & COGL_PIPELINE_LAYER_STATE_AFFECTS_FRAGMENT_CODEGEN)) if ((change & _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx)))
{ {
dirty_glsl_shader_state (owner); dirty_glsl_shader_state (owner);
return; return;

View File

@ -240,12 +240,6 @@ _cogl_pipeline_texture_storage_change_notify (CoglHandle texture)
static void static void
set_glsl_program (GLuint gl_program) set_glsl_program (GLuint gl_program)
{ {
#ifdef HAVE_COGL_GLES
g_return_if_reached ();
#else /* HAVE_COGL_GLES */
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (ctx->current_gl_program != gl_program) if (ctx->current_gl_program != gl_program)
@ -263,8 +257,6 @@ set_glsl_program (GLuint gl_program)
ctx->current_gl_program = 0; ctx->current_gl_program = 0;
} }
} }
#endif /* HAVE_COGL_GLES */
} }
void void
@ -415,7 +407,7 @@ _cogl_get_max_texture_image_units (void)
} }
#endif #endif
#ifndef HAVE_COGL_GLES #if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL)
static gboolean static gboolean
blend_factor_uses_constant (GLenum blend_factor) blend_factor_uses_constant (GLenum blend_factor)
@ -446,21 +438,20 @@ flush_depth_state (CoglDepthState *depth_state)
ctx->depth_writing_enabled_cache = depth_state->write_enabled; ctx->depth_writing_enabled_cache = depth_state->write_enabled;
} }
#ifndef COGL_HAS_GLES if (ctx->driver != COGL_DRIVER_GLES1 &&
if (ctx->depth_range_near_cache != depth_state->range_near || (ctx->depth_range_near_cache != depth_state->range_near ||
ctx->depth_range_far_cache != depth_state->range_far) ctx->depth_range_far_cache != depth_state->range_far))
{ {
#ifdef COGL_HAS_GLES2 if (ctx->driver == COGL_DRIVER_GLES2)
GE (ctx, glDepthRangef (depth_state->range_near, GE (ctx, glDepthRangef (depth_state->range_near,
depth_state->range_far)); depth_state->range_far));
#else else
GE (ctx, glDepthRange (depth_state->range_near, GE (ctx, glDepthRange (depth_state->range_near,
depth_state->range_far)); depth_state->range_far));
#endif
ctx->depth_range_near_cache = depth_state->range_near; ctx->depth_range_near_cache = depth_state->range_near;
ctx->depth_range_far_cache = depth_state->range_far; ctx->depth_range_far_cache = depth_state->range_far;
} }
#endif /* COGL_HAS_GLES */
} }
static void static void
@ -472,8 +463,8 @@ _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 */
#ifndef HAVE_COGL_GLES2 if (ctx->driver != COGL_DRIVER_GLES2 &&
if (!skip_gl_color) !skip_gl_color)
{ {
if ((pipelines_difference & COGL_PIPELINE_STATE_COLOR) || if ((pipelines_difference & COGL_PIPELINE_STATE_COLOR) ||
/* Assume if we were previously told to skip the color, then /* Assume if we were previously told to skip the color, then
@ -488,7 +479,6 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state (
cogl_color_get_alpha_byte (&authority->color))); cogl_color_get_alpha_byte (&authority->color)));
} }
} }
#endif
if (pipelines_difference & COGL_PIPELINE_STATE_BLEND) if (pipelines_difference & COGL_PIPELINE_STATE_BLEND)
{ {
@ -497,97 +487,103 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state (
CoglPipelineBlendState *blend_state = CoglPipelineBlendState *blend_state =
&authority->big_state->blend_state; &authority->big_state->blend_state;
#if defined (HAVE_COGL_GLES2) /* GLES 1 only has glBlendFunc */
gboolean have_blend_equation_seperate = TRUE; if (ctx->driver == COGL_DRIVER_GLES1)
gboolean have_blend_func_separate = TRUE;
#elif defined (HAVE_COGL_GL)
gboolean have_blend_equation_seperate = FALSE;
gboolean have_blend_func_separate = FALSE;
if (ctx->glBlendEquationSeparate) /* Only GL 2.0 + */
have_blend_equation_seperate = TRUE;
if (ctx->glBlendFuncSeparate) /* Only GL 1.4 + */
have_blend_func_separate = TRUE;
#endif
#ifndef HAVE_COGL_GLES /* GLES 1 only has glBlendFunc */
if (blend_factor_uses_constant (blend_state->blend_src_factor_rgb) ||
blend_factor_uses_constant (blend_state->blend_src_factor_alpha) ||
blend_factor_uses_constant (blend_state->blend_dst_factor_rgb) ||
blend_factor_uses_constant (blend_state->blend_dst_factor_alpha))
{ {
float red = GE (ctx, glBlendFunc (blend_state->blend_src_factor_rgb,
cogl_color_get_red_float (&blend_state->blend_constant); blend_state->blend_dst_factor_rgb));
float green = }
cogl_color_get_green_float (&blend_state->blend_constant); #if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL)
float blue = else
cogl_color_get_blue_float (&blend_state->blend_constant); {
float alpha = if (blend_factor_uses_constant (blend_state->blend_src_factor_rgb) ||
cogl_color_get_alpha_float (&blend_state->blend_constant); blend_factor_uses_constant (blend_state
->blend_src_factor_alpha) ||
blend_factor_uses_constant (blend_state->blend_dst_factor_rgb) ||
blend_factor_uses_constant (blend_state->blend_dst_factor_alpha))
{
float red =
cogl_color_get_red_float (&blend_state->blend_constant);
float green =
cogl_color_get_green_float (&blend_state->blend_constant);
float blue =
cogl_color_get_blue_float (&blend_state->blend_constant);
float alpha =
cogl_color_get_alpha_float (&blend_state->blend_constant);
GE (ctx, glBlendColor (red, green, blue, alpha)); GE (ctx, glBlendColor (red, green, blue, alpha));
}
if (ctx->glBlendEquationSeparate &&
blend_state->blend_equation_rgb !=
blend_state->blend_equation_alpha)
GE (ctx,
glBlendEquationSeparate (blend_state->blend_equation_rgb,
blend_state->blend_equation_alpha));
else
GE (ctx, glBlendEquation (blend_state->blend_equation_rgb));
if (ctx->glBlendFuncSeparate &&
(blend_state->blend_src_factor_rgb !=
blend_state->blend_src_factor_alpha ||
(blend_state->blend_src_factor_rgb !=
blend_state->blend_src_factor_alpha)))
GE (ctx, glBlendFuncSeparate (blend_state->blend_src_factor_rgb,
blend_state->blend_dst_factor_rgb,
blend_state->blend_src_factor_alpha,
blend_state->blend_dst_factor_alpha));
else
GE (ctx, glBlendFunc (blend_state->blend_src_factor_rgb,
blend_state->blend_dst_factor_rgb));
}
#endif
}
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
if (ctx->driver != COGL_DRIVER_GLES2)
{
/* Under GLES2 the alpha function is implemented as part of the
fragment shader */
if (pipelines_difference & (COGL_PIPELINE_STATE_ALPHA_FUNC |
COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE))
{
CoglPipeline *authority =
_cogl_pipeline_get_authority (pipeline,
COGL_PIPELINE_STATE_ALPHA_FUNC);
CoglPipelineAlphaFuncState *alpha_state =
&authority->big_state->alpha_state;
/* NB: Currently the Cogl defines are compatible with the GL ones: */
GE (ctx, glAlphaFunc (alpha_state->alpha_func,
alpha_state->alpha_func_reference));
} }
if (have_blend_equation_seperate && /* Under GLES2 the lighting parameters are implemented as uniforms
blend_state->blend_equation_rgb != blend_state->blend_equation_alpha) in the progend */
GE (ctx, glBlendEquationSeparate (blend_state->blend_equation_rgb, if (pipelines_difference & COGL_PIPELINE_STATE_LIGHTING)
blend_state->blend_equation_alpha)); {
else CoglPipeline *authority =
GE (ctx, glBlendEquation (blend_state->blend_equation_rgb)); _cogl_pipeline_get_authority (pipeline,
COGL_PIPELINE_STATE_LIGHTING);
CoglPipelineLightingState *lighting_state =
&authority->big_state->lighting_state;
GE (ctx, glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT,
lighting_state->ambient));
GE (ctx, glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE,
lighting_state->diffuse));
GE (ctx, glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR,
lighting_state->specular));
GE (ctx, glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION,
lighting_state->emission));
GE (ctx, glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS,
&lighting_state->shininess));
}
}
if (have_blend_func_separate &&
(blend_state->blend_src_factor_rgb != blend_state->blend_src_factor_alpha ||
(blend_state->blend_src_factor_rgb !=
blend_state->blend_src_factor_alpha)))
GE (ctx, glBlendFuncSeparate (blend_state->blend_src_factor_rgb,
blend_state->blend_dst_factor_rgb,
blend_state->blend_src_factor_alpha,
blend_state->blend_dst_factor_alpha));
else
#endif #endif
GE (ctx, glBlendFunc (blend_state->blend_src_factor_rgb,
blend_state->blend_dst_factor_rgb));
}
#ifndef HAVE_COGL_GLES2
/* Under GLES2 the alpha function is implemented as part of the
fragment shader */
if (pipelines_difference & (COGL_PIPELINE_STATE_ALPHA_FUNC |
COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE))
{
CoglPipeline *authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_ALPHA_FUNC);
CoglPipelineAlphaFuncState *alpha_state =
&authority->big_state->alpha_state;
/* NB: Currently the Cogl defines are compatible with the GL ones: */
GE (ctx, glAlphaFunc (alpha_state->alpha_func,
alpha_state->alpha_func_reference));
}
/* Under GLES2 the lighting parameters are implemented as uniforms
in the progend */
if (pipelines_difference & COGL_PIPELINE_STATE_LIGHTING)
{
CoglPipeline *authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LIGHTING);
CoglPipelineLightingState *lighting_state =
&authority->big_state->lighting_state;
GE (ctx, glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT,
lighting_state->ambient));
GE (ctx, glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE,
lighting_state->diffuse));
GE (ctx, glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR,
lighting_state->specular));
GE (ctx, glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION,
lighting_state->emission));
GE (ctx, glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS,
&lighting_state->shininess));
}
#endif /* HAVE_COGL_GLES2 */
if (pipelines_difference & COGL_PIPELINE_STATE_DEPTH) if (pipelines_difference & COGL_PIPELINE_STATE_DEPTH)
{ {
@ -635,45 +631,54 @@ get_max_activateable_texture_units (void)
int i; int i;
#ifdef HAVE_COGL_GL #ifdef HAVE_COGL_GL
/* GL_MAX_TEXTURE_COORDS is provided for both GLSL and ARBfp. It if (ctx->driver == COGL_DRIVER_GL)
defines the number of texture coordinates that can be {
uploaded (but doesn't necessarily relate to how many texture /* GL_MAX_TEXTURE_COORDS is provided for both GLSL and ARBfp. It
images can be sampled) */ defines the number of texture coordinates that can be
if (cogl_features_available (COGL_FEATURE_SHADERS_GLSL) || uploaded (but doesn't necessarily relate to how many texture
cogl_features_available (COGL_FEATURE_SHADERS_ARBFP)) images can be sampled) */
/* Previously this code subtracted the value by one but there if (cogl_features_available (COGL_FEATURE_SHADERS_GLSL) ||
was no explanation for why it did this and it doesn't seem cogl_features_available (COGL_FEATURE_SHADERS_ARBFP))
to make sense so it has been removed */ /* Previously this code subtracted the value by one but there
GE (ctx, glGetIntegerv (GL_MAX_TEXTURE_COORDS, values + n_values++)); was no explanation for why it did this and it doesn't seem
to make sense so it has been removed */
GE (ctx, glGetIntegerv (GL_MAX_TEXTURE_COORDS,
values + n_values++));
/* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS is defined for GLSL but /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS is defined for GLSL but
not ARBfp */ not ARBfp */
if (cogl_features_available (COGL_FEATURE_SHADERS_GLSL)) if (cogl_features_available (COGL_FEATURE_SHADERS_GLSL))
GE (ctx, glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, GE (ctx, glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
values + n_values++)); values + n_values++));
}
#endif /* HAVE_COGL_GL */ #endif /* HAVE_COGL_GL */
#ifdef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
{
GE (ctx, glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, values + n_values));
/* Two of the vertex attribs need to be used for the position
and color */
values[n_values++] -= 2;
GE (ctx, glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, values + n_values)); GE (ctx, glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
/* Two of the vertex attribs need to be used for the position values + n_values++));
and color */ }
values[n_values++] -= 2; #endif
GE (ctx, glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES) /* not GLES2 */
values + n_values++)); if (ctx->driver != COGL_DRIVER_GLES2)
{
/* GL_MAX_TEXTURE_UNITS defines the number of units that are
usable from the fixed function pipeline, therefore it isn't
available in GLES2. These are also tied to the number of
texture coordinates that can be uploaded so it should be less
than that available from the shader extensions */
GE (ctx, glGetIntegerv (GL_MAX_TEXTURE_UNITS,
values + n_values++));
#else /* HAVE_COGL_GLES2 */ }
#endif
/* GL_MAX_TEXTURE_UNITS defines the number of units that are
usable from the fixed function pipeline, therefore it isn't
available in GLES2. These are also tied to the number of
texture coordinates that can be uploaded so it should be less
than that available from the shader extensions */
GE (ctx, glGetIntegerv (GL_MAX_TEXTURE_UNITS,
values + n_values++));
#endif /* HAVE_COGL_GLES2 */
g_assert (n_values <= G_N_ELEMENTS (values) && g_assert (n_values <= G_N_ELEMENTS (values) &&
n_values > 0); n_values > 0);
@ -786,8 +791,9 @@ flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data)
/* Under GLES2 the fragment shader will use gl_PointCoord instead of /* Under GLES2 the fragment shader will use gl_PointCoord instead of
replacing the texture coordinates */ replacing the texture coordinates */
#ifndef HAVE_COGL_GLES2 #if defined (HAVE_COGL_GLES) || defined (HAVE_COGL_GL)
if (layers_difference & COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS) if (ctx->driver != COGL_DRIVER_GLES2 &&
(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;
CoglPipelineLayer *authority = CoglPipelineLayer *authority =
@ -799,7 +805,7 @@ flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data)
GE (ctx, glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GE (ctx, glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE,
big_state->point_sprite_coords)); big_state->point_sprite_coords));
} }
#endif /* HAVE_COGL_GLES2 */ #endif
cogl_handle_ref (layer); cogl_handle_ref (layer);
if (unit->layer != COGL_INVALID_HANDLE) if (unit->layer != COGL_INVALID_HANDLE)
@ -1299,7 +1305,7 @@ done:
of the program object so they could be overridden by any of the program object so they could be overridden by any
attribute changes in another program */ attribute changes in another program */
#ifdef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES2
if (!skip_gl_color) if (ctx->driver == COGL_DRIVER_GLES2 && !skip_gl_color)
{ {
int attribute; int attribute;
CoglPipeline *authority = CoglPipeline *authority =

View File

@ -41,58 +41,97 @@
typedef struct _CoglPipelineLayer CoglPipelineLayer; typedef struct _CoglPipelineLayer CoglPipelineLayer;
#define COGL_PIPELINE_LAYER(OBJECT) ((CoglPipelineLayer *)OBJECT) #define COGL_PIPELINE_LAYER(OBJECT) ((CoglPipelineLayer *)OBJECT)
#if defined (HAVE_COGL_GL) #ifdef HAVE_COGL_GL
/* NB: pipeline->fragend is currently a 3bit unsigned int bitfield */ #define COGL_PIPELINE_FRAGEND_ARBFP 0
#define COGL_PIPELINE_FRAGEND_ARBFP 0 #define COGL_PIPELINE_FRAGEND_FIXED 1
#define COGL_PIPELINE_FRAGEND_ARBFP_MASK (1L<<0) #define COGL_PIPELINE_FRAGEND_GLSL 2
#define COGL_PIPELINE_FRAGEND_FIXED 1 #define COGL_PIPELINE_N_FRAGENDS 3
#define COGL_PIPELINE_FRAGEND_FIXED_MASK (1L<<1)
#define COGL_PIPELINE_FRAGEND_GLSL 2
#define COGL_PIPELINE_FRAGEND_GLSL_MASK (1L<<2)
#define COGL_PIPELINE_N_FRAGENDS 3 #else /* HAVE_COGL_GL */
#elif defined (HAVE_COGL_GLES2) #ifdef HAVE_COGL_GLES2
#define COGL_PIPELINE_FRAGEND_GLSL 0 #define COGL_PIPELINE_FRAGEND_GLSL 0
#define COGL_PIPELINE_FRAGEND_GLSL_MASK (1L<<0) #ifdef HAVE_COGL_GLES
#define COGL_PIPELINE_FRAGEND_FIXED 1
#define COGL_PIPELINE_N_FRAGENDS 2
#else
#define COGL_PIPELINE_N_FRAGENDS 1
#endif
#define COGL_PIPELINE_N_FRAGENDS 1 #else /* HAVE_COGL_GLES2 */
#else /* HAVE_COGL_GLES */ #ifdef HAVE_COGL_GLES
#define COGL_PIPELINE_FRAGEND_FIXED 0
#define COGL_PIPELINE_N_FRAGENDS 1
#else
#error No drivers defined
#endif
#define COGL_PIPELINE_FRAGEND_FIXED 0 #endif /* HAVE_COGL_GLES2 */
#define COGL_PIPELINE_FRAGEND_FIXED_MASK (1L<<0)
#define COGL_PIPELINE_N_FRAGENDS 1 #endif /* HAVE_COGL_GL */
#ifdef COGL_PIPELINE_FRAGEND_ARBFP
#define COGL_PIPELINE_FRAGEND_ARBFP_MASK \
(1 << COGL_PIPELINE_FRAGEND_ARBFP)
#endif
#ifdef COGL_PIPELINE_FRAGEND_FIXED
#define COGL_PIPELINE_FRAGEND_FIXED_MASK \
(1 << COGL_PIPELINE_FRAGEND_FIXED)
#endif
#ifdef COGL_PIPELINE_FRAGEND_GLSL
#define COGL_PIPELINE_FRAGEND_GLSL_MASK \
(1 << COGL_PIPELINE_FRAGEND_GLSL)
#endif #endif
#define COGL_PIPELINE_FRAGEND_DEFAULT 0 #define COGL_PIPELINE_FRAGEND_DEFAULT 0
#define COGL_PIPELINE_FRAGEND_UNDEFINED 3 #define COGL_PIPELINE_FRAGEND_UNDEFINED 3
#if defined (HAVE_COGL_GL) #ifdef HAVE_COGL_GL
#define COGL_PIPELINE_VERTEND_FIXED 0 #define COGL_PIPELINE_VERTEND_FIXED 0
#define COGL_PIPELINE_VERTEND_GLSL 1 #define COGL_PIPELINE_VERTEND_GLSL 1
#define COGL_PIPELINE_N_VERTENDS 2
#define COGL_PIPELINE_N_VERTENDS 2 #else /* HAVE_COGL_GL */
#elif defined (HAVE_COGL_GLES2) #ifdef HAVE_COGL_GLES2
#define COGL_PIPELINE_VERTEND_GLSL 0
#define COGL_PIPELINE_N_VERTENDS 1
#else /* HAVE_COGL_GLES */
#define COGL_PIPELINE_VERTEND_FIXED 0
#define COGL_PIPELINE_N_VERTENDS 1
#define COGL_PIPELINE_VERTEND_GLSL 0
#ifdef HAVE_COGL_GLES
#define COGL_PIPELINE_VERTEND_FIXED 1
#define COGL_PIPELINE_N_VERTENDS 2
#else
#define COGL_PIPELINE_N_VERTENDS 1
#endif #endif
#else /* HAVE_COGL_GLES2 */
#ifdef HAVE_COGL_GLES
#define COGL_PIPELINE_VERTEND_FIXED 0
#define COGL_PIPELINE_N_VERTENDS 1
#else
#error No drivers defined
#endif /* HAVE_COGL_GLES */
#endif /* HAVE_COGL_GLES2 */
#endif /* HAVE_COGL_GL */
#ifdef COGL_PIPELINE_VERTEND_FIXED
#define COGL_PIPELINE_VERTEND_FIXED_MASK \
(1 << COGL_PIPELINE_VERTEND_FIXED)
#endif
#ifdef COGL_PIPELINE_VERTEND_GLSL
#define COGL_PIPELINE_VERTEND_GLSL_MASK \
(1 << COGL_PIPELINE_VERTEND_GLSL)
#endif
#define COGL_PIPELINE_VERTEND_DEFAULT 0
#define COGL_PIPELINE_VERTEND_UNDEFINED 3
#define COGL_PIPELINE_VERTEND_DEFAULT 0 #define COGL_PIPELINE_VERTEND_DEFAULT 0
#define COGL_PIPELINE_VERTEND_UNDEFINED 3 #define COGL_PIPELINE_VERTEND_UNDEFINED 3
@ -187,23 +226,6 @@ typedef enum
COGL_PIPELINE_LAYER_STATE_WRAP_MODES | \ COGL_PIPELINE_LAYER_STATE_WRAP_MODES | \
COGL_PIPELINE_LAYER_STATE_COMBINE) COGL_PIPELINE_LAYER_STATE_COMBINE)
/* FIXME: Only texture target changes should really affect the
* codegen, but this is difficult to detect */
#ifdef HAVE_COGL_GLES2
/* On GLES2 we need to use a different varying for the texture lookups
* when point sprite coords are enabled */
#define COGL_PIPELINE_LAYER_STATE_AFFECTS_FRAGMENT_CODEGEN \
(COGL_PIPELINE_LAYER_STATE_COMBINE | \
COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET | \
COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS | \
COGL_PIPELINE_LAYER_STATE_UNIT)
#else
#define COGL_PIPELINE_LAYER_STATE_AFFECTS_FRAGMENT_CODEGEN \
(COGL_PIPELINE_LAYER_STATE_COMBINE | \
COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET | \
COGL_PIPELINE_LAYER_STATE_UNIT)
#endif
#define COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN 0 #define COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN 0
@ -491,19 +513,6 @@ typedef enum _CoglPipelineState
COGL_PIPELINE_STATE_DEPTH | \ COGL_PIPELINE_STATE_DEPTH | \
COGL_PIPELINE_STATE_FOG) COGL_PIPELINE_STATE_FOG)
#ifdef HAVE_COGL_GLES2
/* Under GLES2 the alpha func becomes part of the fragment program
so we can't share programs there */
#define COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN \
(COGL_PIPELINE_STATE_LAYERS | \
COGL_PIPELINE_STATE_ALPHA_FUNC | \
COGL_PIPELINE_STATE_USER_SHADER)
#else
#define COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN \
(COGL_PIPELINE_STATE_LAYERS | \
COGL_PIPELINE_STATE_USER_SHADER)
#endif
#define COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN \ #define COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN \
(COGL_PIPELINE_STATE_LAYERS | \ (COGL_PIPELINE_STATE_LAYERS | \
COGL_PIPELINE_STATE_USER_SHADER) COGL_PIPELINE_STATE_USER_SHADER)
@ -546,7 +555,7 @@ typedef enum _CoglPipelineBlendEnable
typedef struct typedef struct
{ {
/* Determines how this pipeline is blended with other primitives */ /* Determines how this pipeline is blended with other primitives */
#ifndef HAVE_COGL_GLES #if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL)
GLenum blend_equation_rgb; GLenum blend_equation_rgb;
GLenum blend_equation_alpha; GLenum blend_equation_alpha;
GLint blend_src_factor_alpha; GLint blend_src_factor_alpha;
@ -1240,5 +1249,11 @@ _cogl_pipeline_init_state_hash_functions (void);
void void
_cogl_pipeline_init_layer_state_hash_functions (void); _cogl_pipeline_init_layer_state_hash_functions (void);
CoglPipelineLayerState
_cogl_pipeline_get_layer_state_for_fragment_codegen (CoglContext *context);
CoglPipelineState
_cogl_pipeline_get_state_for_fragment_codegen (CoglContext *context);
#endif /* __COGL_PIPELINE_PRIVATE_H */ #endif /* __COGL_PIPELINE_PRIVATE_H */

View File

@ -301,8 +301,11 @@ destroy_glsl_priv (void *user_data)
if (--priv->ref_count == 0) if (--priv->ref_count == 0)
{ {
#ifdef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES2
clear_attribute_cache (priv); if (ctx->driver == COGL_DRIVER_GLES2)
clear_flushed_matrix_stacks (priv); {
clear_attribute_cache (priv);
clear_flushed_matrix_stacks (priv);
}
#endif #endif
if (priv->program) if (priv->program)
@ -411,17 +414,18 @@ get_uniform_cb (CoglPipeline *pipeline,
unit_state->combine_constant_uniform = uniform_location; unit_state->combine_constant_uniform = uniform_location;
#ifdef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
{
g_string_set_size (ctx->codegen_source_buffer, 0);
g_string_append_printf (ctx->codegen_source_buffer,
"cogl_texture_matrix[%i]", state->unit);
g_string_set_size (ctx->codegen_source_buffer, 0); GE_RET( uniform_location,
g_string_append_printf (ctx->codegen_source_buffer, ctx, glGetUniformLocation (state->gl_program,
"cogl_texture_matrix[%i]", state->unit); ctx->codegen_source_buffer->str) );
GE_RET( uniform_location,
ctx, glGetUniformLocation (state->gl_program,
ctx->codegen_source_buffer->str) );
unit_state->texture_matrix_uniform = uniform_location;
unit_state->texture_matrix_uniform = uniform_location;
}
#endif #endif
state->unit++; state->unit++;
@ -454,7 +458,8 @@ update_constants_cb (CoglPipeline *pipeline,
#ifdef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES2
if (unit_state->texture_matrix_uniform != -1 && if (ctx->driver == COGL_DRIVER_GLES2 &&
unit_state->texture_matrix_uniform != -1 &&
(state->update_all || unit_state->dirty_texture_matrix)) (state->update_all || unit_state->dirty_texture_matrix))
{ {
const CoglMatrix *matrix; const CoglMatrix *matrix;
@ -529,9 +534,9 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
authority = _cogl_pipeline_find_equivalent_parent authority = _cogl_pipeline_find_equivalent_parent
(pipeline, (pipeline,
(COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN | (COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN |
COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN) & _cogl_pipeline_get_state_for_fragment_codegen (ctx)) &
~COGL_PIPELINE_STATE_LAYERS, ~COGL_PIPELINE_STATE_LAYERS,
COGL_PIPELINE_LAYER_STATE_AFFECTS_FRAGMENT_CODEGEN | _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx) |
COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN); COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN);
priv = get_glsl_priv (authority); priv = get_glsl_priv (authority);
@ -591,7 +596,8 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
/* Find the largest count of texture coordinate attributes /* Find the largest count of texture coordinate attributes
* associated with each of the shaders so we can ensure a consistent * associated with each of the shaders so we can ensure a consistent
* _cogl_tex_coord[] array declaration across all of the shaders.*/ * _cogl_tex_coord[] array declaration across all of the shaders.*/
if (user_program) if (ctx->driver == COGL_DRIVER_GLES2 &&
user_program)
for (l = user_program->attached_shaders; l; l = l->next) for (l = user_program->attached_shaders; l; l = l->next)
{ {
CoglShader *shader = l->data; CoglShader *shader = l->data;
@ -655,35 +661,40 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
&state); &state);
#ifdef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES2
if (program_changed) if (ctx->driver == COGL_DRIVER_GLES2)
{ {
int i; if (program_changed)
{
int i;
clear_attribute_cache (priv); clear_attribute_cache (priv);
clear_flushed_matrix_stacks (priv); clear_flushed_matrix_stacks (priv);
for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++) for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++)
GE_RET( priv->builtin_uniform_locations[i], GE_RET( priv->builtin_uniform_locations[i],
ctx, glGetUniformLocation (gl_program, ctx,
builtin_uniforms[i].uniform_name) ); glGetUniformLocation (gl_program,
builtin_uniforms[i].uniform_name) );
GE_RET( priv->modelview_uniform, GE_RET( priv->modelview_uniform,
ctx, glGetUniformLocation (gl_program, ctx, glGetUniformLocation (gl_program,
"cogl_modelview_matrix") ); "cogl_modelview_matrix") );
GE_RET( priv->projection_uniform, GE_RET( priv->projection_uniform,
ctx, glGetUniformLocation (gl_program, ctx, glGetUniformLocation (gl_program,
"cogl_projection_matrix") ); "cogl_projection_matrix") );
GE_RET( priv->mvp_uniform, GE_RET( priv->mvp_uniform,
ctx, glGetUniformLocation (gl_program, ctx,
"cogl_modelview_projection_matrix") ); glGetUniformLocation (gl_program,
"cogl_modelview_projection_matrix") );
}
if (program_changed ||
priv->last_used_for_pipeline != pipeline)
priv->dirty_builtin_uniforms = ~(unsigned long) 0;
update_builtin_uniforms (pipeline, gl_program, priv);
} }
if (program_changed ||
priv->last_used_for_pipeline != pipeline)
priv->dirty_builtin_uniforms = ~(unsigned long) 0;
update_builtin_uniforms (pipeline, gl_program, priv);
#endif #endif
if (user_program) if (user_program)
@ -701,10 +712,12 @@ _cogl_pipeline_progend_glsl_pre_change_notify (CoglPipeline *pipeline,
CoglPipelineState change, CoglPipelineState change,
const CoglColor *new_color) const CoglColor *new_color)
{ {
if ((change & COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN)) _COGL_GET_CONTEXT (ctx, NO_RETVAL);
if ((change & _cogl_pipeline_get_state_for_fragment_codegen (ctx)))
dirty_glsl_program_state (pipeline); dirty_glsl_program_state (pipeline);
#ifdef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES2
else else if (ctx->driver == COGL_DRIVER_GLES2)
{ {
int i; int i;
@ -734,7 +747,9 @@ _cogl_pipeline_progend_glsl_layer_pre_change_notify (
CoglPipelineLayer *layer, CoglPipelineLayer *layer,
CoglPipelineLayerState change) CoglPipelineLayerState change)
{ {
if ((change & COGL_PIPELINE_LAYER_STATE_AFFECTS_FRAGMENT_CODEGEN)) _COGL_GET_CONTEXT (ctx, NO_RETVAL);
if ((change & _cogl_pipeline_get_state_for_fragment_codegen (ctx)))
{ {
dirty_glsl_program_state (owner); dirty_glsl_program_state (owner);
return; return;
@ -850,6 +865,9 @@ _cogl_pipeline_progend_glsl_pre_paint (CoglPipeline *pipeline)
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (ctx->driver != COGL_DRIVER_GLES2)
return;
/* We only need to update the matrices if we're using the the GLSL /* We only need to update the matrices if we're using the the GLSL
vertend, but this is a requirement on GLES2 anyway */ vertend, but this is a requirement on GLES2 anyway */
g_return_if_fail (pipeline->vertend == COGL_PIPELINE_VERTEND_GLSL); g_return_if_fail (pipeline->vertend == COGL_PIPELINE_VERTEND_GLSL);

View File

@ -49,9 +49,14 @@ _cogl_pipeline_vertend_fixed_start (CoglPipeline *pipeline,
{ {
CoglProgram *user_program; CoglProgram *user_program;
_COGL_GET_CONTEXT (ctx, FALSE);
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)
return FALSE;
/* If there is a user program with a vertex shader then the /* If there is a user program with a vertex shader then the
appropriate backend for that language should handle it. We can appropriate backend for that language should handle it. We can
still use the fixed vertex backend if the program only contains still use the fixed vertex backend if the program only contains

View File

@ -206,17 +206,13 @@ _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline,
"main ()\n" "main ()\n"
"{\n"); "{\n");
#ifdef HAVE_COGL_GLES2 if (ctx->driver == COGL_DRIVER_GLES2)
/* 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 (priv->source,
g_string_append (priv->source, " cogl_point_size_out = cogl_point_size_in;\n");
" cogl_point_size_out = cogl_point_size_in;\n");
#else /* HAVE_COGL_GLES2 */
/* On regular OpenGL we'll just flush the point size builtin */ /* On regular OpenGL we'll just flush the point size builtin */
if (pipelines_difference & COGL_PIPELINE_STATE_POINT_SIZE) else if (pipelines_difference & COGL_PIPELINE_STATE_POINT_SIZE)
{ {
CoglPipeline *authority = CoglPipeline *authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_POINT_SIZE); _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_POINT_SIZE);
@ -228,8 +224,6 @@ _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline,
} }
} }
#endif /* HAVE_COGL_GLES2 */
return TRUE; return TRUE;
} }
@ -241,32 +235,34 @@ _cogl_pipeline_vertend_glsl_add_layer (CoglPipeline *pipeline,
CoglPipelineVertendPrivate *priv; CoglPipelineVertendPrivate *priv;
int unit_index; int unit_index;
_COGL_GET_CONTEXT (ctx, FALSE);
priv = get_glsl_priv (pipeline); priv = get_glsl_priv (pipeline);
unit_index = _cogl_pipeline_layer_get_unit_index (layer); unit_index = _cogl_pipeline_layer_get_unit_index (layer);
#ifndef HAVE_COGL_GLES2 if (ctx->driver != COGL_DRIVER_GLES2)
/* We are using the fixed function uniforms for the user matrices
and the only way to set them is with the fixed function API so we
still need to flush them here */
if (layers_difference & COGL_PIPELINE_LAYER_STATE_USER_MATRIX)
{ {
CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_USER_MATRIX; /* We are using the fixed function uniforms for the user matrices
CoglPipelineLayer *authority = and the only way to set them is with the fixed function API so we
_cogl_pipeline_layer_get_authority (layer, state); still need to flush them here */
CoglTextureUnit *unit = _cogl_get_texture_unit (unit_index); if (layers_difference & COGL_PIPELINE_LAYER_STATE_USER_MATRIX)
{
CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_USER_MATRIX;
CoglPipelineLayer *authority =
_cogl_pipeline_layer_get_authority (layer, state);
CoglTextureUnit *unit = _cogl_get_texture_unit (unit_index);
_cogl_matrix_stack_set (unit->matrix_stack, _cogl_matrix_stack_set (unit->matrix_stack,
&authority->big_state->matrix); &authority->big_state->matrix);
_cogl_set_active_texture_unit (unit_index); _cogl_set_active_texture_unit (unit_index);
_cogl_matrix_stack_flush_to_gl (unit->matrix_stack, COGL_MATRIX_TEXTURE); _cogl_matrix_stack_flush_to_gl (unit->matrix_stack,
COGL_MATRIX_TEXTURE);
}
} }
#endif /* HAVE_COGL_GLES2 */
if (priv->source == NULL) if (priv->source == NULL)
return TRUE; return TRUE;

View File

@ -49,6 +49,10 @@
#include <glib/gprintf.h> #include <glib/gprintf.h>
#include <string.h> #include <string.h>
#ifndef GL_FUNC_ADD
#define GL_FUNC_ADD 0x8006
#endif
typedef gboolean (*CoglPipelineStateComparitor) (CoglPipeline *authority0, typedef gboolean (*CoglPipelineStateComparitor) (CoglPipeline *authority0,
CoglPipeline *authority1); CoglPipeline *authority1);
@ -275,7 +279,7 @@ _cogl_pipeline_init_default_pipeline (void)
alpha_state->alpha_func_reference = 0.0; alpha_state->alpha_func_reference = 0.0;
/* Not the same as the GL default, but seems saner... */ /* Not the same as the GL default, but seems saner... */
#ifndef HAVE_COGL_GLES #if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL)
blend_state->blend_equation_rgb = GL_FUNC_ADD; blend_state->blend_equation_rgb = GL_FUNC_ADD;
blend_state->blend_equation_alpha = GL_FUNC_ADD; blend_state->blend_equation_alpha = GL_FUNC_ADD;
blend_state->blend_src_factor_alpha = GL_ONE; blend_state->blend_src_factor_alpha = GL_ONE;
@ -821,6 +825,8 @@ _cogl_pipeline_needs_blending_enabled (CoglPipeline *pipeline,
CoglPipelineBlendEnable enabled; CoglPipelineBlendEnable enabled;
unsigned long other_state; unsigned long other_state;
_COGL_GET_CONTEXT (ctx, FALSE);
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_BLENDING))) if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_BLENDING)))
return FALSE; return FALSE;
@ -846,15 +852,18 @@ _cogl_pipeline_needs_blending_enabled (CoglPipeline *pipeline,
* functions... * functions...
*/ */
#ifndef HAVE_COGL_GLES #if defined (HAVE_COGL_GLES2) || defined (HAVE_COGL_GL)
/* GLES 1 can't change the function or have separate alpha factors */ if (ctx->driver != COGL_DRIVER_GLES1)
if (blend_state->blend_equation_rgb != GL_FUNC_ADD || {
blend_state->blend_equation_alpha != GL_FUNC_ADD) /* GLES 1 can't change the function or have separate alpha factors */
return TRUE; if (blend_state->blend_equation_rgb != GL_FUNC_ADD ||
blend_state->blend_equation_alpha != GL_FUNC_ADD)
return TRUE;
if (blend_state->blend_src_factor_alpha != GL_ONE || if (blend_state->blend_src_factor_alpha != GL_ONE ||
blend_state->blend_dst_factor_alpha != GL_ONE_MINUS_SRC_ALPHA) blend_state->blend_dst_factor_alpha != GL_ONE_MINUS_SRC_ALPHA)
return TRUE; return TRUE;
}
#endif #endif
if (blend_state->blend_src_factor_rgb != GL_ONE || if (blend_state->blend_src_factor_rgb != GL_ONE ||
@ -3400,18 +3409,23 @@ _cogl_pipeline_blend_state_equal (CoglPipeline *authority0,
CoglPipelineBlendState *blend_state0 = &authority0->big_state->blend_state; CoglPipelineBlendState *blend_state0 = &authority0->big_state->blend_state;
CoglPipelineBlendState *blend_state1 = &authority1->big_state->blend_state; CoglPipelineBlendState *blend_state1 = &authority1->big_state->blend_state;
#ifndef HAVE_COGL_GLES _COGL_GET_CONTEXT (ctx, FALSE);
if (blend_state0->blend_equation_rgb != blend_state1->blend_equation_rgb)
return FALSE; #if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL)
if (blend_state0->blend_equation_alpha != if (ctx->driver != COGL_DRIVER_GLES1)
blend_state1->blend_equation_alpha) {
return FALSE; if (blend_state0->blend_equation_rgb != blend_state1->blend_equation_rgb)
if (blend_state0->blend_src_factor_alpha != return FALSE;
blend_state1->blend_src_factor_alpha) if (blend_state0->blend_equation_alpha !=
return FALSE; blend_state1->blend_equation_alpha)
if (blend_state0->blend_dst_factor_alpha != return FALSE;
blend_state1->blend_dst_factor_alpha) if (blend_state0->blend_src_factor_alpha !=
return FALSE; blend_state1->blend_src_factor_alpha)
return FALSE;
if (blend_state0->blend_dst_factor_alpha !=
blend_state1->blend_dst_factor_alpha)
return FALSE;
}
#endif #endif
if (blend_state0->blend_src_factor_rgb != if (blend_state0->blend_src_factor_rgb !=
blend_state1->blend_src_factor_rgb) blend_state1->blend_src_factor_rgb)
@ -3419,11 +3433,12 @@ _cogl_pipeline_blend_state_equal (CoglPipeline *authority0,
if (blend_state0->blend_dst_factor_rgb != if (blend_state0->blend_dst_factor_rgb !=
blend_state1->blend_dst_factor_rgb) blend_state1->blend_dst_factor_rgb)
return FALSE; return FALSE;
#ifndef HAVE_COGL_GLES #if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL)
if (blend_state0->blend_src_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR || if (ctx->driver != COGL_DRIVER_GLES1 &&
blend_state0->blend_src_factor_rgb == GL_CONSTANT_COLOR || (blend_state0->blend_src_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR ||
blend_state0->blend_dst_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR || blend_state0->blend_src_factor_rgb == GL_CONSTANT_COLOR ||
blend_state0->blend_dst_factor_rgb == GL_CONSTANT_COLOR) blend_state0->blend_dst_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR ||
blend_state0->blend_dst_factor_rgb == GL_CONSTANT_COLOR))
{ {
if (!cogl_color_equal (&blend_state0->blend_constant, if (!cogl_color_equal (&blend_state0->blend_constant,
&blend_state1->blend_constant)) &blend_state1->blend_constant))
@ -4411,7 +4426,7 @@ arg_to_gl_blend_factor (CoglBlendStringArgument *arg)
return GL_DST_ALPHA; return GL_DST_ALPHA;
} }
} }
#ifndef HAVE_COGL_GLES #if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL)
else if (arg->factor.source.info->type == else if (arg->factor.source.info->type ==
COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT) COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT)
{ {
@ -4442,7 +4457,6 @@ setup_blend_state (CoglBlendStringStatement *statement,
GLint *blend_src_factor, GLint *blend_src_factor,
GLint *blend_dst_factor) GLint *blend_dst_factor)
{ {
#ifndef HAVE_COGL_GLES
switch (statement->function->type) switch (statement->function->type)
{ {
case COGL_BLEND_STRING_FUNCTION_ADD: case COGL_BLEND_STRING_FUNCTION_ADD:
@ -4453,7 +4467,6 @@ setup_blend_state (CoglBlendStringStatement *statement,
g_warning ("Unsupported blend function given"); g_warning ("Unsupported blend function given");
*blend_equation = GL_FUNC_ADD; *blend_equation = GL_FUNC_ADD;
} }
#endif
*blend_src_factor = arg_to_gl_blend_factor (&statement->args[0]); *blend_src_factor = arg_to_gl_blend_factor (&statement->args[0]);
*blend_dst_factor = arg_to_gl_blend_factor (&statement->args[1]); *blend_dst_factor = arg_to_gl_blend_factor (&statement->args[1]);
@ -4473,6 +4486,8 @@ cogl_pipeline_set_blend (CoglPipeline *pipeline,
int count; int count;
CoglPipelineBlendState *blend_state; CoglPipelineBlendState *blend_state;
_COGL_GET_CONTEXT (ctx, FALSE);
g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE);
count = count =
@ -4512,21 +4527,26 @@ cogl_pipeline_set_blend (CoglPipeline *pipeline,
_cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);
blend_state = &pipeline->big_state->blend_state; blend_state = &pipeline->big_state->blend_state;
#ifndef HAVE_COGL_GLES #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES2)
setup_blend_state (rgb, if (ctx->driver != COGL_DRIVER_GLES1)
&blend_state->blend_equation_rgb, {
&blend_state->blend_src_factor_rgb, setup_blend_state (rgb,
&blend_state->blend_dst_factor_rgb); &blend_state->blend_equation_rgb,
setup_blend_state (a, &blend_state->blend_src_factor_rgb,
&blend_state->blend_equation_alpha, &blend_state->blend_dst_factor_rgb);
&blend_state->blend_src_factor_alpha, setup_blend_state (a,
&blend_state->blend_dst_factor_alpha); &blend_state->blend_equation_alpha,
#else &blend_state->blend_src_factor_alpha,
setup_blend_state (rgb, &blend_state->blend_dst_factor_alpha);
NULL, }
&blend_state->blend_src_factor_rgb, else
&blend_state->blend_dst_factor_rgb);
#endif #endif
{
setup_blend_state (rgb,
NULL,
&blend_state->blend_src_factor_rgb,
&blend_state->blend_dst_factor_rgb);
}
/* If we are the current authority see if we can revert to one of our /* If we are the current authority see if we can revert to one of our
* ancestors being the authority */ * ancestors being the authority */
@ -4560,33 +4580,40 @@ void
cogl_pipeline_set_blend_constant (CoglPipeline *pipeline, cogl_pipeline_set_blend_constant (CoglPipeline *pipeline,
const CoglColor *constant_color) const CoglColor *constant_color)
{ {
#ifndef HAVE_COGL_GLES _COGL_GET_CONTEXT (ctx, NO_RETVAL);
CoglPipelineState state = COGL_PIPELINE_STATE_BLEND;
CoglPipeline *authority;
CoglPipelineBlendState *blend_state;
g_return_if_fail (cogl_is_pipeline (pipeline)); g_return_if_fail (cogl_is_pipeline (pipeline));
authority = _cogl_pipeline_get_authority (pipeline, state); if (ctx->driver == COGL_DRIVER_GLES1)
blend_state = &authority->big_state->blend_state;
if (cogl_color_equal (constant_color, &blend_state->blend_constant))
return; return;
/* - Flush journal primitives referencing the current state. #if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL)
* - Make sure the pipeline has no dependants so it may be modified. {
* - If the pipeline isn't currently an authority for the state being CoglPipelineState state = COGL_PIPELINE_STATE_BLEND;
* changed, then initialize that state from the current authority. CoglPipeline *authority;
*/ CoglPipelineBlendState *blend_state;
_cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);
blend_state = &pipeline->big_state->blend_state; authority = _cogl_pipeline_get_authority (pipeline, state);
blend_state->blend_constant = *constant_color;
_cogl_pipeline_update_authority (pipeline, authority, state, blend_state = &authority->big_state->blend_state;
_cogl_pipeline_blend_state_equal); if (cogl_color_equal (constant_color, &blend_state->blend_constant))
return;
handle_automatic_blend_enable (pipeline, state); /* - Flush journal primitives referencing the current state.
* - Make sure the pipeline has no dependants so it may be modified.
* - If the pipeline isn't currently an authority for the state being
* changed, then initialize that state from the current authority.
*/
_cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);
blend_state = &pipeline->big_state->blend_state;
blend_state->blend_constant = *constant_color;
_cogl_pipeline_update_authority (pipeline, authority, state,
_cogl_pipeline_blend_state_equal);
handle_automatic_blend_enable (pipeline, state);
}
#endif #endif
} }
@ -4677,6 +4704,8 @@ cogl_pipeline_set_depth_state (CoglPipeline *pipeline,
CoglPipeline *authority; CoglPipeline *authority;
CoglDepthState *orig_state; CoglDepthState *orig_state;
_COGL_GET_CONTEXT (ctx, FALSE);
g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE);
g_return_val_if_fail (depth_state->magic == COGL_DEPTH_STATE_MAGIC, FALSE); g_return_val_if_fail (depth_state->magic == COGL_DEPTH_STATE_MAGIC, FALSE);
@ -4690,9 +4719,9 @@ cogl_pipeline_set_depth_state (CoglPipeline *pipeline,
orig_state->range_far == depth_state->range_far) orig_state->range_far == depth_state->range_far)
return TRUE; return TRUE;
#ifdef COGL_HAS_GLES if (ctx->driver == COGL_DRIVER_GLES1 &&
if (depth_state->range_near != 0 || (depth_state->range_near != 0 ||
depth_state->range_far != 1) depth_state->range_far != 1))
{ {
g_set_error (error, g_set_error (error,
COGL_ERROR, COGL_ERROR,
@ -4700,7 +4729,6 @@ cogl_pipeline_set_depth_state (CoglPipeline *pipeline,
"glDepthRange not available on GLES 1"); "glDepthRange not available on GLES 1");
return FALSE; return FALSE;
} }
#endif
/* - Flush journal primitives referencing the current state. /* - Flush journal primitives referencing the current state.
* - Make sure the pipeline has no dependants so it may be modified. * - Make sure the pipeline has no dependants so it may be modified.
@ -6070,33 +6098,38 @@ _cogl_pipeline_hash_blend_state (CoglPipeline *authority,
CoglPipelineBlendState *blend_state = &authority->big_state->blend_state; CoglPipelineBlendState *blend_state = &authority->big_state->blend_state;
unsigned int hash; unsigned int hash;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (!authority->real_blend_enable) if (!authority->real_blend_enable)
return; return;
hash = state->hash; hash = state->hash;
#ifndef HAVE_COGL_GLES #if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL)
hash = if (ctx->driver != COGL_DRIVER_GLES1)
_cogl_util_one_at_a_time_hash (hash, &blend_state->blend_equation_rgb,
sizeof (blend_state->blend_equation_rgb));
hash =
_cogl_util_one_at_a_time_hash (hash, &blend_state->blend_equation_alpha,
sizeof (blend_state->blend_equation_alpha));
hash =
_cogl_util_one_at_a_time_hash (hash, &blend_state->blend_src_factor_alpha,
sizeof (blend_state->blend_src_factor_alpha));
hash =
_cogl_util_one_at_a_time_hash (hash, &blend_state->blend_dst_factor_alpha,
sizeof (blend_state->blend_dst_factor_alpha));
if (blend_state->blend_src_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR ||
blend_state->blend_src_factor_rgb == GL_CONSTANT_COLOR ||
blend_state->blend_dst_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR ||
blend_state->blend_dst_factor_rgb == GL_CONSTANT_COLOR)
{ {
hash = hash =
_cogl_util_one_at_a_time_hash (hash, &blend_state->blend_constant, _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_equation_rgb,
sizeof (blend_state->blend_constant)); sizeof (blend_state->blend_equation_rgb));
hash =
_cogl_util_one_at_a_time_hash (hash, &blend_state->blend_equation_alpha,
sizeof (blend_state->blend_equation_alpha));
hash =
_cogl_util_one_at_a_time_hash (hash, &blend_state->blend_src_factor_alpha,
sizeof (blend_state->blend_src_factor_alpha));
hash =
_cogl_util_one_at_a_time_hash (hash, &blend_state->blend_dst_factor_alpha,
sizeof (blend_state->blend_dst_factor_alpha));
if (blend_state->blend_src_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR ||
blend_state->blend_src_factor_rgb == GL_CONSTANT_COLOR ||
blend_state->blend_dst_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR ||
blend_state->blend_dst_factor_rgb == GL_CONSTANT_COLOR)
{
hash =
_cogl_util_one_at_a_time_hash (hash, &blend_state->blend_constant,
sizeof (blend_state->blend_constant));
}
} }
#endif #endif
@ -6698,3 +6731,30 @@ _cogl_pipeline_find_equivalent_parent (CoglPipeline *pipeline,
return authority1; return authority1;
} }
CoglPipelineLayerState
_cogl_pipeline_get_layer_state_for_fragment_codegen (CoglContext *context)
{
CoglPipelineLayerState state =
(COGL_PIPELINE_LAYER_STATE_COMBINE |
COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET |
COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS |
COGL_PIPELINE_LAYER_STATE_UNIT);
if (context->driver == COGL_DRIVER_GLES2)
state |= COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS;
return state;
}
CoglPipelineState
_cogl_pipeline_get_state_for_fragment_codegen (CoglContext *context)
{
CoglPipelineState state = (COGL_PIPELINE_STATE_LAYERS |
COGL_PIPELINE_STATE_USER_SHADER);
if (context->driver == COGL_DRIVER_GLES2)
state |= COGL_PIPELINE_STATE_ALPHA_FUNC;
return state;
}

View File

@ -27,11 +27,19 @@
G_BEGIN_DECLS G_BEGIN_DECLS
gboolean gboolean
_cogl_gl_check_version (GError **error); _cogl_gl_check_gl_version (CoglContext *context,
GError **error);
void void
_cogl_gl_update_features (CoglContext *context); _cogl_gl_update_features (CoglContext *context);
gboolean
_cogl_gles_check_gl_version (CoglContext *context,
GError **error);
void
_cogl_gles_update_features (CoglContext *context);
gboolean gboolean
_cogl_check_extension (const char *name, const char *ext); _cogl_check_extension (const char *name, const char *ext);

View File

@ -106,13 +106,11 @@ cogl_program_attach_shader (CoglHandle program_handle,
shader = _cogl_shader_pointer_from_handle (shader_handle); shader = _cogl_shader_pointer_from_handle (shader_handle);
/* Only one shader is allowed if the type is ARBfp */ /* Only one shader is allowed if the type is ARBfp */
#ifdef HAVE_COGL_GL
if (shader->language == COGL_SHADER_LANGUAGE_ARBFP) if (shader->language == COGL_SHADER_LANGUAGE_ARBFP)
g_return_if_fail (program->attached_shaders == NULL); g_return_if_fail (program->attached_shaders == NULL);
else if (shader->language == COGL_SHADER_LANGUAGE_GLSL) else if (shader->language == COGL_SHADER_LANGUAGE_GLSL)
g_return_if_fail (_cogl_program_get_language (program) == g_return_if_fail (_cogl_program_get_language (program) ==
COGL_SHADER_LANGUAGE_GLSL); COGL_SHADER_LANGUAGE_GLSL);
#endif
program->attached_shaders program->attached_shaders
= g_slist_prepend (program->attached_shaders, = g_slist_prepend (program->attached_shaders,
@ -366,8 +364,6 @@ cogl_program_uniform_matrix (int uniform_no,
uniform_no, size, count, transpose, value); uniform_no, size, count, transpose, value);
} }
#ifndef HAVE_COGL_GLES
/* ARBfp local parameters can be referenced like: /* ARBfp local parameters can be referenced like:
* *
* "program.local[5]" * "program.local[5]"
@ -478,8 +474,6 @@ _cogl_program_flush_uniform_glsl (GLint location,
} }
} }
#endif /* HAVE_COGL_GLES */
#ifdef HAVE_COGL_GL #ifdef HAVE_COGL_GL
static void static void
@ -506,17 +500,13 @@ _cogl_program_flush_uniforms (CoglProgram *program,
GLuint gl_program, GLuint gl_program,
gboolean gl_program_changed) gboolean gl_program_changed)
{ {
#ifdef HAVE_COGL_GLES
g_return_if_reached ();
#else /* HAVE_COGL_GLES */
CoglProgramUniform *uniform; CoglProgramUniform *uniform;
int i; int i;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
g_return_if_fail (ctx->driver != COGL_DRIVER_GLES1);
for (i = 0; i < program->custom_uniforms->len; i++) for (i = 0; i < program->custom_uniforms->len; i++)
{ {
uniform = &g_array_index (program->custom_uniforms, uniform = &g_array_index (program->custom_uniforms,
@ -548,20 +538,18 @@ _cogl_program_flush_uniforms (CoglProgram *program,
&uniform->value); &uniform->value);
break; break;
#ifdef HAVE_COGL_GL
case COGL_SHADER_LANGUAGE_ARBFP: case COGL_SHADER_LANGUAGE_ARBFP:
#ifdef HAVE_COGL_GL
_cogl_program_flush_uniform_arbfp (uniform->location, _cogl_program_flush_uniform_arbfp (uniform->location,
&uniform->value); &uniform->value);
break;
#endif #endif
break;
} }
} }
uniform->dirty = FALSE; uniform->dirty = FALSE;
} }
} }
#endif /* HAVE_COGL_GLES */
} }
CoglShaderLanguage CoglShaderLanguage

View File

@ -24,8 +24,11 @@
#ifndef __COGL_RENDERER_PRIVATE_H #ifndef __COGL_RENDERER_PRIVATE_H
#define __COGL_RENDERER_PRIVATE_H #define __COGL_RENDERER_PRIVATE_H
#include <gmodule.h>
#include "cogl-object-private.h" #include "cogl-object-private.h"
#include "cogl-winsys-private.h" #include "cogl-winsys-private.h"
#include "cogl-internal.h"
#ifdef COGL_HAS_XLIB_SUPPORT #ifdef COGL_HAS_XLIB_SUPPORT
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -44,6 +47,12 @@ struct _CoglRenderer
#ifdef COGL_HAS_XLIB_SUPPORT #ifdef COGL_HAS_XLIB_SUPPORT
Display *foreign_xdpy; Display *foreign_xdpy;
#endif #endif
CoglDriver driver;
#ifndef HAVE_DIRECTLY_LINKED_GL_LIBRARY
GModule *libgl_module;
#endif
#if COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT #if COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT
struct wl_display *foreign_wayland_display; struct wl_display *foreign_wayland_display;
struct wl_compositor *foreign_wayland_compositor; struct wl_compositor *foreign_wayland_compositor;

View File

@ -100,6 +100,11 @@ _cogl_renderer_free (CoglRenderer *renderer)
const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer); const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer);
winsys->renderer_disconnect (renderer); winsys->renderer_disconnect (renderer);
#ifndef HAVE_DIRECTLY_LINKED_GL_LIBRARY
if (renderer->libgl_module)
g_module_close (renderer->libgl_module);
#endif
g_slist_foreach (renderer->event_filters, g_slist_foreach (renderer->event_filters,
(GFunc) native_filter_closure_free, (GFunc) native_filter_closure_free,
NULL); NULL);
@ -166,6 +171,75 @@ cogl_renderer_check_onscreen_template (CoglRenderer *renderer,
return TRUE; return TRUE;
} }
static gboolean
_cogl_renderer_choose_driver (CoglRenderer *renderer,
GError **error)
{
const char *driver_name = g_getenv ("COGL_DRIVER");
const char *libgl_name;
#ifndef HAVE_DIRECTLY_LINKED_GL_LIBRARY
char *libgl_module_path;
#endif
#ifdef HAVE_COGL_GL
if (driver_name == NULL || !strcmp (driver_name, "gl"))
{
renderer->driver = COGL_DRIVER_GL;
libgl_name = COGL_GL_LIBNAME;
goto found;
}
#endif
#ifdef HAVE_COGL_GLES2
if (driver_name == NULL || !strcmp (driver_name, "gles2"))
{
renderer->driver = COGL_DRIVER_GLES2;
libgl_name = COGL_GLES2_LIBNAME;
goto found;
}
#endif
#ifdef HAVE_COGL_GLES
if (driver_name == NULL || !strcmp (driver_name, "gles1"))
{
renderer->driver = COGL_DRIVER_GLES1;
libgl_name = COGL_GLES1_LIBNAME;
goto found;
}
#endif
g_set_error (error,
COGL_DRIVER_ERROR,
COGL_DRIVER_ERROR_NO_SUITABLE_DRIVER_FOUND,
"No suitable driver found");
return FALSE;
found:
#ifndef HAVE_DIRECTLY_LINKED_GL_LIBRARY
libgl_module_path = g_module_build_path (NULL, /* standard lib search path */
libgl_name);
renderer->libgl_module = g_module_open (libgl_module_path,
G_MODULE_BIND_LAZY);
g_free (libgl_module_path);
if (renderer->libgl_module == NULL)
{
g_set_error (error, COGL_DRIVER_ERROR,
COGL_DRIVER_ERROR_FAILED_TO_LOAD_LIBRARY,
"Failed to dynamically open the GL library \"%s\"",
libgl_name);
return FALSE;
}
#endif /* HAVE_DIRECTLY_LINKED_GL_LIBRARY */
return TRUE;
}
/* Final connection API */ /* Final connection API */
gboolean gboolean
@ -177,6 +251,12 @@ cogl_renderer_connect (CoglRenderer *renderer, GError **error)
if (renderer->connected) if (renderer->connected)
return TRUE; return TRUE;
/* The driver needs to be chosen before connecting the renderer
because eglInitialize requires the library containing the GL API
to be loaded before its called */
if (!_cogl_renderer_choose_driver (renderer, error))
return FALSE;
error_message = g_string_new (""); error_message = g_string_new ("");
for (i = 0; i < G_N_ELEMENTS (_cogl_winsys_vtable_getters); i++) for (i = 0; i < G_N_ELEMENTS (_cogl_winsys_vtable_getters); i++)
{ {

View File

@ -29,10 +29,7 @@
#include "cogl.h" #include "cogl.h"
#define _COGL_COMMON_SHADER_BOILERPLATE_GL \
#ifndef HAVE_COGL_GLES2
#define _COGL_COMMON_SHADER_BOILERPLATE \
"#define COGL_VERSION 100\n" \ "#define COGL_VERSION 100\n" \
"\n" \ "\n" \
"#define cogl_modelview_matrix gl_ModelViewMatrix\n" \ "#define cogl_modelview_matrix gl_ModelViewMatrix\n" \
@ -41,8 +38,8 @@
"#define cogl_texture_matrix gl_TextureMatrix\n" \ "#define cogl_texture_matrix gl_TextureMatrix\n" \
"\n" "\n"
#define _COGL_VERTEX_SHADER_BOILERPLATE \ #define _COGL_VERTEX_SHADER_BOILERPLATE_GL \
_COGL_COMMON_SHADER_BOILERPLATE \ _COGL_COMMON_SHADER_BOILERPLATE_GL \
"#define cogl_position_in gl_Vertex\n" \ "#define cogl_position_in gl_Vertex\n" \
"#define cogl_color_in gl_Color\n" \ "#define cogl_color_in gl_Color\n" \
"#define cogl_tex_coord_in gl_MultiTexCoord0\n" \ "#define cogl_tex_coord_in gl_MultiTexCoord0\n" \
@ -61,8 +58,8 @@
"#define cogl_color_out gl_FrontColor\n" \ "#define cogl_color_out gl_FrontColor\n" \
"#define cogl_tex_coord_out gl_TexCoord\n" "#define cogl_tex_coord_out gl_TexCoord\n"
#define _COGL_FRAGMENT_SHADER_BOILERPLATE \ #define _COGL_FRAGMENT_SHADER_BOILERPLATE_GL \
_COGL_COMMON_SHADER_BOILERPLATE \ _COGL_COMMON_SHADER_BOILERPLATE_GL \
"#define cogl_color_in gl_Color\n" \ "#define cogl_color_in gl_Color\n" \
"#define cogl_tex_coord_in gl_TexCoord\n" \ "#define cogl_tex_coord_in gl_TexCoord\n" \
"\n" \ "\n" \
@ -77,9 +74,7 @@
"#define coglFragCoord gl_FragCoord\n" "#define coglFragCoord gl_FragCoord\n"
#endif #endif
#else /* HAVE_COGL_GLES2 */ #define _COGL_COMMON_SHADER_BOILERPLATE_GLES2 \
#define _COGL_COMMON_SHADER_BOILERPLATE \
"#define COGL_VERSION 100\n" \ "#define COGL_VERSION 100\n" \
"\n" \ "\n" \
"uniform mat4 cogl_modelview_matrix;\n" \ "uniform mat4 cogl_modelview_matrix;\n" \
@ -92,8 +87,8 @@
if they are not actually used. The GLSL spec for GLES at least if they are not actually used. The GLSL spec for GLES at least
implies that this will happen for varyings but it doesn't implies that this will happen for varyings but it doesn't
explicitly so for attributes */ explicitly so for attributes */
#define _COGL_VERTEX_SHADER_BOILERPLATE \ #define _COGL_VERTEX_SHADER_BOILERPLATE_GLES2 \
_COGL_COMMON_SHADER_BOILERPLATE \ _COGL_COMMON_SHADER_BOILERPLATE_GLES2 \
"#define cogl_color_out _cogl_color\n" \ "#define cogl_color_out _cogl_color\n" \
"varying vec4 _cogl_color;\n" \ "varying vec4 _cogl_color;\n" \
"#define cogl_tex_coord_out _cogl_tex_coord\n" \ "#define cogl_tex_coord_out _cogl_tex_coord\n" \
@ -105,11 +100,11 @@
"#define cogl_tex_coord_in cogl_tex_coord0_in;\n" \ "#define cogl_tex_coord_in cogl_tex_coord0_in;\n" \
"attribute vec3 cogl_normal_in;\n" "attribute vec3 cogl_normal_in;\n"
#define _COGL_FRAGMENT_SHADER_BOILERPLATE \ #define _COGL_FRAGMENT_SHADER_BOILERPLATE_GLES2 \
"#if __VERSION__ == 100\n" \ "#if __VERSION__ == 100\n" \
"precision highp float;\n" \ "precision highp float;\n" \
"#endif\n" \ "#endif\n" \
_COGL_COMMON_SHADER_BOILERPLATE \ _COGL_COMMON_SHADER_BOILERPLATE_GLES2 \
"\n" \ "\n" \
"varying vec4 _cogl_color;\n" \ "varying vec4 _cogl_color;\n" \
"\n" \ "\n" \
@ -121,7 +116,5 @@
"\n" \ "\n" \
"#define cogl_front_facing gl_FrontFacing\n" "#define cogl_front_facing gl_FrontFacing\n"
#endif /* HAVE_COGL_GLES2 */
#endif /* __COGL_SHADER_BOILERPLATE_H */ #endif /* __COGL_SHADER_BOILERPLATE_H */

View File

@ -31,9 +31,7 @@ typedef struct _CoglShader CoglShader;
typedef enum typedef enum
{ {
COGL_SHADER_LANGUAGE_GLSL, COGL_SHADER_LANGUAGE_GLSL,
#ifdef HAVE_COGL_GL
COGL_SHADER_LANGUAGE_ARBFP COGL_SHADER_LANGUAGE_ARBFP
#endif
} CoglShaderLanguage; } CoglShaderLanguage;
struct _CoglShader struct _CoglShader

View File

@ -41,11 +41,16 @@ static void _cogl_shader_free (CoglShader *shader);
COGL_HANDLE_DEFINE (Shader, shader); COGL_HANDLE_DEFINE (Shader, shader);
COGL_OBJECT_DEFINE_DEPRECATED_REF_COUNTING (shader); COGL_OBJECT_DEFINE_DEPRECATED_REF_COUNTING (shader);
#ifndef GL_FRAGMENT_SHADER
#define GL_FRAGMENT_SHADER 0x8B30
#endif
#ifndef GL_VERTEX_SHADER
#define GL_VERTEX_SHADER 0x8B31
#endif
static void static void
_cogl_shader_free (CoglShader *shader) _cogl_shader_free (CoglShader *shader)
{ {
#ifndef HAVE_COGL_GLES
/* Frees shader resources but its handle is not /* Frees shader resources but its handle is not
released! Do that separately before this! */ released! Do that separately before this! */
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -61,8 +66,6 @@ _cogl_shader_free (CoglShader *shader)
if (shader->gl_handle) if (shader->gl_handle)
GE (ctx, glDeleteShader (shader->gl_handle)); GE (ctx, glDeleteShader (shader->gl_handle));
#endif /* HAVE_COGL_GLES */
g_slice_free (CoglShader, shader); g_slice_free (CoglShader, shader);
} }
@ -98,8 +101,6 @@ cogl_create_shader (CoglShaderType type)
static void static void
delete_shader (CoglShader *shader) delete_shader (CoglShader *shader)
{ {
#ifndef HAVE_COGL_GLES
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
#ifdef HAVE_COGL_GL #ifdef HAVE_COGL_GL
@ -116,8 +117,6 @@ delete_shader (CoglShader *shader)
} }
shader->gl_handle = 0; shader->gl_handle = 0;
#endif /* HAVE_COGL_GLES */
} }
void void
@ -154,16 +153,15 @@ cogl_shader_source (CoglHandle handle,
void void
cogl_shader_compile (CoglHandle handle) cogl_shader_compile (CoglHandle handle)
{ {
#ifdef HAVE_COGL_GL
CoglShader *shader = handle; CoglShader *shader = handle;
#endif
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (!cogl_is_shader (handle)) if (!cogl_is_shader (handle))
return; return;
#ifdef HAVE_COGL_GL if (ctx->driver == COGL_DRIVER_GL)
_cogl_shader_compile_real (shader, 0 /* ignored */); _cogl_shader_compile_real (shader, 0 /* ignored */);
#endif
/* XXX: For GLES2 we don't actually compile anything until the /* XXX: For GLES2 we don't actually compile anything until the
* shader gets used so we have an opportunity to add some * shader gets used so we have an opportunity to add some
@ -183,43 +181,49 @@ _cogl_shader_set_source_with_boilerplate (GLuint shader_gl_handle,
const char **strings_in, const char **strings_in,
const GLint *lengths_in) const GLint *lengths_in)
{ {
#ifndef HAVE_COGL_GLES const char *vertex_boilerplate;
const char *fragment_boilerplate;
static const char vertex_boilerplate[] = _COGL_VERTEX_SHADER_BOILERPLATE;
static const char fragment_boilerplate[] = _COGL_FRAGMENT_SHADER_BOILERPLATE;
const char **strings = g_alloca (sizeof (char *) * (count_in + 3)); const char **strings = g_alloca (sizeof (char *) * (count_in + 3));
GLint *lengths = g_alloca (sizeof (GLint) * (count_in + 3)); GLint *lengths = g_alloca (sizeof (GLint) * (count_in + 3));
int count = 0; int count = 0;
#ifdef HAVE_COGL_GLES2
char *tex_coord_declarations = NULL; char *tex_coord_declarations = NULL;
#endif
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
#ifdef HAVE_COGL_GLES2 if (ctx->driver == COGL_DRIVER_GLES2)
if (cogl_features_available (COGL_FEATURE_TEXTURE_3D)) {
vertex_boilerplate = _COGL_VERTEX_SHADER_BOILERPLATE_GLES2;
fragment_boilerplate = _COGL_FRAGMENT_SHADER_BOILERPLATE_GLES2;
}
else
{
vertex_boilerplate = _COGL_VERTEX_SHADER_BOILERPLATE_GL;
fragment_boilerplate = _COGL_FRAGMENT_SHADER_BOILERPLATE_GL;
}
if (ctx->driver == COGL_DRIVER_GLES2 &&
cogl_features_available (COGL_FEATURE_TEXTURE_3D))
{ {
static const char texture_3d_extension[] = static const char texture_3d_extension[] =
"#extension GL_OES_texture_3D : enable\n"; "#extension GL_OES_texture_3D : enable\n";
strings[count] = texture_3d_extension; strings[count] = texture_3d_extension;
lengths[count++] = sizeof (texture_3d_extension) - 1; lengths[count++] = sizeof (texture_3d_extension) - 1;
} }
#endif
if (shader_gl_type == GL_VERTEX_SHADER) if (shader_gl_type == GL_VERTEX_SHADER)
{ {
strings[count] = vertex_boilerplate; strings[count] = vertex_boilerplate;
lengths[count++] = sizeof (vertex_boilerplate) - 1; lengths[count++] = strlen (vertex_boilerplate);
} }
else if (shader_gl_type == GL_FRAGMENT_SHADER) else if (shader_gl_type == GL_FRAGMENT_SHADER)
{ {
strings[count] = fragment_boilerplate; strings[count] = fragment_boilerplate;
lengths[count++] = sizeof (fragment_boilerplate) - 1; lengths[count++] = strlen (fragment_boilerplate);
} }
#ifdef HAVE_COGL_GLES2 if (ctx->driver == COGL_DRIVER_GLES2 &&
if (n_tex_coord_attribs) n_tex_coord_attribs)
{ {
GString *declarations = g_string_new (NULL); GString *declarations = g_string_new (NULL);
@ -245,7 +249,6 @@ _cogl_shader_set_source_with_boilerplate (GLuint shader_gl_handle,
strings[count] = tex_coord_declarations; strings[count] = tex_coord_declarations;
lengths[count++] = -1; /* null terminated */ lengths[count++] = -1; /* null terminated */
} }
#endif
memcpy (strings + count, strings_in, sizeof (char *) * count_in); memcpy (strings + count, strings_in, sizeof (char *) * count_in);
if (lengths_in) if (lengths_in)
@ -282,19 +285,13 @@ _cogl_shader_set_source_with_boilerplate (GLuint shader_gl_handle,
GE( ctx, glShaderSource (shader_gl_handle, count, GE( ctx, glShaderSource (shader_gl_handle, count,
(const char **) strings, lengths) ); (const char **) strings, lengths) );
#ifdef HAVE_COGL_GLES2
g_free (tex_coord_declarations); g_free (tex_coord_declarations);
#endif
#endif /* HAVE_COGL_GLES */
} }
void void
_cogl_shader_compile_real (CoglHandle handle, _cogl_shader_compile_real (CoglHandle handle,
int n_tex_coord_attribs) int n_tex_coord_attribs)
{ {
#ifndef HAVE_COGL_GLES
CoglShader *shader = handle; CoglShader *shader = handle;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -343,7 +340,9 @@ _cogl_shader_compile_real (CoglHandle handle,
if (shader->gl_handle if (shader->gl_handle
#ifdef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES2
&& shader->n_tex_coord_attribs >= n_tex_coord_attribs &&
(ctx->driver != COGL_DRIVER_GLES2 ||
shader->n_tex_coord_attribs >= n_tex_coord_attribs)
#endif #endif
) )
return; return;
@ -389,19 +388,11 @@ _cogl_shader_compile_real (CoglHandle handle,
} }
#endif #endif
} }
#endif /* HAVE_COGL_GLES */
} }
char * char *
cogl_shader_get_info_log (CoglHandle handle) cogl_shader_get_info_log (CoglHandle handle)
{ {
#ifdef HAVE_COGL_GLES
return NULL;
#else /* HAVE_COGL_GLES */
CoglShader *shader; CoglShader *shader;
_COGL_GET_CONTEXT (ctx, NULL); _COGL_GET_CONTEXT (ctx, NULL);
@ -443,8 +434,6 @@ cogl_shader_get_info_log (CoglHandle handle)
buffer[len] = '\0'; buffer[len] = '\0';
return g_strdup (buffer); return g_strdup (buffer);
} }
#endif /* HAVE_COGL_GLES */
} }
CoglShaderType CoglShaderType
@ -467,12 +456,7 @@ cogl_shader_get_type (CoglHandle handle)
gboolean gboolean
cogl_shader_is_compiled (CoglHandle handle) cogl_shader_is_compiled (CoglHandle handle)
{ {
#ifdef HAVE_COGL_GLES #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES2)
return FALSE;
#else /* HAVE_COGL_GLES */
GLint status; GLint status;
CoglShader *shader; CoglShader *shader;
@ -513,6 +497,7 @@ cogl_shader_is_compiled (CoglHandle handle)
else else
return FALSE; return FALSE;
} }
#else
#endif /* HAVE_COGL_GLES */ return FALSE;
#endif
} }

View File

@ -430,37 +430,38 @@ 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)
{
GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_2D, 0,
GL_TEXTURE_COMPRESSED,
&gl_compressed) );
GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, {
GL_TEXTURE_COMPRESSED, GLint val;
&gl_compressed) );
{ GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_2D, 0,
GLint val; GL_TEXTURE_INTERNAL_FORMAT,
&val) );
GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, gl_int_format = val;
GL_TEXTURE_INTERNAL_FORMAT, }
&val) );
gl_int_format = val;
}
/* If we can query GL for the actual pixel format then we'll ignore
the passed in format and use that. */
if (!ctx->texture_driver->pixel_format_from_gl_internal (gl_int_format,
&format))
return COGL_INVALID_HANDLE;
#else
/* Otherwise we'll assume we can derive the GL format from the
passed in format */
ctx->texture_driver->pixel_format_to_gl (format,
&gl_int_format,
NULL,
NULL);
/* If we can query GL for the actual pixel format then we'll ignore
the passed in format and use that. */
if (!ctx->texture_driver->pixel_format_from_gl_internal (gl_int_format,
&format))
return COGL_INVALID_HANDLE;
}
else
#endif #endif
{
/* Otherwise we'll assume we can derive the GL format from the
passed in format */
ctx->texture_driver->pixel_format_to_gl (format,
&gl_int_format,
NULL,
NULL);
}
/* Note: We always trust the given width and height without querying /* Note: We always trust the given width and height without querying
* the texture object because the user may be creating a Cogl * the texture object because the user may be creating a Cogl
@ -772,7 +773,7 @@ _cogl_texture_2d_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags)
GL_GENERATE_MIPMAP and reuploading the first pixel */ GL_GENERATE_MIPMAP and reuploading the first pixel */
if (cogl_features_available (COGL_FEATURE_OFFSCREEN)) if (cogl_features_available (COGL_FEATURE_OFFSCREEN))
ctx->texture_driver->gl_generate_mipmaps (GL_TEXTURE_2D); ctx->texture_driver->gl_generate_mipmaps (GL_TEXTURE_2D);
#ifndef HAVE_COGL_GLES2 #if defined(HAVE_COGL_GLES) || defined(HAVE_COGL_GL)
else else
{ {
GE( ctx, glTexParameteri (GL_TEXTURE_2D, GE( ctx, glTexParameteri (GL_TEXTURE_2D,

View File

@ -580,8 +580,8 @@ _cogl_texture_3d_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags)
GL_GENERATE_MIPMAP and reuploading the first pixel */ GL_GENERATE_MIPMAP and reuploading the first pixel */
if (cogl_features_available (COGL_FEATURE_OFFSCREEN)) if (cogl_features_available (COGL_FEATURE_OFFSCREEN))
ctx->texture_driver->gl_generate_mipmaps (GL_TEXTURE_3D); ctx->texture_driver->gl_generate_mipmaps (GL_TEXTURE_3D);
#ifndef HAVE_COGL_GLES2 #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
else else if (ctx->driver != COGL_DRIVER_GLES2)
{ {
GE( ctx, glTexParameteri (GL_TEXTURE_3D, GE( ctx, glTexParameteri (GL_TEXTURE_3D,
GL_GENERATE_MIPMAP, GL_GENERATE_MIPMAP,

View File

@ -372,37 +372,36 @@ _cogl_texture_rectangle_new_from_foreign (GLuint gl_handle,
/* Obtain texture parameters */ /* Obtain texture parameters */
#if HAVE_COGL_GL #if HAVE_COGL_GL
if (ctx->driver == COGL_DRIVER_GL)
{
GLint val;
GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_RECTANGLE_ARB, 0, GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_RECTANGLE_ARB, 0,
GL_TEXTURE_COMPRESSED, GL_TEXTURE_COMPRESSED,
&gl_compressed) ); &gl_compressed) );
{ GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_RECTANGLE_ARB, 0,
GLint val; GL_TEXTURE_INTERNAL_FORMAT,
&val) );
GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_RECTANGLE_ARB, 0, gl_int_format = val;
GL_TEXTURE_INTERNAL_FORMAT,
&val) );
gl_int_format = val;
}
/* If we can query GL for the actual pixel format then we'll ignore
the passed in format and use that. */
if (!ctx->texture_driver->pixel_format_from_gl_internal (gl_int_format,
&format))
return COGL_INVALID_HANDLE;
#else
/* Otherwise we'll assume we can derive the GL format from the
passed in format */
ctx->texture_driver->pixel_format_to_gl (format,
&gl_int_format,
NULL,
NULL);
/* If we can query GL for the actual pixel format then we'll ignore
the passed in format and use that. */
if (!ctx->texture_driver->pixel_format_from_gl_internal (gl_int_format,
&format))
return COGL_INVALID_HANDLE;
}
else
#endif #endif
{
/* Otherwise we'll assume we can derive the GL format from the
passed in format */
ctx->texture_driver->pixel_format_to_gl (format,
&gl_int_format,
NULL,
NULL);
}
/* Note: We always trust the given width and height without querying /* Note: We always trust the given width and height without querying
* the texture object because the user may be creating a Cogl * the texture object because the user may be creating a Cogl

View File

@ -194,54 +194,54 @@ _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 */
#ifdef HAVE_COGL_GL if (ctx->driver == COGL_DRIVER_GL)
/* If the source format does not have the same premult flag as the
dst format then we need to copy and convert it */
if (_cogl_texture_needs_premult_conversion (src_format,
dst_format))
{ {
dst_bmp = _cogl_bitmap_copy (src_bmp); /* If the source format does not have the same premult flag as the
dst format then we need to copy and convert it */
if (!_cogl_bitmap_convert_premult_status (dst_bmp, if (_cogl_texture_needs_premult_conversion (src_format,
src_format ^ dst_format))
COGL_PREMULT_BIT))
{ {
cogl_object_unref (dst_bmp); dst_bmp = _cogl_bitmap_copy (src_bmp);
return NULL;
if (!_cogl_bitmap_convert_premult_status (dst_bmp,
src_format ^
COGL_PREMULT_BIT))
{
cogl_object_unref (dst_bmp);
return NULL;
}
} }
else
dst_bmp = cogl_object_ref (src_bmp);
/* Use the source format from the src bitmap type and the internal
format from the dst format type so that GL can do the
conversion */
ctx->texture_driver->pixel_format_to_gl (src_format,
NULL, /* internal format */
out_glformat,
out_gltype);
ctx->texture_driver->pixel_format_to_gl (dst_format,
out_glintformat,
NULL,
NULL);
} }
else else
dst_bmp = cogl_object_ref (src_bmp); {
CoglPixelFormat closest_format;
/* Use the source format from the src bitmap type and the internal closest_format = ctx->texture_driver->pixel_format_to_gl (dst_format,
format from the dst format type so that GL can do the out_glintformat,
conversion */ out_glformat,
ctx->texture_driver->pixel_format_to_gl (src_format, out_gltype);
NULL, /* internal format */
out_glformat,
out_gltype);
ctx->texture_driver->pixel_format_to_gl (dst_format,
out_glintformat,
NULL,
NULL);
#else /* HAVE_COGL_GL */ if (closest_format != src_format)
{ dst_bmp = _cogl_bitmap_convert_format_and_premult (src_bmp,
CoglPixelFormat closest_format; closest_format);
else
closest_format = ctx->texture_driver->pixel_format_to_gl (dst_format, dst_bmp = cogl_object_ref (src_bmp);
out_glintformat, }
out_glformat,
out_gltype);
if (closest_format != src_format)
dst_bmp = _cogl_bitmap_convert_format_and_premult (src_bmp,
closest_format);
else
dst_bmp = cogl_object_ref (src_bmp);
}
#endif /* HAVE_COGL_GL */
if (dst_format_out) if (dst_format_out)
*dst_format_out = dst_format; *dst_format_out = dst_format;

View File

@ -164,15 +164,7 @@ toggle_flag (CoglContext *ctx,
return FALSE; return FALSE;
} }
#ifdef HAVE_COGL_GLES2 #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
/* Under GLES2 there are no builtin client flags so toggle_client_flag
should never be reached */
#define toggle_client_flag(ctx, new_flags, flag, gl_flag) \
g_assert (((new_flags) & (flag)) == 0)
#else /* HAVE_COGL_GLES2 */
static gboolean static gboolean
toggle_client_flag (CoglContext *ctx, toggle_client_flag (CoglContext *ctx,
@ -180,6 +172,8 @@ toggle_client_flag (CoglContext *ctx,
unsigned long flag, unsigned long flag,
GLenum gl_flag) GLenum gl_flag)
{ {
g_return_val_if_fail (ctx->driver != COGL_DRIVER_GLES2, FALSE);
/* Toggles and caches a single client-side enable flag /* Toggles and caches a single client-side enable flag
* on or off by comparing to current state * on or off by comparing to current state
*/ */
@ -201,7 +195,7 @@ toggle_client_flag (CoglContext *ctx,
return FALSE; return FALSE;
} }
#endif /* HAVE_COGL_GLES2 */ #endif
void void
_cogl_enable (unsigned long flags) _cogl_enable (unsigned long flags)
@ -215,13 +209,18 @@ _cogl_enable (unsigned long flags)
COGL_ENABLE_BACKFACE_CULLING, COGL_ENABLE_BACKFACE_CULLING,
GL_CULL_FACE); GL_CULL_FACE);
toggle_client_flag (ctx, flags, #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
COGL_ENABLE_VERTEX_ARRAY, if (ctx->driver != COGL_DRIVER_GLES2)
GL_VERTEX_ARRAY); {
toggle_client_flag (ctx, flags,
COGL_ENABLE_VERTEX_ARRAY,
GL_VERTEX_ARRAY);
toggle_client_flag (ctx, flags, toggle_client_flag (ctx, flags,
COGL_ENABLE_COLOR_ARRAY, COGL_ENABLE_COLOR_ARRAY,
GL_COLOR_ARRAY); GL_COLOR_ARRAY);
}
#endif
} }
unsigned long unsigned long
@ -557,9 +556,9 @@ _cogl_read_pixels_with_rowstride (int x,
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 */
#ifndef COGL_HAS_GL if (ctx->driver != COGL_DRIVER_GL &&
if (gl_format != GL_RGBA || gl_type != GL_UNSIGNED_BYTE || (gl_format != GL_RGBA || gl_type != GL_UNSIGNED_BYTE ||
rowstride != 4 * width) rowstride != 4 * width))
{ {
CoglBitmap *tmp_bmp, *dst_bmp; CoglBitmap *tmp_bmp, *dst_bmp;
guint8 *tmp_data = g_malloc (width * height * 4); guint8 *tmp_data = g_malloc (width * height * 4);
@ -599,7 +598,6 @@ _cogl_read_pixels_with_rowstride (int x,
cogl_object_unref (tmp_bmp); cogl_object_unref (tmp_bmp);
} }
else else
#endif
{ {
ctx->texture_driver->prep_gl_for_pixels_download (rowstride, bpp); ctx->texture_driver->prep_gl_for_pixels_download (rowstride, bpp);

View File

@ -72,13 +72,12 @@ _cogl_get_gl_version (int *major_out, int *minor_out)
} }
gboolean gboolean
_cogl_gl_check_version (GError **error) _cogl_gl_check_gl_version (CoglContext *ctx,
GError **error)
{ {
int major, minor; int major, minor;
const char *gl_extensions; const char *gl_extensions;
_COGL_GET_CONTEXT (ctx, FALSE);
if (!_cogl_get_gl_version (&major, &minor)) if (!_cogl_get_gl_version (&major, &minor))
{ {
g_set_error (error, g_set_error (error,
@ -166,8 +165,7 @@ _cogl_gl_update_features (CoglContext *context)
_cogl_feature_check_ext_functions (context, _cogl_feature_check_ext_functions (context,
gl_major, gl_major,
gl_minor, gl_minor,
gl_extensions, gl_extensions);
0 /* gles_version */);
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0) || if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0) ||
_cogl_check_extension ("GL_ARB_texture_non_power_of_two", gl_extensions)) _cogl_check_extension ("GL_ARB_texture_non_power_of_two", gl_extensions))

View File

@ -33,7 +33,7 @@
#include "cogl-feature-private.h" #include "cogl-feature-private.h"
gboolean gboolean
_cogl_gl_check_version (GError **error) _cogl_gles_check_gl_version (GError **error)
{ {
/* The GLES backend doesn't have any particular version requirements */ /* The GLES backend doesn't have any particular version requirements */
return TRUE; return TRUE;
@ -44,14 +44,11 @@ _cogl_gl_check_version (GError **error)
* different GL contexts so it is the winsys backend's responsiblity * different GL contexts so it is the winsys backend's responsiblity
* to know when to re-query the GL extensions. */ * to know when to re-query the GL extensions. */
void void
_cogl_gl_update_features (CoglContext *context) _cogl_gles_update_features (CoglContext *context)
{ {
CoglPrivateFeatureFlags private_flags = 0; CoglPrivateFeatureFlags private_flags = 0;
CoglFeatureFlags flags = 0; CoglFeatureFlags flags = 0;
const char *gl_extensions; const char *gl_extensions;
#ifndef HAVE_COGL_GLES2
int max_clip_planes = 0;
#endif
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
@ -77,32 +74,31 @@ _cogl_gl_update_features (CoglContext *context)
_cogl_feature_check_ext_functions (context, _cogl_feature_check_ext_functions (context,
-1 /* GL major version */, -1 /* GL major version */,
-1 /* GL minor version */, -1 /* GL minor version */,
gl_extensions, gl_extensions);
#ifdef HAVE_COGL_GLES2
COGL_EXT_IN_GLES2
#else
COGL_EXT_IN_GLES
#endif
);
GE( context, glGetIntegerv (GL_STENCIL_BITS, &num_stencil_bits) ); GE( context, glGetIntegerv (GL_STENCIL_BITS, &num_stencil_bits) );
/* We need at least three stencil bits to combine clips */ /* We need at least three stencil bits to combine clips */
if (num_stencil_bits > 2) if (num_stencil_bits > 2)
flags |= COGL_FEATURE_STENCIL_BUFFER; flags |= COGL_FEATURE_STENCIL_BUFFER;
#ifndef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES
GE( context, glGetIntegerv (GL_MAX_CLIP_PLANES, &max_clip_planes) ); if (context->driver == COGL_DRIVER_GLES1)
if (max_clip_planes >= 4) {
flags |= COGL_FEATURE_FOUR_CLIP_PLANES; int max_clip_planes;
GE( context, glGetIntegerv (GL_MAX_CLIP_PLANES, &max_clip_planes) );
if (max_clip_planes >= 4)
flags |= COGL_FEATURE_FOUR_CLIP_PLANES;
}
#endif #endif
#ifdef HAVE_COGL_GLES2 if (context->driver == COGL_DRIVER_GLES2)
flags |= COGL_FEATURE_SHADERS_GLSL | COGL_FEATURE_OFFSCREEN; {
/* Note GLES 2 core doesn't support mipmaps for npot textures or flags |= COGL_FEATURE_SHADERS_GLSL | COGL_FEATURE_OFFSCREEN;
* repeat modes other than CLAMP_TO_EDGE. */ /* Note GLES 2 core doesn't support mipmaps for npot textures or
flags |= COGL_FEATURE_TEXTURE_NPOT_BASIC; * repeat modes other than CLAMP_TO_EDGE. */
flags |= COGL_FEATURE_DEPTH_RANGE; flags |= COGL_FEATURE_TEXTURE_NPOT_BASIC;
#endif flags |= COGL_FEATURE_DEPTH_RANGE;
}
flags |= COGL_FEATURE_VBOS; flags |= COGL_FEATURE_VBOS;

View File

@ -499,11 +499,10 @@ _cogl_texture_driver_allows_foreign_gl_target (GLenum gl_target)
static void static void
_cogl_texture_driver_gl_generate_mipmaps (GLenum gl_target) _cogl_texture_driver_gl_generate_mipmaps (GLenum gl_target)
{ {
#ifdef HAVE_COGL_GLES2
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
GE( ctx, glGenerateMipmap (gl_target) ); if (ctx->driver == COGL_DRIVER_GLES2)
#endif GE( ctx, glGenerateMipmap (gl_target) );
} }
static CoglPixelFormat static CoglPixelFormat

View File

@ -353,7 +353,8 @@ check_egl_extensions (CoglRenderer *renderer)
egl_renderer->private_features = 0; egl_renderer->private_features = 0;
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 (winsys, if (_cogl_feature_check (winsys,
"EGL", winsys_feature_data + i, 0, 0, 0, "EGL", winsys_feature_data + i, 0, 0,
COGL_DRIVER_GL, /* the driver isn't used */
egl_extensions, egl_extensions,
egl_renderer)) egl_renderer))
{ {
@ -514,7 +515,7 @@ update_winsys_features (CoglContext *context)
check_egl_extensions (context->display->renderer); check_egl_extensions (context->display->renderer);
_cogl_gl_update_features (context); _cogl_context_update_features (context);
#if defined (COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT) || \ #if defined (COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT) || \
defined (COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT) defined (COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT)
@ -619,23 +620,17 @@ try_create_context (CoglDisplay *display,
EGL_BUFFER_SIZE, EGL_DONT_CARE, EGL_BUFFER_SIZE, EGL_DONT_CARE,
#if defined (HAVE_COGL_GL) EGL_RENDERABLE_TYPE, (display->renderer->driver == COGL_DRIVER_GL ?
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_OPENGL_BIT :
#elif defined (HAVE_COGL_GLES2) display->renderer->driver == COGL_DRIVER_GLES1 ?
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_OPENGL_ES_BIT :
#else EGL_OPENGL_ES2_BIT),
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
#endif
EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE EGL_NONE
}; };
#if defined (HAVE_COGL_GLES2) EGLint attribs[3];
EGLint attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
#else
EGLint *attribs = NULL;
#endif
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT #ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
XVisualInfo *xvisinfo; XVisualInfo *xvisinfo;
@ -646,11 +641,19 @@ try_create_context (CoglDisplay *display,
#endif #endif
const char *error_message; const char *error_message;
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;
edpy = egl_renderer->edpy; edpy = egl_renderer->edpy;
#ifdef HAVE_COGL_GL if (display->renderer->driver == COGL_DRIVER_GL)
eglBindAPI (EGL_OPENGL_API); eglBindAPI (EGL_OPENGL_API);
#endif
/* Some GLES hardware can't support a stencil buffer: */ /* Some GLES hardware can't support a stencil buffer: */
if (retry_cookie == 1) if (retry_cookie == 1)

View File

@ -265,17 +265,75 @@ glx_event_filter_cb (XEvent *xevent, void *data)
static void static void
_cogl_winsys_renderer_disconnect (CoglRenderer *renderer) _cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
{ {
CoglGLXRenderer *glx_renderer = renderer->winsys;
_cogl_xlib_renderer_disconnect (renderer); _cogl_xlib_renderer_disconnect (renderer);
if (glx_renderer->libgl_module)
g_module_close (glx_renderer->libgl_module);
g_slice_free (CoglGLXRenderer, renderer->winsys); g_slice_free (CoglGLXRenderer, renderer->winsys);
} }
static gboolean
resolve_core_glx_functions (CoglRenderer *renderer,
GError **error)
{
CoglGLXRenderer *glx_renderer;
glx_renderer = renderer->winsys;
if (!g_module_symbol (glx_renderer->libgl_module, "glXCreatePixmap",
(void **) &glx_renderer->glXCreatePixmap) ||
!g_module_symbol (glx_renderer->libgl_module, "glXDestroyPixmap",
(void **) &glx_renderer->glXDestroyPixmap) ||
!g_module_symbol (glx_renderer->libgl_module, "glXChooseFBConfig",
(void **) &glx_renderer->glXChooseFBConfig) ||
!g_module_symbol (glx_renderer->libgl_module, "glXCreateNewContext",
(void **) &glx_renderer->glXCreateNewContext) ||
!g_module_symbol (glx_renderer->libgl_module, "glXGetFBConfigAttrib",
(void **) &glx_renderer->glXGetFBConfigAttrib) ||
!g_module_symbol (glx_renderer->libgl_module, "glXQueryVersion",
(void **) &glx_renderer->glXQueryVersion) ||
!g_module_symbol (glx_renderer->libgl_module, "glXDestroyContext",
(void **) &glx_renderer->glXDestroyContext) ||
!g_module_symbol (glx_renderer->libgl_module, "glXMakeContextCurrent",
(void **) &glx_renderer->glXMakeContextCurrent) ||
!g_module_symbol (glx_renderer->libgl_module, "glXSwapBuffers",
(void **) &glx_renderer->glXSwapBuffers) ||
!g_module_symbol (glx_renderer->libgl_module, "glXQueryExtension",
(void **) &glx_renderer->glXQueryExtension) ||
!g_module_symbol (glx_renderer->libgl_module, "glXIsDirect",
(void **) &glx_renderer->glXIsDirect) ||
!g_module_symbol (glx_renderer->libgl_module, "glXGetVisualFromFBConfig",
(void **) &glx_renderer->glXGetVisualFromFBConfig) ||
!g_module_symbol (glx_renderer->libgl_module, "glXSelectEvent",
(void **) &glx_renderer->glXSelectEvent) ||
!g_module_symbol (glx_renderer->libgl_module, "glXCreateWindow",
(void **) &glx_renderer->glXCreateWindow) ||
!g_module_symbol (glx_renderer->libgl_module, "glXGetFBConfigs",
(void **) &glx_renderer->glXGetFBConfigs) ||
!g_module_symbol (glx_renderer->libgl_module, "glXDestroyWindow",
(void **) &glx_renderer->glXDestroyWindow) ||
!g_module_symbol (glx_renderer->libgl_module, "glXQueryExtensionsString",
(void **) &glx_renderer->glXQueryExtensionsString))
{
g_set_error (error, COGL_WINSYS_ERROR,
COGL_WINSYS_ERROR_INIT,
"Failed to resolve required GLX symbol");
return FALSE;
}
return TRUE;
}
static gboolean static gboolean
_cogl_winsys_renderer_connect (CoglRenderer *renderer, _cogl_winsys_renderer_connect (CoglRenderer *renderer,
GError **error) GError **error)
{ {
CoglGLXRenderer *glx_renderer; CoglGLXRenderer *glx_renderer;
CoglXlibRenderer *xlib_renderer; CoglXlibRenderer *xlib_renderer;
char *libgl_module_path;
renderer->winsys = g_slice_new0 (CoglGLXRenderer); renderer->winsys = g_slice_new0 (CoglGLXRenderer);
@ -285,9 +343,28 @@ _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 (!glXQueryExtension (xlib_renderer->xdpy, libgl_module_path = g_module_build_path (NULL, /* standard lib search path */
&glx_renderer->glx_error_base, COGL_GL_LIBNAME);
&glx_renderer->glx_event_base))
glx_renderer->libgl_module = g_module_open (libgl_module_path,
G_MODULE_BIND_LAZY);
g_free (libgl_module_path);
if (glx_renderer->libgl_module == NULL)
{
g_set_error (error, COGL_WINSYS_ERROR,
COGL_WINSYS_ERROR_INIT,
"Failed to dynamically open the OpenGL library");
goto error;
}
if (!resolve_core_glx_functions (renderer, error))
goto error;
if (!glx_renderer->glXQueryExtension (xlib_renderer->xdpy,
&glx_renderer->glx_error_base,
&glx_renderer->glx_event_base))
{ {
g_set_error (error, COGL_WINSYS_ERROR, g_set_error (error, COGL_WINSYS_ERROR,
COGL_WINSYS_ERROR_INIT, COGL_WINSYS_ERROR_INIT,
@ -298,9 +375,9 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
/* XXX: Note: For a long time Mesa exported a hybrid GLX, exporting /* XXX: Note: For a long time Mesa exported a hybrid GLX, exporting
* extensions specified to require GLX 1.3, but still reporting 1.2 * extensions specified to require GLX 1.3, but still reporting 1.2
* via glXQueryVersion. */ * via glXQueryVersion. */
if (!glXQueryVersion (xlib_renderer->xdpy, if (!glx_renderer->glXQueryVersion (xlib_renderer->xdpy,
&glx_renderer->glx_major, &glx_renderer->glx_major,
&glx_renderer->glx_minor) &glx_renderer->glx_minor)
|| !(glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 2)) || !(glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 2))
{ {
g_set_error (error, COGL_WINSYS_ERROR, g_set_error (error, COGL_WINSYS_ERROR,
@ -325,17 +402,19 @@ update_winsys_features (CoglContext *context)
CoglXlibRenderer *xlib_renderer = context->display->renderer->winsys; CoglXlibRenderer *xlib_renderer = context->display->renderer->winsys;
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
const char *glx_extensions; const char *glx_extensions;
int default_screen;
int i; int i;
g_return_if_fail (glx_display->glx_context); g_return_if_fail (glx_display->glx_context);
_cogl_gl_update_features (context); _cogl_context_update_features (context);
memset (context->winsys_features, 0, sizeof (context->winsys_features)); memset (context->winsys_features, 0, sizeof (context->winsys_features));
default_screen = DefaultScreen (xlib_renderer->xdpy);
glx_extensions = glx_extensions =
glXQueryExtensionsString (xlib_renderer->xdpy, glx_renderer->glXQueryExtensionsString (xlib_renderer->xdpy,
DefaultScreen (xlib_renderer->xdpy)); default_screen);
COGL_NOTE (WINSYS, " GLX Extensions: %s", glx_extensions); COGL_NOTE (WINSYS, " GLX Extensions: %s", glx_extensions);
@ -346,7 +425,8 @@ update_winsys_features (CoglContext *context)
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 (_cogl_context_get_winsys (context), if (_cogl_feature_check (_cogl_context_get_winsys (context),
"GLX", winsys_feature_data + i, 0, 0, 0, "GLX", winsys_feature_data + i, 0, 0,
COGL_DRIVER_GL, /* the driver isn't used */
glx_extensions, glx_extensions,
glx_renderer)) glx_renderer))
{ {
@ -407,6 +487,7 @@ find_fbconfig (CoglDisplay *display,
GError **error) GError **error)
{ {
CoglXlibRenderer *xlib_renderer = display->renderer->winsys; CoglXlibRenderer *xlib_renderer = display->renderer->winsys;
CoglGLXRenderer *glx_renderer = display->renderer->winsys;
GLXFBConfig *configs = NULL; GLXFBConfig *configs = NULL;
int n_configs, i; int n_configs, i;
static const int attributes[] = { static const int attributes[] = {
@ -424,10 +505,10 @@ find_fbconfig (CoglDisplay *display,
gboolean ret = TRUE; gboolean ret = TRUE;
int xscreen_num = DefaultScreen (xlib_renderer->xdpy); int xscreen_num = DefaultScreen (xlib_renderer->xdpy);
configs = glXChooseFBConfig (xlib_renderer->xdpy, configs = glx_renderer->glXChooseFBConfig (xlib_renderer->xdpy,
xscreen_num, xscreen_num,
attributes, attributes,
&n_configs); &n_configs);
if (!configs || n_configs == 0) if (!configs || n_configs == 0)
{ {
g_set_error (error, COGL_WINSYS_ERROR, g_set_error (error, COGL_WINSYS_ERROR,
@ -443,7 +524,8 @@ find_fbconfig (CoglDisplay *display,
{ {
XVisualInfo *vinfo; XVisualInfo *vinfo;
vinfo = glXGetVisualFromFBConfig (xlib_renderer->xdpy, configs[i]); vinfo = glx_renderer->glXGetVisualFromFBConfig (xlib_renderer->xdpy,
configs[i]);
if (vinfo == NULL) if (vinfo == NULL)
continue; continue;
@ -519,11 +601,12 @@ create_context (CoglDisplay *display, GError **error)
COGL_NOTE (WINSYS, "Creating GLX Context (display: %p)", COGL_NOTE (WINSYS, "Creating GLX Context (display: %p)",
xlib_renderer->xdpy); xlib_renderer->xdpy);
glx_display->glx_context = glXCreateNewContext (xlib_renderer->xdpy, glx_display->glx_context =
config, glx_renderer->glXCreateNewContext (xlib_renderer->xdpy,
GLX_RGBA_TYPE, config,
NULL, GLX_RGBA_TYPE,
True); NULL,
True);
if (glx_display->glx_context == NULL) if (glx_display->glx_context == NULL)
{ {
g_set_error (error, COGL_WINSYS_ERROR, g_set_error (error, COGL_WINSYS_ERROR,
@ -533,7 +616,7 @@ create_context (CoglDisplay *display, GError **error)
} }
glx_renderer->is_direct = glx_renderer->is_direct =
glXIsDirect (xlib_renderer->xdpy, glx_display->glx_context); glx_renderer->glXIsDirect (xlib_renderer->xdpy, glx_display->glx_context);
COGL_NOTE (WINSYS, "Setting %s context", COGL_NOTE (WINSYS, "Setting %s context",
glx_renderer->is_direct ? "direct" : "indirect"); glx_renderer->is_direct ? "direct" : "indirect");
@ -543,7 +626,8 @@ create_context (CoglDisplay *display, GError **error)
* framebuffer is in use. * framebuffer is in use.
*/ */
xvisinfo = glXGetVisualFromFBConfig (xlib_renderer->xdpy, config); xvisinfo = glx_renderer->glXGetVisualFromFBConfig (xlib_renderer->xdpy,
config);
if (xvisinfo == NULL) if (xvisinfo == NULL)
{ {
g_set_error (error, COGL_WINSYS_ERROR, g_set_error (error, COGL_WINSYS_ERROR,
@ -577,10 +661,11 @@ create_context (CoglDisplay *display, GError **error)
* drawables. */ * drawables. */
if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 3) if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 3)
{ {
glx_display->dummy_glxwin = glXCreateWindow (xlib_renderer->xdpy, glx_display->dummy_glxwin =
config, glx_renderer->glXCreateWindow (xlib_renderer->xdpy,
xlib_display->dummy_xwin, config,
NULL); xlib_display->dummy_xwin,
NULL);
} }
if (glx_display->dummy_glxwin) if (glx_display->dummy_glxwin)
@ -591,10 +676,10 @@ create_context (CoglDisplay *display, GError **error)
COGL_NOTE (WINSYS, "Selecting dummy 0x%x for the GLX context", COGL_NOTE (WINSYS, "Selecting dummy 0x%x for the GLX context",
(unsigned int) dummy_drawable); (unsigned int) dummy_drawable);
glXMakeContextCurrent (xlib_renderer->xdpy, glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy,
dummy_drawable, dummy_drawable,
dummy_drawable, dummy_drawable,
glx_display->glx_context); glx_display->glx_context);
XFree (xvisinfo); XFree (xvisinfo);
@ -615,19 +700,23 @@ _cogl_winsys_display_destroy (CoglDisplay *display)
CoglGLXDisplay *glx_display = display->winsys; CoglGLXDisplay *glx_display = display->winsys;
CoglXlibDisplay *xlib_display = display->winsys; CoglXlibDisplay *xlib_display = display->winsys;
CoglXlibRenderer *xlib_renderer = display->renderer->winsys; CoglXlibRenderer *xlib_renderer = display->renderer->winsys;
CoglGLXRenderer *glx_renderer = display->renderer->winsys;
g_return_if_fail (glx_display != NULL); g_return_if_fail (glx_display != NULL);
if (glx_display->glx_context) if (glx_display->glx_context)
{ {
glXMakeContextCurrent (xlib_renderer->xdpy, None, None, NULL); glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy,
glXDestroyContext (xlib_renderer->xdpy, glx_display->glx_context); None, None, NULL);
glx_renderer->glXDestroyContext (xlib_renderer->xdpy,
glx_display->glx_context);
glx_display->glx_context = NULL; glx_display->glx_context = NULL;
} }
if (glx_display->dummy_glxwin) if (glx_display->dummy_glxwin)
{ {
glXDestroyWindow (xlib_renderer->xdpy, glx_display->dummy_glxwin); glx_renderer->glXDestroyWindow (xlib_renderer->xdpy,
glx_display->dummy_glxwin);
glx_display->dummy_glxwin = None; glx_display->dummy_glxwin = None;
} }
@ -761,8 +850,8 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
_cogl_xlib_renderer_trap_errors (display->renderer, &state); _cogl_xlib_renderer_trap_errors (display->renderer, &state);
xvisinfo = glXGetVisualFromFBConfig (xlib_renderer->xdpy, xvisinfo = glx_renderer->glXGetVisualFromFBConfig (xlib_renderer->xdpy,
glx_display->fbconfig); glx_display->fbconfig);
if (xvisinfo == NULL) if (xvisinfo == NULL)
{ {
g_set_error (error, COGL_WINSYS_ERROR, g_set_error (error, COGL_WINSYS_ERROR,
@ -825,10 +914,10 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 3) if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 3)
{ {
glx_onscreen->glxwin = glx_onscreen->glxwin =
glXCreateWindow (xlib_renderer->xdpy, glx_renderer->glXCreateWindow (xlib_renderer->xdpy,
glx_display->fbconfig, glx_display->fbconfig,
xlib_onscreen->xwin, xlib_onscreen->xwin,
NULL); NULL);
} }
#ifdef GLX_INTEL_swap_event #ifdef GLX_INTEL_swap_event
@ -841,9 +930,9 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
* because we rely on it to advance the master clock, and * because we rely on it to advance the master clock, and
* drive redraw/relayout, animations and event handling. * drive redraw/relayout, animations and event handling.
*/ */
glXSelectEvent (xlib_renderer->xdpy, glx_renderer->glXSelectEvent (xlib_renderer->xdpy,
drawable, drawable,
GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK); GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK);
} }
#endif /* GLX_INTEL_swap_event */ #endif /* GLX_INTEL_swap_event */
@ -856,6 +945,7 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
CoglContext *context = framebuffer->context; CoglContext *context = framebuffer->context;
CoglXlibRenderer *xlib_renderer = context->display->renderer->winsys; CoglXlibRenderer *xlib_renderer = context->display->renderer->winsys;
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
CoglXlibTrapState old_state; CoglXlibTrapState old_state;
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys; CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
CoglOnscreenGLX *glx_onscreen = onscreen->winsys; CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
@ -868,7 +958,8 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
if (glx_onscreen->glxwin != None) if (glx_onscreen->glxwin != None)
{ {
glXDestroyWindow (xlib_renderer->xdpy, glx_onscreen->glxwin); glx_renderer->glXDestroyWindow (xlib_renderer->xdpy,
glx_onscreen->glxwin);
glx_onscreen->glxwin = None; glx_onscreen->glxwin = None;
} }
@ -913,9 +1004,9 @@ _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
_cogl_xlib_renderer_trap_errors (context->display->renderer, &old_state); _cogl_xlib_renderer_trap_errors (context->display->renderer, &old_state);
glXMakeContextCurrent (xlib_renderer->xdpy, glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy,
drawable, drawable, drawable, drawable,
glx_display->glx_context); glx_display->glx_context);
} }
else else
{ {
@ -934,10 +1025,10 @@ _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
xlib_onscreen->is_foreign_xwin ? "foreign" : "native", xlib_onscreen->is_foreign_xwin ? "foreign" : "native",
glx_display->glx_context); glx_display->glx_context);
glXMakeContextCurrent (xlib_renderer->xdpy, glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy,
drawable, drawable,
drawable, drawable,
glx_display->glx_context); glx_display->glx_context);
/* In case we are using GLX_SGI_swap_control for vblank syncing /* In case we are using GLX_SGI_swap_control for vblank syncing
* we need call glXSwapIntervalSGI here to make sure that it * we need call glXSwapIntervalSGI here to make sure that it
@ -1252,7 +1343,7 @@ _cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
else else
have_counter = FALSE; have_counter = FALSE;
glXSwapBuffers (xlib_renderer->xdpy, drawable); glx_renderer->glXSwapBuffers (xlib_renderer->xdpy, drawable);
if (have_counter) if (have_counter)
glx_onscreen->last_swap_vsync_counter = _cogl_winsys_get_vsync_counter (); glx_onscreen->last_swap_vsync_counter = _cogl_winsys_get_vsync_counter ();
@ -1341,6 +1432,7 @@ _cogl_winsys_xlib_get_visual_info (void)
{ {
CoglGLXDisplay *glx_display; CoglGLXDisplay *glx_display;
CoglXlibRenderer *xlib_renderer; CoglXlibRenderer *xlib_renderer;
CoglGLXRenderer *glx_renderer;
_COGL_GET_CONTEXT (ctx, NULL); _COGL_GET_CONTEXT (ctx, NULL);
@ -1348,11 +1440,13 @@ _cogl_winsys_xlib_get_visual_info (void)
glx_display = ctx->display->winsys; glx_display = ctx->display->winsys;
xlib_renderer = ctx->display->renderer->winsys; xlib_renderer = ctx->display->renderer->winsys;
glx_renderer = ctx->display->renderer->winsys;
if (!glx_display->found_fbconfig) if (!glx_display->found_fbconfig)
return NULL; return NULL;
return glXGetVisualFromFBConfig (xlib_renderer->xdpy, glx_display->fbconfig); return glx_renderer->glXGetVisualFromFBConfig (xlib_renderer->xdpy,
glx_display->fbconfig);
} }
static gboolean static gboolean
@ -1362,6 +1456,7 @@ get_fbconfig_for_depth (CoglContext *context,
gboolean *can_mipmap_ret) gboolean *can_mipmap_ret)
{ {
CoglXlibRenderer *xlib_renderer; CoglXlibRenderer *xlib_renderer;
CoglGLXRenderer *glx_renderer;
CoglGLXDisplay *glx_display; CoglGLXDisplay *glx_display;
Display *dpy; Display *dpy;
GLXFBConfig *fbconfigs; GLXFBConfig *fbconfigs;
@ -1371,6 +1466,7 @@ get_fbconfig_for_depth (CoglContext *context,
gboolean found = FALSE; gboolean found = FALSE;
xlib_renderer = context->display->renderer->winsys; xlib_renderer = context->display->renderer->winsys;
glx_renderer = context->display->renderer->winsys;
glx_display = context->display->winsys; glx_display = context->display->winsys;
/* Check if we've already got a cached config for this depth */ /* Check if we've already got a cached config for this depth */
@ -1386,7 +1482,8 @@ get_fbconfig_for_depth (CoglContext *context,
dpy = xlib_renderer->xdpy; dpy = xlib_renderer->xdpy;
fbconfigs = glXGetFBConfigs (dpy, DefaultScreen (dpy), &n_elements); fbconfigs = glx_renderer->glXGetFBConfigs (dpy, DefaultScreen (dpy),
&n_elements);
db = G_MAXSHORT; db = G_MAXSHORT;
stencil = G_MAXSHORT; stencil = G_MAXSHORT;
@ -1398,7 +1495,7 @@ get_fbconfig_for_depth (CoglContext *context,
XVisualInfo *vi; XVisualInfo *vi;
int visual_depth; int visual_depth;
vi = glXGetVisualFromFBConfig (dpy, fbconfigs[i]); vi = glx_renderer->glXGetVisualFromFBConfig (dpy, fbconfigs[i]);
if (vi == NULL) if (vi == NULL)
continue; continue;
@ -1409,24 +1506,24 @@ get_fbconfig_for_depth (CoglContext *context,
if (visual_depth != depth) if (visual_depth != depth)
continue; continue;
glXGetFBConfigAttrib (dpy, glx_renderer->glXGetFBConfigAttrib (dpy,
fbconfigs[i], fbconfigs[i],
GLX_ALPHA_SIZE, GLX_ALPHA_SIZE,
&alpha); &alpha);
glXGetFBConfigAttrib (dpy, glx_renderer->glXGetFBConfigAttrib (dpy,
fbconfigs[i], fbconfigs[i],
GLX_BUFFER_SIZE, GLX_BUFFER_SIZE,
&value); &value);
if (value != depth && (value - alpha) != depth) if (value != depth && (value - alpha) != depth)
continue; continue;
value = 0; value = 0;
if (depth == 32) if (depth == 32)
{ {
glXGetFBConfigAttrib (dpy, glx_renderer->glXGetFBConfigAttrib (dpy,
fbconfigs[i], fbconfigs[i],
GLX_BIND_TO_TEXTURE_RGBA_EXT, GLX_BIND_TO_TEXTURE_RGBA_EXT,
&value); &value);
if (value) if (value)
rgba = 1; rgba = 1;
} }
@ -1436,27 +1533,27 @@ get_fbconfig_for_depth (CoglContext *context,
if (rgba) if (rgba)
continue; continue;
glXGetFBConfigAttrib (dpy, glx_renderer->glXGetFBConfigAttrib (dpy,
fbconfigs[i], fbconfigs[i],
GLX_BIND_TO_TEXTURE_RGB_EXT, GLX_BIND_TO_TEXTURE_RGB_EXT,
&value); &value);
if (!value) if (!value)
continue; continue;
} }
glXGetFBConfigAttrib (dpy, glx_renderer->glXGetFBConfigAttrib (dpy,
fbconfigs[i], fbconfigs[i],
GLX_DOUBLEBUFFER, GLX_DOUBLEBUFFER,
&value); &value);
if (value > db) if (value > db)
continue; continue;
db = value; db = value;
glXGetFBConfigAttrib (dpy, glx_renderer->glXGetFBConfigAttrib (dpy,
fbconfigs[i], fbconfigs[i],
GLX_STENCIL_SIZE, GLX_STENCIL_SIZE,
&value); &value);
if (value > stencil) if (value > stencil)
continue; continue;
@ -1465,10 +1562,10 @@ get_fbconfig_for_depth (CoglContext *context,
/* glGenerateMipmap is defined in the offscreen extension */ /* glGenerateMipmap is defined in the offscreen extension */
if (cogl_features_available (COGL_FEATURE_OFFSCREEN)) if (cogl_features_available (COGL_FEATURE_OFFSCREEN))
{ {
glXGetFBConfigAttrib (dpy, glx_renderer->glXGetFBConfigAttrib (dpy,
fbconfigs[i], fbconfigs[i],
GLX_BIND_TO_MIPMAP_TEXTURE_EXT, GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
&value); &value);
if (value < mipmap) if (value < mipmap)
continue; continue;
@ -1548,6 +1645,7 @@ try_create_glx_pixmap (CoglContext *context,
CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys;
CoglRenderer *renderer; CoglRenderer *renderer;
CoglXlibRenderer *xlib_renderer; CoglXlibRenderer *xlib_renderer;
CoglGLXRenderer *glx_renderer;
Display *dpy; Display *dpy;
/* We have to initialize this *opaque* variable because gcc tries to /* We have to initialize this *opaque* variable because gcc tries to
* be too smart for its own good and warns that the variable may be * be too smart for its own good and warns that the variable may be
@ -1560,6 +1658,7 @@ try_create_glx_pixmap (CoglContext *context,
renderer = context->display->renderer; renderer = context->display->renderer;
xlib_renderer = renderer->winsys; xlib_renderer = renderer->winsys;
glx_renderer = renderer->winsys;
dpy = xlib_renderer->xdpy; dpy = xlib_renderer->xdpy;
if (!get_fbconfig_for_depth (context, if (!get_fbconfig_for_depth (context,
@ -1606,10 +1705,11 @@ try_create_glx_pixmap (CoglContext *context,
_cogl_xlib_renderer_trap_errors (renderer, &trap_state); _cogl_xlib_renderer_trap_errors (renderer, &trap_state);
glx_tex_pixmap->glx_pixmap = glXCreatePixmap (dpy, glx_tex_pixmap->glx_pixmap =
fb_config, glx_renderer->glXCreatePixmap (dpy,
tex_pixmap->pixmap, fb_config,
attribs); tex_pixmap->pixmap,
attribs);
glx_tex_pixmap->has_mipmap_space = mipmap; glx_tex_pixmap->has_mipmap_space = mipmap;
XSync (dpy, False); XSync (dpy, False);
@ -1618,7 +1718,7 @@ try_create_glx_pixmap (CoglContext *context,
{ {
COGL_NOTE (TEXTURE_PIXMAP, "Failed to create pixmap for %p", tex_pixmap); COGL_NOTE (TEXTURE_PIXMAP, "Failed to create pixmap for %p", tex_pixmap);
_cogl_xlib_renderer_trap_errors (renderer, &trap_state); _cogl_xlib_renderer_trap_errors (renderer, &trap_state);
glXDestroyPixmap (dpy, glx_tex_pixmap->glx_pixmap); glx_renderer->glXDestroyPixmap (dpy, glx_tex_pixmap->glx_pixmap);
XSync (dpy, False); XSync (dpy, False);
_cogl_xlib_renderer_untrap_errors (renderer, &trap_state); _cogl_xlib_renderer_untrap_errors (renderer, &trap_state);
@ -1702,7 +1802,8 @@ free_glx_pixmap (CoglContext *context,
* http://bugzilla.clutter-project.org/show_bug.cgi?id=2324 * http://bugzilla.clutter-project.org/show_bug.cgi?id=2324
*/ */
_cogl_xlib_renderer_trap_errors (renderer, &trap_state); _cogl_xlib_renderer_trap_errors (renderer, &trap_state);
glXDestroyPixmap (xlib_renderer->xdpy, glx_tex_pixmap->glx_pixmap); glx_renderer->glXDestroyPixmap (xlib_renderer->xdpy,
glx_tex_pixmap->glx_pixmap);
XSync (xlib_renderer->xdpy, False); XSync (xlib_renderer->xdpy, False);
_cogl_xlib_renderer_untrap_errors (renderer, &trap_state); _cogl_xlib_renderer_untrap_errors (renderer, &trap_state);

View File

@ -83,10 +83,10 @@ _cogl_winsys_context_init (CoglContext *context, GError **error)
{ {
context->winsys = &_cogl_winsys_stub_dummy_ptr; context->winsys = &_cogl_winsys_stub_dummy_ptr;
if (!_cogl_gl_check_version (error)) if (!_cogl_context_check_gl_version (context, error))
return FALSE; return FALSE;
_cogl_gl_update_features (context); _cogl_context_update_features (context);
memset (context->winsys_features, 0, sizeof (context->winsys_features)); memset (context->winsys_features, 0, sizeof (context->winsys_features));

View File

@ -513,6 +513,8 @@ get_wgl_extensions_string (HDC dc)
const char * (APIENTRY *pf_wglGetExtensionsStringARB) (HDC); const char * (APIENTRY *pf_wglGetExtensionsStringARB) (HDC);
const char * (APIENTRY *pf_wglGetExtensionsStringEXT) (void); const char * (APIENTRY *pf_wglGetExtensionsStringEXT) (void);
_COGL_GET_CONTEXT (ctx, NULL);
/* According to the docs for these two extensions, you are supposed /* According to the docs for these two extensions, you are supposed
to use wglGetProcAddress to detect their availability so to use wglGetProcAddress to detect their availability so
presumably it will return NULL if they are not available */ presumably it will return NULL if they are not available */
@ -550,7 +552,7 @@ update_winsys_features (CoglContext *context)
g_return_if_fail (wgl_display->wgl_context); g_return_if_fail (wgl_display->wgl_context);
_cogl_gl_update_features (context); _cogl_context_update_features (context);
memset (context->winsys_features, 0, sizeof (context->winsys_features)); memset (context->winsys_features, 0, sizeof (context->winsys_features));
@ -567,7 +569,8 @@ update_winsys_features (CoglContext *context)
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 (_cogl_context_get_winsys (context), if (_cogl_feature_check (_cogl_context_get_winsys (context),
"WGL", winsys_feature_data + i, 0, 0, 0, "WGL", winsys_feature_data + i, 0, 0,
COGL_DRIVER_GL,
wgl_extensions, wgl_extensions,
wgl_renderer)) wgl_renderer))
{ {

View File

@ -356,9 +356,16 @@ dnl ============================================================
dnl ======================================================== dnl ========================================================
dnl Drivers first... dnl Drivers first...
dnl ======================================================== dnl ========================================================
DRIVER_COUNT=0
EGL_CHECKED=no EGL_CHECKED=no
dnl This gets set to yes if Cogl directly links to the GL library API
dnl so it doesn't need to be dlopened. This currently happens on OSX
dnl and WGL where it's not clear if window system API can be separated
dnl from the GL API.
GL_LIBRARY_DIRECTLY_LINKED=no
enabled_drivers=""
AC_ARG_ENABLE( AC_ARG_ENABLE(
[gles1], [gles1],
[AC_HELP_STRING([--enable-gles1=@<:@no/yes@:>@], [Enable support for OpenGL-ES 1.1 @<:@default=no@:>@])], [AC_HELP_STRING([--enable-gles1=@<:@no/yes@:>@], [Enable support for OpenGL-ES 1.1 @<:@default=no@:>@])],
@ -370,9 +377,7 @@ AS_IF([test "x$enable_gles1" = "xyes"],
AS_IF([test "x$platform_win32" = "xyes"], AS_IF([test "x$platform_win32" = "xyes"],
[AC_MSG_ERROR([GLES 1 not available for win32])]) [AC_MSG_ERROR([GLES 1 not available for win32])])
DRIVER_COUNT=$((DRIVER_COUNT + 1)) enabled_drivers="$enabled_drivers gles1"
COGL_DRIVER=gles
glesversion=1.1
cogl_gl_headers="GLES/gl.h GLES/glext.h" cogl_gl_headers="GLES/gl.h GLES/glext.h"
@ -381,7 +386,8 @@ AS_IF([test "x$enable_gles1" = "xyes"],
COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_GLES1" COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_GLES1"
PKG_CHECK_EXISTS([glesv1_cm], PKG_CHECK_EXISTS([glesv1_cm],
[COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES glesv1_cm" [COGL_PKG_REQUIRES_GL="$COGL_PKG_REQUIRES_GL glesv1_cm"
COGL_GLES1_LIBNAME="GLESv1_CM"
NEED_EGL=yes NEED_EGL=yes
], ],
[ [
@ -424,10 +430,10 @@ AS_IF([test "x$enable_gles1" = "xyes"],
# bundles the GLES and EGL API together and -lGLESv1_CM # bundles the GLES and EGL API together and -lGLESv1_CM
# would be used for a standalone GLES API. # would be used for a standalone GLES API.
AC_CHECK_LIB(GLES_CM, [eglInitialize], AC_CHECK_LIB(GLES_CM, [eglInitialize],
[COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -lGLES_CM"], [COGL_GLES1_LIBNAME="GLES_CM"],
[ [
AC_CHECK_LIB(GLESv1_CM, [glFlush], AC_CHECK_LIB(GLESv1_CM, [glFlush],
[COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -lGLESv1_CM" [COGL_GLES1_LIBNAME="GLESv1_CM"
NEED_SEPARATE_EGL=yes NEED_SEPARATE_EGL=yes
], ],
[AC_MSG_ERROR([Unable to locate required GLES 1.x Common Profile library])]) [AC_MSG_ERROR([Unable to locate required GLES 1.x Common Profile library])])
@ -448,9 +454,7 @@ AS_IF([test "x$enable_gles2" = "xyes"],
AS_IF([test "x$platform_win32" = "xyes"], AS_IF([test "x$platform_win32" = "xyes"],
[AC_MSG_ERROR([GLES 2 not available for win32])]) [AC_MSG_ERROR([GLES 2 not available for win32])])
DRIVER_COUNT=$((DRIVER_COUNT + 1)) enabled_drivers="$enabled_drivers gles2"
COGL_DRIVER=gles
glesversion=2.0
cogl_gl_headers="GLES2/gl2.h GLES2/gl2ext.h" cogl_gl_headers="GLES2/gl2.h GLES2/gl2ext.h"
AC_DEFINE([HAVE_COGL_GLES2], 1, [Have GLES 2.0 for rendering]) AC_DEFINE([HAVE_COGL_GLES2], 1, [Have GLES 2.0 for rendering])
@ -458,7 +462,9 @@ AS_IF([test "x$enable_gles2" = "xyes"],
COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_GLES2" COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_GLES2"
PKG_CHECK_EXISTS([glesv2], PKG_CHECK_EXISTS([glesv2],
[COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES glesv2"], [COGL_PKG_REQUIRES_GL="$COGL_PKG_REQUIRES_GL glesv2"
COGL_GLES2_LIBNAME="GLESv2"
],
[ [
# We have to check the two headers independently as GLES2/gl2ext.h # We have to check the two headers independently as GLES2/gl2ext.h
# needs to include GLES2/gl2.h to have the GL types defined (eg. # needs to include GLES2/gl2.h to have the GL types defined (eg.
@ -471,7 +477,7 @@ AS_IF([test "x$enable_gles2" = "xyes"],
[AC_MSG_ERROR([Unable to locate GLES2/gl2ext.h])], [AC_MSG_ERROR([Unable to locate GLES2/gl2ext.h])],
[#include <GLES2/gl2.h>]) [#include <GLES2/gl2.h>])
COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -lGLESv2" COGL_GLES2_LIBNAME="GLESv2"
]) ])
NEED_EGL=yes NEED_EGL=yes
@ -481,12 +487,11 @@ AC_ARG_ENABLE(
[gl], [gl],
[AC_HELP_STRING([--enable-gl=@<:@no/yes@:>@], [Enable support for OpenGL @<:@default=yes@:>@])], [AC_HELP_STRING([--enable-gl=@<:@no/yes@:>@], [Enable support for OpenGL @<:@default=yes@:>@])],
[], [],
[AS_IF([test $DRIVER_COUNT -gt 0], [enable_gl=no], [enable_gl=yes])] [enable_gl=yes]
) )
AS_IF([test "x$enable_gl" = "xyes"], AS_IF([test "x$enable_gl" = "xyes"],
[ [
DRIVER_COUNT=$((DRIVER_COUNT + 1)) enabled_drivers="$enabled_drivers gl"
COGL_DRIVER=gl
PKG_CHECK_EXISTS([x11], [ALLOW_GLX=yes]) PKG_CHECK_EXISTS([x11], [ALLOW_GLX=yes])
@ -496,6 +501,10 @@ AS_IF([test "x$enable_gl" = "xyes"],
[ [
cogl_gl_headers="OpenGL/gl.h" cogl_gl_headers="OpenGL/gl.h"
COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -framework OpenGL" COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -framework OpenGL"
dnl The GL API is being directly linked in so there is
dnl no need to dlopen it separately
GL_LIBRARY_DIRECTLY_LINKED=yes
COGL_GL_LIBNAME=""
], ],
[test "x$platform_win32" = "xyes"], [test "x$platform_win32" = "xyes"],
@ -503,15 +512,22 @@ AS_IF([test "x$enable_gl" = "xyes"],
COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -lopengl32 -lgdi32 -lwinmm" COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -lopengl32 -lgdi32 -lwinmm"
COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -D_WIN32_WINNT=0x0500" COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -D_WIN32_WINNT=0x0500"
ALLOW_WGL=yes ALLOW_WGL=yes
dnl The GL API is being directly linked in so there is
dnl no need to dlopen it separately
GL_LIBRARY_DIRECTLY_LINKED=yes
COGL_GL_LIBNAME=""
], ],
[ [
PKG_CHECK_EXISTS([gl], PKG_CHECK_EXISTS([gl],
[COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES gl"], dnl We don't want to use COGL_PKG_REQUIRES here because we don't want to
dnl directly link against libGL
[COGL_PKG_REQUIRES_GL="$COGL_PKG_REQUIRES_GL gl"],
[AC_CHECK_LIB(GL, [glGetString], [AC_CHECK_LIB(GL, [glGetString],
[COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -lGL"], ,
[AC_MSG_ERROR([Unable to locate required GL library])]) [AC_MSG_ERROR([Unable to locate required GL library])])
]) ])
COGL_GL_LIBNAME="GL"
]) ])
AC_DEFINE([HAVE_COGL_GL], [1], [Have GL for rendering]) AC_DEFINE([HAVE_COGL_GL], [1], [Have GL for rendering])
@ -520,13 +536,18 @@ AS_IF([test "x$enable_gl" = "xyes"],
COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS CLUTTER_COGL_HAS_GL" COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS CLUTTER_COGL_HAS_GL"
]) ])
AS_IF([test $DRIVER_COUNT -gt 1], AM_CONDITIONAL([COGL_DRIVER_GL_SUPPORTED], [test "x$enable_gl" = "xyes"])
[AC_MSG_ERROR(['The --enable-gl{es1,es2} options are currently mutually exclusive'])]) AM_CONDITIONAL([COGL_DRIVER_GLES_SUPPORTED],
[test "x$enable_gles1" = "xyes" || test "x$enable_gles2" = "xyes"])
AC_SUBST([COGL_DRIVER]) AC_SUBST([COGL_GL_LIBNAME])
AC_SUBST([COGL_GLES1_LIBNAME])
AC_SUBST([COGL_GLES2_LIBNAME])
AM_CONDITIONAL([COGL_DRIVER_GL], [test "x$COGL_DRIVER" = "xgl"]) if test "x$GL_LIBRARY_DIRECTLY_LINKED" = "xyes"; then
AM_CONDITIONAL([COGL_DRIVER_GLES], [test "x$COGL_DRIVER" = "xgles"]) AC_DEFINE([HAVE_DIRECTLY_LINKED_GL_LIBRARY], [1],
[Defined if the GL library shouldn't be dlopened])
fi
dnl ======================================================== dnl ========================================================
dnl Check window system integration libraries... dnl Check window system integration libraries...
@ -541,7 +562,7 @@ AC_ARG_ENABLE(
AS_IF([test "x$enable_glx" = "xyes"], AS_IF([test "x$enable_glx" = "xyes"],
[ [
AS_IF([test "x$ALLOW_GLX" != "xyes"], AS_IF([test "x$ALLOW_GLX" != "xyes"],
[AC_MSG_ERROR([GLX not supported with $COGL_DRIVER driver])]) [AC_MSG_ERROR([GLX not supported with this configuration])])
NEED_XLIB=yes NEED_XLIB=yes
SUPPORT_GLX=yes SUPPORT_GLX=yes
@ -568,7 +589,7 @@ AC_ARG_ENABLE(
AS_IF([test "x$enable_wgl" = "xyes"], AS_IF([test "x$enable_wgl" = "xyes"],
[ [
AS_IF([test "x$ALLOW_WGL" != "xyes"], AS_IF([test "x$ALLOW_WGL" != "xyes"],
[AC_MSG_ERROR([WGL not supported with $COGL_DRIVER driver])]) [AC_MSG_ERROR([WGL not supported with this configuration])])
SUPPORT_WGL=yes SUPPORT_WGL=yes
GL_WINSYS_APIS="$GL_WINSYS_APIS wgl" GL_WINSYS_APIS="$GL_WINSYS_APIS wgl"
@ -691,7 +712,7 @@ AC_ARG_ENABLE(
[xlib-egl-platform], [xlib-egl-platform],
[AC_HELP_STRING([--enable-xlib-egl-platform=@<:@no/yes@:>@], [Enable support for the Xlib egl platform @<:@default=auto@:>@])], [AC_HELP_STRING([--enable-xlib-egl-platform=@<:@no/yes@:>@], [Enable support for the Xlib egl platform @<:@default=auto@:>@])],
[], [],
AS_IF([test "x$COGL_DRIVER" = "xgles" && test $EGL_PLATFORM_COUNT -eq 0], AS_IF([test "x$enable_gles1" = "xyes" -o "x$enable_gles2" = "xyes" && test $EGL_PLATFORM_COUNT -eq 0],
[enable_xlib_egl_platform=yes], [enable_xlib_egl_platform=no]) [enable_xlib_egl_platform=yes], [enable_xlib_egl_platform=no])
) )
AS_IF([test "x$enable_xlib_egl_platform" = "xyes"], AS_IF([test "x$enable_xlib_egl_platform" = "xyes"],
@ -823,7 +844,22 @@ AS_IF([test "x$have_glib" = "xno"], AC_MSG_ERROR([glib-2.0 is required]))
COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES glib-2.0" COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES glib-2.0"
AC_SUBST(COGL_PKG_REQUIRES) AC_SUBST(COGL_PKG_REQUIRES)
PKG_CHECK_MODULES(COGL_DEP, [$COGL_PKG_REQUIRES]) PKG_CHECK_MODULES(COGL_DEP, [$COGL_PKG_REQUIRES])
if test -n "$COGL_PKG_REQUIRES_GL"; then
PKG_CHECK_MODULES(COGL_DEP_GL, [$COGL_PKG_REQUIRES_GL])
dnl Strip out the GL libraries from the GL pkg-config files so we can
dnl dynamically load them instead
gl_libs=""
for x in $COGL_DEP_GL_LIBS; do
AS_CASE([$x],
[-lGL], [],
[-lGLESv2], [],
[-lGLESv1_CM], [],
[*], [gl_libs="$gl_libs $x"])
done
COGL_DEP_CFLAGS="$COGL_DEP_CFLAGS $COGL_DEP_CFLAGS_GL"
COGL_DEP_LIBS="$COGL_DEP_LIBS $gl_libs"
fi
dnl ================================================================ dnl ================================================================
dnl Misc program dependencies. dnl Misc program dependencies.
@ -920,7 +956,7 @@ echo " Prefix: ${prefix}"
echo "" echo ""
# Features # Features
echo " • Features:" echo " • Features:"
echo " Driver: ${COGL_DRIVER} ${glesversion}" echo " Drivers: ${enabled_drivers}"
echo " GL Window System APIs:${GL_WINSYS_APIS}" echo " GL Window System APIs:${GL_WINSYS_APIS}"
if test "x$SUPPORT_EGL" = "xyes"; then if test "x$SUPPORT_EGL" = "xyes"; then
echo " EGL Platforms:${EGL_PLATFORMS}" echo " EGL Platforms:${EGL_PLATFORMS}"