mutter/cogl/cogl-material-private.h

739 lines
25 KiB
C
Raw Normal View History

/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
* Copyright (C) 2008,2009,2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* 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
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
*
*
* Authors:
* Robert Bragg <robert@linux.intel.com>
*/
#ifndef __COGL_MATERIAL_PRIVATE_H
#define __COGL_MATERIAL_PRIVATE_H
#include "cogl-material.h"
#include "cogl-matrix.h"
#include "cogl-matrix-stack.h"
#include "cogl-handle.h"
#include <glib.h>
typedef struct _CoglMaterial CoglMaterial;
typedef struct _CoglMaterialLayer CoglMaterialLayer;
/*
* cogl-material.c owns the GPU's texture unit state so we have some
* private structures for describing the current state of a texture
* unit that we track in a per context array (ctx->texture_units) that
* grows according to the largest texture unit used so far...
*
* Roughly speaking the members in this structure are of two kinds:
* either they are a low level reflection of the state we send to
* OpenGL or they are for high level meta data assoicated with the
* texture unit when flushing CoglMaterialLayers that is typically
* used to optimize subsequent re-flushing of the same layer.
*
* The low level members are at the top, and the high level members
* start with the .layer member.
*/
typedef struct _CoglTextureUnit
{
/* The base 0 texture unit index which can be used with
* glActiveTexture () */
int index;
/* Whether or not the corresponding gl_target has been glEnabled */
gboolean enabled;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* The GL target currently glEnabled or the target last enabled
* if .enabled == FALSE */
GLenum current_gl_target;
/* The raw GL texture object name for which we called glBindTexture when
* we flushed the last layer. (NB: The CoglTexture associated
* with a layer may represent more than one GL texture) */
GLuint gl_texture;
/* Foreign textures are those not created or deleted by Cogl. If we ever
* call glBindTexture for a foreign texture then the next time we are
* asked to glBindTexture we can't try and optimize a redundant state
* change because we don't know if the original texture name was deleted
* and now we are being asked to bind a recycled name. */
gboolean is_foreign;
/* We have many components in Cogl that need to temporarily bind arbitrary
* textures e.g. to query texture object parameters and since we don't
* want that to result in too much redundant reflushing of layer state
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
* when all that's needed is to re-bind the layer's gl_texture we use this
* to track when the unit->gl_texture state is out of sync with the GL
* texture object really bound too (GL_TEXTURE0+unit->index).
*
* XXX: as a further optimization cogl-material.c uses a convention
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
* of always using texture unit 1 for these transient bindings so we
* can assume this is only ever TRUE for unit 1.
*/
gboolean dirty_gl_texture;
/* A matrix stack giving us the means to associate a texture
* transform matrix with the texture unit. */
CoglMatrixStack *matrix_stack;
/*
* Higher level layer state associated with the unit...
*/
/* The CoglMaterialLayer whos state was flushed to update this
* texture unit last.
*
* This will be set to NULL if the layer is modified or freed which
* means when we come to flush a layer; if this pointer is still
* valid and == to the layer being flushed we don't need to update
* any texture unit state. */
CoglMaterialLayer *layer;
/* To help minimize the state changes required we track the
* difference flags associated with the layer whos state was last
* flushed to update this texture unit.
*
* Note: we track this explicitly because .layer may get invalidated
* if that layer is modified or deleted. Even if the layer is
* invalidated though these flags can be used to optimize the state
* flush of the next layer
*/
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
unsigned long layer_changes_since_flush;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* Whenever a CoglTexture's internal GL texture storage changes
* cogl-material.c is notified with a call to
* _cogl_material_texture_storage_change_notify which inturn sets
* this to TRUE for each texture unit that it is currently bound
* too. When we later come to flush some material state then we will
* always check this to potentially force an update of the texture
* state even if the material hasn't changed. */
gboolean texture_storage_changed;
} CoglTextureUnit;
CoglTextureUnit *
_cogl_get_texture_unit (int index_);
void
_cogl_destroy_texture_units (void);
void
_cogl_bind_gl_texture_transient (GLenum gl_target,
GLuint gl_texture,
gboolean is_foreign);
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
#if defined (HAVE_COGL_GL)
/* glsl, arbfp, fixed */
#define COGL_MATERIAL_N_BACKENDS 3
#elif defined (HAVE_COGL_GLES2)
/* glsl, fixed */
#define COGL_MATERIAL_N_BACKENDS 2
#else /* HAVE_COGL_GLES */
/* fixed */
#define COGL_MATERIAL_N_BACKENDS 1
#endif
[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 13:46:42 -04:00
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
typedef enum
{
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
COGL_MATERIAL_LAYER_STATE_UNIT = 1L<<0,
COGL_MATERIAL_LAYER_STATE_TEXTURE = 1L<<1,
COGL_MATERIAL_LAYER_STATE_FILTERS = 1L<<2,
COGL_MATERIAL_LAYER_STATE_WRAP_MODES = 1L<<3,
COGL_MATERIAL_LAYER_STATE_COMBINE = 1L<<4,
COGL_MATERIAL_LAYER_STATE_COMBINE_CONSTANT = 1L<<5,
COGL_MATERIAL_LAYER_STATE_USER_MATRIX = 1L<<6,
/* COGL_MATERIAL_LAYER_STATE_TEXTURE_INTERN = 1L<<7, */
COGL_MATERIAL_LAYER_STATE_ALL_SPARSE =
COGL_MATERIAL_LAYER_STATE_UNIT |
COGL_MATERIAL_LAYER_STATE_TEXTURE |
COGL_MATERIAL_LAYER_STATE_FILTERS |
COGL_MATERIAL_LAYER_STATE_WRAP_MODES |
COGL_MATERIAL_LAYER_STATE_COMBINE |
COGL_MATERIAL_LAYER_STATE_COMBINE_CONSTANT |
COGL_MATERIAL_LAYER_STATE_USER_MATRIX,
COGL_MATERIAL_LAYER_STATE_NEEDS_BIG_STATE =
COGL_MATERIAL_LAYER_STATE_COMBINE |
COGL_MATERIAL_LAYER_STATE_COMBINE_CONSTANT |
COGL_MATERIAL_LAYER_STATE_USER_MATRIX
} CoglMaterialLayerState;
typedef struct
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 11:15:40 -05:00
{
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* The texture combine state determines how the color of individual
* texture fragments are calculated. */
GLint texture_combine_rgb_func;
GLint texture_combine_rgb_src[3];
GLint texture_combine_rgb_op[3];
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
GLint texture_combine_alpha_func;
GLint texture_combine_alpha_src[3];
GLint texture_combine_alpha_op[3];
float texture_combine_constant[4];
/* The texture matrix dscribes how to transform texture coordinates */
CoglMatrix matrix;
} CoglMaterialLayerBigState;
struct _CoglMaterialLayer
{
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* XXX: Please think twice about adding members that *have* be
* initialized during a _cogl_material_layer_copy. We are aiming
* to have copies be as cheap as possible and copies may be
* done by the primitives APIs which means they may happen
* in performance critical code paths.
*
* XXX: If you are extending the state we track please consider if
* the state is expected to vary frequently across many materials or
* if the state can be shared among many derived materials instead.
* This will determine if the state should be added directly to this
* structure which will increase the memory overhead for *all*
* layers or if instead it can go under ->big_state.
*/
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* the parent in terms of class hierarchy */
CoglHandleObject _parent;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* Some layers have a material owner, which is to say that the layer
* is referenced in that materials->layer_differences list. A layer
* doesn't always have an owner and may simply be an ancestor for
* other layers that keeps track of some shared state. */
CoglMaterial *owner;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* Layers are sparse structures defined as a diff against
* their parent... */
CoglMaterialLayer *parent;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* As an optimization for creating leaf node layers (the most
* common) we don't require any list node allocations to link
* to a single descendant. */
CoglMaterialLayer *first_child;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* Layers are sparse structures defined as a diff against
* their parent and may have multiple children which depend
* on them to define the values of properties which they don't
* change. */
GList *children;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* The lowest index is blended first then others on top */
int index;
[cogl] Move the texture filters to be a property of the material layer The texture filters are now a property of the material layer rather than the texture object. Whenever a texture is painted with a material it sets the filters on all of the GL textures in the Cogl texture. The filter is cached so that it won't be changed unnecessarily. The automatic mipmap generation has changed so that the mipmaps are only generated when the texture is painted instead of every time the data changes. Changing the texture sets a flag to mark that the mipmaps are dirty. This works better if the FBO extension is available because we can use glGenerateMipmap. If the extension is not available it will temporarily enable automatic mipmap generation and reupload the first pixel of each slice. This requires tracking the data for the first pixel. The COGL_TEXTURE_AUTO_MIPMAP flag has been replaced with COGL_TEXTURE_NO_AUTO_MIPMAP so that it will default to auto-mipmapping. The mipmap generation is now effectively free if you are not using a mipmap filter mode so you would only want to disable it if you had some special reason to generate your own mipmaps. ClutterTexture no longer has to store its own copy of the filter mode. Instead it stores it in the material and the property is directly set and read from that. This fixes problems with the filters getting out of sync when a cogl handle is set on the texture directly. It also avoids the mess of having to rerealize the texture if the filter quality changes to HIGH because Cogl will take of generating the mipmaps if needed.
2009-06-04 11:04:57 -04:00
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* Different material backends (GLSL/ARBfp/Fixed Function) may
* want to associate private data with a layer...
*
* NB: we have per backend pointers because a layer may be
* associated with multiple materials with different backends.
*/
void *backend_priv[COGL_MATERIAL_N_BACKENDS];
cogl-material: Add support for setting the wrap mode for a layer Previously, Cogl's texture coordinate system was effectively always GL_REPEAT so that if an application specifies coordinates outside the range 0→1 it would get repeated copies of the texture. It would however change the mode to GL_CLAMP_TO_EDGE if all of the coordinates are in the range 0→1 so that in the common case that the whole texture is being drawn with linear filtering it will not blend in edge pixels from the opposite sides. This patch adds the option for applications to change the wrap mode per layer. There are now three wrap modes: 'repeat', 'clamp-to-edge' and 'automatic'. The automatic map mode is the default and it implements the previous behaviour. The wrap mode can be changed for the s and t coordinates independently. I've tried to make the internals support setting the r coordinate but as we don't support 3D textures yet I haven't exposed any public API for it. The texture backends still have a set_wrap_mode virtual but this value is intended to be transitory and it will be changed whenever the material is flushed (although the backends are expected to cache it so that it won't use too many GL calls). In my understanding this value was always meant to be transitory and all primitives were meant to set the value before drawing. However there were comments suggesting that this is not the expected behaviour. In particular the vertex buffer drawing code never set a wrap mode so it would end up with whatever the texture was previously used for. These issues are now fixed because the material will always set the wrap modes. There is code to manually implement clamp-to-edge for textures that can't be hardware repeated. However this doesn't fully work because it relies on being able to draw the stretched parts using quads with the same values for tx1 and tx2. The texture iteration code doesn't support this so it breaks. This is a separate bug and it isn't trivially solved. When flushing a material there are now extra options to set wrap mode overrides. The overrides are an array of values for each layer that specifies an override for the s, t or r coordinates. The primitives use this to implement the automatic wrap mode. cogl_polygon also uses it to set GL_CLAMP_TO_BORDER mode for its trick to render sliced textures. Although this code has been added it looks like the sliced trick has been broken for a while and I haven't attempted to fix it here. I've added a constant to represent the maximum number of layers that a material supports so that I can size the overrides array. I've set it to 32 because as far as I can tell we have that limit imposed anyway because the other flush options use a guint32 to store a flag about each layer. The overrides array ends up adding 32 bytes to each flush options struct which may be a concern. http://bugzilla.openedhand.com/show_bug.cgi?id=2063
2010-04-01 06:31:33 -04:00
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* A mask of which state groups are different in this layer
* in comparison to its parent. */
unsigned long differences;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* Common differences
*
* As a basic way to reduce memory usage we divide the layer
* state into two groups; the minimal state modified in 90% of
* all layers and the rest, so that the second group can
* be allocated dynamically when required.
*/
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* Each layer is directly associated with a single texture unit */
int unit_index;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* The texture for this layer, or COGL_INVALID_HANDLE for an empty
* layer */
CoglHandle texture;
gboolean texture_overridden;
/* If ->texture_overridden == TRUE then the texture is instead
* defined by these... */
GLuint slice_gl_texture;
GLenum slice_gl_target;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
CoglMaterialFilter mag_filter;
CoglMaterialFilter min_filter;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
CoglMaterialWrapMode wrap_mode_s;
CoglMaterialWrapMode wrap_mode_t;
CoglMaterialWrapMode wrap_mode_r;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* Infrequent differences aren't currently tracked in
* a separate, dynamically allocated structure as they are
* for materials... */
CoglMaterialLayerBigState *big_state;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* bitfields */
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* Determines if layer->first_child and layer->children are
* initialized pointers. */
unsigned int has_children:1;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* Determines if layer->big_state is valid */
unsigned int has_big_state:1;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
};
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* Used in material->differences masks and for notifying material
* state changes... */
typedef enum _CoglMaterialState
{
COGL_MATERIAL_STATE_COLOR = 1L<<0,
COGL_MATERIAL_STATE_BLEND_ENABLE = 1L<<1,
COGL_MATERIAL_STATE_LAYERS = 1L<<2,
COGL_MATERIAL_STATE_LIGHTING = 1L<<3,
COGL_MATERIAL_STATE_ALPHA_FUNC = 1L<<4,
COGL_MATERIAL_STATE_BLEND = 1L<<5,
COGL_MATERIAL_STATE_USER_SHADER = 1L<<6,
COGL_MATERIAL_STATE_REAL_BLEND_ENABLE = 1L<<7,
COGL_MATERIAL_STATE_ALL_SPARSE =
COGL_MATERIAL_STATE_COLOR |
COGL_MATERIAL_STATE_BLEND_ENABLE |
COGL_MATERIAL_STATE_LAYERS |
COGL_MATERIAL_STATE_LIGHTING |
COGL_MATERIAL_STATE_ALPHA_FUNC |
COGL_MATERIAL_STATE_BLEND |
COGL_MATERIAL_STATE_USER_SHADER,
COGL_MATERIAL_STATE_AFFECTS_BLENDING =
COGL_MATERIAL_STATE_COLOR |
COGL_MATERIAL_STATE_BLEND_ENABLE |
COGL_MATERIAL_STATE_LAYERS |
COGL_MATERIAL_STATE_LIGHTING |
COGL_MATERIAL_STATE_BLEND |
COGL_MATERIAL_STATE_USER_SHADER,
COGL_MATERIAL_STATE_NEEDS_BIG_STATE =
COGL_MATERIAL_STATE_LIGHTING |
COGL_MATERIAL_STATE_ALPHA_FUNC |
COGL_MATERIAL_STATE_BLEND |
COGL_MATERIAL_STATE_USER_SHADER
} CoglMaterialState;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
typedef enum
{
COGL_MATERIAL_LIGHTING_STATE_PROPERTY_AMBIENT = 1,
COGL_MATERIAL_LIGHTING_STATE_PROPERTY_DIFFUSE,
COGL_MATERIAL_LIGHTING_STATE_PROPERTY_SPECULAR,
COGL_MATERIAL_LIGHTING_STATE_PROPERTY_EMISSION,
COGL_MATERIAL_LIGHTING_STATE_PROPERTY_SHININESS
} CoglMaterialLightingStateProperty;
typedef struct
{
/* Standard OpenGL lighting model attributes */
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
float ambient[4];
float diffuse[4];
float specular[4];
float emission[4];
float shininess;
} CoglMaterialLightingState;
typedef struct
{
/* Determines what fragments are discarded based on their alpha */
CoglMaterialAlphaFunc alpha_func;
GLfloat alpha_func_reference;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
} CoglMaterialAlphaFuncState;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
typedef enum _CoglMaterialBlendEnable
{
/* XXX: we want to detect users mistakenly using TRUE or FALSE
* so start the enum at 2. */
COGL_MATERIAL_BLEND_ENABLE_ENABLED = 2,
COGL_MATERIAL_BLEND_ENABLE_DISABLED,
COGL_MATERIAL_BLEND_ENABLE_AUTOMATIC
} CoglMaterialBlendEnable;
typedef struct
{
/* Determines how this material is blended with other primitives */
#ifndef HAVE_COGL_GLES
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
GLenum blend_equation_rgb;
GLenum blend_equation_alpha;
GLint blend_src_factor_alpha;
GLint blend_dst_factor_alpha;
CoglColor blend_constant;
#endif
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
GLint blend_src_factor_rgb;
GLint blend_dst_factor_rgb;
} CoglMaterialBlendState;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
typedef struct
{
CoglMaterialLightingState lighting_state;
CoglMaterialAlphaFuncState alpha_state;
CoglMaterialBlendState blend_state;
CoglHandle user_program;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
} CoglMaterialBigState;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
typedef enum
{
COGL_MATERIAL_FLAG_DIRTY_LAYERS_CACHE = 1L<<0,
COGL_MATERIAL_FLAG_DIRTY_GET_LAYERS_LIST = 1L<<1
} CoglMaterialFlag;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
typedef struct
{
CoglMaterial *owner;
CoglMaterialLayer *layer;
} CoglMaterialLayerCacheEntry;
struct _CoglMaterial
{
/* XXX: Please think twice about adding members that *have* be
* initialized during a cogl_material_copy. We are aiming to have
* copies be as cheap as possible and copies may be done by the
* primitives APIs which means they may happen in performance
* critical code paths.
*
* XXX: If you are extending the state we track please consider if
* the state is expected to vary frequently across many materials or
* if the state can be shared among many derived materials instead.
* This will determine if the state should be added directly to this
* structure which will increase the memory overhead for *all*
* materials or if instead it can go under ->big_state.
*/
/* the parent in terms of class hierarchy */
CoglHandleObject _parent;
/* We need to track if a material is referenced in the journal
* because we can't allow modification to these materials without
* flushing the journal first */
unsigned long journal_ref_count;
/* Materials are sparse structures defined as a diff against
* their parent. */
CoglMaterial *parent;
/* As an optimization for creating leaf node materials (the most
* common) we don't require any list node allocations to link
* to a single descendant.
*
* Only valid if ->has_children bitfield is set */
CoglMaterial *first_child;
/* Materials are sparse structures defined as a diff against
* their parent and may have multiple children which depend
* on them to define the values of properties which they don't
* change.
*
* Only valid if ->has_children bitfield is set */
GList *children;
/* A mask of which sparse state groups are different in this
* material in comparison to its parent. */
unsigned long differences;
/* The fragment processing backend identified by the ->backend
* bitfield can associate private data with a material. */
void *backend_priv;
/* This is the primary color of the material.
*
* This is a sparse property, ref COGL_MATERIAL_STATE_COLOR */
CoglColor color;
/* A material may be made up with multiple layers used to combine
* textures together.
*
* This is sparse state, ref COGL_MATERIAL_STATE_LAYERS */
GList *layer_differences;
unsigned int n_layers;
/* As a basic way to reduce memory usage we divide the material
* state into two groups; the minimal state modified in 90% of
* all materials and the rest, so that the second group can
* be allocated dynamically when required... */
CoglMaterialBigState *big_state;
/* Cached state... */
/* A cached, complete list of the layers this material depends
* on sorted by layer->unit_index. */
CoglMaterialLayer **layers_cache;
/* To avoid a separate ->layers_cache allocation for common
* materials with only a few layers... */
CoglMaterialLayer *short_layers_cache[3];
/* The deprecated cogl_material_get_layers() API returns a
* const GList of layers, which we track here... */
GList *deprecated_get_layers_list;
/* XXX: consider adding an authorities cache to speed up sparse
* property value lookups:
* CoglMaterial *authorities_cache[COGL_MATERIAL_N_SPARSE_PROPERTIES];
* and corresponding authorities_cache_dirty:1 bitfield
*/
/* bitfields */
/* Determines if material->big_state is valid */
unsigned int has_big_state:1;
/* By default blending is enabled automatically depending on the
* unlit color, the lighting colors or the texture format. The user
* can override this to explicitly enable or disable blending.
*
* This is a sparse property */
unsigned int blend_enable:3;
/* There are many factors that can determine if we need to enable
* blending, this holds our final decision */
unsigned int real_blend_enable:1;
/* Determines if material->first_child and material->children are
* initialized pointers. */
unsigned int has_children:1;
unsigned int layers_cache_dirty:1;
unsigned int deprecated_get_layers_list_dirty:1;
/* There are multiple fragment processing backends for CoglMaterial,
* glsl, arbfp and fixed. This identifies the backend being used for
* the material and any private state the backend has associated
* with the material. */
unsigned int backend:3;
/* Determines if ->backend_priv has been initialized */
unsigned int backend_priv_set:1;
};
typedef struct _CoglMaterialBackend
{
int (*get_max_texture_units) (void);
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
gboolean (*start) (CoglMaterial *material,
int n_layers,
unsigned long materials_difference);
gboolean (*add_layer) (CoglMaterial *material,
CoglMaterialLayer *layer,
unsigned long layers_difference);
gboolean (*passthrough) (CoglMaterial *material);
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
gboolean (*end) (CoglMaterial *material,
unsigned long materials_difference);
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
void (*material_pre_change_notify) (CoglMaterial *material,
CoglMaterialState change,
const CoglColor *new_color);
void (*layer_pre_change_notify) (CoglMaterialLayer *layer,
CoglMaterialLayerState change);
void (*free_priv) (CoglMaterial *material);
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
void (*free_layer_priv) (CoglMaterialLayer *layer);
} CoglMaterialBackend;
typedef enum
{
COGL_MATERIAL_PROGRAM_TYPE_GLSL = 1,
COGL_MATERIAL_PROGRAM_TYPE_ARBFP,
COGL_MATERIAL_PROGRAM_TYPE_FIXED
} CoglMaterialProgramType;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
void
_cogl_material_init_default_material (void);
void
_cogl_material_init_default_layers (void);
/*
* SECTION:cogl-material-internals
* @short_description: Functions for creating custom primitives that make use
* of Cogl materials for filling.
*
* Normally you shouldn't need to use this API directly, but if you need to
* developing a custom/specialised primitive - probably using raw OpenGL - then
* this API aims to expose enough of the material internals to support being
* able to fill your geometry according to a given Cogl material.
*/
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
gboolean
_cogl_material_get_real_blend_enabled (CoglHandle handle);
gboolean
_cogl_material_layer_has_user_matrix (CoglHandle layer_handle);
/*
* Ensures the mipmaps are available for the texture in the layer if
* the filter settings would require it
*/
cogl: improves header and coding style consistency We've had complaints that our Cogl code/headers are a bit "special" so this is a first pass at tidying things up by giving them some consistency. These changes are all consistent with how new code in Cogl is being written, but the style isn't consistently applied across all code yet. There are two parts to this patch; but since each one required a large amount of effort to maintain tidy indenting it made sense to combine the changes to reduce the time spent re indenting the same lines. The first change is to use a consistent style for declaring function prototypes in headers. Cogl headers now consistently use this style for prototypes: return_type cogl_function_name (CoglType arg0, CoglType arg1); Not everyone likes this style, but it seems that most of the currently active Cogl developers agree on it. The second change is to constrain the use of redundant glib data types in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all been replaced with int, unsigned int, float, long, unsigned long and char respectively. When talking about pixel data; use of guchar has been replaced with guint8, otherwise unsigned char can be used. The glib types that we continue to use for portability are gboolean, gint{8,16,32,64}, guint{8,16,32,64} and gsize. The general intention is that Cogl should look palatable to the widest range of C programmers including those outside the Gnome community so - especially for the public API - we want to minimize the number of foreign looking typedefs.
2010-02-09 20:57:32 -05:00
void
_cogl_material_layer_ensure_mipmaps (CoglHandle layer_handler);
/*
[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 13:46:42 -04:00
* CoglMaterialFlushFlag:
* @COGL_MATERIAL_FLUSH_FALLBACK_MASK: The fallback_layers member is set to
* a guint32 mask of the layers that can't be supported with the user
* supplied texture and need to be replaced with fallback textures. (1 =
* fallback, and the least significant bit = layer 0)
* @COGL_MATERIAL_FLUSH_DISABLE_MASK: The disable_layers member is set to
* a guint32 mask of the layers that you want to completly disable
* texturing for (1 = fallback, and the least significant bit = layer 0)
* @COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE: The layer0_override_texture member is
* set to a GLuint OpenGL texture name to override the texture used for
* layer 0 of the material. This is intended for dealing with sliced
* textures where you will need to point to each of the texture slices in
* turn when drawing your geometry. Passing a value of 0 is the same as
* not passing the option at all.
* @COGL_MATERIAL_FLUSH_SKIP_GL_COLOR: When flushing the GL state for the
* material don't call glColor.
cogl-material: Add support for setting the wrap mode for a layer Previously, Cogl's texture coordinate system was effectively always GL_REPEAT so that if an application specifies coordinates outside the range 0→1 it would get repeated copies of the texture. It would however change the mode to GL_CLAMP_TO_EDGE if all of the coordinates are in the range 0→1 so that in the common case that the whole texture is being drawn with linear filtering it will not blend in edge pixels from the opposite sides. This patch adds the option for applications to change the wrap mode per layer. There are now three wrap modes: 'repeat', 'clamp-to-edge' and 'automatic'. The automatic map mode is the default and it implements the previous behaviour. The wrap mode can be changed for the s and t coordinates independently. I've tried to make the internals support setting the r coordinate but as we don't support 3D textures yet I haven't exposed any public API for it. The texture backends still have a set_wrap_mode virtual but this value is intended to be transitory and it will be changed whenever the material is flushed (although the backends are expected to cache it so that it won't use too many GL calls). In my understanding this value was always meant to be transitory and all primitives were meant to set the value before drawing. However there were comments suggesting that this is not the expected behaviour. In particular the vertex buffer drawing code never set a wrap mode so it would end up with whatever the texture was previously used for. These issues are now fixed because the material will always set the wrap modes. There is code to manually implement clamp-to-edge for textures that can't be hardware repeated. However this doesn't fully work because it relies on being able to draw the stretched parts using quads with the same values for tx1 and tx2. The texture iteration code doesn't support this so it breaks. This is a separate bug and it isn't trivially solved. When flushing a material there are now extra options to set wrap mode overrides. The overrides are an array of values for each layer that specifies an override for the s, t or r coordinates. The primitives use this to implement the automatic wrap mode. cogl_polygon also uses it to set GL_CLAMP_TO_BORDER mode for its trick to render sliced textures. Although this code has been added it looks like the sliced trick has been broken for a while and I haven't attempted to fix it here. I've added a constant to represent the maximum number of layers that a material supports so that I can size the overrides array. I've set it to 32 because as far as I can tell we have that limit imposed anyway because the other flush options use a guint32 to store a flag about each layer. The overrides array ends up adding 32 bytes to each flush options struct which may be a concern. http://bugzilla.openedhand.com/show_bug.cgi?id=2063
2010-04-01 06:31:33 -04:00
* @COGL_MATERIAL_FLUSH_WRAP_MODE_OVERRIDES: Specifies that a bitmask
* of overrides for the wrap modes for some or all layers is
* given.
[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 13:46:42 -04:00
*/
typedef enum _CoglMaterialFlushFlag
{
cogl-material: Add support for setting the wrap mode for a layer Previously, Cogl's texture coordinate system was effectively always GL_REPEAT so that if an application specifies coordinates outside the range 0→1 it would get repeated copies of the texture. It would however change the mode to GL_CLAMP_TO_EDGE if all of the coordinates are in the range 0→1 so that in the common case that the whole texture is being drawn with linear filtering it will not blend in edge pixels from the opposite sides. This patch adds the option for applications to change the wrap mode per layer. There are now three wrap modes: 'repeat', 'clamp-to-edge' and 'automatic'. The automatic map mode is the default and it implements the previous behaviour. The wrap mode can be changed for the s and t coordinates independently. I've tried to make the internals support setting the r coordinate but as we don't support 3D textures yet I haven't exposed any public API for it. The texture backends still have a set_wrap_mode virtual but this value is intended to be transitory and it will be changed whenever the material is flushed (although the backends are expected to cache it so that it won't use too many GL calls). In my understanding this value was always meant to be transitory and all primitives were meant to set the value before drawing. However there were comments suggesting that this is not the expected behaviour. In particular the vertex buffer drawing code never set a wrap mode so it would end up with whatever the texture was previously used for. These issues are now fixed because the material will always set the wrap modes. There is code to manually implement clamp-to-edge for textures that can't be hardware repeated. However this doesn't fully work because it relies on being able to draw the stretched parts using quads with the same values for tx1 and tx2. The texture iteration code doesn't support this so it breaks. This is a separate bug and it isn't trivially solved. When flushing a material there are now extra options to set wrap mode overrides. The overrides are an array of values for each layer that specifies an override for the s, t or r coordinates. The primitives use this to implement the automatic wrap mode. cogl_polygon also uses it to set GL_CLAMP_TO_BORDER mode for its trick to render sliced textures. Although this code has been added it looks like the sliced trick has been broken for a while and I haven't attempted to fix it here. I've added a constant to represent the maximum number of layers that a material supports so that I can size the overrides array. I've set it to 32 because as far as I can tell we have that limit imposed anyway because the other flush options use a guint32 to store a flag about each layer. The overrides array ends up adding 32 bytes to each flush options struct which may be a concern. http://bugzilla.openedhand.com/show_bug.cgi?id=2063
2010-04-01 06:31:33 -04:00
COGL_MATERIAL_FLUSH_FALLBACK_MASK = 1L<<0,
COGL_MATERIAL_FLUSH_DISABLE_MASK = 1L<<1,
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE = 1L<<2,
COGL_MATERIAL_FLUSH_SKIP_GL_COLOR = 1L<<3,
COGL_MATERIAL_FLUSH_WRAP_MODE_OVERRIDES = 1L<<4
[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 13:46:42 -04:00
} CoglMaterialFlushFlag;
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
/* This isn't defined in the GLES headers */
#ifndef GL_CLAMP_TO_BORDER
#define GL_CLAMP_TO_BORDER 0x812d
#endif
/* GL_ALWAYS is just used here as a value that is known not to clash
* with any valid GL wrap modes.
*
* XXX: keep the values in sync with the CoglMaterialWrapMode enum
* so no conversion is actually needed.
*/
typedef enum _CoglMaterialWrapModeInternal
{
COGL_MATERIAL_WRAP_MODE_INTERNAL_REPEAT = GL_REPEAT,
COGL_MATERIAL_WRAP_MODE_INTERNAL_CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE,
COGL_MATERIAL_WRAP_MODE_INTERNAL_CLAMP_TO_BORDER = GL_CLAMP_TO_BORDER,
COGL_MATERIAL_WRAP_MODE_INTERNAL_AUTOMATIC = GL_ALWAYS
} CoglMaterialWrapModeInternal;
typedef enum _CoglMaterialWrapModeOverride
{
COGL_MATERIAL_WRAP_MODE_OVERRIDE_NONE = 0,
COGL_MATERIAL_WRAP_MODE_OVERRIDE_REPEAT =
COGL_MATERIAL_WRAP_MODE_INTERNAL_REPEAT,
COGL_MATERIAL_WRAP_MODE_OVERRIDE_CLAMP_TO_EDGE =
COGL_MATERIAL_WRAP_MODE_INTERNAL_CLAMP_TO_EDGE,
COGL_MATERIAL_WRAP_MODE_OVERRIDE_CLAMP_TO_BORDER =
COGL_MATERIAL_WRAP_MODE_INTERNAL_CLAMP_TO_BORDER,
} CoglMaterialWrapModeOverride;
cogl-material: Add support for setting the wrap mode for a layer Previously, Cogl's texture coordinate system was effectively always GL_REPEAT so that if an application specifies coordinates outside the range 0→1 it would get repeated copies of the texture. It would however change the mode to GL_CLAMP_TO_EDGE if all of the coordinates are in the range 0→1 so that in the common case that the whole texture is being drawn with linear filtering it will not blend in edge pixels from the opposite sides. This patch adds the option for applications to change the wrap mode per layer. There are now three wrap modes: 'repeat', 'clamp-to-edge' and 'automatic'. The automatic map mode is the default and it implements the previous behaviour. The wrap mode can be changed for the s and t coordinates independently. I've tried to make the internals support setting the r coordinate but as we don't support 3D textures yet I haven't exposed any public API for it. The texture backends still have a set_wrap_mode virtual but this value is intended to be transitory and it will be changed whenever the material is flushed (although the backends are expected to cache it so that it won't use too many GL calls). In my understanding this value was always meant to be transitory and all primitives were meant to set the value before drawing. However there were comments suggesting that this is not the expected behaviour. In particular the vertex buffer drawing code never set a wrap mode so it would end up with whatever the texture was previously used for. These issues are now fixed because the material will always set the wrap modes. There is code to manually implement clamp-to-edge for textures that can't be hardware repeated. However this doesn't fully work because it relies on being able to draw the stretched parts using quads with the same values for tx1 and tx2. The texture iteration code doesn't support this so it breaks. This is a separate bug and it isn't trivially solved. When flushing a material there are now extra options to set wrap mode overrides. The overrides are an array of values for each layer that specifies an override for the s, t or r coordinates. The primitives use this to implement the automatic wrap mode. cogl_polygon also uses it to set GL_CLAMP_TO_BORDER mode for its trick to render sliced textures. Although this code has been added it looks like the sliced trick has been broken for a while and I haven't attempted to fix it here. I've added a constant to represent the maximum number of layers that a material supports so that I can size the overrides array. I've set it to 32 because as far as I can tell we have that limit imposed anyway because the other flush options use a guint32 to store a flag about each layer. The overrides array ends up adding 32 bytes to each flush options struct which may be a concern. http://bugzilla.openedhand.com/show_bug.cgi?id=2063
2010-04-01 06:31:33 -04:00
/* There can't be more than 32 layers because we need to fit a bitmask
of the layers into a guint32 */
#define COGL_MATERIAL_MAX_LAYERS 32
typedef struct _CoglMaterialWrapModeOverrides
{
struct
{
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
CoglMaterialWrapModeOverride s;
CoglMaterialWrapModeOverride t;
CoglMaterialWrapModeOverride r;
cogl-material: Add support for setting the wrap mode for a layer Previously, Cogl's texture coordinate system was effectively always GL_REPEAT so that if an application specifies coordinates outside the range 0→1 it would get repeated copies of the texture. It would however change the mode to GL_CLAMP_TO_EDGE if all of the coordinates are in the range 0→1 so that in the common case that the whole texture is being drawn with linear filtering it will not blend in edge pixels from the opposite sides. This patch adds the option for applications to change the wrap mode per layer. There are now three wrap modes: 'repeat', 'clamp-to-edge' and 'automatic'. The automatic map mode is the default and it implements the previous behaviour. The wrap mode can be changed for the s and t coordinates independently. I've tried to make the internals support setting the r coordinate but as we don't support 3D textures yet I haven't exposed any public API for it. The texture backends still have a set_wrap_mode virtual but this value is intended to be transitory and it will be changed whenever the material is flushed (although the backends are expected to cache it so that it won't use too many GL calls). In my understanding this value was always meant to be transitory and all primitives were meant to set the value before drawing. However there were comments suggesting that this is not the expected behaviour. In particular the vertex buffer drawing code never set a wrap mode so it would end up with whatever the texture was previously used for. These issues are now fixed because the material will always set the wrap modes. There is code to manually implement clamp-to-edge for textures that can't be hardware repeated. However this doesn't fully work because it relies on being able to draw the stretched parts using quads with the same values for tx1 and tx2. The texture iteration code doesn't support this so it breaks. This is a separate bug and it isn't trivially solved. When flushing a material there are now extra options to set wrap mode overrides. The overrides are an array of values for each layer that specifies an override for the s, t or r coordinates. The primitives use this to implement the automatic wrap mode. cogl_polygon also uses it to set GL_CLAMP_TO_BORDER mode for its trick to render sliced textures. Although this code has been added it looks like the sliced trick has been broken for a while and I haven't attempted to fix it here. I've added a constant to represent the maximum number of layers that a material supports so that I can size the overrides array. I've set it to 32 because as far as I can tell we have that limit imposed anyway because the other flush options use a guint32 to store a flag about each layer. The overrides array ends up adding 32 bytes to each flush options struct which may be a concern. http://bugzilla.openedhand.com/show_bug.cgi?id=2063
2010-04-01 06:31:33 -04:00
} values[COGL_MATERIAL_MAX_LAYERS];
} CoglMaterialWrapModeOverrides;
[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 13:46:42 -04:00
/*
* CoglMaterialFlushOptions:
*
*/
[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 13:46:42 -04:00
typedef struct _CoglMaterialFlushOptions
{
cogl-material: Add support for setting the wrap mode for a layer Previously, Cogl's texture coordinate system was effectively always GL_REPEAT so that if an application specifies coordinates outside the range 0→1 it would get repeated copies of the texture. It would however change the mode to GL_CLAMP_TO_EDGE if all of the coordinates are in the range 0→1 so that in the common case that the whole texture is being drawn with linear filtering it will not blend in edge pixels from the opposite sides. This patch adds the option for applications to change the wrap mode per layer. There are now three wrap modes: 'repeat', 'clamp-to-edge' and 'automatic'. The automatic map mode is the default and it implements the previous behaviour. The wrap mode can be changed for the s and t coordinates independently. I've tried to make the internals support setting the r coordinate but as we don't support 3D textures yet I haven't exposed any public API for it. The texture backends still have a set_wrap_mode virtual but this value is intended to be transitory and it will be changed whenever the material is flushed (although the backends are expected to cache it so that it won't use too many GL calls). In my understanding this value was always meant to be transitory and all primitives were meant to set the value before drawing. However there were comments suggesting that this is not the expected behaviour. In particular the vertex buffer drawing code never set a wrap mode so it would end up with whatever the texture was previously used for. These issues are now fixed because the material will always set the wrap modes. There is code to manually implement clamp-to-edge for textures that can't be hardware repeated. However this doesn't fully work because it relies on being able to draw the stretched parts using quads with the same values for tx1 and tx2. The texture iteration code doesn't support this so it breaks. This is a separate bug and it isn't trivially solved. When flushing a material there are now extra options to set wrap mode overrides. The overrides are an array of values for each layer that specifies an override for the s, t or r coordinates. The primitives use this to implement the automatic wrap mode. cogl_polygon also uses it to set GL_CLAMP_TO_BORDER mode for its trick to render sliced textures. Although this code has been added it looks like the sliced trick has been broken for a while and I haven't attempted to fix it here. I've added a constant to represent the maximum number of layers that a material supports so that I can size the overrides array. I've set it to 32 because as far as I can tell we have that limit imposed anyway because the other flush options use a guint32 to store a flag about each layer. The overrides array ends up adding 32 bytes to each flush options struct which may be a concern. http://bugzilla.openedhand.com/show_bug.cgi?id=2063
2010-04-01 06:31:33 -04:00
CoglMaterialFlushFlag flags;
[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 13:46:42 -04:00
cogl-material: Add support for setting the wrap mode for a layer Previously, Cogl's texture coordinate system was effectively always GL_REPEAT so that if an application specifies coordinates outside the range 0→1 it would get repeated copies of the texture. It would however change the mode to GL_CLAMP_TO_EDGE if all of the coordinates are in the range 0→1 so that in the common case that the whole texture is being drawn with linear filtering it will not blend in edge pixels from the opposite sides. This patch adds the option for applications to change the wrap mode per layer. There are now three wrap modes: 'repeat', 'clamp-to-edge' and 'automatic'. The automatic map mode is the default and it implements the previous behaviour. The wrap mode can be changed for the s and t coordinates independently. I've tried to make the internals support setting the r coordinate but as we don't support 3D textures yet I haven't exposed any public API for it. The texture backends still have a set_wrap_mode virtual but this value is intended to be transitory and it will be changed whenever the material is flushed (although the backends are expected to cache it so that it won't use too many GL calls). In my understanding this value was always meant to be transitory and all primitives were meant to set the value before drawing. However there were comments suggesting that this is not the expected behaviour. In particular the vertex buffer drawing code never set a wrap mode so it would end up with whatever the texture was previously used for. These issues are now fixed because the material will always set the wrap modes. There is code to manually implement clamp-to-edge for textures that can't be hardware repeated. However this doesn't fully work because it relies on being able to draw the stretched parts using quads with the same values for tx1 and tx2. The texture iteration code doesn't support this so it breaks. This is a separate bug and it isn't trivially solved. When flushing a material there are now extra options to set wrap mode overrides. The overrides are an array of values for each layer that specifies an override for the s, t or r coordinates. The primitives use this to implement the automatic wrap mode. cogl_polygon also uses it to set GL_CLAMP_TO_BORDER mode for its trick to render sliced textures. Although this code has been added it looks like the sliced trick has been broken for a while and I haven't attempted to fix it here. I've added a constant to represent the maximum number of layers that a material supports so that I can size the overrides array. I've set it to 32 because as far as I can tell we have that limit imposed anyway because the other flush options use a guint32 to store a flag about each layer. The overrides array ends up adding 32 bytes to each flush options struct which may be a concern. http://bugzilla.openedhand.com/show_bug.cgi?id=2063
2010-04-01 06:31:33 -04:00
guint32 fallback_layers;
guint32 disable_layers;
GLuint layer0_override_texture;
CoglMaterialWrapModeOverrides wrap_mode_overrides;
[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 13:46:42 -04:00
} CoglMaterialFlushOptions;
cogl: improves header and coding style consistency We've had complaints that our Cogl code/headers are a bit "special" so this is a first pass at tidying things up by giving them some consistency. These changes are all consistent with how new code in Cogl is being written, but the style isn't consistently applied across all code yet. There are two parts to this patch; but since each one required a large amount of effort to maintain tidy indenting it made sense to combine the changes to reduce the time spent re indenting the same lines. The first change is to use a consistent style for declaring function prototypes in headers. Cogl headers now consistently use this style for prototypes: return_type cogl_function_name (CoglType arg0, CoglType arg1); Not everyone likes this style, but it seems that most of the currently active Cogl developers agree on it. The second change is to constrain the use of redundant glib data types in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all been replaced with int, unsigned int, float, long, unsigned long and char respectively. When talking about pixel data; use of guchar has been replaced with guint8, otherwise unsigned char can be used. The glib types that we continue to use for portability are gboolean, gint{8,16,32,64}, guint{8,16,32,64} and gsize. The general intention is that Cogl should look palatable to the widest range of C programmers including those outside the Gnome community so - especially for the public API - we want to minimize the number of foreign looking typedefs.
2010-02-09 20:57:32 -05:00
void
_cogl_material_get_colorubv (CoglHandle handle,
guint8 *color);
cogl: improves header and coding style consistency We've had complaints that our Cogl code/headers are a bit "special" so this is a first pass at tidying things up by giving them some consistency. These changes are all consistent with how new code in Cogl is being written, but the style isn't consistently applied across all code yet. There are two parts to this patch; but since each one required a large amount of effort to maintain tidy indenting it made sense to combine the changes to reduce the time spent re indenting the same lines. The first change is to use a consistent style for declaring function prototypes in headers. Cogl headers now consistently use this style for prototypes: return_type cogl_function_name (CoglType arg0, CoglType arg1); Not everyone likes this style, but it seems that most of the currently active Cogl developers agree on it. The second change is to constrain the use of redundant glib data types in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all been replaced with int, unsigned int, float, long, unsigned long and char respectively. When talking about pixel data; use of guchar has been replaced with guint8, otherwise unsigned char can be used. The glib types that we continue to use for portability are gboolean, gint{8,16,32,64}, guint{8,16,32,64} and gsize. The general intention is that Cogl should look palatable to the widest range of C programmers including those outside the Gnome community so - especially for the public API - we want to minimize the number of foreign looking typedefs.
2010-02-09 20:57:32 -05:00
void
_cogl_material_flush_gl_state (CoglHandle material,
gboolean skip_gl_state);
[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 13:46:42 -04:00
cogl: improves header and coding style consistency We've had complaints that our Cogl code/headers are a bit "special" so this is a first pass at tidying things up by giving them some consistency. These changes are all consistent with how new code in Cogl is being written, but the style isn't consistently applied across all code yet. There are two parts to this patch; but since each one required a large amount of effort to maintain tidy indenting it made sense to combine the changes to reduce the time spent re indenting the same lines. The first change is to use a consistent style for declaring function prototypes in headers. Cogl headers now consistently use this style for prototypes: return_type cogl_function_name (CoglType arg0, CoglType arg1); Not everyone likes this style, but it seems that most of the currently active Cogl developers agree on it. The second change is to constrain the use of redundant glib data types in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all been replaced with int, unsigned int, float, long, unsigned long and char respectively. When talking about pixel data; use of guchar has been replaced with guint8, otherwise unsigned char can be used. The glib types that we continue to use for portability are gboolean, gint{8,16,32,64}, guint{8,16,32,64} and gsize. The general intention is that Cogl should look palatable to the widest range of C programmers including those outside the Gnome community so - especially for the public API - we want to minimize the number of foreign looking typedefs.
2010-02-09 20:57:32 -05:00
gboolean
_cogl_material_equal (CoglHandle material0_handle,
CoglHandle material1_handle,
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
gboolean skip_gl_color);
[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 13:46:42 -04:00
cogl: improves header and coding style consistency We've had complaints that our Cogl code/headers are a bit "special" so this is a first pass at tidying things up by giving them some consistency. These changes are all consistent with how new code in Cogl is being written, but the style isn't consistently applied across all code yet. There are two parts to this patch; but since each one required a large amount of effort to maintain tidy indenting it made sense to combine the changes to reduce the time spent re indenting the same lines. The first change is to use a consistent style for declaring function prototypes in headers. Cogl headers now consistently use this style for prototypes: return_type cogl_function_name (CoglType arg0, CoglType arg1); Not everyone likes this style, but it seems that most of the currently active Cogl developers agree on it. The second change is to constrain the use of redundant glib data types in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all been replaced with int, unsigned int, float, long, unsigned long and char respectively. When talking about pixel data; use of guchar has been replaced with guint8, otherwise unsigned char can be used. The glib types that we continue to use for portability are gboolean, gint{8,16,32,64}, guint{8,16,32,64} and gsize. The general intention is that Cogl should look palatable to the widest range of C programmers including those outside the Gnome community so - especially for the public API - we want to minimize the number of foreign looking typedefs.
2010-02-09 20:57:32 -05:00
CoglHandle
_cogl_material_journal_ref (CoglHandle material_handle);
void
_cogl_material_journal_unref (CoglHandle material_handle);
cogl-material: Add support for setting the wrap mode for a layer Previously, Cogl's texture coordinate system was effectively always GL_REPEAT so that if an application specifies coordinates outside the range 0→1 it would get repeated copies of the texture. It would however change the mode to GL_CLAMP_TO_EDGE if all of the coordinates are in the range 0→1 so that in the common case that the whole texture is being drawn with linear filtering it will not blend in edge pixels from the opposite sides. This patch adds the option for applications to change the wrap mode per layer. There are now three wrap modes: 'repeat', 'clamp-to-edge' and 'automatic'. The automatic map mode is the default and it implements the previous behaviour. The wrap mode can be changed for the s and t coordinates independently. I've tried to make the internals support setting the r coordinate but as we don't support 3D textures yet I haven't exposed any public API for it. The texture backends still have a set_wrap_mode virtual but this value is intended to be transitory and it will be changed whenever the material is flushed (although the backends are expected to cache it so that it won't use too many GL calls). In my understanding this value was always meant to be transitory and all primitives were meant to set the value before drawing. However there were comments suggesting that this is not the expected behaviour. In particular the vertex buffer drawing code never set a wrap mode so it would end up with whatever the texture was previously used for. These issues are now fixed because the material will always set the wrap modes. There is code to manually implement clamp-to-edge for textures that can't be hardware repeated. However this doesn't fully work because it relies on being able to draw the stretched parts using quads with the same values for tx1 and tx2. The texture iteration code doesn't support this so it breaks. This is a separate bug and it isn't trivially solved. When flushing a material there are now extra options to set wrap mode overrides. The overrides are an array of values for each layer that specifies an override for the s, t or r coordinates. The primitives use this to implement the automatic wrap mode. cogl_polygon also uses it to set GL_CLAMP_TO_BORDER mode for its trick to render sliced textures. Although this code has been added it looks like the sliced trick has been broken for a while and I haven't attempted to fix it here. I've added a constant to represent the maximum number of layers that a material supports so that I can size the overrides array. I've set it to 32 because as far as I can tell we have that limit imposed anyway because the other flush options use a guint32 to store a flag about each layer. The overrides array ends up adding 32 bytes to each flush options struct which may be a concern. http://bugzilla.openedhand.com/show_bug.cgi?id=2063
2010-04-01 06:31:33 -04:00
/* TODO: These should be made public once we add support for 3D
textures in Cogl */
void
_cogl_material_set_layer_wrap_mode_r (CoglHandle material,
int layer_index,
CoglMaterialWrapMode mode);
CoglMaterialWrapMode
_cogl_material_layer_get_wrap_mode_r (CoglHandle layer);
void
_cogl_material_set_user_program (CoglHandle handle,
CoglHandle program);
void
_cogl_delete_gl_texture (GLuint gl_texture);
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
void
_cogl_material_texture_storage_change_notify (CoglHandle texture);
void
_cogl_material_apply_legacy_state (CoglHandle handle);
void
_cogl_gl_use_program_wrapper (GLuint program);
void
_cogl_material_apply_overrides (CoglMaterial *material,
CoglMaterialFlushOptions *options);
CoglMaterial: Implements sparse materials design This is a complete overhaul of the data structures used to manage CoglMaterial state. We have these requirements that were aiming to meet: (Note: the references to "renderlists" correspond to the effort to support scenegraph level shuffling of Clutter actor primitives so we can minimize GPU state changes) Sparse State: We wanted a design that allows sparse descriptions of state so it scales well as we make CoglMaterial responsible for more and more state. It needs to scale well in terms of memory usage and the cost of operations we need to apply to materials such as comparing, copying and flushing their state. I.e. we would rather have these things scale by the number of real changes a material represents not by how much overall state CoglMaterial becomes responsible for. Cheap Copies: As we add support for renderlists in Clutter we will need to be able to get an immutable handle for a given material's current state so that we can retain a record of a primitive with its associated material without worrying that changes to the original material will invalidate that record. No more flush override options: We want to get rid of the flush overrides mechanism we currently use to deal with texture fallbacks, wrap mode changes and to handle the use of highlevel CoglTextures that need to be resolved into lowlevel textures before flushing the material state. The flush options structure has been expanding in size and the structure is logged with every journal entry so it is not an approach that scales well at all. It also makes flushing material state that much more complex. Weak Materials: Again for renderlists we need a way to create materials derived from other materials but without the strict requirement that modifications to the original material wont affect the derived ("weak") material. The only requirement is that its possible to later check if the original material has been changed. A summary of the new design: A CoglMaterial now basically represents a diff against its parent. Each material has a single parent and a mask of state that it changes. Each group of state (such as the blending state) has an "authority" which is found by walking up from a given material through its ancestors checking the difference mask until a match for that group is found. There is only one root node to the graph of all materials, which is the default material first created when Cogl is being initialized. All the groups of state are divided into two types, such that infrequently changed state belongs in a separate "BigState" structure that is only allocated and attached to a material when necessary. CoglMaterialLayers are another sparse structure. Like CoglMaterials they represent a diff against their parent and all the layers are part of another graph with the "default_layer_0" layer being the root node that Cogl creates during initialization. Copying a material is now basically just a case of slice allocating a CoglMaterial, setting the parent to be the source being copied and zeroing the mask of changes. Flush overrides should now be handled by simply relying on the cheapness of copying a material and making changes to it. (This will be done in a follow on commit) Weak material support will be added in a follow on commit.
2010-04-08 07:21:04 -04:00
CoglMaterialBlendEnable
_cogl_material_get_blend_enabled (CoglHandle handle);
void
_cogl_material_set_blend_enabled (CoglHandle handle,
CoglMaterialBlendEnable enable);
#endif /* __COGL_MATERIAL_PRIVATE_H */