material: Adds backend abstraction for fragment processing

As part of an effort to improve the architecture of CoglMaterial
internally this overhauls how we flush layer state to OpenGL by adding a
formal backend abstraction for fragment processing and further
formalizing the CoglTextureUnit abstraction.

There are three backends: "glsl", "arbfp" and "fixed". The fixed backend
uses the OpenGL fixed function APIs to setup the fragment processing,
the arbfp backend uses code generation to handle fragment processing
using an ARBfp program, and the GLSL backend is currently only there as
a formality to handle user programs associated with a material. (i.e.
the glsl backend doesn't yet support code generation)

The GLSL backend has highest precedence, then arbfp and finally the
fixed. If a backend can't support some particular CoglMaterial feature
then it will fallback to the next backend.

This adds three new COGL_DEBUG options:
* "disable-texturing" as expected should disable all texturing
* "disable-arbfp" always make the arbfp backend fallback
* "disable-glsl" always make the glsl backend fallback
* "show-source" show code generated by the arbfp/glsl backends
This commit is contained in:
Robert Bragg 2010-04-26 10:01:43 +01:00
parent 8ebf76a9a9
commit acc44161c1
20 changed files with 2445 additions and 1076 deletions

View File

@ -58,8 +58,6 @@
#define glDeleteBuffers ctx->drv.pf_glDeleteBuffers
#define glMapBuffer ctx->drv.pf_glMapBuffer
#define glUnmapBuffer ctx->drv.pf_glUnmapBuffer
#define glActiveTexture ctx->drv.pf_glActiveTexture
#define glClientActiveTexture ctx->drv.pf_glClientActiveTexture
#ifndef GL_ARRAY_BUFFER
#define GL_ARRAY_BUFFER GL_ARRAY_BUFFER_ARB
#endif

View File

@ -70,6 +70,7 @@ cogl_create_context (void)
_context->enable_flags = 0;
_context->color_alpha = 0;
_context->fog_enabled = FALSE;
_context->enable_backface_culling = FALSE;
_context->flushed_front_winding = COGL_FRONT_WINDING_COUNTER_CLOCKWISE;
@ -81,10 +82,20 @@ cogl_create_context (void)
cogl_matrix_scale (&_context->y_flip_matrix, 1, -1, 1);
_context->flushed_matrix_mode = COGL_MATRIX_MODELVIEW;
_context->texture_units = NULL;
_context->texture_units =
g_array_new (FALSE, FALSE, sizeof (CoglTextureUnit));
/* See cogl-material.c for more details about why we leave texture unit 1
* active by default... */
_context->active_texture_unit = 1;
GE (glActiveTexture (GL_TEXTURE1));
_context->simple_material = cogl_material_new ();
_context->source_material = NULL;
_context->arbfp_source_buffer = g_string_new ("");
_context->legacy_state_set = 0;
_context->default_gl_texture_2d_tex = COGL_INVALID_HANDLE;
_context->default_gl_texture_rect_tex = COGL_INVALID_HANDLE;
@ -93,15 +104,25 @@ cogl_create_context (void)
_context->logged_vertices = g_array_new (FALSE, FALSE, sizeof (GLfloat));
_context->current_material = NULL;
_context->current_material_flags = 0;
memset (&_context->current_material_flush_options,
0, sizeof (CoglMaterialFlushOptions));
_context->current_layers = g_array_new (FALSE, FALSE,
sizeof (CoglLayerInfo));
_context->current_material_flags = COGL_MATERIAL_FLAGS_INIT;
_context->current_material_fallback_layers = 0;
_context->current_material_disable_layers = 0;
_context->current_material_layer0_override = 0;
_context->current_material_skip_gl_color = FALSE;
_cogl_bitmask_init (&_context->texcoord_arrays_enabled);
_cogl_bitmask_init (&_context->temp_bitmask);
_cogl_bitmask_init (&_context->texcoord_arrays_to_disable);
_context->max_texture_units = -1;
_context->max_texture_image_units = -1;
_context->max_activateable_texture_units = -1;
_context->current_program = COGL_INVALID_HANDLE;
_context->current_use_program_type = COGL_MATERIAL_PROGRAM_TYPE_FIXED;
_context->current_gl_program = 0;
_context->framebuffer_stack = _cogl_create_framebuffer_stack ();
window_buffer = _cogl_onscreen_new ();
@ -162,8 +183,6 @@ cogl_create_context (void)
_context->current_pbo = NULL;
_context->max_texture_units = -1;
return TRUE;
}
@ -194,9 +213,6 @@ _cogl_destroy_context (void)
if (_context->logged_vertices)
g_array_free (_context->logged_vertices, TRUE);
if (_context->current_layers)
g_array_free (_context->current_layers, TRUE);
if (_context->quad_indices_byte)
cogl_handle_unref (_context->quad_indices_byte);
if (_context->quad_indices_short)

View File

@ -53,6 +53,7 @@ typedef struct
/* Enable cache */
unsigned long enable_flags;
guint8 color_alpha;
gboolean fog_enabled;
gboolean enable_backface_culling;
CoglFrontWinding flushed_front_winding;
@ -65,11 +66,16 @@ typedef struct
/* Client-side matrix stack or NULL if none */
CoglMatrixMode flushed_matrix_mode;
GList *texture_units;
GArray *texture_units;
int active_texture_unit;
/* Materials */
CoglHandle simple_material;
CoglHandle source_material;
GString *arbfp_source_buffer;
int legacy_state_set;
/* Textures */
CoglHandle default_gl_texture_2d_tex;
@ -86,8 +92,10 @@ typedef struct
/* Some simple caching, to minimize state changes... */
CoglHandle current_material;
unsigned long current_material_flags;
CoglMaterialFlushOptions current_material_flush_options;
GArray *current_layers;
gboolean current_material_fallback_layers;
gboolean current_material_disable_layers;
GLuint current_material_layer0_override;
gboolean current_material_skip_gl_color;
/* Bitmask of texture coordinates arrays that are enabled */
CoglBitmask texcoord_arrays_enabled;
/* These are temporary bitmasks that are used when disabling
@ -129,9 +137,15 @@ typedef struct
chances of getting the same colour during an animation */
guint8 journal_rectangles_color;
/* Cached value for GL_MAX_TEXTURE_UNITS to avoid calling
/* Cached values for GL_MAX_TEXTURE_[IMAGE_]UNITS to avoid calling
glGetInteger too often */
GLint max_texture_units;
GLint max_texture_image_units;
GLint max_activateable_texture_units;
CoglHandle current_program;
CoglMaterialProgramType current_use_program_type;
GLuint current_gl_program;
CoglContextDriver drv;
} CoglContext;

