2009-04-27 14:48:12 +00:00
|
|
|
/*
|
|
|
|
* Cogl
|
|
|
|
*
|
|
|
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
|
|
|
*
|
2013-03-09 20:00:53 +00:00
|
|
|
* Copyright (C) 2008,2009,2010,2013 Intel Corporation.
|
2009-04-27 14:48:12 +00:00
|
|
|
*
|
|
|
|
* 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
|
2010-04-08 11:21:04 +00:00
|
|
|
* License along with this library. If not, see
|
|
|
|
* <http://www.gnu.org/licenses/>.
|
2010-03-01 12:56:10 +00:00
|
|
|
*
|
|
|
|
*
|
2009-04-27 14:48:12 +00:00
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Robert Bragg <robert@linux.intel.com>
|
|
|
|
*/
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2010-07-25 20:36:41 +00:00
|
|
|
#include "cogl-debug.h"
|
2010-11-04 22:25:52 +00:00
|
|
|
#include "cogl-context-private.h"
|
2010-06-22 13:02:17 +00:00
|
|
|
#include "cogl-object.h"
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
#include "cogl-pipeline-private.h"
|
|
|
|
#include "cogl-pipeline-opengl-private.h"
|
2011-09-07 22:44:37 +00:00
|
|
|
#include "cogl-pipeline-state-private.h"
|
2011-09-07 23:42:22 +00:00
|
|
|
#include "cogl-pipeline-layer-state-private.h"
|
2009-01-29 13:40:37 +00:00
|
|
|
#include "cogl-texture-private.h"
|
2009-05-10 23:40:41 +00:00
|
|
|
#include "cogl-blend-string.h"
|
2010-02-10 18:18:30 +00:00
|
|
|
#include "cogl-journal-private.h"
|
2010-04-08 11:21:04 +00:00
|
|
|
#include "cogl-color-private.h"
|
2010-11-04 13:57:36 +00:00
|
|
|
#include "cogl-util.h"
|
2010-04-08 11:21:04 +00:00
|
|
|
#include "cogl-profile.h"
|
2011-04-14 17:12:03 +00:00
|
|
|
#include "cogl-depth-state-private.h"
|
2012-02-17 21:46:39 +00:00
|
|
|
#include "cogl1-context.h"
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
|
|
|
|
#include <glib.h>
|
2009-11-18 00:26:09 +00:00
|
|
|
#include <glib/gprintf.h>
|
2008-12-23 23:35:49 +00:00
|
|
|
#include <string.h>
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
static void _cogl_pipeline_free (CoglPipeline *tex);
|
|
|
|
static void recursively_free_layer_caches (CoglPipeline *pipeline);
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool _cogl_pipeline_is_weak (CoglPipeline *pipeline);
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
|
2010-11-29 16:56:41 +00:00
|
|
|
const CoglPipelineFragend *_cogl_pipeline_fragends[COGL_PIPELINE_N_FRAGENDS];
|
2010-11-29 18:32:21 +00:00
|
|
|
const CoglPipelineVertend *_cogl_pipeline_vertends[COGL_PIPELINE_N_VERTENDS];
|
2010-12-02 14:00:46 +00:00
|
|
|
/* The 'MAX' here is so that we don't define an empty array when there
|
|
|
|
are no progends */
|
|
|
|
const CoglPipelineProgend *
|
|
|
|
_cogl_pipeline_progends[MAX (COGL_PIPELINE_N_PROGENDS, 1)];
|
2010-04-26 09:01:43 +00:00
|
|
|
|
2010-11-29 16:56:41 +00:00
|
|
|
#ifdef COGL_PIPELINE_FRAGEND_GLSL
|
|
|
|
#include "cogl-pipeline-fragend-glsl-private.h"
|
2010-06-15 15:44:52 +00:00
|
|
|
#endif
|
2010-11-29 16:56:41 +00:00
|
|
|
#ifdef COGL_PIPELINE_FRAGEND_ARBFP
|
|
|
|
#include "cogl-pipeline-fragend-arbfp-private.h"
|
2010-06-15 15:44:52 +00:00
|
|
|
#endif
|
2010-11-29 16:56:41 +00:00
|
|
|
#ifdef COGL_PIPELINE_FRAGEND_FIXED
|
|
|
|
#include "cogl-pipeline-fragend-fixed-private.h"
|
2010-04-26 09:01:43 +00:00
|
|
|
#endif
|
|
|
|
|
2010-12-02 20:48:45 +00:00
|
|
|
#ifdef COGL_PIPELINE_VERTEND_GLSL
|
|
|
|
#include "cogl-pipeline-vertend-glsl-private.h"
|
|
|
|
#endif
|
2010-11-29 18:32:21 +00:00
|
|
|
#ifdef COGL_PIPELINE_VERTEND_FIXED
|
|
|
|
#include "cogl-pipeline-vertend-fixed-private.h"
|
|
|
|
#endif
|
|
|
|
|
2012-09-25 20:08:10 +00:00
|
|
|
#ifdef COGL_PIPELINE_PROGEND_FIXED_ARBFP
|
|
|
|
#include "cogl-pipeline-progend-fixed-arbfp-private.h"
|
|
|
|
#endif
|
2011-11-29 14:21:07 +00:00
|
|
|
#ifdef COGL_PIPELINE_PROGEND_FIXED
|
|
|
|
#include "cogl-pipeline-progend-fixed-private.h"
|
|
|
|
#endif
|
|
|
|
#ifdef COGL_PIPELINE_PROGEND_GLSL
|
|
|
|
#include "cogl-pipeline-progend-glsl-private.h"
|
|
|
|
#endif
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
COGL_OBJECT_DEFINE (Pipeline, pipeline);
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
/*
|
2010-10-27 17:54:57 +00:00
|
|
|
* This initializes the first pipeline owned by the Cogl context. All
|
|
|
|
* subsequently instantiated pipelines created via the cogl_pipeline_new()
|
|
|
|
* API will initially be a copy of this pipeline.
|
2010-04-08 11:21:04 +00:00
|
|
|
*
|
2010-10-27 17:54:57 +00:00
|
|
|
* The default pipeline is the topmost ancester for all pipelines.
|
2010-04-08 11:21:04 +00:00
|
|
|
*/
|
2009-11-11 12:50:48 +00:00
|
|
|
void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_init_default_pipeline (void)
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
/* Create new - blank - pipeline */
|
|
|
|
CoglPipeline *pipeline = g_slice_new0 (CoglPipeline);
|
2010-11-04 13:57:36 +00:00
|
|
|
/* XXX: NB: It's important that we zero this to avoid polluting
|
|
|
|
* pipeline hash values with un-initialized data */
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipelineBigState *big_state = g_slice_new0 (CoglPipelineBigState);
|
|
|
|
CoglPipelineLightingState *lighting_state = &big_state->lighting_state;
|
|
|
|
CoglPipelineAlphaFuncState *alpha_state = &big_state->alpha_state;
|
|
|
|
CoglPipelineBlendState *blend_state = &big_state->blend_state;
|
2011-07-11 01:27:54 +00:00
|
|
|
CoglPipelineLogicOpsState *logic_ops_state = &big_state->logic_ops_state;
|
2011-09-15 10:25:39 +00:00
|
|
|
CoglPipelineCullFaceState *cull_face_state = &big_state->cull_face_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
|
|
|
CoglPipelineUniformsState *uniforms_state = &big_state->uniforms_state;
|
2008-12-22 16:19:49 +00:00
|
|
|
|
2009-11-11 12:50:48 +00:00
|
|
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
|
|
|
|
2010-12-02 14:00:46 +00:00
|
|
|
/* Take this opportunity to setup the backends... */
|
2010-11-29 16:56:41 +00:00
|
|
|
#ifdef COGL_PIPELINE_FRAGEND_GLSL
|
|
|
|
_cogl_pipeline_fragends[COGL_PIPELINE_FRAGEND_GLSL] =
|
|
|
|
&_cogl_pipeline_glsl_fragend;
|
2010-06-15 15:44:52 +00:00
|
|
|
#endif
|
2010-11-29 16:56:41 +00:00
|
|
|
#ifdef COGL_PIPELINE_FRAGEND_ARBFP
|
|
|
|
_cogl_pipeline_fragends[COGL_PIPELINE_FRAGEND_ARBFP] =
|
|
|
|
&_cogl_pipeline_arbfp_fragend;
|
2010-06-15 15:44:52 +00:00
|
|
|
#endif
|
2010-11-29 16:56:41 +00:00
|
|
|
#ifdef COGL_PIPELINE_FRAGEND_FIXED
|
|
|
|
_cogl_pipeline_fragends[COGL_PIPELINE_FRAGEND_FIXED] =
|
|
|
|
&_cogl_pipeline_fixed_fragend;
|
2010-06-15 15:44:52 +00:00
|
|
|
#endif
|
2012-09-25 20:08:10 +00:00
|
|
|
#ifdef COGL_PIPELINE_PROGEND_FIXED
|
|
|
|
_cogl_pipeline_progends[COGL_PIPELINE_PROGEND_FIXED_ARBFP] =
|
|
|
|
&_cogl_pipeline_fixed_arbfp_progend;
|
|
|
|
#endif
|
2011-11-29 14:21:07 +00:00
|
|
|
#ifdef COGL_PIPELINE_PROGEND_FIXED
|
|
|
|
_cogl_pipeline_progends[COGL_PIPELINE_PROGEND_FIXED] =
|
|
|
|
&_cogl_pipeline_fixed_progend;
|
|
|
|
#endif
|
2010-12-02 14:00:46 +00:00
|
|
|
#ifdef COGL_PIPELINE_PROGEND_GLSL
|
|
|
|
_cogl_pipeline_progends[COGL_PIPELINE_PROGEND_GLSL] =
|
|
|
|
&_cogl_pipeline_glsl_progend;
|
|
|
|
#endif
|
2010-06-15 15:44:52 +00:00
|
|
|
|
2010-12-02 20:48:45 +00:00
|
|
|
#ifdef COGL_PIPELINE_VERTEND_GLSL
|
|
|
|
_cogl_pipeline_vertends[COGL_PIPELINE_VERTEND_GLSL] =
|
|
|
|
&_cogl_pipeline_glsl_vertend;
|
|
|
|
#endif
|
2010-11-29 18:32:21 +00:00
|
|
|
#ifdef COGL_PIPELINE_VERTEND_FIXED
|
|
|
|
_cogl_pipeline_vertends[COGL_PIPELINE_VERTEND_FIXED] =
|
|
|
|
&_cogl_pipeline_fixed_vertend;
|
|
|
|
#endif
|
|
|
|
|
2011-09-08 23:40:06 +00:00
|
|
|
_cogl_pipeline_node_init (COGL_NODE (pipeline));
|
2010-07-08 10:49:31 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->is_weak = FALSE;
|
|
|
|
pipeline->journal_ref_count = 0;
|
2012-09-25 20:08:10 +00:00
|
|
|
pipeline->progend = COGL_PIPELINE_PROGEND_UNDEFINED;
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->differences = COGL_PIPELINE_STATE_ALL_SPARSE;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->real_blend_enable = FALSE;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->blend_enable = COGL_PIPELINE_BLEND_ENABLE_AUTOMATIC;
|
|
|
|
pipeline->layer_differences = NULL;
|
|
|
|
pipeline->n_layers = 0;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->big_state = big_state;
|
|
|
|
pipeline->has_big_state = TRUE;
|
2010-04-26 09:01:43 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->static_breadcrumb = "default pipeline";
|
|
|
|
pipeline->has_static_breadcrumb = TRUE;
|
2010-05-18 23:36:31 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->age = 0;
|
2010-05-27 14:19:15 +00:00
|
|
|
|
2008-12-23 23:35:49 +00:00
|
|
|
/* Use the same defaults as the GL spec... */
|
2010-10-27 17:54:57 +00:00
|
|
|
cogl_color_init_from_4ub (&pipeline->color, 0xff, 0xff, 0xff, 0xff);
|
2008-12-23 23:35:49 +00:00
|
|
|
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
/* Use the same defaults as the GL spec... */
|
2010-04-08 11:21:04 +00:00
|
|
|
lighting_state->ambient[0] = 0.2;
|
|
|
|
lighting_state->ambient[1] = 0.2;
|
|
|
|
lighting_state->ambient[2] = 0.2;
|
|
|
|
lighting_state->ambient[3] = 1.0;
|
|
|
|
|
|
|
|
lighting_state->diffuse[0] = 0.8;
|
|
|
|
lighting_state->diffuse[1] = 0.8;
|
|
|
|
lighting_state->diffuse[2] = 0.8;
|
|
|
|
lighting_state->diffuse[3] = 1.0;
|
|
|
|
|
|
|
|
lighting_state->specular[0] = 0;
|
|
|
|
lighting_state->specular[1] = 0;
|
|
|
|
lighting_state->specular[2] = 0;
|
|
|
|
lighting_state->specular[3] = 1.0;
|
|
|
|
|
|
|
|
lighting_state->emission[0] = 0;
|
|
|
|
lighting_state->emission[1] = 0;
|
|
|
|
lighting_state->emission[2] = 0;
|
|
|
|
lighting_state->emission[3] = 1.0;
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
|
2010-07-20 16:34:04 +00:00
|
|
|
lighting_state->shininess = 0.0f;
|
|
|
|
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
/* Use the same defaults as the GL spec... */
|
2010-10-27 17:54:57 +00:00
|
|
|
alpha_state->alpha_func = COGL_PIPELINE_ALPHA_FUNC_ALWAYS;
|
2010-04-08 11:21:04 +00:00
|
|
|
alpha_state->alpha_func_reference = 0.0;
|
2008-12-22 16:19:49 +00:00
|
|
|
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
/* Not the same as the GL default, but seems saner... */
|
2011-07-07 19:44:56 +00:00
|
|
|
#if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL)
|
2010-04-08 11:21:04 +00:00
|
|
|
blend_state->blend_equation_rgb = GL_FUNC_ADD;
|
|
|
|
blend_state->blend_equation_alpha = GL_FUNC_ADD;
|
|
|
|
blend_state->blend_src_factor_alpha = GL_ONE;
|
|
|
|
blend_state->blend_dst_factor_alpha = GL_ONE_MINUS_SRC_ALPHA;
|
|
|
|
cogl_color_init_from_4ub (&blend_state->blend_constant,
|
|
|
|
0x00, 0x00, 0x00, 0x00);
|
2009-05-10 23:40:41 +00:00
|
|
|
#endif
|
2010-04-08 11:21:04 +00:00
|
|
|
blend_state->blend_src_factor_rgb = GL_ONE;
|
|
|
|
blend_state->blend_dst_factor_rgb = GL_ONE_MINUS_SRC_ALPHA;
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
big_state->user_program = COGL_INVALID_HANDLE;
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
|
2012-03-31 20:30:26 +00:00
|
|
|
cogl_depth_state_init (&big_state->depth_state);
|
2010-05-26 10:33:32 +00:00
|
|
|
|
2010-03-22 09:32:17 +00:00
|
|
|
big_state->point_size = 1.0f;
|
|
|
|
|
2011-07-11 01:27:54 +00:00
|
|
|
logic_ops_state->color_mask = COGL_COLOR_MASK_ALL;
|
|
|
|
|
2011-09-15 10:25:39 +00:00
|
|
|
cull_face_state->mode = COGL_PIPELINE_CULL_FACE_MODE_NONE;
|
|
|
|
cull_face_state->front_winding = COGL_WINDING_COUNTER_CLOCKWISE;
|
|
|
|
|
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_init (&uniforms_state->override_mask);
|
|
|
|
_cogl_bitmask_init (&uniforms_state->changed_mask);
|
2011-11-04 17:56:44 +00:00
|
|
|
uniforms_state->override_values = NULL;
|
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
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
ctx->default_pipeline = _cogl_pipeline_object_new (pipeline);
|
2009-11-11 12:50:48 +00:00
|
|
|
}
|
|
|
|
|
2010-05-27 19:04:49 +00:00
|
|
|
static void
|
2011-09-08 23:40:06 +00:00
|
|
|
_cogl_pipeline_unparent (CoglNode *pipeline)
|
2010-05-27 19:04:49 +00:00
|
|
|
{
|
2010-07-08 10:49:31 +00:00
|
|
|
/* Chain up */
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_node_unparent_real (pipeline);
|
2010-07-08 10:49:31 +00:00
|
|
|
}
|
2010-05-27 19:04:49 +00:00
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2011-09-08 23:40:06 +00:00
|
|
|
recursively_free_layer_caches_cb (CoglNode *node,
|
2010-07-08 10:49:31 +00:00
|
|
|
void *user_data)
|
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
recursively_free_layer_caches (COGL_PIPELINE (node));
|
2010-07-08 10:49:31 +00:00
|
|
|
return TRUE;
|
2010-05-27 19:04:49 +00:00
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
/* This recursively frees the layers_cache of a pipeline and all of
|
2010-06-10 18:03:57 +00:00
|
|
|
* its descendants.
|
|
|
|
*
|
2010-10-27 17:54:57 +00:00
|
|
|
* For instance if we change a pipelines ->layer_differences list
|
|
|
|
* then that pipeline and all of its descendants may now have
|
2010-06-10 18:03:57 +00:00
|
|
|
* incorrect layer caches. */
|
|
|
|
static void
|
2010-10-27 17:54:57 +00:00
|
|
|
recursively_free_layer_caches (CoglPipeline *pipeline)
|
2010-06-10 18:03:57 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
/* Note: we maintain the invariable that if a pipeline already has a
|
2010-06-10 18:03:57 +00:00
|
|
|
* dirty layers_cache then so do all of its descendants. */
|
2010-10-27 17:54:57 +00:00
|
|
|
if (pipeline->layers_cache_dirty)
|
2010-06-10 18:03:57 +00:00
|
|
|
return;
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (G_UNLIKELY (pipeline->layers_cache != pipeline->short_layers_cache))
|
|
|
|
g_slice_free1 (sizeof (CoglPipelineLayer *) * pipeline->n_layers,
|
|
|
|
pipeline->layers_cache);
|
|
|
|
pipeline->layers_cache_dirty = TRUE;
|
2010-06-10 18:03:57 +00:00
|
|
|
|
2011-09-08 23:40:06 +00:00
|
|
|
_cogl_pipeline_node_foreach_child (COGL_NODE (pipeline),
|
2010-07-08 10:49:31 +00:00
|
|
|
recursively_free_layer_caches_cb,
|
|
|
|
NULL);
|
2010-06-10 18:03:57 +00:00
|
|
|
}
|
|
|
|
|
2010-05-27 19:04:49 +00:00
|
|
|
static void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_set_parent (CoglPipeline *pipeline,
|
|
|
|
CoglPipeline *parent,
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool take_strong_reference)
|
2010-05-27 19:04:49 +00:00
|
|
|
{
|
2010-07-08 10:49:31 +00:00
|
|
|
/* Chain up */
|
2011-09-08 23:40:06 +00:00
|
|
|
_cogl_pipeline_node_set_parent_real (COGL_NODE (pipeline),
|
|
|
|
COGL_NODE (parent),
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_unparent,
|
2010-08-09 15:01:17 +00:00
|
|
|
take_strong_reference);
|
2010-06-14 21:20:27 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
/* Since we just changed the ancestry of the pipeline its cache of
|
2010-06-14 21:20:27 +00:00
|
|
|
* layers could now be invalid so free it... */
|
2010-10-27 17:54:57 +00:00
|
|
|
if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS)
|
|
|
|
recursively_free_layer_caches (pipeline);
|
2010-06-10 18:03:57 +00:00
|
|
|
|
2010-11-29 18:32:21 +00:00
|
|
|
/* If the backends are also caching state along with the pipeline
|
|
|
|
* that depends on the pipeline's ancestry then it may be notified
|
|
|
|
* here...
|
2010-06-10 18:03:57 +00:00
|
|
|
*/
|
2012-09-25 20:08:10 +00:00
|
|
|
if (pipeline->progend != COGL_PIPELINE_PROGEND_UNDEFINED)
|
2010-07-10 02:40:47 +00:00
|
|
|
{
|
2012-09-25 20:08:10 +00:00
|
|
|
const CoglPipelineProgend *progend =
|
|
|
|
_cogl_pipeline_progends[pipeline->progend];
|
2010-11-29 16:56:41 +00:00
|
|
|
const CoglPipelineFragend *fragend =
|
2012-09-25 20:08:10 +00:00
|
|
|
_cogl_pipeline_fragends[progend->fragend];
|
|
|
|
|
|
|
|
/* Currently only the fragends ever care about reparenting of
|
|
|
|
* pipelines... */
|
|
|
|
if (fragend->pipeline_set_parent_notify)
|
|
|
|
fragend->pipeline_set_parent_notify (pipeline);
|
2010-07-10 02:40:47 +00:00
|
|
|
}
|
2010-05-27 19:04:49 +00:00
|
|
|
}
|
|
|
|
|
2010-08-09 15:01:17 +00:00
|
|
|
static void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_promote_weak_ancestors (CoglPipeline *strong)
|
2010-08-09 15:01:17 +00:00
|
|
|
{
|
2011-09-08 23:40:06 +00:00
|
|
|
CoglNode *n;
|
2010-08-09 15:01:17 +00:00
|
|
|
|
2011-10-13 21:34:30 +00:00
|
|
|
_COGL_RETURN_IF_FAIL (!strong->is_weak);
|
2010-08-09 15:01:17 +00:00
|
|
|
|
2011-07-06 11:28:07 +00:00
|
|
|
/* If the parent of strong is weak, then we want to promote it by
|
|
|
|
taking a reference on strong's grandparent. We don't need to take
|
|
|
|
a reference on strong's direct parent */
|
2010-08-09 15:01:17 +00:00
|
|
|
|
2011-09-08 23:40:06 +00:00
|
|
|
if (COGL_NODE (strong)->parent == NULL)
|
2011-07-06 11:28:07 +00:00
|
|
|
return;
|
2010-08-09 15:01:17 +00:00
|
|
|
|
2011-09-08 23:40:06 +00:00
|
|
|
for (n = COGL_NODE (strong)->parent;
|
2011-07-06 11:28:07 +00:00
|
|
|
/* We can assume that all weak pipelines have a parent */
|
|
|
|
COGL_PIPELINE (n)->is_weak;
|
|
|
|
n = n->parent)
|
|
|
|
/* 'n' is weak so we take a reference on its parent */
|
|
|
|
cogl_object_ref (n->parent);
|
2010-08-09 15:01:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_revert_weak_ancestors (CoglPipeline *strong)
|
2010-08-09 15:01:17 +00:00
|
|
|
{
|
2011-09-08 23:40:06 +00:00
|
|
|
CoglNode *n;
|
2010-08-09 15:01:17 +00:00
|
|
|
|
2011-10-13 21:34:30 +00:00
|
|
|
_COGL_RETURN_IF_FAIL (!strong->is_weak);
|
2010-08-09 15:01:17 +00:00
|
|
|
|
2011-07-06 11:28:07 +00:00
|
|
|
/* This reverts the effect of calling
|
|
|
|
_cogl_pipeline_promote_weak_ancestors */
|
2010-08-09 15:01:17 +00:00
|
|
|
|
2011-09-08 23:40:06 +00:00
|
|
|
if (COGL_NODE (strong)->parent == NULL)
|
2011-07-06 11:28:07 +00:00
|
|
|
return;
|
2010-08-09 15:01:17 +00:00
|
|
|
|
2011-09-08 23:40:06 +00:00
|
|
|
for (n = COGL_NODE (strong)->parent;
|
2011-07-06 11:28:07 +00:00
|
|
|
/* We can assume that all weak pipelines have a parent */
|
|
|
|
COGL_PIPELINE (n)->is_weak;
|
|
|
|
n = n->parent)
|
|
|
|
/* 'n' is weak so we unref its parent */
|
|
|
|
cogl_object_unref (n->parent);
|
2010-08-09 15:01:17 +00:00
|
|
|
}
|
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
/* XXX: Always have an eye out for opportunities to lower the cost of
|
2010-10-27 17:54:57 +00:00
|
|
|
* cogl_pipeline_copy. */
|
|
|
|
static CoglPipeline *
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
_cogl_pipeline_copy (CoglPipeline *src, CoglBool is_weak)
|
2009-11-11 12:50:48 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *pipeline = g_slice_new (CoglPipeline);
|
2009-11-11 12:50:48 +00:00
|
|
|
|
2011-09-08 23:40:06 +00:00
|
|
|
_cogl_pipeline_node_init (COGL_NODE (pipeline));
|
2009-11-11 12:50:48 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->is_weak = is_weak;
|
2010-05-27 19:04:49 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->journal_ref_count = 0;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->differences = 0;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->has_big_state = FALSE;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
/* NB: real_blend_enable isn't a sparse property, it's valid for
|
2010-10-27 17:54:57 +00:00
|
|
|
* every pipeline node so we have fast access to it. */
|
|
|
|
pipeline->real_blend_enable = src->real_blend_enable;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
/* XXX:
|
|
|
|
* consider generalizing the idea of "cached" properties. These
|
|
|
|
* would still have an authority like other sparse properties but
|
|
|
|
* you wouldn't have to walk up the ancestry to find the authority
|
2010-10-27 17:54:57 +00:00
|
|
|
* because the value would be cached directly in each pipeline.
|
2010-04-08 11:21:04 +00:00
|
|
|
*/
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->layers_cache_dirty = TRUE;
|
2011-07-12 13:49:21 +00:00
|
|
|
pipeline->deprecated_get_layers_list = NULL;
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->deprecated_get_layers_list_dirty = TRUE;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2012-09-25 20:08:10 +00:00
|
|
|
pipeline->progend = src->progend;
|
2010-11-29 18:32:21 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->has_static_breadcrumb = FALSE;
|
2010-05-18 23:36:31 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->age = 0;
|
2010-05-27 14:19:15 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_set_parent (pipeline, src, !is_weak);
|
2010-08-09 15:01:17 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
/* The semantics for copying a weak pipeline are that we promote all
|
|
|
|
* weak ancestors to temporarily become strong pipelines until the
|
2010-08-09 15:01:17 +00:00
|
|
|
* copy is freed. */
|
|
|
|
if (!is_weak)
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_promote_weak_ancestors (pipeline);
|
2010-06-10 18:03:57 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
return _cogl_pipeline_object_new (pipeline);
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *
|
|
|
|
cogl_pipeline_copy (CoglPipeline *src)
|
2010-08-09 15:01:17 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
return _cogl_pipeline_copy (src, FALSE);
|
2010-08-09 15:01:17 +00:00
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *
|
|
|
|
_cogl_pipeline_weak_copy (CoglPipeline *pipeline,
|
|
|
|
CoglPipelineDestroyCallback callback,
|
2010-08-09 15:01:17 +00:00
|
|
|
void *user_data)
|
2010-05-27 19:04:49 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *copy;
|
|
|
|
CoglPipeline *copy_pipeline;
|
2010-05-27 19:04:49 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
copy = _cogl_pipeline_copy (pipeline, TRUE);
|
|
|
|
copy_pipeline = COGL_PIPELINE (copy);
|
|
|
|
copy_pipeline->destroy_callback = callback;
|
|
|
|
copy_pipeline->destroy_data = user_data;
|
2010-05-27 19:04:49 +00:00
|
|
|
|
|
|
|
return copy;
|
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *
|
2012-02-18 16:03:10 +00:00
|
|
|
cogl_pipeline_new (CoglContext *context)
|
2009-11-11 12:50:48 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *new;
|
2010-05-18 23:36:31 +00:00
|
|
|
|
2012-02-18 16:03:10 +00:00
|
|
|
new = cogl_pipeline_copy (context->default_pipeline);
|
2013-05-30 14:42:35 +00:00
|
|
|
#ifdef COGL_DEBUG_ENABLED
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_set_static_breadcrumb (new, "new");
|
2013-05-30 14:42:35 +00:00
|
|
|
#endif
|
2010-05-18 23:36:31 +00:00
|
|
|
return new;
|
2009-11-11 12:50:48 +00:00
|
|
|
}
|
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2011-09-08 23:40:06 +00:00
|
|
|
destroy_weak_children_cb (CoglNode *node,
|
2010-08-09 15:01:17 +00:00
|
|
|
void *user_data)
|
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *pipeline = COGL_PIPELINE (node);
|
2010-08-09 15:01:17 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (_cogl_pipeline_is_weak (pipeline))
|
2010-08-09 15:01:17 +00:00
|
|
|
{
|
2011-09-08 23:40:06 +00:00
|
|
|
_cogl_pipeline_node_foreach_child (COGL_NODE (pipeline),
|
2010-08-09 15:01:17 +00:00
|
|
|
destroy_weak_children_cb,
|
|
|
|
NULL);
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->destroy_callback (pipeline, pipeline->destroy_data);
|
2011-09-08 23:40:06 +00:00
|
|
|
_cogl_pipeline_unparent (COGL_NODE (pipeline));
|
2010-08-09 15:01:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
static void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_free (CoglPipeline *pipeline)
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
if (!pipeline->is_weak)
|
|
|
|
_cogl_pipeline_revert_weak_ancestors (pipeline);
|
2010-08-09 15:01:17 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
/* Weak pipelines don't take a reference on their parent */
|
2011-09-08 23:40:06 +00:00
|
|
|
_cogl_pipeline_node_foreach_child (COGL_NODE (pipeline),
|
2010-08-09 15:01:17 +00:00
|
|
|
destroy_weak_children_cb,
|
|
|
|
NULL);
|
|
|
|
|
2013-06-08 22:03:25 +00:00
|
|
|
g_assert (_cogl_list_empty (&COGL_NODE (pipeline)->children));
|
2010-08-09 15:01:17 +00:00
|
|
|
|
2011-09-08 23:40:06 +00:00
|
|
|
_cogl_pipeline_unparent (COGL_NODE (pipeline));
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (pipeline->differences & COGL_PIPELINE_STATE_USER_SHADER &&
|
|
|
|
pipeline->big_state->user_program)
|
|
|
|
cogl_handle_unref (pipeline->big_state->user_program);
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
|
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 (pipeline->differences & COGL_PIPELINE_STATE_UNIFORMS)
|
|
|
|
{
|
|
|
|
CoglPipelineUniformsState *uniforms_state
|
|
|
|
= &pipeline->big_state->uniforms_state;
|
2011-11-04 17:56:44 +00:00
|
|
|
int n_overrides = _cogl_bitmask_popcount (&uniforms_state->override_mask);
|
|
|
|
int i;
|
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
|
|
|
|
2011-11-04 17:56:44 +00:00
|
|
|
for (i = 0; i < n_overrides; i++)
|
|
|
|
_cogl_boxed_value_destroy (uniforms_state->override_values + i);
|
|
|
|
g_free (uniforms_state->override_values);
|
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_destroy (&uniforms_state->override_mask);
|
|
|
|
_cogl_bitmask_destroy (&uniforms_state->changed_mask);
|
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE)
|
|
|
|
g_slice_free (CoglPipelineBigState, pipeline->big_state);
|
2009-02-19 09:01:18 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
g_list_foreach (pipeline->layer_differences,
|
2010-06-22 13:02:17 +00:00
|
|
|
(GFunc)cogl_object_unref, NULL);
|
2010-10-27 17:54:57 +00:00
|
|
|
g_list_free (pipeline->layer_differences);
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
2009-02-19 09:01:18 +00:00
|
|
|
|
2011-11-17 16:52:21 +00:00
|
|
|
if (pipeline->differences & COGL_PIPELINE_STATE_VERTEX_SNIPPETS)
|
|
|
|
_cogl_pipeline_snippet_list_free (&pipeline->big_state->vertex_snippets);
|
|
|
|
|
|
|
|
if (pipeline->differences & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS)
|
|
|
|
_cogl_pipeline_snippet_list_free (&pipeline->big_state->fragment_snippets);
|
|
|
|
|
2011-07-06 18:18:22 +00:00
|
|
|
g_list_free (pipeline->deprecated_get_layers_list);
|
|
|
|
|
2011-10-12 14:12:34 +00:00
|
|
|
recursively_free_layer_caches (pipeline);
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
g_slice_free (CoglPipeline, pipeline);
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 17:46:42 +00:00
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_get_real_blend_enabled (CoglPipeline *pipeline)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2011-10-13 21:34:30 +00:00
|
|
|
_COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE);
|
2009-04-02 10:50:44 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
return pipeline->real_blend_enable;
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
2009-04-02 10:50:44 +00:00
|
|
|
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 17:46:42 +00:00
|
|
|
static void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_update_layers_cache (CoglPipeline *pipeline)
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 17:46:42 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
/* Note: we assume this pipeline is a _LAYERS authority */
|
2010-04-08 11:21:04 +00:00
|
|
|
int n_layers;
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *current;
|
2010-04-08 11:21:04 +00:00
|
|
|
int layers_found;
|
2010-04-26 09:01:43 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (G_LIKELY (!pipeline->layers_cache_dirty) ||
|
|
|
|
pipeline->n_layers == 0)
|
2010-04-08 11:21:04 +00:00
|
|
|
return;
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->layers_cache_dirty = FALSE;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
n_layers = pipeline->n_layers;
|
|
|
|
if (G_LIKELY (n_layers < G_N_ELEMENTS (pipeline->short_layers_cache)))
|
2010-04-26 09:01:43 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->layers_cache = pipeline->short_layers_cache;
|
|
|
|
memset (pipeline->layers_cache, 0,
|
|
|
|
sizeof (CoglPipelineLayer *) *
|
|
|
|
G_N_ELEMENTS (pipeline->short_layers_cache));
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->layers_cache =
|
|
|
|
g_slice_alloc0 (sizeof (CoglPipelineLayer *) * n_layers);
|
2010-04-26 09:01:43 +00:00
|
|
|
}
|
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
/* Notes:
|
2010-04-26 09:01:43 +00:00
|
|
|
*
|
2010-10-27 17:54:57 +00:00
|
|
|
* Each pipeline doesn't have to contain a complete list of the layers
|
2010-04-08 11:21:04 +00:00
|
|
|
* it depends on, some of them are indirectly referenced through the
|
2010-10-27 17:54:57 +00:00
|
|
|
* pipeline's ancestors.
|
2010-04-08 11:21:04 +00:00
|
|
|
*
|
2010-10-27 17:54:57 +00:00
|
|
|
* pipeline->layer_differences only contains a list of layers that
|
2010-04-08 11:21:04 +00:00
|
|
|
* have changed in relation to its parent.
|
2010-04-26 09:01:43 +00:00
|
|
|
*
|
2010-10-27 17:54:57 +00:00
|
|
|
* pipeline->layer_differences is not maintained sorted, but it
|
2010-04-08 11:21:04 +00:00
|
|
|
* won't contain multiple layers corresponding to a particular
|
|
|
|
* ->unit_index.
|
|
|
|
*
|
2010-10-27 17:54:57 +00:00
|
|
|
* Some of the ancestor pipelines may reference layers with
|
2010-04-08 11:21:04 +00:00
|
|
|
* ->unit_index values >= n_layers so we ignore them.
|
|
|
|
*
|
|
|
|
* As we ascend through the ancestors we are searching for any
|
2010-10-27 17:54:57 +00:00
|
|
|
* CoglPipelineLayers corresponding to the texture ->unit_index
|
2010-04-08 11:21:04 +00:00
|
|
|
* values in the range [0,n_layers-1]. As soon as a pointer is found
|
|
|
|
* we ignore layers of further ancestors with the same ->unit_index
|
|
|
|
* values.
|
2010-04-26 09:01:43 +00:00
|
|
|
*/
|
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
layers_found = 0;
|
2010-10-27 17:54:57 +00:00
|
|
|
for (current = pipeline;
|
|
|
|
_cogl_pipeline_get_parent (current);
|
|
|
|
current = _cogl_pipeline_get_parent (current))
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
|
|
|
GList *l;
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (!(current->differences & COGL_PIPELINE_STATE_LAYERS))
|
2010-04-08 11:21:04 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
for (l = current->layer_differences; l; l = l->next)
|
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipelineLayer *layer = l->data;
|
|
|
|
int unit_index = _cogl_pipeline_layer_get_unit_index (layer);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (unit_index < n_layers && !pipeline->layers_cache[unit_index])
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->layers_cache[unit_index] = layer;
|
2010-04-08 11:21:04 +00:00
|
|
|
layers_found++;
|
|
|
|
if (layers_found == n_layers)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_warn_if_reached ();
|
|
|
|
}
|
|
|
|
|
2010-07-05 20:33:26 +00:00
|
|
|
/* XXX: Be carefull when using this API that the callback given doesn't result
|
|
|
|
* in the layer cache being invalidated during the iteration! */
|
2010-06-15 15:44:52 +00:00
|
|
|
void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_foreach_layer_internal (CoglPipeline *pipeline,
|
|
|
|
CoglPipelineInternalLayerCallback callback,
|
2010-07-05 20:33:26 +00:00
|
|
|
void *user_data)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *authority =
|
|
|
|
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS);
|
2010-04-08 11:21:04 +00:00
|
|
|
int n_layers;
|
|
|
|
int i;
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool cont;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
n_layers = authority->n_layers;
|
|
|
|
if (n_layers == 0)
|
|
|
|
return;
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_update_layers_cache (authority);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
for (i = 0, cont = TRUE; i < n_layers && cont == TRUE; i++)
|
2010-07-05 20:33:26 +00:00
|
|
|
{
|
2011-10-13 21:34:30 +00:00
|
|
|
_COGL_RETURN_IF_FAIL (authority->layers_cache_dirty == FALSE);
|
2010-07-05 20:33:26 +00:00
|
|
|
cont = callback (authority->layers_cache[i], user_data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-27 10:06:16 +00:00
|
|
|
CoglBool
|
|
|
|
_cogl_pipeline_layer_numbers_equal (CoglPipeline *pipeline0,
|
|
|
|
CoglPipeline *pipeline1)
|
|
|
|
{
|
|
|
|
CoglPipeline *authority0 =
|
|
|
|
_cogl_pipeline_get_authority (pipeline0, COGL_PIPELINE_STATE_LAYERS);
|
|
|
|
CoglPipeline *authority1 =
|
|
|
|
_cogl_pipeline_get_authority (pipeline1, COGL_PIPELINE_STATE_LAYERS);
|
|
|
|
int n_layers = authority0->n_layers;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (authority1->n_layers != n_layers)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
_cogl_pipeline_update_layers_cache (authority0);
|
|
|
|
_cogl_pipeline_update_layers_cache (authority1);
|
|
|
|
|
|
|
|
for (i = 0; i < n_layers; i++)
|
|
|
|
{
|
|
|
|
CoglPipelineLayer *layer0 = authority0->layers_cache[i];
|
|
|
|
CoglPipelineLayer *layer1 = authority1->layers_cache[i];
|
|
|
|
|
|
|
|
if (layer0->index != layer1->index)
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2013-01-19 16:00:33 +00:00
|
|
|
CoglBool
|
|
|
|
_cogl_pipeline_layer_and_unit_numbers_equal (CoglPipeline *pipeline0,
|
|
|
|
CoglPipeline *pipeline1)
|
|
|
|
{
|
|
|
|
CoglPipeline *authority0 =
|
|
|
|
_cogl_pipeline_get_authority (pipeline0, COGL_PIPELINE_STATE_LAYERS);
|
|
|
|
CoglPipeline *authority1 =
|
|
|
|
_cogl_pipeline_get_authority (pipeline1, COGL_PIPELINE_STATE_LAYERS);
|
|
|
|
int n_layers = authority0->n_layers;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (authority1->n_layers != n_layers)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
_cogl_pipeline_update_layers_cache (authority0);
|
|
|
|
_cogl_pipeline_update_layers_cache (authority1);
|
|
|
|
|
|
|
|
for (i = 0; i < n_layers; i++)
|
|
|
|
{
|
|
|
|
CoglPipelineLayer *layer0 = authority0->layers_cache[i];
|
|
|
|
CoglPipelineLayer *layer1 = authority1->layers_cache[i];
|
|
|
|
int unit0, unit1;
|
|
|
|
|
|
|
|
if (layer0->index != layer1->index)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
unit0 = _cogl_pipeline_layer_get_unit_index (layer0);
|
|
|
|
unit1 = _cogl_pipeline_layer_get_unit_index (layer1);
|
|
|
|
if (unit0 != unit1)
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2010-07-05 20:33:26 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int *indices;
|
|
|
|
} AppendLayerIndexState;
|
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2010-10-27 17:54:57 +00:00
|
|
|
append_layer_index_cb (CoglPipelineLayer *layer,
|
2010-07-05 20:33:26 +00:00
|
|
|
void *user_data)
|
|
|
|
{
|
|
|
|
AppendLayerIndexState *state = user_data;
|
|
|
|
state->indices[state->i++] = layer->index;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-10-27 17:54:57 +00:00
|
|
|
cogl_pipeline_foreach_layer (CoglPipeline *pipeline,
|
|
|
|
CoglPipelineLayerCallback callback,
|
2010-07-05 20:33:26 +00:00
|
|
|
void *user_data)
|
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *authority =
|
|
|
|
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS);
|
2010-07-05 20:33:26 +00:00
|
|
|
AppendLayerIndexState state;
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool cont;
|
2010-07-05 20:33:26 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
/* XXX: We don't know what the user is going to want to do to the layers
|
|
|
|
* but any modification of layers can result in the layer graph changing
|
2010-10-27 17:54:57 +00:00
|
|
|
* which could confuse _cogl_pipeline_foreach_layer_internal(). We first
|
2010-07-05 20:33:26 +00:00
|
|
|
* get a list of layer indices which will remain valid so long as the
|
|
|
|
* user doesn't remove layers. */
|
|
|
|
|
|
|
|
state.i = 0;
|
|
|
|
state.indices = g_alloca (authority->n_layers * sizeof (int));
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_foreach_layer_internal (pipeline,
|
2010-07-05 20:33:26 +00:00
|
|
|
append_layer_index_cb,
|
|
|
|
&state);
|
|
|
|
|
|
|
|
for (i = 0, cont = TRUE; i < authority->n_layers && cont; i++)
|
2010-10-27 17:54:57 +00:00
|
|
|
cont = callback (pipeline, state.indices[i], user_data);
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2010-10-27 17:54:57 +00:00
|
|
|
layer_has_alpha_cb (CoglPipelineLayer *layer, void *data)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool *has_alpha = data;
|
2011-09-08 23:40:06 +00:00
|
|
|
*has_alpha = _cogl_pipeline_layer_has_alpha (layer);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2011-09-08 23:40:06 +00:00
|
|
|
/* return FALSE to stop iterating layers if we find any layer
|
|
|
|
* has alpha ...
|
2010-04-08 11:21:04 +00:00
|
|
|
*
|
2011-09-08 23:40:06 +00:00
|
|
|
* FIXME: actually we should never be bailing out because it's
|
|
|
|
* always possible that a later layer could discard any previous
|
|
|
|
* alpha!
|
2010-04-08 11:21:04 +00:00
|
|
|
*/
|
|
|
|
|
2011-09-08 23:40:06 +00:00
|
|
|
return !(*has_alpha);
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
2013-05-16 14:19:30 +00:00
|
|
|
/* NB: If this pipeline returns FALSE that doesn't mean that the
|
|
|
|
* pipeline is definitely opaque, it just means that that the
|
|
|
|
* given changes dont imply transparency.
|
|
|
|
*
|
|
|
|
* If you want to find out of the pipeline is opaque then assuming
|
|
|
|
* this returns FALSE for a set of changes then you can follow
|
|
|
|
* up
|
|
|
|
*/
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2013-05-16 14:19:30 +00:00
|
|
|
_cogl_pipeline_change_implies_transparency (CoglPipeline *pipeline,
|
|
|
|
unsigned int changes,
|
|
|
|
const CoglColor *override_color,
|
|
|
|
CoglBool unknown_color_alpha)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
|
|
|
/* In the case of a layer state change we need to check everything
|
|
|
|
* else first since they contribute to the has_alpha status of the
|
2013-05-16 14:19:30 +00:00
|
|
|
* "PREVIOUS" layer. */
|
2010-10-27 17:54:57 +00:00
|
|
|
if (changes & COGL_PIPELINE_STATE_LAYERS)
|
|
|
|
changes = COGL_PIPELINE_STATE_AFFECTS_BLENDING;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2013-05-16 14:19:30 +00:00
|
|
|
if (unknown_color_alpha)
|
|
|
|
return TRUE;
|
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
if ((override_color && cogl_color_get_alpha_byte (override_color) != 0xff))
|
|
|
|
return TRUE;
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (changes & COGL_PIPELINE_STATE_COLOR)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
|
|
|
CoglColor tmp;
|
2010-10-27 17:54:57 +00:00
|
|
|
cogl_pipeline_get_color (pipeline, &tmp);
|
2010-04-08 11:21:04 +00:00
|
|
|
if (cogl_color_get_alpha_byte (&tmp) != 0xff)
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (changes & COGL_PIPELINE_STATE_USER_SHADER)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2010-11-01 20:33:20 +00:00
|
|
|
/* We can't make any assumptions about the alpha channel if the user
|
|
|
|
* is using an unknown fragment shader.
|
|
|
|
*
|
|
|
|
* TODO: check that it isn't just a vertex shader!
|
|
|
|
*/
|
2010-10-27 17:54:57 +00:00
|
|
|
if (_cogl_pipeline_get_user_program (pipeline) != COGL_INVALID_HANDLE)
|
2010-04-08 11:21:04 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2011-11-25 17:59:52 +00:00
|
|
|
if (changes & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS)
|
|
|
|
{
|
|
|
|
if (!_cogl_pipeline_has_non_layer_fragment_snippets (pipeline))
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (changes & COGL_PIPELINE_STATE_VERTEX_SNIPPETS)
|
|
|
|
{
|
|
|
|
if (!_cogl_pipeline_has_non_layer_vertex_snippets (pipeline))
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
/* XXX: we should only need to look at these if lighting is enabled
|
|
|
|
*/
|
2010-10-27 17:54:57 +00:00
|
|
|
if (changes & COGL_PIPELINE_STATE_LIGHTING)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2010-11-01 20:33:20 +00:00
|
|
|
/* XXX: This stuff is showing up in sysprof reports which is
|
|
|
|
* silly because lighting isn't currently actually supported
|
|
|
|
* by Cogl except for these token properties. When we actually
|
|
|
|
* expose lighting support we can avoid these checks when
|
|
|
|
* lighting is disabled. */
|
|
|
|
#if 0
|
2010-04-08 11:21:04 +00:00
|
|
|
CoglColor tmp;
|
2010-10-27 17:54:57 +00:00
|
|
|
cogl_pipeline_get_ambient (pipeline, &tmp);
|
2010-04-08 11:21:04 +00:00
|
|
|
if (cogl_color_get_alpha_byte (&tmp) != 0xff)
|
|
|
|
return TRUE;
|
2010-10-27 17:54:57 +00:00
|
|
|
cogl_pipeline_get_diffuse (pipeline, &tmp);
|
2010-04-08 11:21:04 +00:00
|
|
|
if (cogl_color_get_alpha_byte (&tmp) != 0xff)
|
|
|
|
return TRUE;
|
2010-10-27 17:54:57 +00:00
|
|
|
cogl_pipeline_get_specular (pipeline, &tmp);
|
2010-04-08 11:21:04 +00:00
|
|
|
if (cogl_color_get_alpha_byte (&tmp) != 0xff)
|
|
|
|
return TRUE;
|
2010-10-27 17:54:57 +00:00
|
|
|
cogl_pipeline_get_emission (pipeline, &tmp);
|
2010-04-08 11:21:04 +00:00
|
|
|
if (cogl_color_get_alpha_byte (&tmp) != 0xff)
|
|
|
|
return TRUE;
|
2010-11-01 20:33:20 +00:00
|
|
|
#endif
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (changes & COGL_PIPELINE_STATE_LAYERS)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
|
|
|
/* has_alpha tracks the alpha status of the GL_PREVIOUS layer.
|
2010-10-27 17:54:57 +00:00
|
|
|
* To start with that's defined by the pipeline color which
|
2010-04-08 11:21:04 +00:00
|
|
|
* must be fully opaque if we got this far. */
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool has_alpha = FALSE;
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_foreach_layer_internal (pipeline,
|
2010-07-05 20:33:26 +00:00
|
|
|
layer_has_alpha_cb,
|
|
|
|
&has_alpha);
|
2010-04-08 11:21:04 +00:00
|
|
|
if (has_alpha)
|
|
|
|
return TRUE;
|
|
|
|
}
|
2010-12-03 16:59:52 +00:00
|
|
|
|
2013-05-16 14:19:30 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static CoglBool
|
|
|
|
_cogl_pipeline_needs_blending_enabled (CoglPipeline *pipeline,
|
|
|
|
unsigned int changes,
|
|
|
|
const CoglColor *override_color,
|
|
|
|
CoglBool unknown_color_alpha)
|
|
|
|
{
|
|
|
|
CoglPipeline *enable_authority;
|
|
|
|
CoglPipeline *blend_authority;
|
|
|
|
CoglPipelineBlendState *blend_state;
|
|
|
|
CoglPipelineBlendEnable enabled;
|
|
|
|
|
|
|
|
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_BLENDING)))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* We unconditionally check the _BLEND_ENABLE state first because
|
|
|
|
* all the other changes are irrelevent if blend_enable != _AUTOMATIC
|
|
|
|
*/
|
|
|
|
enable_authority =
|
|
|
|
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND_ENABLE);
|
|
|
|
|
|
|
|
enabled = enable_authority->blend_enable;
|
|
|
|
if (enabled != COGL_PIPELINE_BLEND_ENABLE_AUTOMATIC)
|
|
|
|
return enabled == COGL_PIPELINE_BLEND_ENABLE_ENABLED ? TRUE : FALSE;
|
|
|
|
|
|
|
|
blend_authority =
|
|
|
|
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND);
|
|
|
|
|
|
|
|
blend_state = &blend_authority->big_state->blend_state;
|
|
|
|
|
|
|
|
/* We are trying to identify some cases that are equivalent to
|
|
|
|
* blending being disable, where the output is simply GL_SRC_COLOR.
|
|
|
|
*
|
|
|
|
* Note: we currently only consider a few cases that can be
|
|
|
|
* optimized but there could be opportunities to special case more
|
|
|
|
* blend functions later.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* As the most common way that we currently use to effectively
|
|
|
|
* disable blending is to use an equation of
|
|
|
|
* "RGBA=ADD(SRC_COLOR, 0)" that's the first thing we check
|
|
|
|
* for... */
|
|
|
|
if (blend_state->blend_equation_rgb == GL_FUNC_ADD &&
|
|
|
|
blend_state->blend_equation_alpha == GL_FUNC_ADD &&
|
|
|
|
blend_state->blend_src_factor_alpha == GL_ONE &&
|
|
|
|
blend_state->blend_dst_factor_alpha == GL_ZERO)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* NB: The default blending equation for Cogl is
|
|
|
|
* "RGBA=ADD(SRC_COLOR, DST_COLOR * (1-SRC_COLOR[A]))"
|
|
|
|
*
|
|
|
|
* Next we check if the default blending equation is being used. If
|
|
|
|
* so then we follow that by looking for cases where SRC_COLOR[A] ==
|
|
|
|
* 1 since that simplifies "DST_COLOR * (1-SRC_COLOR[A])" to 0 which
|
|
|
|
* also effectively requires no blending.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (blend_state->blend_equation_rgb != GL_FUNC_ADD ||
|
|
|
|
blend_state->blend_equation_alpha != GL_FUNC_ADD)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
if (blend_state->blend_src_factor_alpha != GL_ONE ||
|
|
|
|
blend_state->blend_dst_factor_alpha != GL_ONE_MINUS_SRC_ALPHA)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
if (blend_state->blend_src_factor_rgb != GL_ONE ||
|
|
|
|
blend_state->blend_dst_factor_rgb != GL_ONE_MINUS_SRC_ALPHA)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/* Given the above constraints, it's now a case of finding any
|
|
|
|
* SRC_ALPHA that != 1 */
|
|
|
|
|
|
|
|
if (_cogl_pipeline_change_implies_transparency (pipeline, changes,
|
|
|
|
override_color,
|
|
|
|
unknown_color_alpha))
|
|
|
|
return TRUE;
|
|
|
|
|
2010-12-03 16:59:52 +00:00
|
|
|
/* At this point, considering just the state that has changed it
|
|
|
|
* looks like blending isn't needed. If blending was previously
|
|
|
|
* enabled though it could be that some other state still requires
|
2013-05-16 14:19:30 +00:00
|
|
|
* that we have blending enabled because it implies transparency.
|
|
|
|
* In this case we still need to go and check the other state...
|
2010-12-03 16:59:52 +00:00
|
|
|
*
|
2013-05-16 14:19:30 +00:00
|
|
|
* XXX: We could explicitly keep track of the mask of state groups
|
|
|
|
* that are currently causing blending to be enabled so that we
|
|
|
|
* never have to resort to checking *all* the state and can instead
|
|
|
|
* always limit the check to those in the mask.
|
2010-12-03 16:59:52 +00:00
|
|
|
*/
|
|
|
|
if (pipeline->real_blend_enable)
|
2010-11-01 20:33:20 +00:00
|
|
|
{
|
2013-05-16 14:19:30 +00:00
|
|
|
unsigned int other_state =
|
|
|
|
COGL_PIPELINE_STATE_AFFECTS_BLENDING & ~changes;
|
2010-11-01 20:33:20 +00:00
|
|
|
if (other_state &&
|
2013-05-16 14:19:30 +00:00
|
|
|
_cogl_pipeline_change_implies_transparency (pipeline, other_state, NULL, FALSE))
|
2010-11-01 20:33:20 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2010-07-10 02:40:47 +00:00
|
|
|
void
|
2012-09-25 20:08:10 +00:00
|
|
|
_cogl_pipeline_set_progend (CoglPipeline *pipeline, int progend)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2012-09-25 20:08:10 +00:00
|
|
|
pipeline->progend = progend;
|
2010-11-29 18:32:21 +00:00
|
|
|
}
|
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
static void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_copy_differences (CoglPipeline *dest,
|
|
|
|
CoglPipeline *src,
|
2010-04-08 11:21:04 +00:00
|
|
|
unsigned long differences)
|
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipelineBigState *big_state;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (differences & COGL_PIPELINE_STATE_COLOR)
|
2010-04-08 11:21:04 +00:00
|
|
|
dest->color = src->color;
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (differences & COGL_PIPELINE_STATE_BLEND_ENABLE)
|
2010-04-08 11:21:04 +00:00
|
|
|
dest->blend_enable = src->blend_enable;
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (differences & COGL_PIPELINE_STATE_LAYERS)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
|
|
|
GList *l;
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (dest->differences & COGL_PIPELINE_STATE_LAYERS &&
|
2010-04-08 11:21:04 +00:00
|
|
|
dest->layer_differences)
|
|
|
|
{
|
|
|
|
g_list_foreach (dest->layer_differences,
|
2010-06-22 13:02:17 +00:00
|
|
|
(GFunc)cogl_object_unref,
|
2010-04-08 11:21:04 +00:00
|
|
|
NULL);
|
|
|
|
g_list_free (dest->layer_differences);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (l = src->layer_differences; l; l = l->next)
|
|
|
|
{
|
|
|
|
/* NB: a layer can't have more than one ->owner so we can't
|
|
|
|
* simply take a references on each of the original
|
|
|
|
* layer_differences, we have to derive new layers from the
|
|
|
|
* originals instead. */
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipelineLayer *copy = _cogl_pipeline_layer_copy (l->data);
|
|
|
|
_cogl_pipeline_add_layer_difference (dest, copy, FALSE);
|
2010-06-22 13:02:17 +00:00
|
|
|
cogl_object_unref (copy);
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
2010-08-08 12:09:27 +00:00
|
|
|
|
|
|
|
/* Note: we initialize n_layers after adding the layer differences
|
|
|
|
* since the act of adding the layers will initialize n_layers to 0
|
|
|
|
* because dest isn't initially a STATE_LAYERS authority. */
|
|
|
|
dest->n_layers = src->n_layers;
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
|
|
|
if (!dest->has_big_state)
|
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
dest->big_state = g_slice_new (CoglPipelineBigState);
|
2010-04-08 11:21:04 +00:00
|
|
|
dest->has_big_state = TRUE;
|
|
|
|
}
|
|
|
|
big_state = dest->big_state;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
goto check_for_blending_change;
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (differences & COGL_PIPELINE_STATE_LIGHTING)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
|
|
|
memcpy (&big_state->lighting_state,
|
|
|
|
&src->big_state->lighting_state,
|
2010-10-27 17:54:57 +00:00
|
|
|
sizeof (CoglPipelineLightingState));
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (differences & COGL_PIPELINE_STATE_ALPHA_FUNC)
|
2010-11-22 18:29:50 +00:00
|
|
|
big_state->alpha_state.alpha_func =
|
|
|
|
src->big_state->alpha_state.alpha_func;
|
|
|
|
|
|
|
|
if (differences & COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE)
|
|
|
|
big_state->alpha_state.alpha_func_reference =
|
|
|
|
src->big_state->alpha_state.alpha_func_reference;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (differences & COGL_PIPELINE_STATE_BLEND)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
|
|
|
memcpy (&big_state->blend_state,
|
|
|
|
&src->big_state->blend_state,
|
2010-10-27 17:54:57 +00:00
|
|
|
sizeof (CoglPipelineBlendState));
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (differences & COGL_PIPELINE_STATE_USER_SHADER)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
|
|
|
if (src->big_state->user_program)
|
|
|
|
big_state->user_program =
|
|
|
|
cogl_handle_ref (src->big_state->user_program);
|
2010-06-09 12:53:34 +00:00
|
|
|
else
|
2010-04-08 11:21:04 +00:00
|
|
|
big_state->user_program = COGL_INVALID_HANDLE;
|
2009-06-17 22:31:11 +00:00
|
|
|
}
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (differences & COGL_PIPELINE_STATE_DEPTH)
|
2010-05-26 10:33:32 +00:00
|
|
|
{
|
|
|
|
memcpy (&big_state->depth_state,
|
|
|
|
&src->big_state->depth_state,
|
2011-04-14 17:12:03 +00:00
|
|
|
sizeof (CoglDepthState));
|
2010-05-26 10:33:32 +00:00
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (differences & COGL_PIPELINE_STATE_FOG)
|
2010-07-10 00:36:22 +00:00
|
|
|
{
|
|
|
|
memcpy (&big_state->fog_state,
|
|
|
|
&src->big_state->fog_state,
|
2010-10-27 17:54:57 +00:00
|
|
|
sizeof (CoglPipelineFogState));
|
2010-07-10 00:36:22 +00:00
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (differences & COGL_PIPELINE_STATE_POINT_SIZE)
|
2010-03-22 09:32:17 +00:00
|
|
|
big_state->point_size = src->big_state->point_size;
|
|
|
|
|
2012-11-08 16:56:02 +00:00
|
|
|
if (differences & COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE)
|
|
|
|
big_state->per_vertex_point_size = src->big_state->per_vertex_point_size;
|
|
|
|
|
2011-07-11 01:27:54 +00:00
|
|
|
if (differences & COGL_PIPELINE_STATE_LOGIC_OPS)
|
|
|
|
{
|
|
|
|
memcpy (&big_state->logic_ops_state,
|
|
|
|
&src->big_state->logic_ops_state,
|
|
|
|
sizeof (CoglPipelineLogicOpsState));
|
|
|
|
}
|
|
|
|
|
2011-09-15 10:25:39 +00:00
|
|
|
if (differences & COGL_PIPELINE_STATE_CULL_FACE)
|
|
|
|
{
|
|
|
|
memcpy (&big_state->cull_face_state,
|
|
|
|
&src->big_state->cull_face_state,
|
|
|
|
sizeof (CoglPipelineCullFaceState));
|
|
|
|
}
|
|
|
|
|
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 (differences & COGL_PIPELINE_STATE_UNIFORMS)
|
|
|
|
{
|
2011-11-04 17:56:44 +00:00
|
|
|
int n_overrides =
|
|
|
|
_cogl_bitmask_popcount (&src->big_state->uniforms_state.override_mask);
|
|
|
|
int i;
|
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
|
|
|
|
2011-11-04 17:56:44 +00:00
|
|
|
big_state->uniforms_state.override_values =
|
|
|
|
g_malloc (n_overrides * sizeof (CoglBoxedValue));
|
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
|
|
|
|
2011-11-04 17:56:44 +00:00
|
|
|
for (i = 0; i < n_overrides; i++)
|
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
|
|
|
{
|
2011-11-04 17:56:44 +00:00
|
|
|
CoglBoxedValue *dst_bv =
|
|
|
|
big_state->uniforms_state.override_values + i;
|
|
|
|
const CoglBoxedValue *src_bv =
|
|
|
|
src->big_state->uniforms_state.override_values + i;
|
|
|
|
|
|
|
|
_cogl_boxed_value_copy (dst_bv, src_bv);
|
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_init (&big_state->uniforms_state.override_mask);
|
|
|
|
_cogl_bitmask_set_bits (&big_state->uniforms_state.override_mask,
|
|
|
|
&src->big_state->uniforms_state.override_mask);
|
|
|
|
|
|
|
|
_cogl_bitmask_init (&big_state->uniforms_state.changed_mask);
|
|
|
|
}
|
|
|
|
|
2011-11-17 16:52:21 +00:00
|
|
|
if (differences & COGL_PIPELINE_STATE_VERTEX_SNIPPETS)
|
|
|
|
_cogl_pipeline_snippet_list_copy (&big_state->vertex_snippets,
|
|
|
|
&src->big_state->vertex_snippets);
|
|
|
|
|
|
|
|
if (differences & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS)
|
|
|
|
_cogl_pipeline_snippet_list_copy (&big_state->fragment_snippets,
|
|
|
|
&src->big_state->fragment_snippets);
|
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
/* XXX: we shouldn't bother doing this in most cases since
|
2010-10-27 17:54:57 +00:00
|
|
|
* _copy_differences is typically used to initialize pipeline state
|
2010-04-08 11:21:04 +00:00
|
|
|
* by copying it from the current authority, so it's not actually
|
|
|
|
* *changing* anything.
|
|
|
|
*/
|
|
|
|
check_for_blending_change:
|
2010-10-27 17:54:57 +00:00
|
|
|
if (differences & COGL_PIPELINE_STATE_AFFECTS_BLENDING)
|
2013-05-16 14:19:30 +00:00
|
|
|
dest->dirty_real_blend_enable = TRUE;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
dest->differences |= differences;
|
2010-04-26 09:01:43 +00:00
|
|
|
}
|
2009-06-17 22:31:11 +00:00
|
|
|
|
2010-04-26 09:01:43 +00:00
|
|
|
static void
|
2011-01-12 17:11:48 +00:00
|
|
|
_cogl_pipeline_init_multi_property_sparse_state (CoglPipeline *pipeline,
|
|
|
|
CoglPipelineState change)
|
2010-04-26 09:01:43 +00:00
|
|
|
{
|
2011-01-12 17:11:48 +00:00
|
|
|
CoglPipeline *authority;
|
|
|
|
|
2011-10-13 21:34:30 +00:00
|
|
|
_COGL_RETURN_IF_FAIL (change & COGL_PIPELINE_STATE_ALL_SPARSE);
|
2011-01-12 17:11:48 +00:00
|
|
|
|
|
|
|
if (!(change & COGL_PIPELINE_STATE_MULTI_PROPERTY))
|
2010-04-26 09:01:43 +00:00
|
|
|
return;
|
|
|
|
|
2011-01-12 17:11:48 +00:00
|
|
|
authority = _cogl_pipeline_get_authority (pipeline, change);
|
2010-08-08 12:41:15 +00:00
|
|
|
|
2011-01-12 17:11:48 +00:00
|
|
|
switch (change)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2011-01-12 17:11:48 +00:00
|
|
|
/* XXX: avoid using a default: label so we get a warning if we
|
|
|
|
* don't explicitly handle a newly defined state-group here. */
|
|
|
|
case COGL_PIPELINE_STATE_COLOR:
|
|
|
|
case COGL_PIPELINE_STATE_BLEND_ENABLE:
|
|
|
|
case COGL_PIPELINE_STATE_ALPHA_FUNC:
|
|
|
|
case COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE:
|
|
|
|
case COGL_PIPELINE_STATE_POINT_SIZE:
|
|
|
|
case COGL_PIPELINE_STATE_USER_SHADER:
|
2012-11-08 16:56:02 +00:00
|
|
|
case COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE:
|
2011-01-12 17:11:48 +00:00
|
|
|
case COGL_PIPELINE_STATE_REAL_BLEND_ENABLE:
|
|
|
|
g_return_if_reached ();
|
|
|
|
|
|
|
|
case COGL_PIPELINE_STATE_LAYERS:
|
|
|
|
pipeline->n_layers = authority->n_layers;
|
|
|
|
pipeline->layer_differences = NULL;
|
|
|
|
break;
|
|
|
|
case COGL_PIPELINE_STATE_LIGHTING:
|
|
|
|
{
|
|
|
|
memcpy (&pipeline->big_state->lighting_state,
|
|
|
|
&authority->big_state->lighting_state,
|
|
|
|
sizeof (CoglPipelineLightingState));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case COGL_PIPELINE_STATE_BLEND:
|
|
|
|
{
|
|
|
|
memcpy (&pipeline->big_state->blend_state,
|
|
|
|
&authority->big_state->blend_state,
|
|
|
|
sizeof (CoglPipelineBlendState));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case COGL_PIPELINE_STATE_DEPTH:
|
|
|
|
{
|
|
|
|
memcpy (&pipeline->big_state->depth_state,
|
|
|
|
&authority->big_state->depth_state,
|
2011-04-14 17:12:03 +00:00
|
|
|
sizeof (CoglDepthState));
|
2011-01-12 17:11:48 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case COGL_PIPELINE_STATE_FOG:
|
|
|
|
{
|
|
|
|
memcpy (&pipeline->big_state->fog_state,
|
|
|
|
&authority->big_state->fog_state,
|
|
|
|
sizeof (CoglPipelineFogState));
|
|
|
|
break;
|
|
|
|
}
|
2011-07-11 01:27:54 +00:00
|
|
|
case COGL_PIPELINE_STATE_LOGIC_OPS:
|
|
|
|
{
|
|
|
|
memcpy (&pipeline->big_state->logic_ops_state,
|
|
|
|
&authority->big_state->logic_ops_state,
|
|
|
|
sizeof (CoglPipelineLogicOpsState));
|
|
|
|
break;
|
|
|
|
}
|
2011-09-15 10:25:39 +00:00
|
|
|
case COGL_PIPELINE_STATE_CULL_FACE:
|
|
|
|
{
|
|
|
|
memcpy (&pipeline->big_state->cull_face_state,
|
|
|
|
&authority->big_state->cull_face_state,
|
|
|
|
sizeof (CoglPipelineCullFaceState));
|
|
|
|
break;
|
|
|
|
}
|
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
|
|
|
case COGL_PIPELINE_STATE_UNIFORMS:
|
|
|
|
{
|
|
|
|
CoglPipelineUniformsState *uniforms_state =
|
|
|
|
&pipeline->big_state->uniforms_state;
|
|
|
|
_cogl_bitmask_init (&uniforms_state->override_mask);
|
|
|
|
_cogl_bitmask_init (&uniforms_state->changed_mask);
|
2011-11-04 17:56:44 +00:00
|
|
|
uniforms_state->override_values = NULL;
|
2011-11-28 22:10:10 +00:00
|
|
|
break;
|
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
|
|
|
}
|
2011-11-17 16:52:21 +00:00
|
|
|
case COGL_PIPELINE_STATE_VERTEX_SNIPPETS:
|
|
|
|
_cogl_pipeline_snippet_list_copy (&pipeline->big_state->vertex_snippets,
|
|
|
|
&authority->big_state->vertex_snippets);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS:
|
|
|
|
_cogl_pipeline_snippet_list_copy (&pipeline->big_state->fragment_snippets,
|
|
|
|
&authority->big_state->
|
|
|
|
fragment_snippets);
|
|
|
|
break;
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2011-09-08 23:40:06 +00:00
|
|
|
check_if_strong_cb (CoglNode *node, void *user_data)
|
2010-05-27 19:04:49 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *pipeline = COGL_PIPELINE (node);
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool *has_strong_child = user_data;
|
2010-05-27 19:04:49 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (!_cogl_pipeline_is_weak (pipeline))
|
2010-05-27 19:04:49 +00:00
|
|
|
{
|
|
|
|
*has_strong_child = TRUE;
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-08-09 15:01:17 +00:00
|
|
|
|
2010-05-27 19:04:49 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2010-10-27 17:54:57 +00:00
|
|
|
has_strong_children (CoglPipeline *pipeline)
|
2010-05-27 19:04:49 +00:00
|
|
|
{
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool has_strong_child = FALSE;
|
2011-09-08 23:40:06 +00:00
|
|
|
_cogl_pipeline_node_foreach_child (COGL_NODE (pipeline),
|
2010-07-08 10:49:31 +00:00
|
|
|
check_if_strong_cb,
|
|
|
|
&has_strong_child);
|
2010-05-27 19:04:49 +00:00
|
|
|
return has_strong_child;
|
|
|
|
}
|
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_is_weak (CoglPipeline *pipeline)
|
2010-08-09 15:01:17 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
if (pipeline->is_weak && !has_strong_children (pipeline))
|
2010-08-09 15:01:17 +00:00
|
|
|
return TRUE;
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2011-09-08 23:40:06 +00:00
|
|
|
reparent_children_cb (CoglNode *node,
|
2010-08-09 15:01:17 +00:00
|
|
|
void *user_data)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *pipeline = COGL_PIPELINE (node);
|
|
|
|
CoglPipeline *parent = user_data;
|
2010-05-27 19:04:49 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_set_parent (pipeline, parent, TRUE);
|
2010-05-27 19:04:49 +00:00
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2011-09-07 22:44:37 +00:00
|
|
|
void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_pre_change_notify (CoglPipeline *pipeline,
|
|
|
|
CoglPipelineState change,
|
2010-09-13 20:26:31 +00:00
|
|
|
const CoglColor *new_color,
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool from_layer_change)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
|
|
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
|
|
|
|
|
|
|
/* If primitives have been logged in the journal referencing the
|
2010-10-27 17:54:57 +00:00
|
|
|
* current state of this pipeline we need to flush the journal
|
2010-04-08 11:21:04 +00:00
|
|
|
* before we can modify it... */
|
2010-10-27 17:54:57 +00:00
|
|
|
if (pipeline->journal_ref_count)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool skip_journal_flush = FALSE;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
/* XXX: We don't usually need to flush the journal just due to
|
2010-10-27 17:54:57 +00:00
|
|
|
* color changes since pipeline colors are logged in the
|
2010-04-08 11:21:04 +00:00
|
|
|
* journal's vertex buffer. The exception is when the change in
|
|
|
|
* color enables or disables the need for blending. */
|
2010-10-27 17:54:57 +00:00
|
|
|
if (change == COGL_PIPELINE_STATE_COLOR)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool will_need_blending =
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_needs_blending_enabled (pipeline,
|
2010-04-08 11:21:04 +00:00
|
|
|
change,
|
2013-05-16 14:19:30 +00:00
|
|
|
new_color,
|
|
|
|
FALSE);
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool blend_enable = pipeline->real_blend_enable ? TRUE : FALSE;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
if (will_need_blending == blend_enable)
|
|
|
|
skip_journal_flush = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!skip_journal_flush)
|
2011-01-06 13:25:45 +00:00
|
|
|
{
|
|
|
|
/* XXX: note we use cogl_flush() not _cogl_flush_journal() so
|
|
|
|
* we will flush *all* known journals that might reference the
|
|
|
|
* current pipeline. */
|
|
|
|
cogl_flush ();
|
|
|
|
}
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
2011-06-27 10:50:48 +00:00
|
|
|
/* XXX:
|
|
|
|
* To simplify things for the vertex, fragment and program backends
|
|
|
|
* we are careful about how we report STATE_LAYERS changes.
|
2010-11-29 18:32:21 +00:00
|
|
|
*
|
2011-06-27 10:50:48 +00:00
|
|
|
* All STATE_LAYERS change notification with the exception of
|
|
|
|
* ->n_layers will also result in layer_pre_change_notifications.
|
2012-09-25 20:08:10 +00:00
|
|
|
* For backends that perform code generation for fragment processing
|
|
|
|
* they typically need to understand the details of how layers get
|
|
|
|
* changed to determine if they need to repeat codegen. It doesn't
|
|
|
|
* help them to report a pipeline STATE_LAYERS change for all layer
|
|
|
|
* changes since it's so broad, they really need to wait for the
|
|
|
|
* specific layer change to be notified. What does help though is
|
|
|
|
* to report a STATE_LAYERS change for a change in ->n_layers
|
|
|
|
* because they typically do need to repeat codegen in that case.
|
2010-11-29 18:32:21 +00:00
|
|
|
*
|
2011-06-27 10:50:48 +00:00
|
|
|
* Here we ensure that change notifications against a pipeline or
|
|
|
|
* against a layer are mutually exclusive as far as fragment, vertex
|
|
|
|
* and program backends are concerned.
|
2010-11-29 18:32:21 +00:00
|
|
|
*/
|
2012-09-25 20:08:10 +00:00
|
|
|
if (!from_layer_change &&
|
|
|
|
pipeline->progend != COGL_PIPELINE_PROGEND_UNDEFINED)
|
2010-07-10 02:40:47 +00:00
|
|
|
{
|
2012-09-25 20:08:10 +00:00
|
|
|
const CoglPipelineProgend *progend =
|
|
|
|
_cogl_pipeline_progends[pipeline->progend];
|
|
|
|
const CoglPipelineVertend *vertend =
|
|
|
|
_cogl_pipeline_vertends[progend->vertend];
|
|
|
|
const CoglPipelineFragend *fragend =
|
|
|
|
_cogl_pipeline_fragends[progend->fragend];
|
2010-09-13 23:18:02 +00:00
|
|
|
|
2012-09-25 20:08:10 +00:00
|
|
|
if (vertend->pipeline_pre_change_notify)
|
|
|
|
vertend->pipeline_pre_change_notify (pipeline, change, new_color);
|
2010-11-29 18:32:21 +00:00
|
|
|
|
2012-09-25 20:08:10 +00:00
|
|
|
if (fragend->pipeline_pre_change_notify)
|
|
|
|
fragend->pipeline_pre_change_notify (pipeline, change, new_color);
|
2010-11-29 18:32:21 +00:00
|
|
|
|
2012-09-25 20:08:10 +00:00
|
|
|
if (progend->pipeline_pre_change_notify)
|
|
|
|
progend->pipeline_pre_change_notify (pipeline, change, new_color);
|
2010-07-10 02:40:47 +00:00
|
|
|
}
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
/* There may be an arbitrary tree of descendants of this pipeline;
|
|
|
|
* any of which may indirectly depend on this pipeline as the
|
2010-08-09 15:01:17 +00:00
|
|
|
* authority for some set of properties. (Meaning for example that
|
|
|
|
* one of its descendants derives its color or blending state from
|
2010-10-27 17:54:57 +00:00
|
|
|
* this pipeline.)
|
2010-04-08 11:21:04 +00:00
|
|
|
*
|
2010-10-27 17:54:57 +00:00
|
|
|
* We can't modify any property that this pipeline is the authority
|
|
|
|
* for unless we create another pipeline to take its place first and
|
|
|
|
* make sure descendants reference this new pipeline instead.
|
2010-04-08 11:21:04 +00:00
|
|
|
*/
|
2010-08-09 15:01:17 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
/* The simplest descendants to handle are weak pipelines; we simply
|
|
|
|
* destroy them if we are modifying a pipeline they depend on. This
|
|
|
|
* means weak pipelines never cause us to do a copy-on-write. */
|
2011-09-08 23:40:06 +00:00
|
|
|
_cogl_pipeline_node_foreach_child (COGL_NODE (pipeline),
|
2010-08-09 15:01:17 +00:00
|
|
|
destroy_weak_children_cb,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
/* If there are still children remaining though we'll need to
|
|
|
|
* perform a copy-on-write and reparent the dependants as children
|
|
|
|
* of the copy. */
|
2013-06-08 22:03:25 +00:00
|
|
|
if (!_cogl_list_empty (&COGL_NODE (pipeline)->children))
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *new_authority;
|
2010-07-08 10:49:31 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
COGL_STATIC_COUNTER (pipeline_copy_on_write_counter,
|
|
|
|
"pipeline copy on write counter",
|
|
|
|
"Increments each time a pipeline "
|
2010-04-08 11:21:04 +00:00
|
|
|
"must be copied to allow modification",
|
|
|
|
0 /* no application private data */);
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
COGL_COUNTER_INC (_cogl_uprof_context, pipeline_copy_on_write_counter);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-07-08 10:49:31 +00:00
|
|
|
new_authority =
|
2010-10-27 17:54:57 +00:00
|
|
|
cogl_pipeline_copy (_cogl_pipeline_get_parent (pipeline));
|
2013-05-30 14:42:35 +00:00
|
|
|
#ifdef COGL_DEBUG_ENABLED
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_set_static_breadcrumb (new_authority,
|
2010-05-18 23:36:31 +00:00
|
|
|
"pre_change_notify:copy-on-write");
|
2013-05-30 14:42:35 +00:00
|
|
|
#endif
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
/* We could explicitly walk the descendants, OR together the set
|
2010-10-27 17:54:57 +00:00
|
|
|
* of differences that we determine this pipeline is the
|
2010-04-08 11:21:04 +00:00
|
|
|
* authority on and only copy those differences copied across.
|
|
|
|
*
|
|
|
|
* Or, if we don't explicitly walk the descendants we at least
|
2010-10-27 17:54:57 +00:00
|
|
|
* know that pipeline->differences represents the largest set of
|
|
|
|
* differences that this pipeline could possibly be an authority
|
2010-04-08 11:21:04 +00:00
|
|
|
* on.
|
|
|
|
*
|
|
|
|
* We do the later just because it's simplest, but we might need
|
|
|
|
* to come back to this later...
|
|
|
|
*/
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_copy_differences (new_authority, pipeline,
|
|
|
|
pipeline->differences);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
/* Reparent the dependants of pipeline to be children of
|
2010-04-08 11:21:04 +00:00
|
|
|
* new_authority instead... */
|
2011-09-08 23:40:06 +00:00
|
|
|
_cogl_pipeline_node_foreach_child (COGL_NODE (pipeline),
|
2010-08-09 15:01:17 +00:00
|
|
|
reparent_children_cb,
|
2010-07-08 10:49:31 +00:00
|
|
|
new_authority);
|
2010-07-03 17:44:47 +00:00
|
|
|
|
|
|
|
/* The children will keep the new authority alive so drop the
|
|
|
|
* reference we got when copying... */
|
|
|
|
cogl_object_unref (new_authority);
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
/* At this point we know we have a pipeline with no strong
|
2010-05-27 19:04:49 +00:00
|
|
|
* dependants (though we may have some weak children) so we are now
|
2010-10-27 17:54:57 +00:00
|
|
|
* free to modify the pipeline. */
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->age++;
|
2010-05-27 14:19:15 +00:00
|
|
|
|
2011-01-12 17:11:48 +00:00
|
|
|
if (change & COGL_PIPELINE_STATE_NEEDS_BIG_STATE &&
|
|
|
|
!pipeline->has_big_state)
|
|
|
|
{
|
|
|
|
pipeline->big_state = g_slice_new (CoglPipelineBigState);
|
|
|
|
pipeline->has_big_state = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Note: conceptually we have just been notified that a single
|
|
|
|
* property value is about to change, but since some state-groups
|
|
|
|
* contain multiple properties and 'pipeline' is about to take over
|
|
|
|
* being the authority for the property's corresponding state-group
|
|
|
|
* we need to maintain the integrity of the other property values
|
|
|
|
* too.
|
|
|
|
*
|
|
|
|
* To ensure this we handle multi-property state-groups by copying
|
|
|
|
* all the values from the old-authority to the new...
|
|
|
|
*
|
|
|
|
* We don't have to worry about non-sparse property groups since
|
|
|
|
* we never take over being an authority for such properties so
|
|
|
|
* they automatically maintain integrity.
|
|
|
|
*/
|
2010-10-27 17:54:57 +00:00
|
|
|
if (change & COGL_PIPELINE_STATE_ALL_SPARSE &&
|
|
|
|
!(pipeline->differences & change))
|
2010-08-08 12:41:15 +00:00
|
|
|
{
|
2011-01-12 17:11:48 +00:00
|
|
|
_cogl_pipeline_init_multi_property_sparse_state (pipeline, change);
|
|
|
|
pipeline->differences |= change;
|
2010-08-08 12:41:15 +00:00
|
|
|
}
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
/* Each pipeline has a sorted cache of the layers it depends on
|
|
|
|
* which will need updating via _cogl_pipeline_update_layers_cache
|
|
|
|
* if a pipeline's layers are changed. */
|
|
|
|
if (change == COGL_PIPELINE_STATE_LAYERS)
|
|
|
|
recursively_free_layer_caches (pipeline);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
/* If the pipeline being changed is the same as the last pipeline we
|
2010-04-08 11:21:04 +00:00
|
|
|
* flushed then we keep a track of the changes so we can try to
|
2010-10-27 17:54:57 +00:00
|
|
|
* minimize redundant OpenGL calls if the same pipeline is flushed
|
2010-04-08 11:21:04 +00:00
|
|
|
* again.
|
|
|
|
*/
|
2010-10-27 17:54:57 +00:00
|
|
|
if (ctx->current_pipeline == pipeline)
|
|
|
|
ctx->current_pipeline_changes_since_flush |= change;
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-09-08 23:40:06 +00:00
|
|
|
void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_add_layer_difference (CoglPipeline *pipeline,
|
|
|
|
CoglPipelineLayer *layer,
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool inc_n_layers)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2011-10-13 21:34:30 +00:00
|
|
|
_COGL_RETURN_IF_FAIL (layer->owner == NULL);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
layer->owner = pipeline;
|
2010-06-22 13:02:17 +00:00
|
|
|
cogl_object_ref (layer);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
/* - Flush journal primitives referencing the current state.
|
2010-10-27 17:54:57 +00:00
|
|
|
* - Make sure the pipeline has no dependants so it may be modified.
|
|
|
|
* - If the pipeline isn't currently an authority for the state being
|
2010-04-08 11:21:04 +00:00
|
|
|
* changed, then initialize that state from the current authority.
|
|
|
|
*/
|
2011-06-27 10:50:48 +00:00
|
|
|
/* Note: the last argument to _cogl_pipeline_pre_change_notify is
|
|
|
|
* needed to differentiate STATE_LAYER changes which don't affect
|
|
|
|
* the number of layers from those that do. NB: Layer change
|
|
|
|
* notifications that don't change the number of layers don't get
|
|
|
|
* forwarded to the fragend. */
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_pre_change_notify (pipeline,
|
|
|
|
COGL_PIPELINE_STATE_LAYERS,
|
2010-09-13 20:26:31 +00:00
|
|
|
NULL,
|
2011-06-27 10:50:48 +00:00
|
|
|
!inc_n_layers);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->differences |= COGL_PIPELINE_STATE_LAYERS;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->layer_differences =
|
|
|
|
g_list_prepend (pipeline->layer_differences, layer);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
if (inc_n_layers)
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->n_layers++;
|
2013-03-09 20:00:53 +00:00
|
|
|
|
|
|
|
/* Adding a layer difference may mean this pipeline now overrides
|
|
|
|
* all of the layers of its parent which might make the parent
|
|
|
|
* redundant so we should try to prune the hierarchy */
|
|
|
|
_cogl_pipeline_prune_redundant_ancestry (pipeline);
|
2010-04-26 09:01:43 +00:00
|
|
|
}
|
|
|
|
|
2011-09-08 23:40:06 +00:00
|
|
|
void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_remove_layer_difference (CoglPipeline *pipeline,
|
|
|
|
CoglPipelineLayer *layer,
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool dec_n_layers)
|
2010-04-26 09:01:43 +00:00
|
|
|
{
|
2010-04-08 11:21:04 +00:00
|
|
|
/* - Flush journal primitives referencing the current state.
|
2010-10-27 17:54:57 +00:00
|
|
|
* - Make sure the pipeline has no dependants so it may be modified.
|
|
|
|
* - If the pipeline isn't currently an authority for the state being
|
2010-04-08 11:21:04 +00:00
|
|
|
* changed, then initialize that state from the current authority.
|
2010-04-26 09:01:43 +00:00
|
|
|
*/
|
2011-06-27 10:50:48 +00:00
|
|
|
/* Note: the last argument to _cogl_pipeline_pre_change_notify is
|
|
|
|
* needed to differentiate STATE_LAYER changes which don't affect
|
|
|
|
* the number of layers from those that do. NB: Layer change
|
|
|
|
* notifications that don't change the number of layers don't get
|
|
|
|
* forwarded to the fragend. */
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_pre_change_notify (pipeline,
|
|
|
|
COGL_PIPELINE_STATE_LAYERS,
|
2010-09-13 20:26:31 +00:00
|
|
|
NULL,
|
2011-06-27 10:50:48 +00:00
|
|
|
!dec_n_layers);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2012-05-24 11:54:44 +00:00
|
|
|
/* We only need to remove the layer difference if the pipeline is
|
|
|
|
* currently the owner. If it is not the owner then one of two
|
|
|
|
* things will happen to make sure this layer is replaced. If it is
|
|
|
|
* the last layer being removed then decrementing n_layers will
|
|
|
|
* ensure that the last layer is skipped. If it is any other layer
|
|
|
|
* then the subsequent layers will have been shifted down and cause
|
|
|
|
* it be replaced */
|
|
|
|
if (layer->owner == pipeline)
|
|
|
|
{
|
|
|
|
layer->owner = NULL;
|
|
|
|
cogl_object_unref (layer);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2012-05-24 11:54:44 +00:00
|
|
|
pipeline->layer_differences =
|
|
|
|
g_list_remove (pipeline->layer_differences, layer);
|
|
|
|
}
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2012-05-24 11:54:44 +00:00
|
|
|
pipeline->differences |= COGL_PIPELINE_STATE_LAYERS;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
if (dec_n_layers)
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->n_layers--;
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_try_reverting_layers_authority (CoglPipeline *authority,
|
|
|
|
CoglPipeline *old_authority)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2010-07-08 10:49:31 +00:00
|
|
|
if (authority->layer_differences == NULL &&
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_get_parent (authority))
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
|
|
|
/* If the previous _STATE_LAYERS authority has the same
|
|
|
|
* ->n_layers then we can revert to that being the authority
|
|
|
|
* again. */
|
|
|
|
if (!old_authority)
|
|
|
|
{
|
|
|
|
old_authority =
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority),
|
|
|
|
COGL_PIPELINE_STATE_LAYERS);
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (old_authority->n_layers == authority->n_layers)
|
2010-10-27 17:54:57 +00:00
|
|
|
authority->differences &= ~COGL_PIPELINE_STATE_LAYERS;
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-07 22:44:37 +00:00
|
|
|
void
|
2013-05-16 14:19:30 +00:00
|
|
|
_cogl_pipeline_update_real_blend_enable (CoglPipeline *pipeline,
|
|
|
|
CoglBool unknown_color_alpha)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2013-05-16 14:19:30 +00:00
|
|
|
CoglPipeline *parent;
|
|
|
|
unsigned int differences;
|
|
|
|
|
|
|
|
if (pipeline->dirty_real_blend_enable == FALSE &&
|
|
|
|
pipeline->unknown_color_alpha == unknown_color_alpha)
|
|
|
|
return;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2013-05-16 14:19:30 +00:00
|
|
|
if (pipeline->dirty_real_blend_enable)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2013-05-16 14:19:30 +00:00
|
|
|
differences = pipeline->differences;
|
|
|
|
|
|
|
|
parent = _cogl_pipeline_get_parent (pipeline);
|
|
|
|
while (parent->dirty_real_blend_enable)
|
|
|
|
{
|
|
|
|
differences |= parent->differences;
|
|
|
|
parent = _cogl_pipeline_get_parent (parent);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We initialize the pipeline's real_blend_enable with a known
|
|
|
|
* reference value from its nearest ancestor with clean state so
|
|
|
|
* we can then potentially reduce the work involved in checking
|
|
|
|
* if the pipeline really needs blending itself because we can
|
|
|
|
* just look at the things that differ between the ancestor and
|
|
|
|
* this pipeline.
|
2010-04-08 11:21:04 +00:00
|
|
|
*/
|
2013-05-16 14:19:30 +00:00
|
|
|
pipeline->real_blend_enable = parent->real_blend_enable;
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
2013-05-16 14:19:30 +00:00
|
|
|
else /* pipeline->unknown_color_alpha != unknown_color_alpha */
|
|
|
|
differences = 0;
|
|
|
|
|
|
|
|
/* Note we don't call _cogl_pipeline_pre_change_notify() for this
|
|
|
|
* state change because ->real_blend_enable is lazily derived from
|
|
|
|
* other state while flushing the pipeline and we'd need to avoid
|
|
|
|
* recursion problems in cases where _pre_change_notify() flushes
|
|
|
|
* the journal if the pipeline is referenced by a journal.
|
|
|
|
*/
|
|
|
|
pipeline->real_blend_enable =
|
|
|
|
_cogl_pipeline_needs_blending_enabled (pipeline, differences,
|
|
|
|
NULL, unknown_color_alpha);
|
|
|
|
pipeline->dirty_real_blend_enable = FALSE;
|
|
|
|
pipeline->unknown_color_alpha = unknown_color_alpha;
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int keep_n;
|
|
|
|
int current_pos;
|
|
|
|
int first_index_to_prune;
|
2010-10-27 17:54:57 +00:00
|
|
|
} CoglPipelinePruneLayersInfo;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2010-10-27 17:54:57 +00:00
|
|
|
update_prune_layers_info_cb (CoglPipelineLayer *layer, void *user_data)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipelinePruneLayersInfo *state = user_data;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
if (state->current_pos == state->keep_n)
|
|
|
|
{
|
|
|
|
state->first_index_to_prune = layer->index;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
state->current_pos++;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_prune_to_n_layers (CoglPipeline *pipeline, int n)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2011-06-27 10:50:48 +00:00
|
|
|
CoglPipeline *authority =
|
|
|
|
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS);
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipelinePruneLayersInfo state;
|
2010-04-08 11:21:04 +00:00
|
|
|
GList *l;
|
|
|
|
GList *next;
|
|
|
|
|
2011-06-27 10:50:48 +00:00
|
|
|
if (authority->n_layers <= n)
|
|
|
|
return;
|
|
|
|
|
2012-09-05 13:30:55 +00:00
|
|
|
/* This call to foreach_layer_internal needs to be done before
|
|
|
|
* calling pre_change_notify because it recreates the layer cache.
|
|
|
|
* We are relying on pre_change_notify to clear the layer cache
|
|
|
|
* before we change the number of layers */
|
2010-04-08 11:21:04 +00:00
|
|
|
state.keep_n = n;
|
|
|
|
state.current_pos = 0;
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_foreach_layer_internal (pipeline,
|
2010-07-05 20:33:26 +00:00
|
|
|
update_prune_layers_info_cb,
|
|
|
|
&state);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2012-09-05 13:30:55 +00:00
|
|
|
_cogl_pipeline_pre_change_notify (pipeline,
|
|
|
|
COGL_PIPELINE_STATE_LAYERS,
|
|
|
|
NULL,
|
|
|
|
FALSE);
|
|
|
|
|
2011-06-27 10:50:48 +00:00
|
|
|
pipeline->differences |= COGL_PIPELINE_STATE_LAYERS;
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->n_layers = n;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
/* It's possible that this pipeline owns some of the layers being
|
2010-04-08 11:21:04 +00:00
|
|
|
* discarded, so we'll need to unlink them... */
|
2010-10-27 17:54:57 +00:00
|
|
|
for (l = pipeline->layer_differences; l; l = next)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipelineLayer *layer = l->data;
|
2010-04-08 11:21:04 +00:00
|
|
|
next = l->next; /* we're modifying the list we're iterating */
|
|
|
|
|
2012-09-05 13:36:55 +00:00
|
|
|
if (layer->index >= state.first_index_to_prune)
|
2011-06-27 10:50:48 +00:00
|
|
|
_cogl_pipeline_remove_layer_difference (pipeline, layer, FALSE);
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
2011-06-27 10:50:48 +00:00
|
|
|
|
|
|
|
pipeline->differences |= COGL_PIPELINE_STATE_LAYERS;
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
/* The layer we are trying to find */
|
|
|
|
int layer_index;
|
|
|
|
|
|
|
|
/* The layer we find or untouched if not found */
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipelineLayer *layer;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
/* If the layer can't be found then a new layer should be
|
|
|
|
* inserted after this texture unit index... */
|
|
|
|
int insert_after;
|
|
|
|
|
|
|
|
/* When adding a layer we need the list of layers to shift up
|
|
|
|
* to a new texture unit. When removing we need the list of
|
|
|
|
* layers to shift down.
|
|
|
|
*
|
|
|
|
* Note: the list isn't sorted */
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipelineLayer **layers_to_shift;
|
2010-04-08 11:21:04 +00:00
|
|
|
int n_layers_to_shift;
|
|
|
|
|
|
|
|
/* When adding a layer we don't need a complete list of
|
|
|
|
* layers_to_shift if we find a layer already corresponding to the
|
|
|
|
* layer_index. */
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool ignore_shift_layers_if_found;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
} CoglPipelineLayerInfo;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
/* Returns TRUE once we know there is nothing more to update */
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2010-10-27 17:54:57 +00:00
|
|
|
update_layer_info (CoglPipelineLayer *layer,
|
|
|
|
CoglPipelineLayerInfo *layer_info)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
|
|
|
if (layer->index == layer_info->layer_index)
|
|
|
|
{
|
|
|
|
layer_info->layer = layer;
|
|
|
|
if (layer_info->ignore_shift_layers_if_found)
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else if (layer->index < layer_info->layer_index)
|
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
int unit_index = _cogl_pipeline_layer_get_unit_index (layer);
|
2010-04-08 11:21:04 +00:00
|
|
|
layer_info->insert_after = unit_index;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
layer_info->layers_to_shift[layer_info->n_layers_to_shift++] =
|
|
|
|
layer;
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Returns FALSE to break out of a _foreach_layer () iteration */
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2010-10-27 17:54:57 +00:00
|
|
|
update_layer_info_cb (CoglPipelineLayer *layer,
|
2010-04-08 11:21:04 +00:00
|
|
|
void *user_data)
|
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipelineLayerInfo *layer_info = user_data;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
if (update_layer_info (layer, layer_info))
|
|
|
|
return FALSE; /* break */
|
|
|
|
else
|
|
|
|
return TRUE; /* continue */
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_get_layer_info (CoglPipeline *pipeline,
|
|
|
|
CoglPipelineLayerInfo *layer_info)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
/* Note: we are assuming this pipeline is a _STATE_LAYERS authority */
|
|
|
|
int n_layers = pipeline->n_layers;
|
2010-04-08 11:21:04 +00:00
|
|
|
int i;
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
/* FIXME: _cogl_pipeline_foreach_layer_internal now calls
|
|
|
|
* _cogl_pipeline_update_layers_cache anyway so this codepath is
|
2010-04-08 11:21:04 +00:00
|
|
|
* pointless! */
|
|
|
|
if (layer_info->ignore_shift_layers_if_found &&
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->layers_cache_dirty)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
|
|
|
/* The expectation is that callers of
|
2010-10-27 17:54:57 +00:00
|
|
|
* _cogl_pipeline_get_layer_info are likely to be modifying the
|
|
|
|
* list of layers associated with a pipeline so in this case
|
2010-04-08 11:21:04 +00:00
|
|
|
* where we don't have a cache of the layers and we don't
|
2010-10-27 17:54:57 +00:00
|
|
|
* necessarily have to iterate all the layers of the pipeline we
|
2010-04-08 11:21:04 +00:00
|
|
|
* use a foreach_layer callback instead of updating the cache
|
|
|
|
* and iterating that as below. */
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_foreach_layer_internal (pipeline,
|
2010-07-05 20:33:26 +00:00
|
|
|
update_layer_info_cb,
|
|
|
|
layer_info);
|
2010-04-08 11:21:04 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_update_layers_cache (pipeline);
|
2010-04-08 11:21:04 +00:00
|
|
|
for (i = 0; i < n_layers; i++)
|
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipelineLayer *layer = pipeline->layers_cache[i];
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
if (update_layer_info (layer, layer_info))
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-07 23:42:22 +00:00
|
|
|
CoglPipelineLayer *
|
2012-02-09 20:38:03 +00:00
|
|
|
_cogl_pipeline_get_layer_with_flags (CoglPipeline *pipeline,
|
|
|
|
int layer_index,
|
|
|
|
CoglPipelineGetLayerFlags flags)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *authority =
|
|
|
|
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS);
|
|
|
|
CoglPipelineLayerInfo layer_info;
|
|
|
|
CoglPipelineLayer *layer;
|
2010-04-08 11:21:04 +00:00
|
|
|
int unit_index;
|
|
|
|
int i;
|
2011-09-20 19:46:38 +00:00
|
|
|
CoglContext *ctx;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
/* The layer index of the layer we want info about */
|
|
|
|
layer_info.layer_index = layer_index;
|
|
|
|
|
|
|
|
/* If a layer already exists with the given index this will be
|
|
|
|
* updated. */
|
|
|
|
layer_info.layer = NULL;
|
|
|
|
|
|
|
|
/* If a layer isn't found for the given index we'll need to know
|
|
|
|
* where to insert a new layer. */
|
|
|
|
layer_info.insert_after = -1;
|
|
|
|
|
|
|
|
/* If a layer can't be found then we'll need to insert a new layer
|
|
|
|
* and bump up the texture unit for all layers with an index
|
|
|
|
* > layer_index. */
|
|
|
|
layer_info.layers_to_shift =
|
2010-10-27 17:54:57 +00:00
|
|
|
g_alloca (sizeof (CoglPipelineLayer *) * authority->n_layers);
|
2010-04-08 11:21:04 +00:00
|
|
|
layer_info.n_layers_to_shift = 0;
|
|
|
|
|
|
|
|
/* If an exact match is found though we don't need a complete
|
|
|
|
* list of layers with indices > layer_index... */
|
|
|
|
layer_info.ignore_shift_layers_if_found = TRUE;
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_get_layer_info (authority, &layer_info);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2012-02-09 20:38:03 +00:00
|
|
|
if (layer_info.layer || (flags & COGL_PIPELINE_GET_LAYER_NO_CREATE))
|
2010-04-08 11:21:04 +00:00
|
|
|
return layer_info.layer;
|
|
|
|
|
2011-09-20 19:46:38 +00:00
|
|
|
ctx = _cogl_context_get_default ();
|
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
unit_index = layer_info.insert_after + 1;
|
|
|
|
if (unit_index == 0)
|
2010-10-27 17:54:57 +00:00
|
|
|
layer = _cogl_pipeline_layer_copy (ctx->default_layer_0);
|
2010-04-08 11:21:04 +00:00
|
|
|
else
|
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipelineLayer *new;
|
|
|
|
layer = _cogl_pipeline_layer_copy (ctx->default_layer_n);
|
|
|
|
new = _cogl_pipeline_set_layer_unit (NULL, layer, unit_index);
|
2010-04-08 11:21:04 +00:00
|
|
|
/* Since we passed a newly allocated layer we wouldn't expect
|
|
|
|
* _set_layer_unit() to have to allocate *another* layer. */
|
|
|
|
g_assert (new == layer);
|
|
|
|
}
|
2010-07-07 18:23:57 +00:00
|
|
|
layer->index = layer_index;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
for (i = 0; i < layer_info.n_layers_to_shift; i++)
|
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipelineLayer *shift_layer = layer_info.layers_to_shift[i];
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
unit_index = _cogl_pipeline_layer_get_unit_index (shift_layer);
|
|
|
|
_cogl_pipeline_set_layer_unit (pipeline, shift_layer, unit_index + 1);
|
2010-04-08 11:21:04 +00:00
|
|
|
/* NB: shift_layer may not be writeable so _set_layer_unit()
|
|
|
|
* will allocate a derived layer internally which will become
|
2010-10-27 17:54:57 +00:00
|
|
|
* owned by pipeline. Check the return value if we need to do
|
2010-04-08 11:21:04 +00:00
|
|
|
* anything else with this layer. */
|
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_add_layer_difference (pipeline, layer, TRUE);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-06-22 13:02:17 +00:00
|
|
|
cogl_object_unref (layer);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
return layer;
|
|
|
|
}
|
|
|
|
|
2011-09-07 23:42:22 +00:00
|
|
|
void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_prune_empty_layer_difference (CoglPipeline *layers_authority,
|
|
|
|
CoglPipelineLayer *layer)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
|
|
|
/* Find the GList link that references the empty layer */
|
|
|
|
GList *link = g_list_find (layers_authority->layer_differences, layer);
|
2010-10-27 17:54:57 +00:00
|
|
|
/* No pipeline directly owns the root node layer so this is safe... */
|
|
|
|
CoglPipelineLayer *layer_parent = _cogl_pipeline_layer_get_parent (layer);
|
|
|
|
CoglPipelineLayerInfo layer_info;
|
|
|
|
CoglPipeline *old_layers_authority;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2011-10-13 21:34:30 +00:00
|
|
|
_COGL_RETURN_IF_FAIL (link != NULL);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
/* If the layer's parent doesn't have an owner then we can simply
|
|
|
|
* take ownership ourselves and drop our reference on the empty
|
2011-04-05 16:30:29 +00:00
|
|
|
* layer. We don't want to take ownership of the root node layer so
|
|
|
|
* we also need to verify that the parent has a parent
|
2010-04-08 11:21:04 +00:00
|
|
|
*/
|
2011-04-05 16:30:29 +00:00
|
|
|
if (layer_parent->index == layer->index && layer_parent->owner == NULL &&
|
|
|
|
_cogl_pipeline_layer_get_parent (layer_parent) != NULL)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2010-06-22 13:02:17 +00:00
|
|
|
cogl_object_ref (layer_parent);
|
2011-04-05 16:01:24 +00:00
|
|
|
layer_parent->owner = layers_authority;
|
|
|
|
link->data = layer_parent;
|
2010-06-22 13:02:17 +00:00
|
|
|
cogl_object_unref (layer);
|
2010-04-08 11:21:04 +00:00
|
|
|
recursively_free_layer_caches (layers_authority);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now we want to find the layer that would become the authority for
|
|
|
|
* layer->index if we were to remove layer from
|
|
|
|
* layers_authority->layer_differences
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* The layer index of the layer we want info about */
|
|
|
|
layer_info.layer_index = layer->index;
|
|
|
|
|
|
|
|
/* If a layer already exists with the given index this will be
|
|
|
|
* updated. */
|
|
|
|
layer_info.layer = NULL;
|
|
|
|
|
|
|
|
/* If a layer can't be found then we'll need to insert a new layer
|
|
|
|
* and bump up the texture unit for all layers with an index
|
|
|
|
* > layer_index. */
|
|
|
|
layer_info.layers_to_shift =
|
2010-10-27 17:54:57 +00:00
|
|
|
g_alloca (sizeof (CoglPipelineLayer *) * layers_authority->n_layers);
|
2010-04-08 11:21:04 +00:00
|
|
|
layer_info.n_layers_to_shift = 0;
|
|
|
|
|
|
|
|
/* If an exact match is found though we don't need a complete
|
|
|
|
* list of layers with indices > layer_index... */
|
|
|
|
layer_info.ignore_shift_layers_if_found = TRUE;
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
/* We know the default/root pipeline isn't a LAYERS authority so it's
|
|
|
|
* safe to use the result of _cogl_pipeline_get_parent (layers_authority)
|
2010-07-08 10:49:31 +00:00
|
|
|
* without checking it.
|
|
|
|
*/
|
2010-04-08 11:21:04 +00:00
|
|
|
old_layers_authority =
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_get_authority (_cogl_pipeline_get_parent (layers_authority),
|
|
|
|
COGL_PIPELINE_STATE_LAYERS);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_get_layer_info (old_layers_authority, &layer_info);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
/* If layer is the defining layer for the corresponding ->index then
|
|
|
|
* we can't get rid of it. */
|
|
|
|
if (!layer_info.layer)
|
|
|
|
return;
|
|
|
|
|
2010-07-08 10:49:31 +00:00
|
|
|
/* If the layer that would become the authority for layer->index is
|
2010-10-27 17:54:57 +00:00
|
|
|
* _cogl_pipeline_layer_get_parent (layer) then we can simply remove the
|
2010-07-08 10:49:31 +00:00
|
|
|
* layer difference. */
|
2010-10-27 17:54:57 +00:00
|
|
|
if (layer_info.layer == _cogl_pipeline_layer_get_parent (layer))
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_remove_layer_difference (layers_authority, layer, FALSE);
|
|
|
|
_cogl_pipeline_try_reverting_layers_authority (layers_authority,
|
2010-04-08 11:21:04 +00:00
|
|
|
old_layers_authority);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int i;
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *pipeline;
|
2010-04-08 11:21:04 +00:00
|
|
|
unsigned long fallback_layers;
|
2010-10-27 17:54:57 +00:00
|
|
|
} CoglPipelineFallbackState;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2010-10-27 17:54:57 +00:00
|
|
|
fallback_layer_cb (CoglPipelineLayer *layer, void *user_data)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipelineFallbackState *state = user_data;
|
|
|
|
CoglPipeline *pipeline = state->pipeline;
|
2012-02-09 12:52:45 +00:00
|
|
|
CoglTextureType texture_type = _cogl_pipeline_layer_get_texture_type (layer);
|
|
|
|
CoglTexture *texture = NULL;
|
2010-04-08 11:21:04 +00:00
|
|
|
COGL_STATIC_COUNTER (layer_fallback_counter,
|
|
|
|
"layer fallback counter",
|
|
|
|
"Increments each time a layer's texture is "
|
|
|
|
"forced to a fallback texture",
|
|
|
|
0 /* no application private data */);
|
|
|
|
|
|
|
|
_COGL_GET_CONTEXT (ctx, FALSE);
|
|
|
|
|
|
|
|
if (!(state->fallback_layers & 1<<state->i))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
COGL_COUNTER_INC (_cogl_uprof_context, layer_fallback_counter);
|
|
|
|
|
2012-02-09 12:52:45 +00:00
|
|
|
switch (texture_type)
|
|
|
|
{
|
|
|
|
case COGL_TEXTURE_TYPE_2D:
|
2012-02-18 14:58:39 +00:00
|
|
|
texture = COGL_TEXTURE (ctx->default_gl_texture_2d_tex);
|
2012-02-09 12:52:45 +00:00
|
|
|
break;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2012-02-09 12:52:45 +00:00
|
|
|
case COGL_TEXTURE_TYPE_3D:
|
2012-02-18 14:58:39 +00:00
|
|
|
texture = COGL_TEXTURE (ctx->default_gl_texture_3d_tex);
|
2012-02-09 12:52:45 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case COGL_TEXTURE_TYPE_RECTANGLE:
|
2012-02-18 14:58:39 +00:00
|
|
|
texture = COGL_TEXTURE (ctx->default_gl_texture_rect_tex);
|
2012-02-09 12:52:45 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (texture == NULL)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
|
|
|
g_warning ("We don't have a fallback texture we can use to fill "
|
2010-10-27 17:54:57 +00:00
|
|
|
"in for an invalid pipeline layer, since it was "
|
2010-04-08 11:21:04 +00:00
|
|
|
"using an unsupported texture target ");
|
|
|
|
/* might get away with this... */
|
2012-02-18 14:58:39 +00:00
|
|
|
texture = COGL_TEXTURE (ctx->default_gl_texture_2d_tex);
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
cogl_pipeline_set_layer_texture (pipeline, layer->index, texture);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
state->i++;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2011-09-07 23:42:22 +00:00
|
|
|
typedef struct
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2011-09-07 23:42:22 +00:00
|
|
|
CoglPipeline *pipeline;
|
2012-04-16 13:14:10 +00:00
|
|
|
CoglTexture *texture;
|
2011-09-07 23:42:22 +00:00
|
|
|
} CoglPipelineOverrideLayerState;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2011-09-07 23:42:22 +00:00
|
|
|
override_layer_texture_cb (CoglPipelineLayer *layer, void *user_data)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2011-09-07 23:42:22 +00:00
|
|
|
CoglPipelineOverrideLayerState *state = user_data;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2011-09-07 23:42:22 +00:00
|
|
|
cogl_pipeline_set_layer_texture (state->pipeline,
|
|
|
|
layer->index,
|
|
|
|
state->texture);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2011-09-07 23:42:22 +00:00
|
|
|
return TRUE;
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2011-09-07 23:42:22 +00:00
|
|
|
_cogl_pipeline_apply_overrides (CoglPipeline *pipeline,
|
|
|
|
CoglPipelineFlushOptions *options)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2011-09-07 23:42:22 +00:00
|
|
|
COGL_STATIC_COUNTER (apply_overrides_counter,
|
|
|
|
"pipeline overrides counter",
|
|
|
|
"Increments each time we have to apply "
|
|
|
|
"override options to a pipeline",
|
|
|
|
0 /* no application private data */);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2011-09-07 23:42:22 +00:00
|
|
|
COGL_COUNTER_INC (_cogl_uprof_context, apply_overrides_counter);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2011-09-07 23:42:22 +00:00
|
|
|
if (options->flags & COGL_PIPELINE_FLUSH_DISABLE_MASK)
|
|
|
|
{
|
|
|
|
int i;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2011-09-07 23:42:22 +00:00
|
|
|
/* NB: we can assume that once we see one bit to disable
|
|
|
|
* a layer, all subsequent layers are also disabled. */
|
|
|
|
for (i = 0; i < 32 && options->disable_layers & (1<<i); i++)
|
|
|
|
;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2011-09-07 23:42:22 +00:00
|
|
|
_cogl_pipeline_prune_to_n_layers (pipeline, i);
|
|
|
|
}
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2011-09-07 23:42:22 +00:00
|
|
|
if (options->flags & COGL_PIPELINE_FLUSH_FALLBACK_MASK)
|
|
|
|
{
|
|
|
|
CoglPipelineFallbackState state;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2011-09-07 23:42:22 +00:00
|
|
|
state.i = 0;
|
|
|
|
state.pipeline = pipeline;
|
|
|
|
state.fallback_layers = options->fallback_layers;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2011-09-07 23:42:22 +00:00
|
|
|
_cogl_pipeline_foreach_layer_internal (pipeline,
|
|
|
|
fallback_layer_cb,
|
|
|
|
&state);
|
|
|
|
}
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2011-09-07 23:42:22 +00:00
|
|
|
if (options->flags & COGL_PIPELINE_FLUSH_LAYER0_OVERRIDE)
|
|
|
|
{
|
|
|
|
CoglPipelineOverrideLayerState state;
|
|
|
|
|
|
|
|
_cogl_pipeline_prune_to_n_layers (pipeline, 1);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2011-09-07 23:42:22 +00:00
|
|
|
/* NB: we are overriding the first layer, but we don't know
|
|
|
|
* the user's given layer_index, which is why we use
|
|
|
|
* _cogl_pipeline_foreach_layer_internal() here even though we know
|
|
|
|
* there's only one layer. */
|
|
|
|
state.pipeline = pipeline;
|
|
|
|
state.texture = options->layer0_override_texture;
|
|
|
|
_cogl_pipeline_foreach_layer_internal (pipeline,
|
|
|
|
override_layer_texture_cb,
|
|
|
|
&state);
|
|
|
|
}
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_layers_equal (CoglPipeline *authority0,
|
2010-12-03 11:36:49 +00:00
|
|
|
CoglPipeline *authority1,
|
|
|
|
unsigned long differences,
|
|
|
|
CoglPipelineEvalFlags flags)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (authority0->n_layers != authority1->n_layers)
|
|
|
|
return FALSE;
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_update_layers_cache (authority0);
|
|
|
|
_cogl_pipeline_update_layers_cache (authority1);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
for (i = 0; i < authority0->n_layers; i++)
|
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
if (!_cogl_pipeline_layer_equal (authority0->layers_cache[i],
|
2010-12-03 11:36:49 +00:00
|
|
|
authority1->layers_cache[i],
|
|
|
|
differences,
|
|
|
|
flags))
|
2010-04-08 11:21:04 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
/* Determine the mask of differences between two pipelines */
|
2010-07-10 02:40:47 +00:00
|
|
|
unsigned long
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_compare_differences (CoglPipeline *pipeline0,
|
|
|
|
CoglPipeline *pipeline1)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2011-09-20 20:58:26 +00:00
|
|
|
GSList *head0 = NULL;
|
|
|
|
GSList *head1 = NULL;
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *node0;
|
|
|
|
CoglPipeline *node1;
|
2011-09-20 20:58:26 +00:00
|
|
|
int len0 = 0;
|
|
|
|
int len1 = 0;
|
2010-04-08 11:21:04 +00:00
|
|
|
int count;
|
2011-09-20 20:58:26 +00:00
|
|
|
GSList *common_ancestor0;
|
|
|
|
GSList *common_ancestor1;
|
2010-10-27 17:54:57 +00:00
|
|
|
unsigned long pipelines_difference = 0;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
/* Algorithm:
|
|
|
|
*
|
2011-09-20 20:58:26 +00:00
|
|
|
* 1) Walk the ancestors of each pipeline to the root node, adding a
|
|
|
|
* pointer to each ancester node to two linked lists
|
2010-04-08 11:21:04 +00:00
|
|
|
*
|
2011-09-20 20:58:26 +00:00
|
|
|
* 2) Compare the lists to find the nodes where they start to
|
|
|
|
* differ marking the common_ancestor node for each list.
|
2010-04-08 11:21:04 +00:00
|
|
|
*
|
2011-09-20 20:58:26 +00:00
|
|
|
* 3) For each list now iterate starting after the common_ancestor
|
|
|
|
* nodes ORing each nodes ->difference mask into the final
|
|
|
|
* differences mask.
|
2010-04-08 11:21:04 +00:00
|
|
|
*/
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
for (node0 = pipeline0; node0; node0 = _cogl_pipeline_get_parent (node0))
|
2011-09-20 20:58:26 +00:00
|
|
|
{
|
|
|
|
GSList *link = alloca (sizeof (GSList));
|
|
|
|
link->next = head0;
|
|
|
|
link->data = node0;
|
|
|
|
head0 = link;
|
|
|
|
len0++;
|
|
|
|
}
|
2010-10-27 17:54:57 +00:00
|
|
|
for (node1 = pipeline1; node1; node1 = _cogl_pipeline_get_parent (node1))
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2011-09-20 20:58:26 +00:00
|
|
|
GSList *link = alloca (sizeof (GSList));
|
|
|
|
link->next = head1;
|
|
|
|
link->data = node1;
|
|
|
|
head1 = link;
|
|
|
|
len1++;
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
2011-09-20 20:58:26 +00:00
|
|
|
/* NB: There's no point looking at the head entries since we know both
|
|
|
|
* pipelines must have the same default pipeline as their root node. */
|
|
|
|
common_ancestor0 = head0;
|
|
|
|
common_ancestor1 = head1;
|
|
|
|
head0 = head0->next;
|
|
|
|
head1 = head1->next;
|
|
|
|
count = MIN (len0, len1) - 1;
|
|
|
|
while (count--)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2011-09-20 20:58:26 +00:00
|
|
|
if (head0->data != head1->data)
|
2010-04-08 11:21:04 +00:00
|
|
|
break;
|
2011-09-20 20:58:26 +00:00
|
|
|
common_ancestor0 = head0;
|
|
|
|
common_ancestor1 = head1;
|
|
|
|
head0 = head0->next;
|
|
|
|
head1 = head1->next;
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
2011-09-20 20:58:26 +00:00
|
|
|
for (head0 = common_ancestor0->next; head0; head0 = head0->next)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2011-09-20 20:58:26 +00:00
|
|
|
node0 = head0->data;
|
|
|
|
pipelines_difference |= node0->differences;
|
|
|
|
}
|
|
|
|
for (head1 = common_ancestor1->next; head1; head1 = head1->next)
|
|
|
|
{
|
|
|
|
node1 = head1->data;
|
2010-10-27 17:54:57 +00:00
|
|
|
pipelines_difference |= node1->differences;
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
return pipelines_difference;
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
2010-12-03 11:36:49 +00:00
|
|
|
static void
|
|
|
|
_cogl_pipeline_resolve_authorities (CoglPipeline *pipeline,
|
|
|
|
unsigned long differences,
|
|
|
|
CoglPipeline **authorities)
|
|
|
|
{
|
|
|
|
unsigned long remaining = differences;
|
|
|
|
CoglPipeline *authority = pipeline;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
unsigned long found = authority->differences & remaining;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (found == 0)
|
|
|
|
continue;
|
|
|
|
|
2010-12-07 16:36:44 +00:00
|
|
|
for (i = 0; TRUE; i++)
|
2010-12-03 11:36:49 +00:00
|
|
|
{
|
|
|
|
unsigned long state = (1L<<i);
|
|
|
|
|
|
|
|
if (state & found)
|
|
|
|
authorities[i] = authority;
|
|
|
|
else if (state > found)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
remaining &= ~found;
|
|
|
|
if (remaining == 0)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
while ((authority = _cogl_pipeline_get_parent (authority)));
|
|
|
|
|
|
|
|
g_assert (remaining == 0);
|
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
/* Comparison of two arbitrary pipelines is done by:
|
|
|
|
* 1) walking up the parents of each pipeline until a common
|
2010-04-08 11:21:04 +00:00
|
|
|
* ancestor is found, and at each step ORing together the
|
|
|
|
* difference masks.
|
|
|
|
*
|
|
|
|
* 2) using the final difference mask to determine which state
|
|
|
|
* groups to compare.
|
|
|
|
*
|
2010-12-03 11:36:49 +00:00
|
|
|
* This is used, for example, by the Cogl journal to compare pipelines so that
|
|
|
|
* it can split up geometry that needs different OpenGL state.
|
2010-04-08 11:21:04 +00:00
|
|
|
*
|
2010-12-03 11:36:49 +00:00
|
|
|
* XXX: When comparing texture layers, _cogl_pipeline_equal will actually
|
|
|
|
* compare the underlying GL texture handle that the Cogl texture uses so that
|
|
|
|
* atlas textures and sub textures will be considered equal if they point to
|
|
|
|
* the same texture. This is useful for comparing pipelines in the journal but
|
|
|
|
* it means that _cogl_pipeline_equal doesn't strictly compare whether the
|
|
|
|
* pipelines are the same. If we needed those semantics we could perhaps add
|
|
|
|
* another function or some flags to control the behaviour.
|
2011-03-30 15:33:04 +00:00
|
|
|
*
|
|
|
|
* XXX: Similarly when comparing the wrap modes,
|
|
|
|
* COGL_PIPELINE_WRAP_MODE_AUTOMATIC is considered to be the same as
|
|
|
|
* COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE because once they get to the
|
|
|
|
* journal stage they act exactly the same.
|
2010-04-08 11:21:04 +00:00
|
|
|
*/
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_equal (CoglPipeline *pipeline0,
|
|
|
|
CoglPipeline *pipeline1,
|
2013-05-16 14:19:30 +00:00
|
|
|
unsigned int differences,
|
2010-12-03 11:36:49 +00:00
|
|
|
unsigned long layer_differences,
|
|
|
|
CoglPipelineEvalFlags flags)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2010-12-03 11:36:49 +00:00
|
|
|
unsigned long pipelines_difference;
|
|
|
|
CoglPipeline *authorities0[COGL_PIPELINE_STATE_SPARSE_COUNT];
|
|
|
|
CoglPipeline *authorities1[COGL_PIPELINE_STATE_SPARSE_COUNT];
|
2012-02-20 00:09:37 +00:00
|
|
|
int bit;
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool ret;
|
2010-12-03 11:36:49 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
COGL_STATIC_TIMER (pipeline_equal_timer,
|
2010-07-26 14:21:18 +00:00
|
|
|
"Mainloop", /* parent */
|
2010-10-27 17:54:57 +00:00
|
|
|
"_cogl_pipeline_equal",
|
|
|
|
"The time spent comparing cogl pipelines",
|
2010-07-26 14:21:18 +00:00
|
|
|
0 /* no application private data */);
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
COGL_TIMER_START (_cogl_uprof_context, pipeline_equal_timer);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (pipeline0 == pipeline1)
|
2010-07-26 14:21:18 +00:00
|
|
|
{
|
|
|
|
ret = TRUE;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = FALSE;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2013-05-16 14:19:30 +00:00
|
|
|
_cogl_pipeline_update_real_blend_enable (pipeline0, FALSE);
|
|
|
|
_cogl_pipeline_update_real_blend_enable (pipeline1, FALSE);
|
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
/* First check non-sparse properties */
|
|
|
|
|
2010-12-03 11:36:49 +00:00
|
|
|
if (differences & COGL_PIPELINE_STATE_REAL_BLEND_ENABLE &&
|
|
|
|
pipeline0->real_blend_enable != pipeline1->real_blend_enable)
|
2010-07-26 14:21:18 +00:00
|
|
|
goto done;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
/* Then check sparse properties */
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipelines_difference =
|
|
|
|
_cogl_pipeline_compare_differences (pipeline0, pipeline1);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-12-03 11:36:49 +00:00
|
|
|
/* Only compare the sparse state groups requested by the caller... */
|
|
|
|
pipelines_difference &= differences;
|
|
|
|
|
|
|
|
_cogl_pipeline_resolve_authorities (pipeline0,
|
|
|
|
pipelines_difference,
|
|
|
|
authorities0);
|
|
|
|
_cogl_pipeline_resolve_authorities (pipeline1,
|
|
|
|
pipelines_difference,
|
|
|
|
authorities1);
|
|
|
|
|
2012-02-20 00:09:37 +00:00
|
|
|
COGL_FLAGS_FOREACH_START (&pipelines_difference, 1, bit)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2012-02-20 00:09:37 +00:00
|
|
|
/* XXX: We considered having an array of callbacks for each state index
|
|
|
|
* that we'd call here but decided that this way the compiler is more
|
|
|
|
* likely going to be able to in-line the comparison functions and use
|
|
|
|
* the index to jump straight to the required code. */
|
|
|
|
switch ((CoglPipelineStateIndex)bit)
|
|
|
|
{
|
|
|
|
case COGL_PIPELINE_STATE_COLOR_INDEX:
|
|
|
|
if (!cogl_color_equal (&authorities0[bit]->color,
|
|
|
|
&authorities1[bit]->color))
|
|
|
|
goto done;
|
|
|
|
break;
|
|
|
|
case COGL_PIPELINE_STATE_LIGHTING_INDEX:
|
|
|
|
if (!_cogl_pipeline_lighting_state_equal (authorities0[bit],
|
|
|
|
authorities1[bit]))
|
|
|
|
goto done;
|
|
|
|
break;
|
|
|
|
case COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX:
|
|
|
|
if (!_cogl_pipeline_alpha_func_state_equal (authorities0[bit],
|
|
|
|
authorities1[bit]))
|
|
|
|
goto done;
|
|
|
|
break;
|
|
|
|
case COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX:
|
|
|
|
if (!_cogl_pipeline_alpha_func_reference_state_equal (
|
|
|
|
authorities0[bit],
|
|
|
|
authorities1[bit]))
|
|
|
|
goto done;
|
|
|
|
break;
|
|
|
|
case COGL_PIPELINE_STATE_BLEND_INDEX:
|
|
|
|
/* We don't need to compare the detailed blending state if we know
|
|
|
|
* blending is disabled for both pipelines. */
|
|
|
|
if (pipeline0->real_blend_enable)
|
|
|
|
{
|
|
|
|
if (!_cogl_pipeline_blend_state_equal (authorities0[bit],
|
|
|
|
authorities1[bit]))
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case COGL_PIPELINE_STATE_DEPTH_INDEX:
|
|
|
|
if (!_cogl_pipeline_depth_state_equal (authorities0[bit],
|
|
|
|
authorities1[bit]))
|
|
|
|
goto done;
|
|
|
|
break;
|
|
|
|
case COGL_PIPELINE_STATE_FOG_INDEX:
|
|
|
|
if (!_cogl_pipeline_fog_state_equal (authorities0[bit],
|
|
|
|
authorities1[bit]))
|
|
|
|
goto done;
|
|
|
|
break;
|
|
|
|
case COGL_PIPELINE_STATE_CULL_FACE_INDEX:
|
|
|
|
if (!_cogl_pipeline_cull_face_state_equal (authorities0[bit],
|
|
|
|
authorities1[bit]))
|
|
|
|
goto done;
|
|
|
|
break;
|
|
|
|
case COGL_PIPELINE_STATE_POINT_SIZE_INDEX:
|
|
|
|
if (!_cogl_pipeline_point_size_equal (authorities0[bit],
|
|
|
|
authorities1[bit]))
|
|
|
|
goto done;
|
|
|
|
break;
|
2012-11-08 16:56:02 +00:00
|
|
|
case COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE_INDEX:
|
|
|
|
if (!_cogl_pipeline_per_vertex_point_size_equal (authorities0[bit],
|
|
|
|
authorities1[bit]))
|
|
|
|
goto done;
|
|
|
|
break;
|
2012-02-20 00:09:37 +00:00
|
|
|
case COGL_PIPELINE_STATE_LOGIC_OPS_INDEX:
|
|
|
|
if (!_cogl_pipeline_logic_ops_state_equal (authorities0[bit],
|
|
|
|
authorities1[bit]))
|
|
|
|
goto done;
|
|
|
|
break;
|
|
|
|
case COGL_PIPELINE_STATE_USER_SHADER_INDEX:
|
|
|
|
if (!_cogl_pipeline_user_shader_equal (authorities0[bit],
|
|
|
|
authorities1[bit]))
|
|
|
|
goto done;
|
|
|
|
break;
|
|
|
|
case COGL_PIPELINE_STATE_UNIFORMS_INDEX:
|
|
|
|
if (!_cogl_pipeline_uniforms_state_equal (authorities0[bit],
|
|
|
|
authorities1[bit]))
|
|
|
|
goto done;
|
|
|
|
break;
|
|
|
|
case COGL_PIPELINE_STATE_VERTEX_SNIPPETS_INDEX:
|
|
|
|
if (!_cogl_pipeline_vertex_snippets_state_equal (authorities0[bit],
|
|
|
|
authorities1[bit]))
|
|
|
|
goto done;
|
|
|
|
break;
|
|
|
|
case COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS_INDEX:
|
|
|
|
if (!_cogl_pipeline_fragment_snippets_state_equal (authorities0[bit],
|
|
|
|
authorities1[bit]))
|
|
|
|
goto done;
|
|
|
|
break;
|
|
|
|
case COGL_PIPELINE_STATE_LAYERS_INDEX:
|
|
|
|
{
|
|
|
|
if (!_cogl_pipeline_layers_equal (authorities0[bit],
|
|
|
|
authorities1[bit],
|
|
|
|
layer_differences,
|
|
|
|
flags))
|
|
|
|
goto done;
|
|
|
|
break;
|
|
|
|
}
|
2011-11-17 16:52:21 +00:00
|
|
|
|
2012-02-20 00:09:37 +00:00
|
|
|
case COGL_PIPELINE_STATE_BLEND_ENABLE_INDEX:
|
|
|
|
case COGL_PIPELINE_STATE_REAL_BLEND_ENABLE_INDEX:
|
|
|
|
case COGL_PIPELINE_STATE_COUNT:
|
|
|
|
g_warn_if_reached ();
|
|
|
|
}
|
2010-12-03 11:36:49 +00:00
|
|
|
}
|
2012-02-20 00:09:37 +00:00
|
|
|
COGL_FLAGS_FOREACH_END;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-07-26 14:21:18 +00:00
|
|
|
ret = TRUE;
|
|
|
|
done:
|
2010-10-27 17:54:57 +00:00
|
|
|
COGL_TIMER_STOP (_cogl_uprof_context, pipeline_equal_timer);
|
2010-07-26 14:21:18 +00:00
|
|
|
return ret;
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 17:46:42 +00:00
|
|
|
}
|
|
|
|
|
2008-12-23 23:35:49 +00:00
|
|
|
void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_prune_redundant_ancestry (CoglPipeline *pipeline)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *new_parent = _cogl_pipeline_get_parent (pipeline);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-09-23 21:18:42 +00:00
|
|
|
/* Before considering pruning redundant ancestry we check if this
|
2010-10-27 17:54:57 +00:00
|
|
|
* pipeline is an authority for layer state and if so only consider
|
2010-09-23 21:18:42 +00:00
|
|
|
* reparenting if it *owns* all the layers it depends on. NB: A
|
2010-10-27 17:54:57 +00:00
|
|
|
* pipeline can be be a STATE_LAYERS authority but it may still
|
2010-09-23 21:18:42 +00:00
|
|
|
* defer to its ancestors to define the state for some of its
|
|
|
|
* layers.
|
|
|
|
*
|
2010-10-27 17:54:57 +00:00
|
|
|
* For example a pipeline that derives from a parent with 5 layers
|
2010-09-23 21:18:42 +00:00
|
|
|
* can become a STATE_LAYERS authority by simply changing it's
|
|
|
|
* ->n_layers count to 4 and in that case it can still defer to its
|
|
|
|
* ancestors to define the state of those 4 layers.
|
|
|
|
*
|
2010-10-27 17:54:57 +00:00
|
|
|
* If a pipeline depends on any ancestors for layer state then we
|
2010-09-23 21:18:42 +00:00
|
|
|
* immediatly bail out.
|
|
|
|
*/
|
2010-10-27 17:54:57 +00:00
|
|
|
if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS)
|
2010-09-23 21:18:42 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
if (pipeline->n_layers != g_list_length (pipeline->layer_differences))
|
2010-09-23 21:18:42 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
/* walk up past ancestors that are now redundant and potentially
|
2010-10-27 17:54:57 +00:00
|
|
|
* reparent the pipeline. */
|
|
|
|
while (_cogl_pipeline_get_parent (new_parent) &&
|
|
|
|
(new_parent->differences | pipeline->differences) ==
|
|
|
|
pipeline->differences)
|
|
|
|
new_parent = _cogl_pipeline_get_parent (new_parent);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (new_parent != _cogl_pipeline_get_parent (pipeline))
|
2010-08-09 15:01:17 +00:00
|
|
|
{
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool is_weak = _cogl_pipeline_is_weak (pipeline);
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_set_parent (pipeline, new_parent, is_weak ? FALSE : TRUE);
|
2010-08-09 15:01:17 +00:00
|
|
|
}
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
|
|
|
|
2011-09-07 22:44:37 +00:00
|
|
|
void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_update_authority (CoglPipeline *pipeline,
|
|
|
|
CoglPipeline *authority,
|
|
|
|
CoglPipelineState state,
|
|
|
|
CoglPipelineStateComparitor comparitor)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
|
|
|
/* If we are the current authority see if we can revert to one of
|
|
|
|
* our ancestors being the authority */
|
2010-10-27 17:54:57 +00:00
|
|
|
if (pipeline == authority &&
|
|
|
|
_cogl_pipeline_get_parent (authority) != NULL)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *parent = _cogl_pipeline_get_parent (authority);
|
|
|
|
CoglPipeline *old_authority =
|
|
|
|
_cogl_pipeline_get_authority (parent, state);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
|
|
|
if (comparitor (authority, old_authority))
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->differences &= ~state;
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
2010-10-27 17:54:57 +00:00
|
|
|
else if (pipeline != authority)
|
2010-04-08 11:21:04 +00:00
|
|
|
{
|
|
|
|
/* If we weren't previously the authority on this state then we
|
|
|
|
* need to extended our differences mask and so it's possible
|
|
|
|
* that some of our ancestry will now become redundant, so we
|
|
|
|
* aim to reparent ourselves if that's true... */
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->differences |= state;
|
|
|
|
_cogl_pipeline_prune_redundant_ancestry (pipeline);
|
2010-04-08 11:21:04 +00:00
|
|
|
}
|
Fully integrates CoglMaterial throughout the rest of Cogl
This glues CoglMaterial in as the fundamental way that Cogl describes how to
fill in geometry.
It adds cogl_set_source (), which is used to set the material which will be
used by all subsequent drawing functions
It adds cogl_set_source_texture as a convenience for setting up a default
material with a single texture layer, and cogl_set_source_color is now also
a convenience for setting up a material with a solid fill.
"drawing functions" include, cogl_rectangle, cogl_texture_rectangle,
cogl_texture_multiple_rectangles, cogl_texture_polygon (though the
cogl_texture_* funcs have been renamed; see below for details),
cogl_path_fill/stroke and cogl_vertex_buffer_draw*.
cogl_texture_rectangle, cogl_texture_multiple_rectangles and
cogl_texture_polygon no longer take a texture handle; instead the current
source material is referenced. The functions have also been renamed to:
cogl_rectangle_with_texture_coords, cogl_rectangles_with_texture_coords
and cogl_polygon respectivly.
Most code that previously did:
cogl_texture_rectangle (tex_handle, x, y,...);
needs to be changed to now do:
cogl_set_source_texture (tex_handle);
cogl_rectangle_with_texture_coords (x, y,....);
In the less likely case where you were blending your source texture with a color
like:
cogl_set_source_color4ub (r,g,b,a); /* where r,g,b,a isn't just white */
cogl_texture_rectangle (tex_handle, x, y,...);
you will need your own material to do that:
mat = cogl_material_new ();
cogl_material_set_color4ub (r,g,b,a);
cogl_material_set_layer (mat, 0, tex_handle));
cogl_set_source_material (mat);
Code that uses the texture coordinates, 0, 0, 1, 1 don't need to use
cog_rectangle_with_texure_coords since these are the coordinates that
cogl_rectangle will use.
For cogl_texture_polygon; as well as dropping the texture handle, the
n_vertices and vertices arguments were transposed for consistency. So
code previously written as:
cogl_texture_polygon (tex_handle, 3, verts, TRUE);
need to be written as:
cogl_set_source_texture (tex_handle);
cogl_polygon (verts, 3, TRUE);
All of the unit tests have been updated to now use the material API and
test-cogl-material has been renamed to test-cogl-multitexture since any
textured quad is now technically a test of CoglMaterial but this test
specifically creates a material with multiple texture layers.
Note: The GLES backend has not been updated yet; that will be done in a
following commit.
2009-01-23 16:15:40 +00:00
|
|
|
}
|
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool
|
2011-09-14 14:25:58 +00:00
|
|
|
_cogl_pipeline_get_fog_enabled (CoglPipeline *pipeline)
|
|
|
|
{
|
|
|
|
CoglPipeline *authority;
|
|
|
|
|
2011-10-13 21:34:30 +00:00
|
|
|
_COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE);
|
2011-09-14 14:25:58 +00:00
|
|
|
|
|
|
|
authority =
|
|
|
|
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_FOG);
|
|
|
|
return authority->big_state->fog_state.enabled;
|
|
|
|
}
|
|
|
|
|
2011-09-07 22:44:37 +00:00
|
|
|
unsigned long
|
|
|
|
_cogl_pipeline_get_age (CoglPipeline *pipeline)
|
2008-12-23 23:35:49 +00:00
|
|
|
{
|
2011-10-13 21:34:30 +00:00
|
|
|
_COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), 0);
|
Fully integrates CoglMaterial throughout the rest of Cogl
This glues CoglMaterial in as the fundamental way that Cogl describes how to
fill in geometry.
It adds cogl_set_source (), which is used to set the material which will be
used by all subsequent drawing functions
It adds cogl_set_source_texture as a convenience for setting up a default
material with a single texture layer, and cogl_set_source_color is now also
a convenience for setting up a material with a solid fill.
"drawing functions" include, cogl_rectangle, cogl_texture_rectangle,
cogl_texture_multiple_rectangles, cogl_texture_polygon (though the
cogl_texture_* funcs have been renamed; see below for details),
cogl_path_fill/stroke and cogl_vertex_buffer_draw*.
cogl_texture_rectangle, cogl_texture_multiple_rectangles and
cogl_texture_polygon no longer take a texture handle; instead the current
source material is referenced. The functions have also been renamed to:
cogl_rectangle_with_texture_coords, cogl_rectangles_with_texture_coords
and cogl_polygon respectivly.
Most code that previously did:
cogl_texture_rectangle (tex_handle, x, y,...);
needs to be changed to now do:
cogl_set_source_texture (tex_handle);
cogl_rectangle_with_texture_coords (x, y,....);
In the less likely case where you were blending your source texture with a color
like:
cogl_set_source_color4ub (r,g,b,a); /* where r,g,b,a isn't just white */
cogl_texture_rectangle (tex_handle, x, y,...);
you will need your own material to do that:
mat = cogl_material_new ();
cogl_material_set_color4ub (r,g,b,a);
cogl_material_set_layer (mat, 0, tex_handle));
cogl_set_source_material (mat);
Code that uses the texture coordinates, 0, 0, 1, 1 don't need to use
cog_rectangle_with_texure_coords since these are the coordinates that
cogl_rectangle will use.
For cogl_texture_polygon; as well as dropping the texture handle, the
n_vertices and vertices arguments were transposed for consistency. So
code previously written as:
cogl_texture_polygon (tex_handle, 3, verts, TRUE);
need to be written as:
cogl_set_source_texture (tex_handle);
cogl_polygon (verts, 3, TRUE);
All of the unit tests have been updated to now use the material API and
test-cogl-material has been renamed to test-cogl-multitexture since any
textured quad is now technically a test of CoglMaterial but this test
specifically creates a material with multiple texture layers.
Note: The GLES backend has not been updated yet; that will be done in a
following commit.
2009-01-23 16:15:40 +00:00
|
|
|
|
2011-09-07 22:44:37 +00:00
|
|
|
return pipeline->age;
|
Fully integrates CoglMaterial throughout the rest of Cogl
This glues CoglMaterial in as the fundamental way that Cogl describes how to
fill in geometry.
It adds cogl_set_source (), which is used to set the material which will be
used by all subsequent drawing functions
It adds cogl_set_source_texture as a convenience for setting up a default
material with a single texture layer, and cogl_set_source_color is now also
a convenience for setting up a material with a solid fill.
"drawing functions" include, cogl_rectangle, cogl_texture_rectangle,
cogl_texture_multiple_rectangles, cogl_texture_polygon (though the
cogl_texture_* funcs have been renamed; see below for details),
cogl_path_fill/stroke and cogl_vertex_buffer_draw*.
cogl_texture_rectangle, cogl_texture_multiple_rectangles and
cogl_texture_polygon no longer take a texture handle; instead the current
source material is referenced. The functions have also been renamed to:
cogl_rectangle_with_texture_coords, cogl_rectangles_with_texture_coords
and cogl_polygon respectivly.
Most code that previously did:
cogl_texture_rectangle (tex_handle, x, y,...);
needs to be changed to now do:
cogl_set_source_texture (tex_handle);
cogl_rectangle_with_texture_coords (x, y,....);
In the less likely case where you were blending your source texture with a color
like:
cogl_set_source_color4ub (r,g,b,a); /* where r,g,b,a isn't just white */
cogl_texture_rectangle (tex_handle, x, y,...);
you will need your own material to do that:
mat = cogl_material_new ();
cogl_material_set_color4ub (r,g,b,a);
cogl_material_set_layer (mat, 0, tex_handle));
cogl_set_source_material (mat);
Code that uses the texture coordinates, 0, 0, 1, 1 don't need to use
cog_rectangle_with_texure_coords since these are the coordinates that
cogl_rectangle will use.
For cogl_texture_polygon; as well as dropping the texture handle, the
n_vertices and vertices arguments were transposed for consistency. So
code previously written as:
cogl_texture_polygon (tex_handle, 3, verts, TRUE);
need to be written as:
cogl_set_source_texture (tex_handle);
cogl_polygon (verts, 3, TRUE);
All of the unit tests have been updated to now use the material API and
test-cogl-material has been renamed to test-cogl-multitexture since any
textured quad is now technically a test of CoglMaterial but this test
specifically creates a material with multiple texture layers.
Note: The GLES backend has not been updated yet; that will be done in a
following commit.
2009-01-23 16:15:40 +00:00
|
|
|
}
|
|
|
|
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
void
|
2010-10-27 17:54:57 +00:00
|
|
|
cogl_pipeline_remove_layer (CoglPipeline *pipeline, int layer_index)
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *authority;
|
|
|
|
CoglPipelineLayerInfo layer_info;
|
2010-04-08 11:21:04 +00:00
|
|
|
int i;
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
|
2011-10-13 21:34:30 +00:00
|
|
|
_COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
authority =
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS);
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 17:46:42 +00:00
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
/* The layer index of the layer we want info about */
|
|
|
|
layer_info.layer_index = layer_index;
|
2010-04-26 09:01:43 +00:00
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
/* This will be updated with a reference to the layer being removed
|
|
|
|
* if it can be found. */
|
|
|
|
layer_info.layer = NULL;
|
2009-06-24 17:34:06 +00:00
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
/* This will be filled in with a list of layers that need to be
|
|
|
|
* dropped down to a lower texture unit to fill the gap of the
|
|
|
|
* removed layer. */
|
|
|
|
layer_info.layers_to_shift =
|
2010-10-27 17:54:57 +00:00
|
|
|
g_alloca (sizeof (CoglPipelineLayer *) * authority->n_layers);
|
2010-04-08 11:21:04 +00:00
|
|
|
layer_info.n_layers_to_shift = 0;
|
2010-04-26 09:01:43 +00:00
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
/* Unlike when we query layer info when adding a layer we must
|
|
|
|
* always have a complete layers_to_shift list... */
|
|
|
|
layer_info.ignore_shift_layers_if_found = FALSE;
|
2009-06-24 17:34:06 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_get_layer_info (authority, &layer_info);
|
2010-04-26 09:01:43 +00:00
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
if (layer_info.layer == NULL)
|
|
|
|
return;
|
2010-04-26 09:01:43 +00:00
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
for (i = 0; i < layer_info.n_layers_to_shift; i++)
|
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipelineLayer *shift_layer = layer_info.layers_to_shift[i];
|
|
|
|
int unit_index = _cogl_pipeline_layer_get_unit_index (shift_layer);
|
|
|
|
_cogl_pipeline_set_layer_unit (pipeline, shift_layer, unit_index - 1);
|
2010-04-08 11:21:04 +00:00
|
|
|
/* NB: shift_layer may not be writeable so _set_layer_unit()
|
|
|
|
* will allocate a derived layer internally which will become
|
2010-10-27 17:54:57 +00:00
|
|
|
* owned by pipeline. Check the return value if we need to do
|
2010-04-08 11:21:04 +00:00
|
|
|
* anything else with this layer. */
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
}
|
Fully integrates CoglMaterial throughout the rest of Cogl
This glues CoglMaterial in as the fundamental way that Cogl describes how to
fill in geometry.
It adds cogl_set_source (), which is used to set the material which will be
used by all subsequent drawing functions
It adds cogl_set_source_texture as a convenience for setting up a default
material with a single texture layer, and cogl_set_source_color is now also
a convenience for setting up a material with a solid fill.
"drawing functions" include, cogl_rectangle, cogl_texture_rectangle,
cogl_texture_multiple_rectangles, cogl_texture_polygon (though the
cogl_texture_* funcs have been renamed; see below for details),
cogl_path_fill/stroke and cogl_vertex_buffer_draw*.
cogl_texture_rectangle, cogl_texture_multiple_rectangles and
cogl_texture_polygon no longer take a texture handle; instead the current
source material is referenced. The functions have also been renamed to:
cogl_rectangle_with_texture_coords, cogl_rectangles_with_texture_coords
and cogl_polygon respectivly.
Most code that previously did:
cogl_texture_rectangle (tex_handle, x, y,...);
needs to be changed to now do:
cogl_set_source_texture (tex_handle);
cogl_rectangle_with_texture_coords (x, y,....);
In the less likely case where you were blending your source texture with a color
like:
cogl_set_source_color4ub (r,g,b,a); /* where r,g,b,a isn't just white */
cogl_texture_rectangle (tex_handle, x, y,...);
you will need your own material to do that:
mat = cogl_material_new ();
cogl_material_set_color4ub (r,g,b,a);
cogl_material_set_layer (mat, 0, tex_handle));
cogl_set_source_material (mat);
Code that uses the texture coordinates, 0, 0, 1, 1 don't need to use
cog_rectangle_with_texure_coords since these are the coordinates that
cogl_rectangle will use.
For cogl_texture_polygon; as well as dropping the texture handle, the
n_vertices and vertices arguments were transposed for consistency. So
code previously written as:
cogl_texture_polygon (tex_handle, 3, verts, TRUE);
need to be written as:
cogl_set_source_texture (tex_handle);
cogl_polygon (verts, 3, TRUE);
All of the unit tests have been updated to now use the material API and
test-cogl-material has been renamed to test-cogl-multitexture since any
textured quad is now technically a test of CoglMaterial but this test
specifically creates a material with multiple texture layers.
Note: The GLES backend has not been updated yet; that will be done in a
following commit.
2009-01-23 16:15:40 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_remove_layer_difference (pipeline, layer_info.layer, TRUE);
|
|
|
|
_cogl_pipeline_try_reverting_layers_authority (pipeline, NULL);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2013-05-16 14:19:30 +00:00
|
|
|
pipeline->dirty_real_blend_enable = TRUE;
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
}
|
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2010-10-27 17:54:57 +00:00
|
|
|
prepend_layer_to_list_cb (CoglPipelineLayer *layer,
|
2010-04-08 11:21:04 +00:00
|
|
|
void *user_data)
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
{
|
2010-04-08 11:21:04 +00:00
|
|
|
GList **layers = user_data;
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
*layers = g_list_prepend (*layers, layer);
|
|
|
|
return TRUE;
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
}
|
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
/* TODO: deprecate this API and replace it with
|
2010-10-27 17:54:57 +00:00
|
|
|
* cogl_pipeline_foreach_layer
|
2010-04-08 11:21:04 +00:00
|
|
|
* TODO: update the docs to note that if the user modifies any layers
|
|
|
|
* then the list may become invalid.
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
*/
|
|
|
|
const GList *
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_get_layers (CoglPipeline *pipeline)
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
{
|
2011-10-13 21:34:30 +00:00
|
|
|
_COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), NULL);
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
if (!pipeline->deprecated_get_layers_list_dirty)
|
|
|
|
g_list_free (pipeline->deprecated_get_layers_list);
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->deprecated_get_layers_list = NULL;
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_foreach_layer_internal (pipeline,
|
2010-07-05 20:33:26 +00:00
|
|
|
prepend_layer_to_list_cb,
|
2010-10-27 17:54:57 +00:00
|
|
|
&pipeline->deprecated_get_layers_list);
|
|
|
|
pipeline->deprecated_get_layers_list =
|
|
|
|
g_list_reverse (pipeline->deprecated_get_layers_list);
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->deprecated_get_layers_list_dirty = 0;
|
2010-04-08 11:21:04 +00:00
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
return pipeline->deprecated_get_layers_list;
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
}
|
|
|
|
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 17:46:42 +00:00
|
|
|
int
|
2010-10-27 17:54:57 +00:00
|
|
|
cogl_pipeline_get_n_layers (CoglPipeline *pipeline)
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 17:46:42 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *authority;
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 17:46:42 +00:00
|
|
|
|
2011-10-13 21:34:30 +00:00
|
|
|
_COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), 0);
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 17:46:42 +00:00
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
authority =
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS);
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 17:46:42 +00:00
|
|
|
|
2010-04-08 11:21:04 +00:00
|
|
|
return authority->n_layers;
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 17:46:42 +00:00
|
|
|
}
|
|
|
|
|
2010-07-28 12:59:34 +00:00
|
|
|
void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_pre_paint_for_layer (CoglPipeline *pipeline,
|
2010-07-28 12:59:34 +00:00
|
|
|
int layer_id)
|
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipelineLayer *layer = _cogl_pipeline_get_layer (pipeline, layer_id);
|
|
|
|
_cogl_pipeline_layer_pre_paint (layer);
|
2010-07-28 12:59:34 +00:00
|
|
|
}
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
/* While a pipeline is referenced by the Cogl journal we can not allow
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 17:46:42 +00:00
|
|
|
* modifications, so this gives us a mechanism to track journal
|
|
|
|
* references separately */
|
2010-10-27 17:54:57 +00:00
|
|
|
CoglPipeline *
|
|
|
|
_cogl_pipeline_journal_ref (CoglPipeline *pipeline)
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 17:46:42 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->journal_ref_count++;
|
|
|
|
return cogl_object_ref (pipeline);
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 17:46:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_journal_unref (CoglPipeline *pipeline)
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 17:46:42 +00:00
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->journal_ref_count--;
|
|
|
|
cogl_object_unref (pipeline);
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 20:11:30 +00:00
|
|
|
}
|
|
|
|
|
2013-05-30 14:42:35 +00:00
|
|
|
#ifdef COGL_DEBUG_ENABLED
|
2010-04-26 09:01:43 +00:00
|
|
|
void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_apply_legacy_state (CoglPipeline *pipeline)
|
2010-04-26 09:01:43 +00:00
|
|
|
{
|
|
|
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
|
|
|
|
2010-05-26 10:33:32 +00:00
|
|
|
/* It was a mistake that we ever copied the OpenGL style API for
|
|
|
|
* associating these things directly with the context when we
|
|
|
|
* originally wrote Cogl. Until the corresponding deprecated APIs
|
|
|
|
* can be removed though we now shoehorn the state changes through
|
2010-10-27 17:54:57 +00:00
|
|
|
* the cogl_pipeline API instead.
|
2010-05-26 10:33:32 +00:00
|
|
|
*/
|
|
|
|
|
2010-10-27 17:54:57 +00:00
|
|
|
/* A program explicitly set on the pipeline has higher precedence than
|
2010-08-05 09:46:54 +00:00
|
|
|
* one associated with the context using cogl_program_use() */
|
|
|
|
if (ctx->current_program &&
|
2010-10-27 17:54:57 +00:00
|
|
|
cogl_pipeline_get_user_program (pipeline) == COGL_INVALID_HANDLE)
|
|
|
|
cogl_pipeline_set_user_program (pipeline, ctx->current_program);
|
2010-05-26 10:33:32 +00:00
|
|
|
|
|
|
|
if (ctx->legacy_depth_test_enabled)
|
2011-04-14 17:12:03 +00:00
|
|
|
{
|
|
|
|
CoglDepthState depth_state;
|
|
|
|
cogl_depth_state_init (&depth_state);
|
|
|
|
cogl_depth_state_set_test_enabled (&depth_state, TRUE);
|
|
|
|
cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL);
|
|
|
|
}
|
2010-07-06 19:18:26 +00:00
|
|
|
|
|
|
|
if (ctx->legacy_fog_state.enabled)
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_set_fog_state (pipeline, &ctx->legacy_fog_state);
|
2011-09-15 10:25:39 +00:00
|
|
|
|
|
|
|
if (ctx->legacy_backface_culling_enabled)
|
2011-11-08 13:58:33 +00:00
|
|
|
cogl_pipeline_set_cull_face_mode (pipeline,
|
|
|
|
COGL_PIPELINE_CULL_FACE_MODE_BACK);
|
2010-04-26 09:01:43 +00:00
|
|
|
}
|
|
|
|
|
2010-05-18 23:36:31 +00:00
|
|
|
void
|
2010-10-27 17:54:57 +00:00
|
|
|
_cogl_pipeline_set_static_breadcrumb (CoglPipeline *pipeline,
|
2010-05-18 23:36:31 +00:00
|
|
|
const char *breadcrumb)
|
|
|
|
{
|
2010-10-27 17:54:57 +00:00
|
|
|
pipeline->has_static_breadcrumb = TRUE;
|
|
|
|
pipeline->static_breadcrumb = breadcrumb;
|
2010-05-18 23:36:31 +00:00
|
|
|
}
|
2013-05-30 14:42:35 +00:00
|
|
|
#endif
|
2010-05-18 23:36:31 +00:00
|
|
|
|
2010-11-04 13:57:36 +00:00
|
|
|
typedef void (*LayerStateHashFunction) (CoglPipelineLayer *authority,
|
|
|
|
CoglPipelineLayer **authorities,
|
2011-09-07 22:44:37 +00:00
|
|
|
CoglPipelineHashState *state);
|
2010-11-04 13:57:36 +00:00
|
|
|
|
|
|
|
static LayerStateHashFunction
|
|
|
|
layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT];
|
|
|
|
|
|
|
|
/* XXX: We don't statically initialize the array of hash functions, so
|
|
|
|
* we won't get caught out by later re-indexing the groups for some
|
|
|
|
* reason. */
|
|
|
|
void
|
|
|
|
_cogl_pipeline_init_layer_state_hash_functions (void)
|
|
|
|
{
|
|
|
|
CoglPipelineLayerStateIndex _index;
|
|
|
|
layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_UNIT_INDEX] =
|
|
|
|
_cogl_pipeline_layer_hash_unit_state;
|
2012-02-09 12:52:45 +00:00
|
|
|
layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX] =
|
|
|
|
_cogl_pipeline_layer_hash_texture_type_state;
|
2011-01-11 16:02:06 +00:00
|
|
|
layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX] =
|
|
|
|
_cogl_pipeline_layer_hash_texture_data_state;
|
2012-04-04 21:20:04 +00:00
|
|
|
layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_SAMPLER_INDEX] =
|
|
|
|
_cogl_pipeline_layer_hash_sampler_state;
|
2010-11-04 13:57:36 +00:00
|
|
|
layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX] =
|
|
|
|
_cogl_pipeline_layer_hash_combine_state;
|
|
|
|
layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX] =
|
|
|
|
_cogl_pipeline_layer_hash_combine_constant_state;
|
|
|
|
layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX] =
|
|
|
|
_cogl_pipeline_layer_hash_user_matrix_state;
|
|
|
|
_index = COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX;
|
2011-11-28 19:58:15 +00:00
|
|
|
layer_state_hash_functions[_index] =
|
|
|
|
_cogl_pipeline_layer_hash_point_sprite_state;
|
|
|
|
_index = COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS_INDEX;
|
2010-11-04 13:57:36 +00:00
|
|
|
layer_state_hash_functions[_index] =
|
|
|
|
_cogl_pipeline_layer_hash_point_sprite_state;
|
2011-11-25 17:36:03 +00:00
|
|
|
_index = COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS_INDEX;
|
|
|
|
layer_state_hash_functions[_index] =
|
|
|
|
_cogl_pipeline_layer_hash_fragment_snippets_state;
|
2010-11-04 13:57:36 +00:00
|
|
|
|
2012-04-16 16:23:15 +00:00
|
|
|
{
|
2010-11-04 13:57:36 +00:00
|
|
|
/* So we get a big error if we forget to update this code! */
|
2012-04-16 16:23:15 +00:00
|
|
|
_COGL_STATIC_ASSERT (COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT == 10,
|
|
|
|
"Don't forget to install a hash function for new "
|
|
|
|
"pipeline state and update assert at end of "
|
|
|
|
"_cogl_pipeline_init_state_hash_functions");
|
|
|
|
}
|
2010-11-04 13:57:36 +00:00
|
|
|
}
|
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2010-11-04 13:57:36 +00:00
|
|
|
_cogl_pipeline_hash_layer_cb (CoglPipelineLayer *layer,
|
|
|
|
void *user_data)
|
|
|
|
{
|
2011-09-07 22:44:37 +00:00
|
|
|
CoglPipelineHashState *state = user_data;
|
2010-11-04 13:57:36 +00:00
|
|
|
unsigned long differences = state->layer_differences;
|
|
|
|
CoglPipelineLayer *authorities[COGL_PIPELINE_LAYER_STATE_COUNT];
|
|
|
|
unsigned long mask;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* Theoretically we would hash non-sparse layer state here but
|
|
|
|
* currently layers don't have any. */
|
|
|
|
|
|
|
|
/* XXX: we resolve all the authorities here - not just those
|
|
|
|
* corresponding to hash_state->layer_differences - because
|
|
|
|
* the hashing of some state groups actually depends on the values
|
|
|
|
* in other groups. For example we don't hash layer combine
|
|
|
|
* constants if they are aren't referenced by the current layer
|
|
|
|
* combine function.
|
|
|
|
*/
|
|
|
|
mask = COGL_PIPELINE_LAYER_STATE_ALL_SPARSE;
|
|
|
|
_cogl_pipeline_layer_resolve_authorities (layer,
|
|
|
|
mask,
|
|
|
|
authorities);
|
|
|
|
|
|
|
|
/* So we go right ahead and hash the sparse state... */
|
|
|
|
for (i = 0; i < COGL_PIPELINE_LAYER_STATE_COUNT; i++)
|
|
|
|
{
|
|
|
|
unsigned long current_state = (1L<<i);
|
|
|
|
|
|
|
|
/* XXX: we are hashing the un-mixed hash values of all the
|
|
|
|
* individual state groups; we should provide a means to test
|
|
|
|
* the quality of the final hash values we are getting with this
|
|
|
|
* approach... */
|
|
|
|
if (differences & current_state)
|
|
|
|
{
|
|
|
|
CoglPipelineLayer *authority = authorities[i];
|
|
|
|
layer_state_hash_functions[i] (authority, authorities, state);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (current_state > differences)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2011-09-07 22:44:37 +00:00
|
|
|
void
|
2010-11-04 13:57:36 +00:00
|
|
|
_cogl_pipeline_hash_layers_state (CoglPipeline *authority,
|
2011-09-07 22:44:37 +00:00
|
|
|
CoglPipelineHashState *state)
|
2010-11-04 13:57:36 +00:00
|
|
|
{
|
|
|
|
state->hash =
|
|
|
|
_cogl_util_one_at_a_time_hash (state->hash, &authority->n_layers,
|
|
|
|
sizeof (authority->n_layers));
|
|
|
|
_cogl_pipeline_foreach_layer_internal (authority,
|
|
|
|
_cogl_pipeline_hash_layer_cb,
|
|
|
|
state);
|
|
|
|
}
|
|
|
|
|
2011-09-07 22:44:37 +00:00
|
|
|
typedef void (*StateHashFunction) (CoglPipeline *authority, CoglPipelineHashState *state);
|
2010-11-04 13:57:36 +00:00
|
|
|
|
|
|
|
static StateHashFunction
|
|
|
|
state_hash_functions[COGL_PIPELINE_STATE_SPARSE_COUNT];
|
|
|
|
|
|
|
|
/* We don't statically initialize the array of hash functions
|
|
|
|
* so we won't get caught out by later re-indexing the groups for
|
|
|
|
* some reason. */
|
|
|
|
void
|
|
|
|
_cogl_pipeline_init_state_hash_functions (void)
|
|
|
|
{
|
|
|
|
state_hash_functions[COGL_PIPELINE_STATE_COLOR_INDEX] =
|
|
|
|
_cogl_pipeline_hash_color_state;
|
|
|
|
state_hash_functions[COGL_PIPELINE_STATE_BLEND_ENABLE_INDEX] =
|
|
|
|
_cogl_pipeline_hash_blend_enable_state;
|
|
|
|
state_hash_functions[COGL_PIPELINE_STATE_LAYERS_INDEX] =
|
|
|
|
_cogl_pipeline_hash_layers_state;
|
|
|
|
state_hash_functions[COGL_PIPELINE_STATE_LIGHTING_INDEX] =
|
|
|
|
_cogl_pipeline_hash_lighting_state;
|
|
|
|
state_hash_functions[COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX] =
|
|
|
|
_cogl_pipeline_hash_alpha_func_state;
|
|
|
|
state_hash_functions[COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX] =
|
|
|
|
_cogl_pipeline_hash_alpha_func_reference_state;
|
|
|
|
state_hash_functions[COGL_PIPELINE_STATE_BLEND_INDEX] =
|
|
|
|
_cogl_pipeline_hash_blend_state;
|
|
|
|
state_hash_functions[COGL_PIPELINE_STATE_USER_SHADER_INDEX] =
|
|
|
|
_cogl_pipeline_hash_user_shader_state;
|
|
|
|
state_hash_functions[COGL_PIPELINE_STATE_DEPTH_INDEX] =
|
|
|
|
_cogl_pipeline_hash_depth_state;
|
|
|
|
state_hash_functions[COGL_PIPELINE_STATE_FOG_INDEX] =
|
|
|
|
_cogl_pipeline_hash_fog_state;
|
2011-09-15 10:25:39 +00:00
|
|
|
state_hash_functions[COGL_PIPELINE_STATE_CULL_FACE_INDEX] =
|
|
|
|
_cogl_pipeline_hash_cull_face_state;
|
2010-11-04 13:57:36 +00:00
|
|
|
state_hash_functions[COGL_PIPELINE_STATE_POINT_SIZE_INDEX] =
|
|
|
|
_cogl_pipeline_hash_point_size_state;
|
2012-11-08 16:56:02 +00:00
|
|
|
state_hash_functions[COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE_INDEX] =
|
|
|
|
_cogl_pipeline_hash_per_vertex_point_size_state;
|
2011-07-11 01:27:54 +00:00
|
|
|
state_hash_functions[COGL_PIPELINE_STATE_LOGIC_OPS_INDEX] =
|
|
|
|
_cogl_pipeline_hash_logic_ops_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
|
|
|
state_hash_functions[COGL_PIPELINE_STATE_UNIFORMS_INDEX] =
|
|
|
|
_cogl_pipeline_hash_uniforms_state;
|
2011-11-17 16:52:21 +00:00
|
|
|
state_hash_functions[COGL_PIPELINE_STATE_VERTEX_SNIPPETS_INDEX] =
|
|
|
|
_cogl_pipeline_hash_vertex_snippets_state;
|
|
|
|
state_hash_functions[COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS_INDEX] =
|
|
|
|
_cogl_pipeline_hash_fragment_snippets_state;
|
2010-11-04 13:57:36 +00:00
|
|
|
|
2012-04-16 16:23:15 +00:00
|
|
|
{
|
2010-11-04 13:57:36 +00:00
|
|
|
/* So we get a big error if we forget to update this code! */
|
2012-11-08 16:56:02 +00:00
|
|
|
_COGL_STATIC_ASSERT (COGL_PIPELINE_STATE_SPARSE_COUNT == 17,
|
2012-04-16 16:23:15 +00:00
|
|
|
"Make sure to install a hash function for "
|
|
|
|
"newly added pipeline state and update assert "
|
|
|
|
"in _cogl_pipeline_init_state_hash_functions");
|
|
|
|
}
|
2010-11-04 13:57:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int
|
|
|
|
_cogl_pipeline_hash (CoglPipeline *pipeline,
|
2013-05-16 14:19:30 +00:00
|
|
|
unsigned int differences,
|
2010-11-04 13:57:36 +00:00
|
|
|
unsigned long layer_differences,
|
|
|
|
CoglPipelineEvalFlags flags)
|
|
|
|
{
|
|
|
|
CoglPipeline *authorities[COGL_PIPELINE_STATE_SPARSE_COUNT];
|
2013-05-16 14:19:30 +00:00
|
|
|
unsigned int mask;
|
2010-11-04 13:57:36 +00:00
|
|
|
int i;
|
2011-09-07 22:44:37 +00:00
|
|
|
CoglPipelineHashState state;
|
2010-11-04 13:57:36 +00:00
|
|
|
unsigned int final_hash = 0;
|
|
|
|
|
|
|
|
state.hash = 0;
|
|
|
|
state.layer_differences = layer_differences;
|
2010-12-08 11:35:16 +00:00
|
|
|
state.flags = flags;
|
2010-11-04 13:57:36 +00:00
|
|
|
|
2013-05-16 14:19:30 +00:00
|
|
|
_cogl_pipeline_update_real_blend_enable (pipeline, FALSE);
|
|
|
|
|
2010-11-04 13:57:36 +00:00
|
|
|
/* hash non-sparse state */
|
|
|
|
|
|
|
|
if (differences & COGL_PIPELINE_STATE_REAL_BLEND_ENABLE)
|
|
|
|
{
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool enable = pipeline->real_blend_enable;
|
2010-11-04 13:57:36 +00:00
|
|
|
state.hash =
|
|
|
|
_cogl_util_one_at_a_time_hash (state.hash, &enable, sizeof (enable));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* hash sparse state */
|
|
|
|
|
|
|
|
mask = differences & COGL_PIPELINE_STATE_ALL_SPARSE;
|
|
|
|
_cogl_pipeline_resolve_authorities (pipeline, mask, authorities);
|
|
|
|
|
|
|
|
for (i = 0; i < COGL_PIPELINE_STATE_SPARSE_COUNT; i++)
|
|
|
|
{
|
2013-05-16 14:19:30 +00:00
|
|
|
unsigned int current_state = (1<<i);
|
2010-11-04 13:57:36 +00:00
|
|
|
|
|
|
|
/* XXX: we are hashing the un-mixed hash values of all the
|
|
|
|
* individual state groups; we should provide a means to test
|
|
|
|
* the quality of the final hash values we are getting with this
|
|
|
|
* approach... */
|
|
|
|
if (differences & current_state)
|
|
|
|
{
|
|
|
|
CoglPipeline *authority = authorities[i];
|
|
|
|
state_hash_functions[i] (authority, &state);
|
|
|
|
final_hash = _cogl_util_one_at_a_time_hash (final_hash, &state.hash,
|
|
|
|
sizeof (state.hash));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (current_state > differences)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return _cogl_util_one_at_a_time_mix (final_hash);
|
|
|
|
}
|
|
|
|
|
2013-03-26 11:17:55 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
CoglContext *context;
|
|
|
|
CoglPipeline *src_pipeline;
|
|
|
|
CoglPipeline *dst_pipeline;
|
|
|
|
unsigned int layer_differences;
|
|
|
|
} DeepCopyData;
|
|
|
|
|
|
|
|
static CoglBool
|
|
|
|
deep_copy_layer_cb (CoglPipelineLayer *src_layer,
|
|
|
|
void *user_data)
|
|
|
|
{
|
|
|
|
DeepCopyData *data = user_data;
|
|
|
|
CoglPipelineLayer *dst_layer;
|
|
|
|
unsigned int differences = data->layer_differences;
|
|
|
|
|
|
|
|
dst_layer = _cogl_pipeline_get_layer (data->dst_pipeline, src_layer->index);
|
|
|
|
|
|
|
|
while (src_layer != data->context->default_layer_n &&
|
|
|
|
src_layer != data->context->default_layer_0 &&
|
|
|
|
differences)
|
|
|
|
{
|
|
|
|
unsigned long to_copy = differences & src_layer->differences;
|
|
|
|
|
|
|
|
if (to_copy)
|
|
|
|
{
|
|
|
|
_cogl_pipeline_layer_copy_differences (dst_layer, src_layer, to_copy);
|
|
|
|
differences ^= to_copy;
|
|
|
|
}
|
|
|
|
|
|
|
|
src_layer = COGL_PIPELINE_LAYER (COGL_NODE (src_layer)->parent);
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
CoglPipeline *
|
|
|
|
_cogl_pipeline_deep_copy (CoglPipeline *pipeline,
|
|
|
|
unsigned long differences,
|
|
|
|
unsigned long layer_differences)
|
|
|
|
{
|
|
|
|
CoglPipeline *new, *authority;
|
|
|
|
CoglBool copy_layer_state;
|
|
|
|
|
|
|
|
_COGL_GET_CONTEXT (ctx, NULL);
|
|
|
|
|
|
|
|
if ((differences & COGL_PIPELINE_STATE_LAYERS))
|
|
|
|
{
|
|
|
|
copy_layer_state = TRUE;
|
|
|
|
differences &= ~COGL_PIPELINE_STATE_LAYERS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
copy_layer_state = FALSE;
|
|
|
|
|
|
|
|
new = cogl_pipeline_new (ctx);
|
|
|
|
|
|
|
|
for (authority = pipeline;
|
|
|
|
authority != ctx->default_pipeline && differences;
|
|
|
|
authority = COGL_PIPELINE (COGL_NODE (authority)->parent))
|
|
|
|
{
|
|
|
|
unsigned long to_copy = differences & authority->differences;
|
|
|
|
|
|
|
|
if (to_copy)
|
|
|
|
{
|
|
|
|
_cogl_pipeline_copy_differences (new, authority, to_copy);
|
|
|
|
differences ^= to_copy;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (copy_layer_state)
|
|
|
|
{
|
|
|
|
DeepCopyData data;
|
|
|
|
|
|
|
|
/* The unit index doesn't need to be copied because it should
|
|
|
|
* end up with the same values anyway because the new pipeline
|
|
|
|
* will have the same indices as the source pipeline */
|
|
|
|
layer_differences &= ~COGL_PIPELINE_LAYER_STATE_UNIT;
|
|
|
|
|
|
|
|
data.context = ctx;
|
|
|
|
data.src_pipeline = pipeline;
|
|
|
|
data.dst_pipeline = new;
|
|
|
|
data.layer_differences = layer_differences;
|
|
|
|
|
|
|
|
_cogl_pipeline_foreach_layer_internal (pipeline,
|
|
|
|
deep_copy_layer_cb,
|
|
|
|
&data);
|
|
|
|
}
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2010-11-19 10:43:52 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
CoglPipelineLayer **layers;
|
|
|
|
} AddLayersToArrayState;
|
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2010-11-19 10:43:52 +00:00
|
|
|
add_layer_to_array_cb (CoglPipelineLayer *layer,
|
|
|
|
void *user_data)
|
|
|
|
{
|
|
|
|
AddLayersToArrayState *state = user_data;
|
|
|
|
state->layers[state->i++] = layer;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2010-12-01 17:06:18 +00:00
|
|
|
/* This tries to find the oldest ancestor whose pipeline and layer
|
|
|
|
state matches the given flags. This is mostly used to detect code
|
|
|
|
gen authorities so that we can reduce the numer of programs
|
|
|
|
generated */
|
2010-11-19 10:43:52 +00:00
|
|
|
CoglPipeline *
|
2010-12-01 17:06:18 +00:00
|
|
|
_cogl_pipeline_find_equivalent_parent (CoglPipeline *pipeline,
|
|
|
|
CoglPipelineState pipeline_state,
|
2011-01-11 16:02:06 +00:00
|
|
|
CoglPipelineLayerState layer_state)
|
2010-11-19 10:43:52 +00:00
|
|
|
{
|
|
|
|
CoglPipeline *authority0;
|
|
|
|
CoglPipeline *authority1;
|
|
|
|
int n_layers;
|
|
|
|
CoglPipelineLayer **authority0_layers;
|
|
|
|
CoglPipelineLayer **authority1_layers;
|
|
|
|
|
|
|
|
/* Find the first pipeline that modifies state that affects the
|
2010-12-01 17:06:18 +00:00
|
|
|
* state or any layer state... */
|
2010-11-19 10:43:52 +00:00
|
|
|
authority0 = _cogl_pipeline_get_authority (pipeline,
|
2010-12-01 17:06:18 +00:00
|
|
|
pipeline_state |
|
|
|
|
COGL_PIPELINE_STATE_LAYERS);
|
2010-11-19 10:43:52 +00:00
|
|
|
|
2010-12-01 17:06:18 +00:00
|
|
|
/* Find the next ancestor after that, that also modifies the
|
|
|
|
* state... */
|
2010-11-19 10:43:52 +00:00
|
|
|
if (_cogl_pipeline_get_parent (authority0))
|
|
|
|
{
|
|
|
|
authority1 =
|
|
|
|
_cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority0),
|
2010-12-01 17:06:18 +00:00
|
|
|
pipeline_state |
|
|
|
|
COGL_PIPELINE_STATE_LAYERS);
|
2010-11-19 10:43:52 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
return authority0;
|
|
|
|
|
2010-12-01 15:48:37 +00:00
|
|
|
n_layers = cogl_pipeline_get_n_layers (authority0);
|
2010-11-19 10:43:52 +00:00
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
AddLayersToArrayState state;
|
2010-12-01 17:06:18 +00:00
|
|
|
int i;
|
2010-11-19 10:43:52 +00:00
|
|
|
|
2010-12-01 15:48:37 +00:00
|
|
|
if (n_layers != cogl_pipeline_get_n_layers (authority1))
|
|
|
|
return authority0;
|
|
|
|
|
|
|
|
/* If the programs differ by anything that isn't part of the
|
|
|
|
layer state then we can't continue */
|
2010-12-01 17:06:18 +00:00
|
|
|
if (pipeline_state &&
|
2010-12-01 15:48:37 +00:00
|
|
|
(_cogl_pipeline_compare_differences (authority0, authority1) &
|
2010-12-01 17:06:18 +00:00
|
|
|
pipeline_state))
|
2010-11-19 10:43:52 +00:00
|
|
|
return authority0;
|
|
|
|
|
|
|
|
authority0_layers =
|
|
|
|
g_alloca (sizeof (CoglPipelineLayer *) * n_layers);
|
|
|
|
state.i = 0;
|
|
|
|
state.layers = authority0_layers;
|
|
|
|
_cogl_pipeline_foreach_layer_internal (authority0,
|
|
|
|
add_layer_to_array_cb,
|
|
|
|
&state);
|
|
|
|
|
|
|
|
authority1_layers =
|
|
|
|
g_alloca (sizeof (CoglPipelineLayer *) * n_layers);
|
|
|
|
state.i = 0;
|
|
|
|
state.layers = authority1_layers;
|
|
|
|
_cogl_pipeline_foreach_layer_internal (authority1,
|
|
|
|
add_layer_to_array_cb,
|
|
|
|
&state);
|
|
|
|
|
2010-12-01 17:06:18 +00:00
|
|
|
for (i = 0; i < n_layers; i++)
|
2011-01-11 16:02:06 +00:00
|
|
|
{
|
|
|
|
unsigned long layer_differences;
|
|
|
|
|
|
|
|
if (authority0_layers[i] == authority1_layers[i])
|
|
|
|
continue;
|
|
|
|
|
|
|
|
layer_differences =
|
|
|
|
_cogl_pipeline_layer_compare_differences (authority0_layers[i],
|
|
|
|
authority1_layers[i]);
|
|
|
|
|
|
|
|
if (layer_differences & layer_state)
|
|
|
|
return authority0;
|
|
|
|
}
|
2010-11-19 10:43:52 +00:00
|
|
|
|
|
|
|
/* Find the next ancestor after that, that also modifies state
|
|
|
|
* affecting codegen... */
|
|
|
|
|
|
|
|
if (!_cogl_pipeline_get_parent (authority1))
|
|
|
|
break;
|
|
|
|
|
|
|
|
authority0 = authority1;
|
|
|
|
authority1 =
|
|
|
|
_cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority1),
|
2010-12-01 17:06:18 +00:00
|
|
|
pipeline_state |
|
|
|
|
COGL_PIPELINE_STATE_LAYERS);
|
2010-11-19 10:43:52 +00:00
|
|
|
if (authority1 == authority0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return authority1;
|
|
|
|
}
|
2011-07-07 19:44:56 +00:00
|
|
|
|
|
|
|
CoglPipelineLayerState
|
|
|
|
_cogl_pipeline_get_layer_state_for_fragment_codegen (CoglContext *context)
|
|
|
|
{
|
|
|
|
CoglPipelineLayerState state =
|
|
|
|
(COGL_PIPELINE_LAYER_STATE_COMBINE |
|
2012-02-09 12:52:45 +00:00
|
|
|
COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE |
|
2011-11-25 17:36:03 +00:00
|
|
|
COGL_PIPELINE_LAYER_STATE_UNIT |
|
|
|
|
COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS);
|
2011-07-07 19:44:56 +00:00
|
|
|
|
2012-09-26 19:32:36 +00:00
|
|
|
/* If the driver supports GLSL then we might be using gl_PointCoord
|
|
|
|
* to implement the sprite coords. In that case the generated code
|
|
|
|
* depends on the point sprite state */
|
|
|
|
if (cogl_has_feature (context, COGL_FEATURE_ID_GLSL))
|
2011-07-07 19:44:56 +00:00
|
|
|
state |= COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS;
|
|
|
|
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
CoglPipelineState
|
|
|
|
_cogl_pipeline_get_state_for_fragment_codegen (CoglContext *context)
|
|
|
|
{
|
|
|
|
CoglPipelineState state = (COGL_PIPELINE_STATE_LAYERS |
|
2011-11-17 16:52:21 +00:00
|
|
|
COGL_PIPELINE_STATE_USER_SHADER |
|
|
|
|
COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS);
|
2011-07-07 19:44:56 +00:00
|
|
|
|
2012-09-26 19:32:36 +00:00
|
|
|
if (!(context->private_feature_flags & COGL_PRIVATE_FEATURE_ALPHA_TEST))
|
2011-07-07 19:44:56 +00:00
|
|
|
state |= COGL_PIPELINE_STATE_ALPHA_FUNC;
|
|
|
|
|
|
|
|
return 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
|
|
|
|
|
|
|
int
|
|
|
|
cogl_pipeline_get_uniform_location (CoglPipeline *pipeline,
|
|
|
|
const char *uniform_name)
|
|
|
|
{
|
2011-11-04 18:26:17 +00:00
|
|
|
void *location_ptr;
|
|
|
|
char *uniform_name_copy;
|
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_GET_CONTEXT (ctx, -1);
|
|
|
|
|
|
|
|
/* This API is designed as if the uniform locations are specific to
|
|
|
|
a pipeline but they are actually unique across a whole
|
|
|
|
CoglContext. Potentially this could just be
|
|
|
|
cogl_context_get_uniform_location but it seems to make sense to
|
|
|
|
keep the API this way so that we can change the internals if need
|
|
|
|
be. */
|
|
|
|
|
|
|
|
/* Look for an existing uniform with this name */
|
2011-11-04 18:26:17 +00:00
|
|
|
if (g_hash_table_lookup_extended (ctx->uniform_name_hash,
|
|
|
|
uniform_name,
|
|
|
|
NULL,
|
|
|
|
&location_ptr))
|
|
|
|
return GPOINTER_TO_INT (location_ptr);
|
|
|
|
|
|
|
|
uniform_name_copy = g_strdup (uniform_name);
|
|
|
|
g_ptr_array_add (ctx->uniform_names, uniform_name_copy);
|
|
|
|
g_hash_table_insert (ctx->uniform_name_hash,
|
|
|
|
uniform_name_copy,
|
|
|
|
GINT_TO_POINTER (ctx->n_uniform_names));
|
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 ctx->n_uniform_names++;
|
|
|
|
}
|