mutter/cogl/cogl-pipeline-progend-glsl.c

1124 lines
36 KiB
C
Raw Normal View History

/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 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
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
*
*
* Authors:
* Neil Roberts <neil@linux.intel.com>
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
cogl-pipeline: Add support for setting uniform values This adds the following new public experimental functions to set uniform values on a CoglPipeline: void cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, int uniform_location, float value); void cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, int uniform_location, int value); void cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const float *value); void cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const int *value); void cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, int uniform_location, int dimensions, int count, gboolean transpose, const float *value); These are similar to the old functions used to set uniforms on a CoglProgram. To get a value to pass in as the uniform_location there is also: int cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, const char *uniform_name); Conceptually the uniform locations are tied to the pipeline so that whenever setting a value for a new pipeline the application is expected to call this function. However in practice the uniform locations are global to the CoglContext. The names are stored in a linked list where the position in the list is the uniform location. The global indices are used so that each pipeline can store a mask of which uniforms it overrides. That way it is quicker to detect which uniforms are different from the last pipeline that used the same CoglProgramState so it can avoid flushing uniforms that haven't changed. Currently the values are not actually compared which means that it will only avoid flushing a uniform if there is a common ancestor that sets the value (or if the same pipeline is being flushed again - in which case the pipeline and its common ancestor are the same thing). The uniform values are stored in the big state of the pipeline as a sparse linked list. A bitmask stores which values have been overridden and only overridden values are stored in the linked list. Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-03 17:20:43 +00:00
#include <string.h>
#include "cogl-util.h"
#include "cogl-context-private.h"
#include "cogl-pipeline-private.h"
#include "cogl-pipeline-opengl-private.h"
#ifdef COGL_PIPELINE_PROGEND_GLSL
#include "cogl.h"
#include "cogl-internal.h"
#include "cogl-context-private.h"
#include "cogl-handle.h"
#include "cogl-program-private.h"
#include "cogl-pipeline-fragend-glsl-private.h"
#include "cogl-pipeline-vertend-glsl-private.h"
#include "cogl-pipeline-cache.h"
cogl-pipeline: Add support for setting uniform values This adds the following new public experimental functions to set uniform values on a CoglPipeline: void cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, int uniform_location, float value); void cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, int uniform_location, int value); void cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const float *value); void cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const int *value); void cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, int uniform_location, int dimensions, int count, gboolean transpose, const float *value); These are similar to the old functions used to set uniforms on a CoglProgram. To get a value to pass in as the uniform_location there is also: int cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, const char *uniform_name); Conceptually the uniform locations are tied to the pipeline so that whenever setting a value for a new pipeline the application is expected to call this function. However in practice the uniform locations are global to the CoglContext. The names are stored in a linked list where the position in the list is the uniform location. The global indices are used so that each pipeline can store a mask of which uniforms it overrides. That way it is quicker to detect which uniforms are different from the last pipeline that used the same CoglProgramState so it can avoid flushing uniforms that haven't changed. Currently the values are not actually compared which means that it will only avoid flushing a uniform if there is a common ancestor that sets the value (or if the same pipeline is being flushed again - in which case the pipeline and its common ancestor are the same thing). The uniform values are stored in the big state of the pipeline as a sparse linked list. A bitmask stores which values have been overridden and only overridden values are stored in the linked list. Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-03 17:20:43 +00:00
#include "cogl-pipeline-state-private.h"
#include "cogl-attribute-private.h"
#ifdef HAVE_COGL_GLES2
/* These are used to generalise updating some uniforms that are
required when building for GLES2 */
typedef void (* UpdateUniformFunc) (CoglPipeline *pipeline,
int uniform_location,
void *getter_func);
static void update_float_uniform (CoglPipeline *pipeline,
int uniform_location,
void *getter_func);
typedef struct
{
const char *uniform_name;
void *getter_func;
UpdateUniformFunc update_func;
CoglPipelineState change;
} BuiltinUniformData;
static BuiltinUniformData builtin_uniforms[] =
{
{ "cogl_point_size_in",
cogl_pipeline_get_point_size, update_float_uniform,
COGL_PIPELINE_STATE_POINT_SIZE },
{ "_cogl_alpha_test_ref",
cogl_pipeline_get_alpha_test_reference, update_float_uniform,
COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE }
};
#endif /* HAVE_COGL_GLES2 */
const CoglPipelineProgend _cogl_pipeline_glsl_progend;
typedef struct _UnitState
{
unsigned int dirty_combine_constant:1;
unsigned int dirty_texture_matrix:1;
GLint combine_constant_uniform;
GLint texture_matrix_uniform;
} UnitState;
typedef struct
{
unsigned int ref_count;
/* Age that the user program had last time we generated a GL
program. If it's different then we need to relink the program */
unsigned int user_program_age;
GLuint program;
/* To allow writing shaders that are portable between GLES 2 and
* OpenGL Cogl prepends a number of boilerplate #defines and
* declarations to user shaders. One of those declarations is an
* array of texture coordinate varyings, but to know how to emit the
* declaration we need to know how many texture coordinate
* attributes are in use. The boilerplate also needs to be changed
* if this changes. */
int n_tex_coord_attribs;
#ifdef HAVE_COGL_GLES2
unsigned long dirty_builtin_uniforms;
GLint builtin_uniform_locations[G_N_ELEMENTS (builtin_uniforms)];
GLint modelview_uniform;
GLint projection_uniform;
GLint mvp_uniform;
CoglMatrixStack *flushed_modelview_stack;
unsigned int flushed_modelview_stack_age;
gboolean flushed_modelview_is_identity;
CoglMatrixStack *flushed_projection_stack;
unsigned int flushed_projection_stack_age;
#endif
/* We need to track the last pipeline that the program was used with
* so know if we need to update all of the uniforms */
CoglPipeline *last_used_for_pipeline;
cogl-pipeline: Add support for setting uniform values This adds the following new public experimental functions to set uniform values on a CoglPipeline: void cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, int uniform_location, float value); void cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, int uniform_location, int value); void cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const float *value); void cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const int *value); void cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, int uniform_location, int dimensions, int count, gboolean transpose, const float *value); These are similar to the old functions used to set uniforms on a CoglProgram. To get a value to pass in as the uniform_location there is also: int cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, const char *uniform_name); Conceptually the uniform locations are tied to the pipeline so that whenever setting a value for a new pipeline the application is expected to call this function. However in practice the uniform locations are global to the CoglContext. The names are stored in a linked list where the position in the list is the uniform location. The global indices are used so that each pipeline can store a mask of which uniforms it overrides. That way it is quicker to detect which uniforms are different from the last pipeline that used the same CoglProgramState so it can avoid flushing uniforms that haven't changed. Currently the values are not actually compared which means that it will only avoid flushing a uniform if there is a common ancestor that sets the value (or if the same pipeline is being flushed again - in which case the pipeline and its common ancestor are the same thing). The uniform values are stored in the big state of the pipeline as a sparse linked list. A bitmask stores which values have been overridden and only overridden values are stored in the linked list. Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-03 17:20:43 +00:00
/* Array of GL uniform locations indexed by Cogl's uniform
location. We are careful only to allocated this array if a custom
uniform is actually set */
GArray *uniform_locations;
/* Array of attribute locations. */
GArray *attribute_locations;
UnitState *unit_state;
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
} CoglPipelineProgramState;
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
static CoglUserDataKey program_state_key;
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
static CoglPipelineProgramState *
get_program_state (CoglPipeline *pipeline)
{
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
return cogl_object_get_user_data (COGL_OBJECT (pipeline), &program_state_key);
}
cogl-pipeline: Add support for setting uniform values This adds the following new public experimental functions to set uniform values on a CoglPipeline: void cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, int uniform_location, float value); void cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, int uniform_location, int value); void cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const float *value); void cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const int *value); void cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, int uniform_location, int dimensions, int count, gboolean transpose, const float *value); These are similar to the old functions used to set uniforms on a CoglProgram. To get a value to pass in as the uniform_location there is also: int cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, const char *uniform_name); Conceptually the uniform locations are tied to the pipeline so that whenever setting a value for a new pipeline the application is expected to call this function. However in practice the uniform locations are global to the CoglContext. The names are stored in a linked list where the position in the list is the uniform location. The global indices are used so that each pipeline can store a mask of which uniforms it overrides. That way it is quicker to detect which uniforms are different from the last pipeline that used the same CoglProgramState so it can avoid flushing uniforms that haven't changed. Currently the values are not actually compared which means that it will only avoid flushing a uniform if there is a common ancestor that sets the value (or if the same pipeline is being flushed again - in which case the pipeline and its common ancestor are the same thing). The uniform values are stored in the big state of the pipeline as a sparse linked list. A bitmask stores which values have been overridden and only overridden values are stored in the linked list. Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-03 17:20:43 +00:00
#define UNIFORM_LOCATION_UNKNOWN -2
#define ATTRIBUTE_LOCATION_UNKNOWN -2
/* Under GLES2 the vertex attribute API needs to query the attribute
numbers because it can't used the fixed function API to set the
builtin attributes. We cache the attributes here because the
progend knows when the program is changed so it can clear the
cache. This should always be called after the pipeline is flushed
so they can assert that the gl program is valid */
/* All attributes names get internally mapped to a global set of
* sequential indices when they are setup which we need to need to
* then be able to map to a GL attribute location once we have
* a linked GLSL program */
int
_cogl_pipeline_progend_glsl_get_attrib_location (CoglPipeline *pipeline,
int name_index)
{
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
CoglPipelineProgramState *program_state = get_program_state (pipeline);
int *locations;
_COGL_GET_CONTEXT (ctx, -1);
_COGL_RETURN_VAL_IF_FAIL (program_state != NULL, -1);
_COGL_RETURN_VAL_IF_FAIL (program_state->program != 0, -1);
if (G_UNLIKELY (program_state->attribute_locations == NULL))
program_state->attribute_locations =
g_array_new (FALSE, FALSE, sizeof (int));
if (G_UNLIKELY (program_state->attribute_locations->len <= name_index))
{
int i = program_state->attribute_locations->len;
g_array_set_size (program_state->attribute_locations, name_index + 1);
for (; i < program_state->attribute_locations->len; i++)
g_array_index (program_state->attribute_locations, int, i)
= ATTRIBUTE_LOCATION_UNKNOWN;
}
locations = &g_array_index (program_state->attribute_locations, int, 0);
if (locations[name_index] == ATTRIBUTE_LOCATION_UNKNOWN)
{
CoglAttributeNameState *name_state =
g_array_index (ctx->attribute_name_index_map,
CoglAttributeNameState *, name_index);
_COGL_RETURN_VAL_IF_FAIL (name_state != NULL, 0);
GE_RET( locations[name_index],
ctx, glGetAttribLocation (program_state->program,
name_state->name) );
}
return locations[name_index];
}
static void
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
clear_attribute_cache (CoglPipelineProgramState *program_state)
{
if (program_state->attribute_locations)
{
g_array_free (program_state->attribute_locations, TRUE);
program_state->attribute_locations = NULL;
}
}
#ifdef HAVE_COGL_GLES2
static void
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
clear_flushed_matrix_stacks (CoglPipelineProgramState *program_state)
{
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
if (program_state->flushed_modelview_stack)
{
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
cogl_object_unref (program_state->flushed_modelview_stack);
program_state->flushed_modelview_stack = NULL;
}
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
if (program_state->flushed_projection_stack)
{
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
cogl_object_unref (program_state->flushed_projection_stack);
program_state->flushed_projection_stack = NULL;
}
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state->flushed_modelview_is_identity = FALSE;
}
#endif /* HAVE_COGL_GLES2 */
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
static CoglPipelineProgramState *
program_state_new (int n_layers)
{
CoglPipelineProgramState *program_state;
program_state = g_slice_new (CoglPipelineProgramState);
program_state->ref_count = 1;
program_state->program = 0;
program_state->n_tex_coord_attribs = 0;
program_state->unit_state = g_new (UnitState, n_layers);
cogl-pipeline: Add support for setting uniform values This adds the following new public experimental functions to set uniform values on a CoglPipeline: void cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, int uniform_location, float value); void cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, int uniform_location, int value); void cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const float *value); void cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const int *value); void cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, int uniform_location, int dimensions, int count, gboolean transpose, const float *value); These are similar to the old functions used to set uniforms on a CoglProgram. To get a value to pass in as the uniform_location there is also: int cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, const char *uniform_name); Conceptually the uniform locations are tied to the pipeline so that whenever setting a value for a new pipeline the application is expected to call this function. However in practice the uniform locations are global to the CoglContext. The names are stored in a linked list where the position in the list is the uniform location. The global indices are used so that each pipeline can store a mask of which uniforms it overrides. That way it is quicker to detect which uniforms are different from the last pipeline that used the same CoglProgramState so it can avoid flushing uniforms that haven't changed. Currently the values are not actually compared which means that it will only avoid flushing a uniform if there is a common ancestor that sets the value (or if the same pipeline is being flushed again - in which case the pipeline and its common ancestor are the same thing). The uniform values are stored in the big state of the pipeline as a sparse linked list. A bitmask stores which values have been overridden and only overridden values are stored in the linked list. Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-03 17:20:43 +00:00
program_state->uniform_locations = NULL;
program_state->attribute_locations = NULL;
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
#ifdef HAVE_COGL_GLES2
program_state->flushed_modelview_stack = NULL;
program_state->flushed_modelview_is_identity = FALSE;
program_state->flushed_projection_stack = NULL;
#endif
return program_state;
}
static void
destroy_program_state (void *user_data,
void *instance)
{
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
CoglPipelineProgramState *program_state = user_data;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* If the program state was last used for this pipeline then clear
it so that if same address gets used again for a new pipeline
then we won't think it's the same pipeline and avoid updating the
uniforms */
if (program_state->last_used_for_pipeline == instance)
program_state->last_used_for_pipeline = NULL;
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
if (--program_state->ref_count == 0)
{
clear_attribute_cache (program_state);
#ifdef HAVE_COGL_GLES2
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
2011-07-07 19:44:56 +00:00
if (ctx->driver == COGL_DRIVER_GLES2)
clear_flushed_matrix_stacks (program_state);
#endif
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
if (program_state->program)
GE( ctx, glDeleteProgram (program_state->program) );
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
g_free (program_state->unit_state);
cogl-pipeline: Add support for setting uniform values This adds the following new public experimental functions to set uniform values on a CoglPipeline: void cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, int uniform_location, float value); void cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, int uniform_location, int value); void cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const float *value); void cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const int *value); void cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, int uniform_location, int dimensions, int count, gboolean transpose, const float *value); These are similar to the old functions used to set uniforms on a CoglProgram. To get a value to pass in as the uniform_location there is also: int cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, const char *uniform_name); Conceptually the uniform locations are tied to the pipeline so that whenever setting a value for a new pipeline the application is expected to call this function. However in practice the uniform locations are global to the CoglContext. The names are stored in a linked list where the position in the list is the uniform location. The global indices are used so that each pipeline can store a mask of which uniforms it overrides. That way it is quicker to detect which uniforms are different from the last pipeline that used the same CoglProgramState so it can avoid flushing uniforms that haven't changed. Currently the values are not actually compared which means that it will only avoid flushing a uniform if there is a common ancestor that sets the value (or if the same pipeline is being flushed again - in which case the pipeline and its common ancestor are the same thing). The uniform values are stored in the big state of the pipeline as a sparse linked list. A bitmask stores which values have been overridden and only overridden values are stored in the linked list. Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-03 17:20:43 +00:00
if (program_state->uniform_locations)
g_array_free (program_state->uniform_locations, TRUE);
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
g_slice_free (CoglPipelineProgramState, program_state);
}
}
static void
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
set_program_state (CoglPipeline *pipeline,
CoglPipelineProgramState *program_state)
{
_cogl_object_set_user_data (COGL_OBJECT (pipeline),
&program_state_key,
program_state,
destroy_program_state);
}
static void
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
dirty_program_state (CoglPipeline *pipeline)
{
cogl_object_set_user_data (COGL_OBJECT (pipeline),
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
&program_state_key,
NULL,
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
NULL);
}
static void
link_program (GLint gl_program)
{
GLint link_status;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
GE( ctx, glLinkProgram (gl_program) );
GE( ctx, glGetProgramiv (gl_program, GL_LINK_STATUS, &link_status) );
if (!link_status)
{
GLint log_length;
GLsizei out_log_length;
char *log;
GE( ctx, glGetProgramiv (gl_program, GL_INFO_LOG_LENGTH, &log_length) );
log = g_malloc (log_length);
GE( ctx, glGetProgramInfoLog (gl_program, log_length,
&out_log_length, log) );
g_warning ("Failed to link GLSL program:\n%.*s\n",
log_length, log);
g_free (log);
}
}
typedef struct
{
int unit;
GLuint gl_program;
gboolean update_all;
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
CoglPipelineProgramState *program_state;
} UpdateUniformsState;
static gboolean
get_uniform_cb (CoglPipeline *pipeline,
int layer_index,
void *user_data)
{
UpdateUniformsState *state = user_data;
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
CoglPipelineProgramState *program_state = state->program_state;
UnitState *unit_state = &program_state->unit_state[state->unit];
GLint uniform_location;
_COGL_GET_CONTEXT (ctx, FALSE);
/* We can reuse the source buffer to create the uniform name because
the program has now been linked */
g_string_set_size (ctx->codegen_source_buffer, 0);
g_string_append_printf (ctx->codegen_source_buffer,
"_cogl_sampler_%i", state->unit);
GE_RET( uniform_location,
ctx, glGetUniformLocation (state->gl_program,
ctx->codegen_source_buffer->str) );
/* We can set the uniform immediately because the samplers are the
unit index not the texture object number so it will never
change. Unfortunately GL won't let us use a constant instead of a
uniform */
if (uniform_location != -1)
GE( ctx, glUniform1i (uniform_location, state->unit) );
g_string_set_size (ctx->codegen_source_buffer, 0);
g_string_append_printf (ctx->codegen_source_buffer,
"_cogl_layer_constant_%i", state->unit);
GE_RET( uniform_location,
ctx, glGetUniformLocation (state->gl_program,
ctx->codegen_source_buffer->str) );
unit_state->combine_constant_uniform = uniform_location;
#ifdef HAVE_COGL_GLES2
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
2011-07-07 19:44:56 +00:00
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);
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
2011-07-07 19:44:56 +00:00
GE_RET( uniform_location,
ctx, glGetUniformLocation (state->gl_program,
ctx->codegen_source_buffer->str) );
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
2011-07-07 19:44:56 +00:00
unit_state->texture_matrix_uniform = uniform_location;
}
#endif
state->unit++;
return TRUE;
}
static gboolean
update_constants_cb (CoglPipeline *pipeline,
int layer_index,
void *user_data)
{
UpdateUniformsState *state = user_data;
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
CoglPipelineProgramState *program_state = state->program_state;
UnitState *unit_state = &program_state->unit_state[state->unit++];
_COGL_GET_CONTEXT (ctx, FALSE);
if (unit_state->combine_constant_uniform != -1 &&
(state->update_all || unit_state->dirty_combine_constant))
{
float constant[4];
_cogl_pipeline_get_layer_combine_constant (pipeline,
layer_index,
constant);
GE (ctx, glUniform4fv (unit_state->combine_constant_uniform,
1, constant));
unit_state->dirty_combine_constant = FALSE;
}
#ifdef HAVE_COGL_GLES2
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
2011-07-07 19:44:56 +00:00
if (ctx->driver == COGL_DRIVER_GLES2 &&
unit_state->texture_matrix_uniform != -1 &&
(state->update_all || unit_state->dirty_texture_matrix))
{
const CoglMatrix *matrix;
const float *array;
matrix = _cogl_pipeline_get_layer_matrix (pipeline, layer_index);
array = cogl_matrix_get_array (matrix);
GE (ctx, glUniformMatrix4fv (unit_state->texture_matrix_uniform,
1, FALSE, array));
unit_state->dirty_texture_matrix = FALSE;
}
#endif /* HAVE_COGL_GLES2 */
return TRUE;
}
#ifdef HAVE_COGL_GLES2
static void
update_builtin_uniforms (CoglPipeline *pipeline,
GLuint gl_program,
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
CoglPipelineProgramState *program_state)
{
int i;
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
if (program_state->dirty_builtin_uniforms == 0)
return;
for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++)
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
if ((program_state->dirty_builtin_uniforms & (1 << i)) &&
program_state->builtin_uniform_locations[i] != -1)
builtin_uniforms[i].update_func (pipeline,
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state
->builtin_uniform_locations[i],
builtin_uniforms[i].getter_func);
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state->dirty_builtin_uniforms = 0;
}
#endif /* HAVE_COGL_GLES2 */
cogl-pipeline: Add support for setting uniform values This adds the following new public experimental functions to set uniform values on a CoglPipeline: void cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, int uniform_location, float value); void cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, int uniform_location, int value); void cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const float *value); void cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const int *value); void cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, int uniform_location, int dimensions, int count, gboolean transpose, const float *value); These are similar to the old functions used to set uniforms on a CoglProgram. To get a value to pass in as the uniform_location there is also: int cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, const char *uniform_name); Conceptually the uniform locations are tied to the pipeline so that whenever setting a value for a new pipeline the application is expected to call this function. However in practice the uniform locations are global to the CoglContext. The names are stored in a linked list where the position in the list is the uniform location. The global indices are used so that each pipeline can store a mask of which uniforms it overrides. That way it is quicker to detect which uniforms are different from the last pipeline that used the same CoglProgramState so it can avoid flushing uniforms that haven't changed. Currently the values are not actually compared which means that it will only avoid flushing a uniform if there is a common ancestor that sets the value (or if the same pipeline is being flushed again - in which case the pipeline and its common ancestor are the same thing). The uniform values are stored in the big state of the pipeline as a sparse linked list. A bitmask stores which values have been overridden and only overridden values are stored in the linked list. Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-03 17:20:43 +00:00
typedef struct
{
CoglPipelineProgramState *program_state;
unsigned long *uniform_differences;
int n_differences;
CoglContext *ctx;
const CoglBoxedValue *values;
int value_index;
cogl-pipeline: Add support for setting uniform values This adds the following new public experimental functions to set uniform values on a CoglPipeline: void cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, int uniform_location, float value); void cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, int uniform_location, int value); void cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const float *value); void cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const int *value); void cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, int uniform_location, int dimensions, int count, gboolean transpose, const float *value); These are similar to the old functions used to set uniforms on a CoglProgram. To get a value to pass in as the uniform_location there is also: int cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, const char *uniform_name); Conceptually the uniform locations are tied to the pipeline so that whenever setting a value for a new pipeline the application is expected to call this function. However in practice the uniform locations are global to the CoglContext. The names are stored in a linked list where the position in the list is the uniform location. The global indices are used so that each pipeline can store a mask of which uniforms it overrides. That way it is quicker to detect which uniforms are different from the last pipeline that used the same CoglProgramState so it can avoid flushing uniforms that haven't changed. Currently the values are not actually compared which means that it will only avoid flushing a uniform if there is a common ancestor that sets the value (or if the same pipeline is being flushed again - in which case the pipeline and its common ancestor are the same thing). The uniform values are stored in the big state of the pipeline as a sparse linked list. A bitmask stores which values have been overridden and only overridden values are stored in the linked list. Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-03 17:20:43 +00:00
} FlushUniformsClosure;
static gboolean
flush_uniform_cb (int uniform_num, void *user_data)
{
FlushUniformsClosure *data = user_data;
if (COGL_FLAGS_GET (data->uniform_differences, uniform_num))
{
GArray *uniform_locations;
GLint uniform_location;
if (data->program_state->uniform_locations == NULL)
data->program_state->uniform_locations =
g_array_new (FALSE, FALSE, sizeof (GLint));
uniform_locations = data->program_state->uniform_locations;
if (uniform_locations->len <= uniform_num)
{
unsigned int old_len = uniform_locations->len;
g_array_set_size (uniform_locations, uniform_num + 1);
while (old_len <= uniform_num)
{
g_array_index (uniform_locations, GLint, old_len) =
UNIFORM_LOCATION_UNKNOWN;
old_len++;
}
}
uniform_location = g_array_index (uniform_locations, GLint, uniform_num);
if (uniform_location == UNIFORM_LOCATION_UNKNOWN)
{
const char *uniform_name =
g_ptr_array_index (data->ctx->uniform_names, uniform_num);
cogl-pipeline: Add support for setting uniform values This adds the following new public experimental functions to set uniform values on a CoglPipeline: void cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, int uniform_location, float value); void cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, int uniform_location, int value); void cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const float *value); void cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const int *value); void cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, int uniform_location, int dimensions, int count, gboolean transpose, const float *value); These are similar to the old functions used to set uniforms on a CoglProgram. To get a value to pass in as the uniform_location there is also: int cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, const char *uniform_name); Conceptually the uniform locations are tied to the pipeline so that whenever setting a value for a new pipeline the application is expected to call this function. However in practice the uniform locations are global to the CoglContext. The names are stored in a linked list where the position in the list is the uniform location. The global indices are used so that each pipeline can store a mask of which uniforms it overrides. That way it is quicker to detect which uniforms are different from the last pipeline that used the same CoglProgramState so it can avoid flushing uniforms that haven't changed. Currently the values are not actually compared which means that it will only avoid flushing a uniform if there is a common ancestor that sets the value (or if the same pipeline is being flushed again - in which case the pipeline and its common ancestor are the same thing). The uniform values are stored in the big state of the pipeline as a sparse linked list. A bitmask stores which values have been overridden and only overridden values are stored in the linked list. Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-03 17:20:43 +00:00
uniform_location =
data->ctx->glGetUniformLocation (data->program_state->program,
uniform_name);
g_array_index (uniform_locations, GLint, uniform_num) =
uniform_location;
}
if (uniform_location != -1)
_cogl_boxed_value_set_uniform (data->ctx,
uniform_location,
data->values + data->value_index);
cogl-pipeline: Add support for setting uniform values This adds the following new public experimental functions to set uniform values on a CoglPipeline: void cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, int uniform_location, float value); void cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, int uniform_location, int value); void cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const float *value); void cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const int *value); void cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, int uniform_location, int dimensions, int count, gboolean transpose, const float *value); These are similar to the old functions used to set uniforms on a CoglProgram. To get a value to pass in as the uniform_location there is also: int cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, const char *uniform_name); Conceptually the uniform locations are tied to the pipeline so that whenever setting a value for a new pipeline the application is expected to call this function. However in practice the uniform locations are global to the CoglContext. The names are stored in a linked list where the position in the list is the uniform location. The global indices are used so that each pipeline can store a mask of which uniforms it overrides. That way it is quicker to detect which uniforms are different from the last pipeline that used the same CoglProgramState so it can avoid flushing uniforms that haven't changed. Currently the values are not actually compared which means that it will only avoid flushing a uniform if there is a common ancestor that sets the value (or if the same pipeline is being flushed again - in which case the pipeline and its common ancestor are the same thing). The uniform values are stored in the big state of the pipeline as a sparse linked list. A bitmask stores which values have been overridden and only overridden values are stored in the linked list. Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-03 17:20:43 +00:00
data->n_differences--;
COGL_FLAGS_SET (data->uniform_differences, uniform_num, FALSE);
}
data->value_index++;
cogl-pipeline: Add support for setting uniform values This adds the following new public experimental functions to set uniform values on a CoglPipeline: void cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, int uniform_location, float value); void cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, int uniform_location, int value); void cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const float *value); void cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const int *value); void cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, int uniform_location, int dimensions, int count, gboolean transpose, const float *value); These are similar to the old functions used to set uniforms on a CoglProgram. To get a value to pass in as the uniform_location there is also: int cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, const char *uniform_name); Conceptually the uniform locations are tied to the pipeline so that whenever setting a value for a new pipeline the application is expected to call this function. However in practice the uniform locations are global to the CoglContext. The names are stored in a linked list where the position in the list is the uniform location. The global indices are used so that each pipeline can store a mask of which uniforms it overrides. That way it is quicker to detect which uniforms are different from the last pipeline that used the same CoglProgramState so it can avoid flushing uniforms that haven't changed. Currently the values are not actually compared which means that it will only avoid flushing a uniform if there is a common ancestor that sets the value (or if the same pipeline is being flushed again - in which case the pipeline and its common ancestor are the same thing). The uniform values are stored in the big state of the pipeline as a sparse linked list. A bitmask stores which values have been overridden and only overridden values are stored in the linked list. Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-03 17:20:43 +00:00
return data->n_differences > 0;
}
static void
_cogl_pipeline_progend_glsl_flush_uniforms (CoglPipeline *pipeline,
CoglPipelineProgramState *
program_state,
GLuint gl_program,
gboolean program_changed)
{
CoglPipelineUniformsState *uniforms_state;
FlushUniformsClosure data;
int n_uniform_longs;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (pipeline->differences & COGL_PIPELINE_STATE_UNIFORMS)
uniforms_state = &pipeline->big_state->uniforms_state;
else
uniforms_state = NULL;
data.program_state = program_state;
data.ctx = ctx;
n_uniform_longs = COGL_FLAGS_N_LONGS_FOR_SIZE (ctx->n_uniform_names);
data.uniform_differences = g_newa (unsigned long, n_uniform_longs);
/* Try to find a common ancestor for the values that were already
flushed on the pipeline that this program state was last used for
so we can avoid flushing those */
if (program_changed || program_state->last_used_for_pipeline == NULL)
{
if (program_changed)
{
/* The program has changed so all of the uniform locations
are invalid */
if (program_state->uniform_locations)
g_array_set_size (program_state->uniform_locations, 0);
}
/* We need to flush everything so mark all of the uniforms as
dirty */
memset (data.uniform_differences, 0xff,
n_uniform_longs * sizeof (unsigned long));
data.n_differences = G_MAXINT;
}
else if (program_state->last_used_for_pipeline)
{
int i;
memset (data.uniform_differences, 0,
n_uniform_longs * sizeof (unsigned long));
_cogl_pipeline_compare_uniform_differences
(data.uniform_differences,
program_state->last_used_for_pipeline,
pipeline);
/* We need to be sure to flush any uniforms that have changed
since the last flush */
if (uniforms_state)
_cogl_bitmask_set_flags (&uniforms_state->changed_mask,
data.uniform_differences);
/* Count the number of differences. This is so we can stop early
when we've flushed all of them */
data.n_differences = 0;
for (i = 0; i < n_uniform_longs; i++)
data.n_differences +=
_cogl_util_popcountl (data.uniform_differences[i]);
}
while (pipeline && data.n_differences > 0)
{
if (pipeline->differences & COGL_PIPELINE_STATE_UNIFORMS)
{
const CoglPipelineUniformsState *parent_uniforms_state =
&pipeline->big_state->uniforms_state;
data.values = parent_uniforms_state->override_values;
data.value_index = 0;
cogl-pipeline: Add support for setting uniform values This adds the following new public experimental functions to set uniform values on a CoglPipeline: void cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, int uniform_location, float value); void cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, int uniform_location, int value); void cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const float *value); void cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const int *value); void cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, int uniform_location, int dimensions, int count, gboolean transpose, const float *value); These are similar to the old functions used to set uniforms on a CoglProgram. To get a value to pass in as the uniform_location there is also: int cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, const char *uniform_name); Conceptually the uniform locations are tied to the pipeline so that whenever setting a value for a new pipeline the application is expected to call this function. However in practice the uniform locations are global to the CoglContext. The names are stored in a linked list where the position in the list is the uniform location. The global indices are used so that each pipeline can store a mask of which uniforms it overrides. That way it is quicker to detect which uniforms are different from the last pipeline that used the same CoglProgramState so it can avoid flushing uniforms that haven't changed. Currently the values are not actually compared which means that it will only avoid flushing a uniform if there is a common ancestor that sets the value (or if the same pipeline is being flushed again - in which case the pipeline and its common ancestor are the same thing). The uniform values are stored in the big state of the pipeline as a sparse linked list. A bitmask stores which values have been overridden and only overridden values are stored in the linked list. Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-03 17:20:43 +00:00
_cogl_bitmask_foreach (&parent_uniforms_state->override_mask,
flush_uniform_cb,
&data);
}
pipeline = _cogl_pipeline_get_parent (pipeline);
}
if (uniforms_state)
_cogl_bitmask_clear_all (&uniforms_state->changed_mask);
}
static void
_cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
unsigned long pipelines_difference,
int n_tex_coord_attribs)
{
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
CoglPipelineProgramState *program_state;
GLuint gl_program;
gboolean program_changed = FALSE;
UpdateUniformsState state;
CoglProgram *user_program;
CoglPipeline *template_pipeline = NULL;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* If neither of the glsl fragend or vertends are used then we don't
need to do anything */
if (pipeline->fragend != COGL_PIPELINE_FRAGEND_GLSL &&
pipeline->vertend != COGL_PIPELINE_VERTEND_GLSL)
return;
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state = get_program_state (pipeline);
user_program = cogl_pipeline_get_user_program (pipeline);
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
if (program_state == NULL)
{
CoglPipeline *authority;
/* Get the authority for anything affecting program state. This
should include both fragment codegen state and vertex codegen
state */
authority = _cogl_pipeline_find_equivalent_parent
(pipeline,
(COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN |
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
2011-07-07 19:44:56 +00:00
_cogl_pipeline_get_state_for_fragment_codegen (ctx)) &
~COGL_PIPELINE_STATE_LAYERS,
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
2011-07-07 19:44:56 +00:00
_cogl_pipeline_get_layer_state_for_fragment_codegen (ctx) |
COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN);
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state = get_program_state (authority);
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
if (program_state == NULL)
{
/* Check if there is already a similar cached pipeline whose
program state we can share */
if (G_LIKELY (!(COGL_DEBUG_ENABLED
(COGL_DEBUG_DISABLE_PROGRAM_CACHES))))
{
template_pipeline =
_cogl_pipeline_cache_get_combined_template (ctx->pipeline_cache,
authority);
program_state = get_program_state (template_pipeline);
}
if (program_state)
program_state->ref_count++;
else
program_state
= program_state_new (cogl_pipeline_get_n_layers (authority));
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
set_program_state (authority, program_state);
if (template_pipeline)
{
program_state->ref_count++;
set_program_state (template_pipeline, program_state);
}
}
if (authority != pipeline)
{
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state->ref_count++;
set_program_state (pipeline, program_state);
}
}
/* If the program has changed since the last link then we do
* need to relink
*
* Also if the number of texture coordinate attributes in use has
* changed, then delete the program so we can prepend a new
* _cogl_tex_coord[] varying array declaration. */
if ((program_state->program && user_program &&
user_program->age != program_state->user_program_age) ||
(ctx->driver == COGL_DRIVER_GLES2 &&
n_tex_coord_attribs != program_state->n_tex_coord_attribs))
{
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
GE( ctx, glDeleteProgram (program_state->program) );
program_state->program = 0;
}
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
if (program_state->program == 0)
{
GLuint backend_shader;
GSList *l;
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
GE_RET( program_state->program, ctx, glCreateProgram () );
/* Attach all of the shader from the user program */
if (user_program)
{
for (l = user_program->attached_shaders; l; l = l->next)
{
CoglShader *shader = l->data;
_cogl_shader_compile_real (shader, n_tex_coord_attribs);
g_assert (shader->language == COGL_SHADER_LANGUAGE_GLSL);
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
GE( ctx, glAttachShader (program_state->program,
shader->gl_handle) );
}
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state->user_program_age = user_program->age;
}
/* Attach any shaders from the GLSL backends */
if (pipeline->fragend == COGL_PIPELINE_FRAGEND_GLSL &&
(backend_shader = _cogl_pipeline_fragend_glsl_get_shader (pipeline)))
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
GE( ctx, glAttachShader (program_state->program, backend_shader) );
if (pipeline->vertend == COGL_PIPELINE_VERTEND_GLSL &&
(backend_shader = _cogl_pipeline_vertend_glsl_get_shader (pipeline)))
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
GE( ctx, glAttachShader (program_state->program, backend_shader) );
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
link_program (program_state->program);
program_changed = TRUE;
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state->n_tex_coord_attribs = n_tex_coord_attribs;
}
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
gl_program = program_state->program;
if (pipeline->fragend == COGL_PIPELINE_FRAGEND_GLSL)
_cogl_use_fragment_program (gl_program, COGL_PIPELINE_PROGRAM_TYPE_GLSL);
if (pipeline->vertend == COGL_PIPELINE_VERTEND_GLSL)
_cogl_use_vertex_program (gl_program, COGL_PIPELINE_PROGRAM_TYPE_GLSL);
state.unit = 0;
state.gl_program = gl_program;
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
state.program_state = program_state;
if (program_changed)
{
cogl_pipeline_foreach_layer (pipeline,
get_uniform_cb,
&state);
clear_attribute_cache (program_state);
}
state.unit = 0;
state.update_all = (program_changed ||
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state->last_used_for_pipeline != pipeline);
cogl_pipeline_foreach_layer (pipeline,
update_constants_cb,
&state);
#ifdef HAVE_COGL_GLES2
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
2011-07-07 19:44:56 +00:00
if (ctx->driver == COGL_DRIVER_GLES2)
{
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
2011-07-07 19:44:56 +00:00
if (program_changed)
{
int i;
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
clear_flushed_matrix_stacks (program_state);
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
2011-07-07 19:44:56 +00:00
for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++)
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
GE_RET( program_state->builtin_uniform_locations[i], ctx,
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
2011-07-07 19:44:56 +00:00
glGetUniformLocation (gl_program,
builtin_uniforms[i].uniform_name) );
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
GE_RET( program_state->modelview_uniform, ctx,
glGetUniformLocation (gl_program,
"cogl_modelview_matrix") );
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
GE_RET( program_state->projection_uniform, ctx,
glGetUniformLocation (gl_program,
"cogl_projection_matrix") );
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
GE_RET( program_state->mvp_uniform, ctx,
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
2011-07-07 19:44:56 +00:00
glGetUniformLocation (gl_program,
"cogl_modelview_projection_matrix") );
}
if (program_changed ||
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state->last_used_for_pipeline != pipeline)
program_state->dirty_builtin_uniforms = ~(unsigned long) 0;
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
update_builtin_uniforms (pipeline, gl_program, program_state);
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
2011-07-07 19:44:56 +00:00
}
#endif
cogl-pipeline: Add support for setting uniform values This adds the following new public experimental functions to set uniform values on a CoglPipeline: void cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, int uniform_location, float value); void cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, int uniform_location, int value); void cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const float *value); void cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, int uniform_location, int n_components, int count, const int *value); void cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, int uniform_location, int dimensions, int count, gboolean transpose, const float *value); These are similar to the old functions used to set uniforms on a CoglProgram. To get a value to pass in as the uniform_location there is also: int cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, const char *uniform_name); Conceptually the uniform locations are tied to the pipeline so that whenever setting a value for a new pipeline the application is expected to call this function. However in practice the uniform locations are global to the CoglContext. The names are stored in a linked list where the position in the list is the uniform location. The global indices are used so that each pipeline can store a mask of which uniforms it overrides. That way it is quicker to detect which uniforms are different from the last pipeline that used the same CoglProgramState so it can avoid flushing uniforms that haven't changed. Currently the values are not actually compared which means that it will only avoid flushing a uniform if there is a common ancestor that sets the value (or if the same pipeline is being flushed again - in which case the pipeline and its common ancestor are the same thing). The uniform values are stored in the big state of the pipeline as a sparse linked list. A bitmask stores which values have been overridden and only overridden values are stored in the linked list. Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-03 17:20:43 +00:00
_cogl_pipeline_progend_glsl_flush_uniforms (pipeline,
program_state,
gl_program,
program_changed);
if (user_program)
_cogl_program_flush_uniforms (user_program,
gl_program,
program_changed);
/* We need to track the last pipeline that the program was used with
* so know if we need to update all of the uniforms */
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state->last_used_for_pipeline = pipeline;
}
static void
_cogl_pipeline_progend_glsl_pre_change_notify (CoglPipeline *pipeline,
CoglPipelineState change,
const CoglColor *new_color)
{
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
2011-07-07 19:44:56 +00:00
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if ((change & _cogl_pipeline_get_state_for_fragment_codegen (ctx)))
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
dirty_program_state (pipeline);
#ifdef HAVE_COGL_GLES2
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
2011-07-07 19:44:56 +00:00
else if (ctx->driver == COGL_DRIVER_GLES2)
{
int i;
for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++)
if ((change & builtin_uniforms[i].change))
{
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
CoglPipelineProgramState *program_state
= get_program_state (pipeline);
if (program_state)
program_state->dirty_builtin_uniforms |= 1 << i;
return;
}
}
#endif /* HAVE_COGL_GLES2 */
}
/* NB: layers are considered immutable once they have any dependants
* so although multiple pipelines can end up depending on a single
* static layer, we can guarantee that if a layer is being *changed*
* then it can only have one pipeline depending on it.
*
* XXX: Don't forget this is *pre* change, we can't read the new value
* yet!
*/
static void
_cogl_pipeline_progend_glsl_layer_pre_change_notify (
CoglPipeline *owner,
CoglPipelineLayer *layer,
CoglPipelineLayerState change)
{
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
2011-07-07 19:44:56 +00:00
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if ((change & _cogl_pipeline_get_state_for_fragment_codegen (ctx)))
{
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
dirty_program_state (owner);
return;
}
if (change & COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT)
{
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
CoglPipelineProgramState *program_state = get_program_state (owner);
if (program_state)
{
int unit_index = _cogl_pipeline_layer_get_unit_index (layer);
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state->unit_state[unit_index].dirty_combine_constant = TRUE;
}
}
if (change & COGL_PIPELINE_LAYER_STATE_USER_MATRIX)
{
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
CoglPipelineProgramState *program_state = get_program_state (owner);
if (program_state)
{
int unit_index = _cogl_pipeline_layer_get_unit_index (layer);
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state->unit_state[unit_index].dirty_texture_matrix = TRUE;
}
}
}
#ifdef HAVE_COGL_GLES2
static void
flush_modelview_cb (CoglContext *ctx,
gboolean is_identity,
const CoglMatrix *matrix,
void *user_data)
{
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
CoglPipelineProgramState *program_state = user_data;
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
GE( ctx, glUniformMatrix4fv (program_state->modelview_uniform, 1, FALSE,
cogl_matrix_get_array (matrix)) );
}
static void
flush_projection_cb (CoglContext *ctx,
gboolean is_identity,
const CoglMatrix *matrix,
void *user_data)
{
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
CoglPipelineProgramState *program_state = user_data;
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
GE( ctx, glUniformMatrix4fv (program_state->projection_uniform, 1, FALSE,
cogl_matrix_get_array (matrix)) );
}
typedef struct
{
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
CoglPipelineProgramState *program_state;
const CoglMatrix *projection_matrix;
} FlushCombinedData;
static void
flush_combined_step_two_cb (CoglContext *ctx,
gboolean is_identity,
const CoglMatrix *matrix,
void *user_data)
{
FlushCombinedData *data = user_data;
CoglMatrix mvp_matrix;
/* If the modelview is the identity then we can bypass the matrix
multiplication */
if (is_identity)
{
const float *array = cogl_matrix_get_array (data->projection_matrix);
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
GE( ctx, glUniformMatrix4fv (data->program_state->mvp_uniform,
1, FALSE, array ) );
}
else
{
cogl_matrix_multiply (&mvp_matrix,
data->projection_matrix,
matrix);
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
GE( ctx, glUniformMatrix4fv (data->program_state->mvp_uniform, 1, FALSE,
cogl_matrix_get_array (&mvp_matrix)) );
}
}
static void
flush_combined_step_one_cb (CoglContext *ctx,
gboolean is_identity,
const CoglMatrix *matrix,
void *user_data)
{
FlushCombinedData data;
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
data.program_state = user_data;
data.projection_matrix = matrix;
_cogl_prepare_matrix_stack_for_flush (ctx,
ctx->flushed_modelview_stack,
COGL_MATRIX_MODELVIEW,
flush_combined_step_two_cb,
&data);
}
static void
_cogl_pipeline_progend_glsl_pre_paint (CoglPipeline *pipeline)
{
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
CoglPipelineProgramState *program_state = get_program_state (pipeline);
gboolean modelview_changed;
gboolean projection_changed;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
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
2011-07-07 19:44:56 +00:00
if (ctx->driver != COGL_DRIVER_GLES2)
return;
/* We only need to update the matrices if we're using the the GLSL
vertend, but this is a requirement on GLES2 anyway */
_COGL_RETURN_IF_FAIL (pipeline->vertend == COGL_PIPELINE_VERTEND_GLSL);
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state = get_program_state (pipeline);
/* An initial pipeline is flushed while creating the context. At
this point there are no matrices flushed so we can't do
anything */
if (ctx->flushed_modelview_stack == NULL ||
ctx->flushed_projection_stack == NULL)
return;
/* When flushing from the journal the modelview matrix is usually
the identity matrix so it makes sense to optimise this case by
specifically checking whether we already have the identity matrix
which will catch a lot of common cases of redundant flushing */
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
if (program_state->flushed_modelview_is_identity &&
_cogl_matrix_stack_has_identity_flag (ctx->flushed_modelview_stack))
modelview_changed = FALSE;
else
modelview_changed =
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state->flushed_modelview_stack != ctx->flushed_modelview_stack ||
program_state->flushed_modelview_stack_age !=
_cogl_matrix_stack_get_age (program_state->flushed_modelview_stack);
projection_changed =
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state->flushed_projection_stack != ctx->flushed_projection_stack ||
program_state->flushed_projection_stack_age !=
_cogl_matrix_stack_get_age (program_state->flushed_projection_stack);
if (modelview_changed)
{
cogl_object_ref (ctx->flushed_modelview_stack);
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
if (program_state->flushed_modelview_stack)
cogl_object_unref (program_state->flushed_modelview_stack);
program_state->flushed_modelview_stack = ctx->flushed_modelview_stack;
program_state->flushed_modelview_stack_age =
_cogl_matrix_stack_get_age (ctx->flushed_modelview_stack);
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state->flushed_modelview_is_identity =
_cogl_matrix_stack_has_identity_flag (ctx->flushed_modelview_stack);
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
if (program_state->modelview_uniform != -1)
_cogl_prepare_matrix_stack_for_flush (ctx,
program_state
->flushed_modelview_stack,
COGL_MATRIX_MODELVIEW,
flush_modelview_cb,
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state);
}
if (projection_changed)
{
cogl_object_ref (ctx->flushed_projection_stack);
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
if (program_state->flushed_projection_stack)
cogl_object_unref (program_state->flushed_projection_stack);
program_state->flushed_projection_stack = ctx->flushed_projection_stack;
program_state->flushed_projection_stack_age =
_cogl_matrix_stack_get_age (ctx->flushed_projection_stack);
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
if (program_state->projection_uniform != -1)
_cogl_prepare_matrix_stack_for_flush (ctx,
program_state
->flushed_projection_stack,
COGL_MATRIX_PROJECTION,
flush_projection_cb,
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state);
}
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
if (program_state->mvp_uniform != -1 &&
(modelview_changed || projection_changed))
_cogl_prepare_matrix_stack_for_flush (ctx,
ctx->flushed_projection_stack,
COGL_MATRIX_PROJECTION,
flush_combined_step_one_cb,
pipeline: Unify how the backends store private data Previously the fragends had a separate private data pointer which was used by the GLSL and ARBfp fragends to store a tiny struct containing a single pointer to the ref-counted shader state. The space for the private data pointer is reserved in all of the pipelines for all of the potential backends. The vertends and progends however did this differently by directly storing the pointer to the ref counted data using cogl_object_set_user_data. This patch unifies the different methods so that they all use cogl_object_set_user_data and the fragends don't bother with the separate tiny allocation for the private data. The private data pointer array has been removed from CoglPipeline and the corresponding fragend virtual to free the private data has also been removed because this can instead be done with the destroy notify from the object user data. The variable names used have been unified so that all of the vertends and fragends name their data struct CoglPipelineShaderState and use a variable called shader_state to refer to it. The progend uses CoglPipelineProgramState and a variable called program_state. This should also fix two potential bugs. the ARBfp fragend was apprently leaking a reference to the private state when it creates the private data because it was adding a reference before stroring the pointer to the newly allocated data but the ref count is already set to 1 on creation. The other potential bug is that the free function for CoglPipeline was only calling the free_priv virtual for the currently used fragend of the pipeline. The design of the fragends is meant to allow a pipeline to have multiple fragend priv datas because a child pipeline could be attaching its fragend data to the ancestor and its allowed to pick a different fragend.
2011-06-30 12:39:48 +00:00
program_state);
}
static void
update_float_uniform (CoglPipeline *pipeline,
int uniform_location,
void *getter_func)
{
float (* float_getter_func) (CoglPipeline *) = getter_func;
float value;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
value = float_getter_func (pipeline);
GE( ctx, glUniform1f (uniform_location, value) );
}
#endif
const CoglPipelineProgend _cogl_pipeline_glsl_progend =
{
_cogl_pipeline_progend_glsl_end,
_cogl_pipeline_progend_glsl_pre_change_notify,
_cogl_pipeline_progend_glsl_layer_pre_change_notify,
#ifdef HAVE_COGL_GLES2
_cogl_pipeline_progend_glsl_pre_paint
#else
NULL
#endif
};
#endif /* COGL_PIPELINE_PROGEND_GLSL */