View File

@ -50,6 +50,7 @@ static const GDebugKey cogl_log_debug_keys[] = {
{ "draw", COGL_DEBUG_DRAW },
{ "opengl", COGL_DEBUG_OPENGL },
{ "pango", COGL_DEBUG_PANGO },
{ "show-source", COGL_DEBUG_SHOW_SOURCE}
};
static const int n_cogl_log_debug_keys =
G_N_ELEMENTS (cogl_log_debug_keys);
@ -61,7 +62,10 @@ static const GDebugKey cogl_behavioural_debug_keys[] = {
{ "disable-software-transform", COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM },
{ "force-scanline-paths", COGL_DEBUG_FORCE_SCANLINE_PATHS },
{ "dump-atlas-image", COGL_DEBUG_DUMP_ATLAS_IMAGE },
{ "disable-atlas", COGL_DEBUG_DISABLE_ATLAS }
{ "disable-atlas", COGL_DEBUG_DISABLE_ATLAS },
{ "disable-texturing", COGL_DEBUG_DISABLE_TEXTURING},
{ "disable-arbfp", COGL_DEBUG_DISABLE_ARBFP},
{ "disable-glsl", COGL_DEBUG_DISABLE_GLSL}
};
static const int n_cogl_behavioural_debug_keys =
G_N_ELEMENTS (cogl_behavioural_debug_keys);
@ -115,6 +119,10 @@ _cogl_parse_debug_string (const char *value,
OPT ("force-scanline-paths:", "use a scanline based path rasterizer");
OPT ("dump-atlas-image:", "dump atlas changes to an image file");
OPT ("disable-atlas:", "disable texture atlasing");
OPT ("disable-texturing:", "disable texturing primitives");
OPT ("disable-arbfp:", "disable use of ARBfp");
OPT ("disable-glsl:", "disable use of GLSL");
OPT ("show-source:", "show generated ARBfp/GLSL");
OPT ("opengl:", "traces some select OpenGL calls");
g_printerr ("\n%28s\n", "Special debug values:");
OPT ("all:", "Enables all non-behavioural debug options");

View File

@ -46,7 +46,11 @@ typedef enum {
COGL_DEBUG_ATLAS = 1 << 15,
COGL_DEBUG_DUMP_ATLAS_IMAGE = 1 << 16,
COGL_DEBUG_DISABLE_ATLAS = 1 << 17,
COGL_DEBUG_OPENGL = 1 << 18
COGL_DEBUG_OPENGL = 1 << 18,
COGL_DEBUG_DISABLE_TEXTURING = 1 << 19,
COGL_DEBUG_DISABLE_ARBFP = 1 << 20,
COGL_DEBUG_DISABLE_GLSL = 1 << 21,
COGL_DEBUG_SHOW_SOURCE = 1 << 22
} CoglDebugFlags;
#ifdef COGL_ENABLE_DEBUG

View File

@ -115,21 +115,6 @@ _cogl_enable (unsigned long flags);
unsigned long
_cogl_get_enable (void);
typedef struct _CoglTextureUnit
{
int index;
CoglMatrixStack *matrix_stack;
} CoglTextureUnit;
CoglTextureUnit *
_cogl_get_texture_unit (int index_);
void
_cogl_destroy_texture_units (void);
unsigned int
_cogl_get_max_texture_image_units (void);
void
_cogl_flush_face_winding (void);

View File

@ -792,7 +792,16 @@ _cogl_journal_log_quad (const float *position,
disable_layers = (1 << n_layers) - 1;
disable_layers = ~disable_layers;
entry->material = _cogl_material_journal_ref (material);
if (G_UNLIKELY (ctx->legacy_state_set))
{
material = cogl_material_copy (material);
_cogl_material_apply_legacy_state (material);
entry->material = _cogl_material_journal_ref (material);
cogl_handle_unref (material);
}
else
entry->material = _cogl_material_journal_ref (material);
entry->n_layers = n_layers;
entry->flush_options.flags =
COGL_MATERIAL_FLUSH_FALLBACK_MASK |

View File

@ -29,6 +29,7 @@
#include "cogl-material.h"
#include "cogl-matrix.h"
#include "cogl-matrix-stack.h"
#include "cogl-handle.h"
#include <glib.h>
@ -36,6 +37,92 @@
typedef struct _CoglMaterial CoglMaterial;
typedef struct _CoglMaterialLayer CoglMaterialLayer;
/*
* cogl-material.c owns the GPU's texture unit state so we have some
* private structures for describing the current state of a texture
* unit that we track in a per context array (ctx->texture_units) that
* grows according to the largest texture unit used so far...
*
* Roughly speaking the members in this structure are of two kinds:
* either they are a low level reflection of the state we send to
* OpenGL or they are for high level meta data assoicated with the
* texture unit when flushing CoglMaterialLayers that is typically
* used to optimize subsequent re-flushing of the same layer.
*
* The low level members are at the top, and the high level members
* start with the .layer member.
*/
typedef struct _CoglTextureUnit
{
/* The base 0 texture unit index which can be used with
* glActiveTexture () */
int index;
/* Whether or not the corresponding gl_target has been glEnabled */
gboolean enabled;
/* The GL target currently glEnabled or 0 if .enabled == FALSE */
GLenum enabled_gl_target;
/* The raw GL texture object name for which we called glBindTexture when
* we flushed the last layer. (NB: The CoglTexture associated
* with a layer may represent more than one GL texture) */
GLuint gl_texture;
/* A matrix stack giving us the means to associate a texture
* transform matrix with the texture unit. */
CoglMatrixStack *matrix_stack;
/*
* Higher level layer state associated with the unit...
*/
/* The CoglMaterialLayer whos state was flushed to update this
* texture unit last.
*
* This will be set to NULL if the layer is modified or freed which
* means when we come to flush a layer; if this pointer is still
* valid and == to the layer being flushed we don't need to update
* any texture unit state. */
CoglMaterialLayer *layer;
/* To help minimize the state changes required we track the
* difference flags associated with the layer whos state was last
* flushed to update this texture unit.
*
* Note: we track this explicitly because .layer may get invalidated
* if that layer is modified or deleted. Even if the layer is
* invalidated though these flags can be used to optimize the state
* flush of the next layer
*/
unsigned long layer_differences;
/* The options that may have affected how the layer state updated
* this texture unit. */
gboolean fallback;
gboolean layer0_overridden;
/* When flushing a layers state, fallback options may mean that a
* different CoglTexture is used than layer->texture.
*
* Once a layers state has been flushed we have to keep track of
* changes to that layer so if we are asked to re-flush the same
* layer later we will know what work is required. This also means
* we need to keep track of changes to the CoglTexture of that layer
* so we need to explicitly keep a reference to the final texture
* chosen.
*/
CoglHandle texture;
} CoglTextureUnit;
CoglTextureUnit *
_cogl_get_texture_unit (int index_);
void
_cogl_destroy_texture_units (void);
typedef enum _CoglMaterialEqualFlags
{
/* Return FALSE if any component of either material isn't set to its
@ -46,35 +133,41 @@ typedef enum _CoglMaterialEqualFlags
} CoglMaterialEqualFlags;
/* XXX: I don't think gtk-doc supports having private enums so these aren't
* bundled in with CoglMaterialLayerFlags */
typedef enum _CoglMaterialLayerPrivFlags
typedef enum _CoglMaterialLayerDifferenceFlags
{
/* Ref: CoglMaterialLayerFlags
COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX = 1L<<0
*/
COGL_MATERIAL_LAYER_FLAG_DIRTY = 1L<<1,
COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE = 1L<<2
} CoglMaterialLayerPrivFlags;
COGL_MATERIAL_LAYER_DIFFERENCE_TEXTURE = 1L<<0,
COGL_MATERIAL_LAYER_DIFFERENCE_COMBINE = 1L<<1,
COGL_MATERIAL_LAYER_DIFFERENCE_COMBINE_CONSTANT = 1L<<2,
COGL_MATERIAL_LAYER_DIFFERENCE_USER_MATRIX = 1L<<3,
COGL_MATERIAL_LAYER_DIFFERENCE_FILTERS = 1L<<4
} CoglMaterialLayerDifferenceFlags;
/* For tracking the state of a layer that's been flushed to OpenGL */
typedef struct _CoglLayerInfo
typedef enum _CoglMaterialLayerChangeFlags
{
CoglHandle handle;
unsigned long flags;
GLenum gl_target;
GLuint gl_texture;
gboolean fallback;
gboolean disabled;
gboolean layer0_overridden;
} CoglLayerInfo;
COGL_MATERIAL_LAYER_CHANGE_TEXTURE = 1L<<0,
COGL_MATERIAL_LAYER_CHANGE_COMBINE = 1L<<1,
COGL_MATERIAL_LAYER_CHANGE_COMBINE_CONSTANT = 1L<<2,
COGL_MATERIAL_LAYER_CHANGE_USER_MATRIX = 1L<<3,
COGL_MATERIAL_LAYER_CHANGE_FILTERS = 1L<<4,
COGL_MATERIAL_LAYER_CHANGE_TEXTURE_INTERN = 1L<<5,
COGL_MATERIAL_LAYER_CHANGE_UNIT = 1L<<6
} CoglMaterialLayerChangeFlags;
struct _CoglMaterialLayer
{
CoglHandleObject _parent;
/* Parent material */
CoglMaterial *material;
unsigned int index; /*!< lowest index is blended first then others on
top */
unsigned long flags;
int unit_index;
unsigned long differences;
CoglHandle texture; /*!< The texture for this layer, or
COGL_INVALID_HANDLE for an empty layer */
@ -100,33 +193,48 @@ struct _CoglMaterialLayer
/* TODO: Support purely GLSL based material layers */
CoglMatrix matrix;
/* Different material backends (GLSL/ARBfp/Fixed Function) may
* want to associate private data with a layer... */
void *backend_priv;
};
typedef enum _CoglMaterialFlags
{
COGL_MATERIAL_FLAG_SHOWN_SAMPLER_WARNING = 1L<<0,
COGL_MATERIAL_FLAG_DEFAULT_COLOR = 1L<<1,
COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL = 1L<<2,
COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC = 1L<<3,
COGL_MATERIAL_FLAG_ENABLE_BLEND = 1L<<4,
COGL_MATERIAL_FLAG_DEFAULT_BLEND = 1L<<5
COGL_MATERIAL_FLAG_DEFAULT_BLEND = 1L<<5,
COGL_MATERIAL_FLAG_DEFAULT_USER_SHADER = 1L<<6,
COGL_MATERIAL_FLAG_DEFAULT_LAYERS = 1L<<7
} CoglMaterialFlags;
/* ARBfp1.0 program (Fog + ARB_texture_env_combine) */
typedef struct _CoglMaterialProgram
{
GString *source;
GLuint gl_program;
/* This defines the initialization state for
* ctx->current_material_flags which should result in the first
* material flush explicitly initializing everything
*/
#define COGL_MATERIAL_FLAGS_INIT \
COGL_MATERIAL_FLAG_DEFAULT_USER_SHADER
gboolean *sampled;
} CoglMaterialProgram;
typedef enum _CoglMaterialChangeFlag
{
COGL_MATERIAL_CHANGE_COLOR = 1L<<1,
COGL_MATERIAL_CHANGE_GL_MATERIAL = 1L<<2,
COGL_MATERIAL_CHANGE_ALPHA_FUNC = 1L<<3,
COGL_MATERIAL_CHANGE_ENABLE_BLEND = 1L<<4,
COGL_MATERIAL_CHANGE_BLEND = 1L<<5,
COGL_MATERIAL_CHANGE_USER_SHADER = 1L<<6,
COGL_MATERIAL_CHANGE_LAYERS = 1L<<7
} CoglMaterialChangeFlag;
struct _CoglMaterial
{
CoglHandleObject _parent;
unsigned long journal_ref_count;
int backend;
unsigned long flags;
/* If no lighting is enabled; this is the basic material color */
@ -154,12 +262,39 @@ struct _CoglMaterial
GLint blend_src_factor_rgb;
GLint blend_dst_factor_rgb;
CoglMaterialProgram program;
CoglHandle user_program;
GList *layers;
unsigned int n_layers;
void *backend_priv;
};
typedef struct _CoglMaterialBackend
{
int (*get_max_texture_units) (void);
gboolean (*start) (CoglMaterial *material);
gboolean (*add_layer) (CoglMaterialLayer *layer);
gboolean (*passthrough) (CoglMaterial *material);
gboolean (*end) (CoglMaterial *material);
void (*material_change_notify) (CoglMaterial *material,
unsigned long changes,
GLubyte *new_color);
void (*layer_change_notify) (CoglMaterialLayer *layer,
unsigned long changes);
void (*free_priv) (CoglMaterial *material);
} CoglMaterialBackend;
typedef enum
{
COGL_MATERIAL_PROGRAM_TYPE_GLSL = 1,
COGL_MATERIAL_PROGRAM_TYPE_ARBFP,
COGL_MATERIAL_PROGRAM_TYPE_FIXED
} CoglMaterialProgramType;
/*
* SECTION:cogl-material-internals
* @short_description: Functions for creating custom primitives that make use
@ -197,29 +332,8 @@ _cogl_material_init_default_material (void);
unsigned long
_cogl_material_get_cogl_enable_flags (CoglHandle handle);
/*
* CoglMaterialLayerFlags:
* @COGL_MATERIAL_LAYER_FLAG_USER_MATRIX: Means the user has supplied a
* custom texture matrix.
*/
typedef enum _CoglMaterialLayerFlags
{
COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX = 1L<<0
} CoglMaterialLayerFlags;
/* XXX: NB: if you add flags here you will need to update
* CoglMaterialLayerPrivFlags!!! */
/*
* cogl_material_layer_get_flags:
* @layer_handle: A CoglMaterialLayer layer handle
*
* This lets you get a number of flag attributes about the layer. Normally
* you shouldn't need to use this function directly since Cogl will do this
* internally, but if you are developing custom primitives directly with
* OpenGL you may need this.
*/
unsigned long
_cogl_material_layer_get_flags (CoglHandle layer_handle);
gboolean
_cogl_material_layer_has_user_matrix (CoglHandle layer_handle);
/*
* Ensures the mipmaps are available for the texture in the layer if
@ -322,5 +436,15 @@ _cogl_material_set_layer_wrap_mode_r (CoglHandle material,
CoglMaterialWrapMode
_cogl_material_layer_get_wrap_mode_r (CoglHandle layer);
void
_cogl_material_set_user_program (CoglHandle handle,
CoglHandle program);
void
_cogl_material_apply_legacy_state (CoglHandle handle);
void
_cogl_gl_use_program_wrapper (GLuint program);
#endif /* __COGL_MATERIAL_PRIVATE_H */

File diff suppressed because it is too large Load Diff

View File

@ -132,6 +132,7 @@ _cogl_path_stroke_nodes (void)
unsigned long enable_flags = COGL_ENABLE_VERTEX_ARRAY;
CoglPathData *data;
CoglMaterialFlushOptions options;
CoglHandle source;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -151,7 +152,15 @@ _cogl_path_stroke_nodes (void)
/* disable all texture layers */
options.disable_layers = (guint32)~0;
_cogl_material_flush_gl_state (ctx->source_material, &options);
if (G_UNLIKELY (ctx->legacy_state_set))
{
source = cogl_material_copy (ctx->source_material);
_cogl_material_apply_legacy_state (source);
}
else
source = ctx->source_material;
_cogl_material_flush_gl_state (source, &options);
while (path_start < data->path_nodes->len)
{
@ -163,6 +172,9 @@ _cogl_path_stroke_nodes (void)
path_start += node->path_size;
}
if (G_UNLIKELY (source != ctx->source_material))
cogl_handle_unref (source);
}
static void
@ -332,6 +344,8 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path,
unsigned int bounds_w,
unsigned int bounds_h)
{
CoglHandle source;
/* This is our edge list it stores intersections between our
* curve and scanlines, it should probably be implemented with a
* data structure that has smaller overhead for inserting the
@ -359,6 +373,14 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path,
* always be done first when preparing to draw. */
_cogl_framebuffer_flush_state (_cogl_get_framebuffer (), 0);
if (G_UNLIKELY (ctx->legacy_state_set))
{
source = cogl_material_copy (ctx->source_material);
_cogl_material_apply_legacy_state (source);
}
else
source = ctx->source_material;
_cogl_material_flush_gl_state (ctx->source_material, NULL);
_cogl_enable (COGL_ENABLE_VERTEX_ARRAY
@ -502,6 +524,9 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path,
GE (glDrawArrays (GL_TRIANGLES, 0, spans * 2 * 3));
g_free (coords);
}
if (G_UNLIKELY (source != ctx->source_material))
cogl_handle_unref (source);
}
static void

View File

@ -59,8 +59,6 @@
#define glDeleteBuffers ctx->drv.pf_glDeleteBuffers
#define glMapBuffer ctx->drv.pf_glMapBuffer
#define glUnmapBuffer ctx->drv.pf_glUnmapBuffer
#define glActiveTexture ctx->drv.pf_glActiveTexture
#define glClientActiveTexture ctx->drv.pf_glClientActiveTexture
#ifndef GL_PIXEL_UNPACK_BUFFER
#define GL_PIXEL_UNPACK_BUFFER GL_PIXEL_UNPACK_BUFFER_ARB

View File

@ -516,7 +516,6 @@ _cogl_rectangles_with_multitexture_coords (
{
CoglHandle layer = tmp->data;
CoglHandle tex_handle;
unsigned long flags;
if (cogl_material_layer_get_type (layer)
!= COGL_MATERIAL_LAYER_TYPE_TEXTURE)
@ -619,8 +618,7 @@ _cogl_rectangles_with_multitexture_coords (
* waste or if using GL_TEXTURE_RECTANGLE_ARB) then we don't support
* multi texturing since we don't know if the result will end up trying
* to texture from the waste area. */
flags = _cogl_material_layer_get_flags (layer);
if (flags & COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX
if (_cogl_material_layer_has_user_matrix (layer)
&& !_cogl_texture_can_hardware_repeat (tex_handle))
{
static gboolean warning_seen = FALSE;
@ -838,6 +836,7 @@ draw_polygon_sub_texture_cb (CoglHandle tex_handle,
float virtual_origin_y;
float v_to_s_scale_x;
float v_to_s_scale_y;
CoglHandle source;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -888,9 +887,20 @@ draw_polygon_sub_texture_cb (CoglHandle tex_handle,
options.wrap_mode_overrides.values[0].t =
COGL_MATERIAL_WRAP_MODE_OVERRIDE_CLAMP_TO_BORDER;
_cogl_material_flush_gl_state (ctx->source_material, &options);
if (G_UNLIKELY (ctx->legacy_state_set))
{
source = cogl_material_copy (ctx->source_material);
_cogl_material_apply_legacy_state (source);
}
else
source = ctx->source_material;
_cogl_material_flush_gl_state (source, &options);
GE (glDrawArrays (GL_TRIANGLE_FAN, 0, state->n_vertices));
if (G_UNLIKELY (source != ctx->source_material))
cogl_handle_unref (source);
}
/* handles 2d-sliced textures with > 1 slice */
@ -963,6 +973,7 @@ _cogl_multitexture_polygon_single_primitive (const CoglTextureVertex *vertices,
GList *tmp;
GLfloat *v;
CoglMaterialFlushOptions options;
CoglHandle source;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -1028,9 +1039,21 @@ _cogl_multitexture_polygon_single_primitive (const CoglTextureVertex *vertices,
options.flags |= COGL_MATERIAL_FLUSH_WRAP_MODE_OVERRIDES;
options.wrap_mode_overrides = *wrap_mode_overrides;
}
_cogl_material_flush_gl_state (ctx->source_material, &options);
if (G_UNLIKELY (ctx->legacy_state_set))
{
source = cogl_material_copy (ctx->source_material);
_cogl_material_apply_legacy_state (source);
}
else
source = ctx->source_material;
_cogl_material_flush_gl_state (source, &options);
GE (glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices));
if (G_UNLIKELY (source != ctx->source_material))
cogl_handle_unref (source);
}
void

View File

@ -159,7 +159,6 @@
#define glDeleteBuffers ctx->drv.pf_glDeleteBuffers
#define glMapBuffer ctx->drv.pf_glMapBuffer
#define glUnmapBuffer ctx->drv.pf_glUnmapBuffer
#define glActiveTexture ctx->drv.pf_glActiveTexture
#define glClientActiveTexture ctx->drv.pf_glClientActiveTexture
#ifndef GL_ARRAY_BUFFER
#define GL_ARRAY_BUFFER GL_ARRAY_BUFFER_ARB
@ -1509,7 +1508,7 @@ get_gl_type_from_attribute_flags (CoglVertexBufferAttribFlags flags)
}
}
static void
static CoglHandle
enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
{
GList *tmp;
@ -1522,8 +1521,9 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
guint32 fallback_layers = 0;
int i;
CoglMaterialFlushOptions options;
CoglHandle source;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
if (buffer->new_attributes)
cogl_vertex_buffer_submit_real (buffer);
@ -1717,18 +1717,29 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
options.fallback_layers = fallback_layers;
_cogl_material_flush_gl_state (ctx->source_material, &options);
enable_flags |= _cogl_material_get_cogl_enable_flags (ctx->source_material);
if (G_UNLIKELY (ctx->legacy_state_set))
{
source = cogl_material_copy (ctx->source_material);
_cogl_material_apply_legacy_state (source);
}
else
source = ctx->source_material;
_cogl_material_flush_gl_state (source, &options);
enable_flags |= _cogl_material_get_cogl_enable_flags (source);
if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
_cogl_enable (enable_flags);
_cogl_flush_face_winding ();
return source;
}
static void
disable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
disable_state_for_drawing_buffer (CoglVertexBuffer *buffer,
CoglHandle source)
{
GList *tmp;
GLenum gl_type;
@ -1738,6 +1749,9 @@ disable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (G_UNLIKELY (source != ctx->source_material))
cogl_handle_unref (source);
/* Disable all the client state that cogl doesn't currently know
* about:
*/
@ -1798,6 +1812,7 @@ cogl_vertex_buffer_draw (CoglHandle handle,
int count)
{
CoglVertexBuffer *buffer;
CoglHandle source;
if (!cogl_is_vertex_buffer (handle))
return;
@ -1806,11 +1821,11 @@ cogl_vertex_buffer_draw (CoglHandle handle,
buffer = _cogl_vertex_buffer_pointer_from_handle (handle);
enable_state_for_drawing_buffer (buffer);
source = enable_state_for_drawing_buffer (buffer);
GE (glDrawArrays (mode, first, count));
disable_state_for_drawing_buffer (buffer);
disable_state_for_drawing_buffer (buffer, source);
}
static int
@ -1934,6 +1949,7 @@ cogl_vertex_buffer_draw_elements (CoglHandle handle,
(cogl_get_features () & COGL_FEATURE_VBOS) ? FALSE : TRUE;
gsize byte_offset;
CoglVertexBufferIndices *indices = NULL;
CoglHandle source;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -1949,7 +1965,7 @@ cogl_vertex_buffer_draw_elements (CoglHandle handle,
indices = _cogl_vertex_buffer_indices_pointer_from_handle (indices_handle);
enable_state_for_drawing_buffer (buffer);
source = enable_state_for_drawing_buffer (buffer);
byte_offset = indices_offset * get_indices_type_size (indices->type);
if (fallback)
@ -1961,7 +1977,7 @@ cogl_vertex_buffer_draw_elements (CoglHandle handle,
GE (glDrawRangeElements (mode, min_index, max_index,
count, indices->type, (void *)byte_offset));
disable_state_for_drawing_buffer (buffer);
disable_state_for_drawing_buffer (buffer, source);
GE (glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0));
}

View File

@ -493,6 +493,9 @@ cogl_get_features (void)
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_DISABLE_VBOS))
ctx->feature_flags &= ~COGL_FEATURE_VBOS;
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_DISABLE_GLSL))
ctx->feature_flags &= ~COGL_FEATURE_SHADERS_GLSL;
return ctx->feature_flags;
}
@ -515,6 +518,9 @@ _cogl_features_available_private (CoglFeatureFlagsPrivate features)
if (!ctx->features_cached)
_cogl_features_init ();
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_DISABLE_ARBFP))
ctx->feature_flags_private &= ~COGL_FEATURE_PRIVATE_ARB_FP;
return (ctx->feature_flags_private & features) == features;
}
@ -571,6 +577,8 @@ cogl_set_fog (const CoglColor *fog_color,
GLfloat fogColor[4];
GLenum gl_mode = GL_LINEAR;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* The cogl journal doesn't currently track fog state changes */
_cogl_journal_flush ();
@ -606,15 +614,20 @@ cogl_set_fog (const CoglColor *fog_color,
glFogf (GL_FOG_DENSITY, (GLfloat) density);
glFogf (GL_FOG_START, (GLfloat) z_near);
glFogf (GL_FOG_END, (GLfloat) z_far);
ctx->fog_enabled = TRUE;
}
void
cogl_disable_fog (void)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Currently the journal can't track changes to fog state... */
_cogl_journal_flush ();
glDisable (GL_FOG);
ctx->fog_enabled = FALSE;
}
void
@ -876,102 +889,6 @@ cogl_end_gl (void)
ctx->in_begin_gl_block = FALSE;
}
static CoglTextureUnit *
_cogl_texture_unit_new (int index_)
{
CoglTextureUnit *unit = g_new0 (CoglTextureUnit, 1);
unit->matrix_stack = _cogl_matrix_stack_new ();
unit->index = index_;
return unit;
}
static void
_cogl_texture_unit_free (CoglTextureUnit *unit)
{
_cogl_matrix_stack_destroy (unit->matrix_stack);
g_free (unit);
}
CoglTextureUnit *
_cogl_get_texture_unit (int index_)
{
GList *l;
CoglTextureUnit *unit;
_COGL_GET_CONTEXT (ctx, NULL);
for (l = ctx->texture_units; l; l = l->next)
{
unit = l->data;
if (unit->index == index_)
return unit;
/* The units are always sorted, so at this point we know this unit
* doesn't exist */
if (unit->index > index_)
break;
}
/* NB: if we now insert a new layer before l, that will maintain order.
*/
unit = _cogl_texture_unit_new (index_);
/* Note: see comment after for() loop above */
ctx->texture_units =
g_list_insert_before (ctx->texture_units, l, unit);
return unit;
}
void
_cogl_destroy_texture_units (void)
{
GList *l;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
for (l = ctx->texture_units; l; l = l->next)
_cogl_texture_unit_free (l->data);
g_list_free (ctx->texture_units);
}
/*
* This is more complicated than that, another pass needs to be done when
* cogl have a neat way of saying if we are using the fixed function pipeline
* or not (for the GL case):
* MAX_TEXTURE_UNITS: fixed function pipeline, a texture unit has both a
* sampler and a set of texture coordinates
* MAX_TEXTURE_IMAGE_UNITS: number of samplers one can use from a fragment
* program/shader (ARBfp1.0 asm/GLSL)
* MAX_VERTEX_TEXTURE_UNITS: number of samplers one can use from a vertex
* program/shader (can be 0)
* MAX_COMBINED_TEXTURE_IMAGE_UNITS: Maximum samplers one can use, counting both
* the vertex and fragment shaders
*
* If both the vertex shader and the fragment processing stage access the same
* texture image unit, then that counts as using two texture image units
* against the latter limit: http://www.opengl.org/sdk/docs/man/xhtml/glGet.xml
*
* Note that, for now, we use GL_MAX_TEXTURE_UNITS as we are exposing the
* fixed function pipeline.
*/
unsigned int
_cogl_get_max_texture_image_units (void)
{
_COGL_GET_CONTEXT (ctx, 0);
/* This function is called quite often so we cache the value to
avoid too many GL calls */
if (ctx->max_texture_units == -1)
{
ctx->max_texture_units = 1;
GE( glGetIntegerv (GL_MAX_TEXTURE_UNITS, &ctx->max_texture_units) );
}
return ctx->max_texture_units;
}
void
cogl_push_matrix (void)
{

View File

@ -41,6 +41,8 @@ typedef struct _CoglContextDriver
{
/* This defines a list of function pointers */
#include "cogl-feature-functions.h"
GLint gl_max_program_temoraries_arb;
} CoglContextDriver;
#undef COGL_FEATURE_BEGIN

View File

@ -119,6 +119,9 @@ COGL_FEATURE_BEGIN (arbfp, 255, 255,
COGL_FEATURE_FUNCTION (void, glGenPrograms,
(GLsizei n,
GLuint *programs))
COGL_FEATURE_FUNCTION (void, glDeletePrograms,
(GLsizei n,
GLuint *programs))
COGL_FEATURE_FUNCTION (void, glBindProgram,
(GLenum target,
GLuint program))
@ -127,47 +130,51 @@ COGL_FEATURE_FUNCTION (void, glProgramString,
GLenum format,
GLsizei len,
const void *program))
COGL_FEATURE_FUNCTION (void, glProgramLocalParameter4fv,
(GLenum target,
GLuint index,
GLfloat *params))
COGL_FEATURE_END ()
/* The function names in OpenGL 2.0 are different so we can't easily
just check for GL 2.0 */
COGL_FEATURE_BEGIN (shaders_glsl, 255, 255,
"ARB\0",
"shader_objects\0"
"vertex_shader\0"
"fragment_shader\0",
COGL_FEATURE_BEGIN (shaders_glsl, 2, 0,
"\0",
"\0",
COGL_FEATURE_SHADERS_GLSL,
0)
COGL_FEATURE_FUNCTION (GLhandleARB, glCreateProgramObject,
COGL_FEATURE_FUNCTION (GLuint, glCreateProgram,
(void))
COGL_FEATURE_FUNCTION (GLhandleARB, glCreateShaderObject,
COGL_FEATURE_FUNCTION (GLuint, glCreateShader,
(GLenum shaderType))
COGL_FEATURE_FUNCTION (void, glShaderSource,
(GLhandleARB shaderObj,
(GLuint shader,
GLsizei count,
const GLcharARB* *string,
const GLchar **string,
const GLint *length))
COGL_FEATURE_FUNCTION (void, glCompileShader,
(GLhandleARB shaderObj))
COGL_FEATURE_FUNCTION (void, glAttachObject,
(GLhandleARB containerObj,
GLhandleARB obj))
(GLuint shader))
COGL_FEATURE_FUNCTION (void, glDeleteShader,
(GLuint shader))
COGL_FEATURE_FUNCTION (void, glAttachShader,
(GLuint program,
GLuint shader))
COGL_FEATURE_FUNCTION (void, glLinkProgram,
(GLhandleARB programObj))
COGL_FEATURE_FUNCTION (void, glUseProgramObject,
(GLhandleARB programObj))
(GLuint program))
COGL_FEATURE_FUNCTION (void, glUseProgram,
(GLuint program))
COGL_FEATURE_FUNCTION (GLint, glGetUniformLocation,
(GLhandleARB programObj,
const GLcharARB *name))
COGL_FEATURE_FUNCTION (void, glDeleteObject,
(GLhandleARB obj))
COGL_FEATURE_FUNCTION (void, glGetInfoLog,
(GLhandleARB obj,
(GLuint program,
const GLchar *name))
COGL_FEATURE_FUNCTION (void, glDeleteProgram,
(GLuint program))
COGL_FEATURE_FUNCTION (void, glGetShaderInfoLog,
(GLuint shader,
GLsizei maxLength,
GLsizei *length,
GLcharARB *infoLog))
COGL_FEATURE_FUNCTION (void, glGetObjectParameteriv,
(GLhandleARB obj,
GLchar *infoLog))
COGL_FEATURE_FUNCTION (void, glGetShaderiv,
(GLuint shader,
GLenum pname,
GLint *params))

View File

@ -3,7 +3,7 @@
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2008,2009 Intel Corporation.
* Copyright (C) 2008,2009,2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -35,9 +35,9 @@
#include <glib.h>
#define glCreateProgramObject ctx->drv.pf_glCreateProgramObject
#define glAttachObject ctx->drv.pf_glAttachObject
#define glUseProgramObject ctx->drv.pf_glUseProgramObject
#define glCreateProgram ctx->drv.pf_glCreateProgram
#define glAttachShader ctx->drv.pf_glAttachShader
#define glUseProgram ctx->drv.pf_glUseProgram
#define glLinkProgram ctx->drv.pf_glLinkProgram
#define glGetUniformLocation ctx->drv.pf_glGetUniformLocation
#define glUniform1f ctx->drv.pf_glUniform1f
@ -59,7 +59,7 @@
#define glUniformMatrix2fv ctx->drv.pf_glUniformMatrix2fv
#define glUniformMatrix3fv ctx->drv.pf_glUniformMatrix3fv
#define glUniformMatrix4fv ctx->drv.pf_glUniformMatrix4fv
#define glDeleteObject ctx->drv.pf_glDeleteObject
#define glDeleteProgram ctx->drv.pf_glDeleteProgram
static void _cogl_program_free (CoglProgram *program);
@ -71,7 +71,7 @@ _cogl_program_free (CoglProgram *program)
/* Frees program resources but its handle is not
released! Do that separately before this! */
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
glDeleteObject (program->gl_handle);
GE (glDeleteProgram (program->gl_handle));
}
CoglHandle
@ -81,7 +81,7 @@ cogl_create_program (void)
_COGL_GET_CONTEXT (ctx, NULL);
program = g_slice_new (CoglProgram);
program->gl_handle = glCreateProgramObject ();
program->gl_handle = glCreateProgram ();
return _cogl_program_handle_new (program);
}
@ -101,7 +101,7 @@ cogl_program_attach_shader (CoglHandle program_handle,
program = _cogl_program_pointer_from_handle (program_handle);
shader = _cogl_shader_pointer_from_handle (shader_handle);
glAttachObject (program->gl_handle, shader->gl_handle);
GE (glAttachShader (program->gl_handle, shader->gl_handle));
}
void
@ -115,33 +115,27 @@ cogl_program_link (CoglHandle handle)
program = _cogl_program_pointer_from_handle (handle);
glLinkProgram (program->gl_handle);
GE (glLinkProgram (program->gl_handle));
}
void
cogl_program_use (CoglHandle handle)
{
CoglProgram *program;
GLhandleARB gl_handle;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (handle != COGL_INVALID_HANDLE && !cogl_is_program (handle))
return;
g_return_if_fail (handle == COGL_INVALID_HANDLE ||
cogl_is_program (handle));
/* The Cogl journal doesn't currently cope with the use of
* shaders so we have to flush all priitives whenever the
* current shader changes... */
_cogl_journal_flush ();
if (ctx->current_program == 0 && handle != 0)
ctx->legacy_state_set++;
else if (handle == 0 && ctx->current_program != 0)
ctx->legacy_state_set--;
if (handle == COGL_INVALID_HANDLE)
gl_handle = 0;
else
{
program = _cogl_program_pointer_from_handle (handle);
gl_handle = program->gl_handle;
}
glUseProgramObject (gl_handle);
if (handle != COGL_INVALID_HANDLE)
cogl_handle_ref (handle);
if (ctx->current_program != COGL_INVALID_HANDLE)
cogl_handle_unref (ctx->current_program);
ctx->current_program = handle;
}
int
@ -163,16 +157,34 @@ void
cogl_program_uniform_1f (int uniform_no,
float value)
{
CoglProgram *program;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
glUniform1f (uniform_no, value);
program = ctx->current_program;
g_return_if_fail (program != NULL);
_cogl_gl_use_program_wrapper (program->gl_handle);
GE (glUniform1f (uniform_no, value));
}
void
cogl_program_uniform_1i (int uniform_no,
int value)
{
CoglProgram *program;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
glUniform1i (uniform_no, value);
program = ctx->current_program;
g_return_if_fail (program != NULL);
_cogl_gl_use_program_wrapper (program->gl_handle);
GE (glUniform1i (uniform_no, value));
}
void
@ -181,21 +193,29 @@ cogl_program_uniform_float (int uniform_no,
int count,
const GLfloat *value)
{
CoglProgram *program;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
program = ctx->current_program;
g_return_if_fail (program != NULL);
_cogl_gl_use_program_wrapper (program->gl_handle);
switch (size)
{
case 1:
glUniform1fv (uniform_no, count, value);
GE (glUniform1fv (uniform_no, count, value));
break;
case 2:
glUniform2fv (uniform_no, count, value);
GE (glUniform2fv (uniform_no, count, value));
break;
case 3:
glUniform3fv (uniform_no, count, value);
GE (glUniform3fv (uniform_no, count, value));
break;
case 4:
glUniform4fv (uniform_no, count, value);
GE (glUniform4fv (uniform_no, count, value));
break;
default:
g_warning ("%s called with invalid size parameter", G_STRFUNC);
@ -208,8 +228,16 @@ cogl_program_uniform_int (int uniform_no,
int count,
const int *value)
{
CoglProgram *program;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
program = ctx->current_program;
g_return_if_fail (program != NULL);
_cogl_gl_use_program_wrapper (program->gl_handle);
switch (size)
{
case 1:
@ -236,18 +264,26 @@ cogl_program_uniform_matrix (int uniform_no,
gboolean transpose,
const GLfloat *value)
{
CoglProgram *program;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
program = ctx->current_program;
g_return_if_fail (program != NULL);
_cogl_gl_use_program_wrapper (program->gl_handle);
switch (size)
{
case 2 :
glUniformMatrix2fv (uniform_no, count, transpose, value);
GE (glUniformMatrix2fv (uniform_no, count, transpose, value));
break;
case 3 :
glUniformMatrix3fv (uniform_no, count, transpose, value);
GE (glUniformMatrix3fv (uniform_no, count, transpose, value));
break;
case 4 :
glUniformMatrix4fv (uniform_no, count, transpose, value);
GE (glUniformMatrix4fv (uniform_no, count, transpose, value));
break;
default :
g_warning ("%s called with invalid size parameter", G_STRFUNC);

View File

@ -31,7 +31,7 @@ typedef struct _CoglProgram CoglProgram;
struct _CoglProgram
{
CoglHandleObject _parent;
GLhandleARB gl_handle;
GLuint gl_handle;
};
CoglProgram *_cogl_program_pointer_from_handle (CoglHandle handle);

View File

@ -3,7 +3,7 @@
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2007,2008,2009 Intel Corporation.
* Copyright (C) 2007,2008,2009,2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -33,12 +33,12 @@
#include <glib.h>
#define glCreateShaderObject ctx->drv.pf_glCreateShaderObject
#define glGetObjectParameteriv ctx->drv.pf_glGetObjectParameteriv
#define glGetInfoLog ctx->drv.pf_glGetInfoLog
#define glCompileShader ctx->drv.pf_glCompileShader
#define glShaderSource ctx->drv.pf_glShaderSource
#define glDeleteObject ctx->drv.pf_glDeleteObject
#define glCreateShader ctx->drv.pf_glCreateShader
#define glGetShaderiv ctx->drv.pf_glGetShaderiv
#define glGetShaderInfoLog ctx->drv.pf_glGetShaderInfoLog
#define glCompileShader ctx->drv.pf_glCompileShader
#define glShaderSource ctx->drv.pf_glShaderSource
#define glDeleteShader ctx->drv.pf_glDeleteShader
static void _cogl_shader_free (CoglShader *shader);
@ -50,7 +50,7 @@ _cogl_shader_free (CoglShader *shader)
/* Frees shader resources but its handle is not
released! Do that separately before this! */
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
glDeleteObject (shader->gl_handle);
glDeleteShader (shader->gl_handle);
}
CoglHandle
@ -73,7 +73,7 @@ cogl_create_shader (CoglShaderType type)
}
shader = g_slice_new (CoglShader);
shader->gl_handle = glCreateShaderObject (gl_type);
shader->gl_handle = glCreateShader (gl_type);
return _cogl_shader_handle_new (shader);
}
@ -112,7 +112,7 @@ cogl_shader_get_info_log (CoglHandle handle)
{
CoglShader *shader;
char buffer[512];
int len;
GLsizei len;
_COGL_GET_CONTEXT (ctx, NULL);
if (!cogl_is_shader (handle))
@ -120,7 +120,7 @@ cogl_shader_get_info_log (CoglHandle handle)
shader = _cogl_shader_pointer_from_handle (handle);
glGetInfoLog (shader->gl_handle, 511, &len, buffer);
glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer);
buffer[len]='\0';
return g_strdup (buffer);
@ -142,7 +142,7 @@ cogl_shader_get_type (CoglHandle handle)
shader = _cogl_shader_pointer_from_handle (handle);
GE (glGetObjectParameteriv (shader->gl_handle, GL_SHADER_TYPE, &type));
GE (glGetShaderiv (shader->gl_handle, GL_SHADER_TYPE, &type));
if (type == GL_VERTEX_SHADER)
return COGL_SHADER_TYPE_VERTEX;
else if (type == GL_FRAGMENT_SHADER)
@ -167,7 +167,7 @@ cogl_shader_is_compiled (CoglHandle handle)
shader = _cogl_shader_pointer_from_handle (handle);
GE (glGetObjectParameteriv (shader->gl_handle, GL_COMPILE_STATUS, &status));
GE (glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status));
if (status == GL_TRUE)
return TRUE;
else

View File

@ -115,11 +115,22 @@ cogl_program_use (CoglHandle handle)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (handle != COGL_INVALID_HANDLE && !cogl_is_program (handle))
return;
g_return_if_fail (handle == COGL_INVALID_HANDLE ||
cogl_is_program (handle));
if (ctx->current_program == 0 && handle != 0)
ctx->legacy_state_set++;
else if (handle == 0 && ctx->current_program != 0)
ctx->legacy_state_set--;
ctx->drv.gles2.settings.user_program = handle;
ctx->drv.gles2.settings_dirty = TRUE;
if (handle != COGL_INVALID_HANDLE)
cogl_handle_ref (handle);
if (ctx->current_program != COGL_INVALID_HANDLE)
cogl_handle_unref (ctx->current_program);
ctx->current_program = handle;
}
int