Commit Graph

84 Commits

Author SHA1 Message Date
Neil Roberts
c33ce5fc6b Use GL_ARB_sampler_objects
GL_ARB_sampler_objects provides a GL object which overrides the
sampler state part of a texture object with different values. The
sampler state that Cogl currently exposes is the wrap modes and
filters. Cogl exposes the state as part of the pipeline layer state
but without this extension GL only exposes it as part of the texture
object state. This means that it won't work to use a single texture
multiple times in one primitive with different sampler states. It also
makes switching between different sampler states with a single texture
not terribly efficient because it has to change the texture object
state every time.

This patch adds a cache for sampler states in a shared hash table
attached to the CoglContext. The entire set of parameters for the
sampler state is used as the key for the hash table. When a unique
state is encountered the sampler cache will create a new entry,
otherwise it will return a const pointer to an existing entry. That
means we can have a single pointer to represent any combination of
sampler state.

Pipeline layers now just store this single pointer rather than storing
all of the sampler state. The two separate state flags for wrap modes
and filters have now been combined into one. It should be faster to
compare the sampler state now because instead of comparing each value
it can just compare the pointers to the cached sampler entries. The
hash table of cached sampler states should only need to perform its
more expensive hash on the state when a property is changed on a
pipeline, not every time it is flushed.

When the sampler objects extension is available each cached sampler
state will also get a sampler object to represent it. The common code
to flush the GL state will now simply bind this object to a unit
instead of flushing the state though the CoglTexture when possible.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2012-04-05 13:47:36 +01:00
Neil Roberts
be9d5b34c6 pipeline: Use cogl_depth_state_init to init default depth state
The previous code to initialise the depth state on the default
pipeline wasn't initialising the magic number. If you later tried to
retrieve the depth state using cogl_pipeline_get_depth_state you would
end up with an invalid depth state struct and you would just get
warnings if you tried to use it for anything. This patch just replaces
the initialisation with a call to cogl_depth_state_init because it
uses the same values anyway.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2012-04-03 16:36:54 +01:00
Neil Roberts
2c596f5e2e pipeline: Point sprite state shouldn't affect codegen on GL
I think this slipped in as a cut-and-paste error in b2e735ff.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2012-03-07 15:13:30 +00:00
Neil Roberts
185630085c Add -Wmissing-declarations to maintainer flags and fix problems
This option to GCC makes it give a warning whenever a global function
is defined without a declaration. This should catch cases were we've
defined a function but forgot to put it in a header. In that case it
is either only used within one file so we should make it static or we
should declare it in a header.

The following changes where made to fix problems:

• Some functions were made static

• cogl-path.h (the one containing the 1.0 API) was split into two
  files, one defining the functions and one defining the enums so that
  cogl-path.c can include the enum and function declarations from the
  2.0 API as well as the function declarations from the 1.0 API.

• cogl2-clip-state has been removed. This only had one experimental
  function called cogl_clip_push_from_path but as this is unstable we
  might as well remove it favour of the equivalent cogl_framebuffer_*
  API.

• The GLX, SDL and WGL winsys's now have a private header to define
  their get_vtable function instead of directly declaring in the C
  file where it is called.

• All places that were calling COGL_OBJECT_DEFINE need to have the
  cogl_is_whatever function declared so these have been added either
  as a public function or in a private header.

• Some files that were not including the header containing their
  function declarations have been fixed to do so.

• Any unused error quark functions have been removed. If we later want
  them we should add them back one by one and add a declaration for
  them in a header.

• _cogl_is_framebuffer has been renamed to cogl_is_framebuffer and
  made a public function with a declaration in cogl-framebuffer.h

• Similarly for CoglOnscreen.

• cogl_vdraw_indexed_attributes is called
  cogl_framebuffer_vdraw_indexed_attributes in the header. The
  definition has been changed to match the header.

• cogl_index_buffer_allocate has been removed. This had no declaration
  and I'm not sure what it's supposed to do.

• CoglJournal has been changed to use the internal CoglObject macro so
  that it won't define an exported cogl_is_journal symbol.

• The _cogl_blah_pointer_from_handle functions have been removed.
  CoglHandle isn't used much anymore anyway and in the few places
  where it is used I think it's safe to just use the implicit cast
  from void* to the right type.

• The test-utils.h header for the conformance tests explicitly
  disables the -Wmissing-declaration option using a pragma because all
  of the tests declare their main function without a header. Any
  mistakes relating to missing declarations aren't really important
  for the tests.

• cogl_quaternion_init_from_quaternion and init_from_matrix have been
  given declarations in cogl-quaternion.h

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2012-03-06 18:45:44 +00:00
Robert Bragg
785e6375eb Adds a context arg to cogl_pipeline_new()
As we move towards Cogl 2.0 we are aiming to remove the need for a
default global CoglContext and so everything should be explicitly
related to a context somehow. CoglPipelines are top level objects and
so this patch adds a context argument to cogl_pipeline_new().

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2012-02-21 12:38:24 +00:00
Robert Bragg
0a2a3d7c80 context: removes some uses of CoglHandle
There were several members of the CoglContext struct using the
CoglHandle type for things that now have replacement typedefs which
this patch fixes.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2012-02-21 12:37:55 +00:00
Robert Bragg
1bba0f5d99 pipeline: make _equal() cost scale by n bits in differences
This improves the implementation of _cogl_pipeline_equal() to ensure
that the cost of the function scales by the number of bits set in the
pipelines_difference variable set after calling
_cogl_pipeline_compare_differences() instead of scaling by the number of
state groups cogl tracks.

As Cogl tracks more and more state groups we don't want
_cogl_pipeline_equal() to get slower.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2012-02-20 23:16:37 +00:00
Robert Bragg
680f63a48c Remove all internal includes of cogl.h
The cogl.h header is meant to be the public header for including the 1.x
api used by Clutter so we should stop using that as a convenient way to
include all likely prototypes and typedefs. Actually we already do a
good job of listing the specific headers we depend on in each of the .c
files we have so mostly this patch just strip out the redundant
includes for cogl.h with a few fixups where that broke the build.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2012-02-20 23:12:45 +00:00
Robert Bragg
ee940a3d0d Move all types/prototypes from cogl.h -> cogl[1]-context.h
So we can get to the point where cogl.h is merely an aggregation of
header includes for the 1.x api this moves all the function prototypes
and type definitions into a cogl-context.h and a new cogl1-context.h.

Ideally no code internally should ever need to include cogl.h as it just
represents the public facing header for accessing the 1.x api which
should only be used by Clutter.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2012-02-20 23:12:44 +00:00
Neil Roberts
740bd12f2d Add a version of _cogl_pipeline_get_layer which does not create it
This adds _cogl_pipeline_get_layer_with_flags which takes a set of
flags to modify the behaviour. The only flag currently available is
one to disable creating the layer if the layer index does not already
exist.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2012-02-13 17:15:35 +00:00
Neil Roberts
b96e6900f5 cogl-pipeline-layer: Use CoglTextureType instead of GL target enum
Instead of storing the GLenum for the target of the last used texture
for a layer it now stores the CoglTextureType instead. The state name
has been renamed to 'texture type' instead of 'texture target'.
Previously the default pipeline layer would store 0 here to represent
that there is no texture. This has been changed to store
COGL_TEXTURE_TYPE_2D instead which means that all pipeline layers
always have a valid value for the texture type. Any places that were
previously fetching the texture from a layer to determine the target
(for example when generating shaders or when enabling a particular
texture target) now use the texture type instead. This means they will
work even for layers that don't have a texture.

This also changes it so that when binding a fallback texture instead
of always using a 2D texture it will now use the default texture
corresponding to the texture type of the layer. That way when the
generated shader tries to do a texture lookup for that type of texture
it will get a valid texture object. To make this work the patch adds a
default texture for 3D textures to the context and also makes the
default rectangle texture actually be a rectangle texture instead of
using a 2D texture.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2012-02-13 17:09:34 +00:00
Neil Roberts
f005f517fe Flush matrices in the progend and flip with a vector
Previously flushing the matrices was performed as part of the
framebuffer state. When on GLES2 this matrix flushing is actually
diverted so that it only keeps a reference to the intended matrix
stack. This is necessary because on GLES2 there are no builtin
uniforms so it can't actually flush the matrices until the program for
the pipeline is generated. When the matrices are flushed it would
store the age of modifications on the matrix stack so that it could
detect when the matrix hasn't changed and avoid flushing it.

This patch changes it so that the pipeline is responsible for flushing
the matrices even when we are using the GL builtins. The same
mechanism for detecting unmodified matrix stacks is used in all
cases. There is a new CoglMatrixStackCache type which is used to store
a reference to the intended matrix stack along with its last flushed
age. There are now two of these attached to the CoglContext to track
the flushed state for the global matrix builtins and also two for each
glsl progend program state to track the flushed state for a
program. The framebuffer matrix flush now just updates the intended
matrix stacks without actually trying to flush.

When a vertex snippet is attached to the pipeline, the GLSL vertend
will now avoid using the projection matrix to flip the rendering. This
is necessary because any vertex snippet may cause the projection
matrix not to be used. Instead the flip is done as a forced final step
by multiplying cogl_position_out by a vec4 uniform. This uniform is
updated as part of the progend pre_paint depending on whether the
framebuffer is offscreen or not.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:06 +00:00
Neil Roberts
68b3643b25 snippet: Add a hook for the layer texture coordinate transformation
This adds a hook called COGL_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM.
This can be used to alter the application of the layer user matrix to
a texture coordinate or it can bypass it altogether.

This is the first per-layer hook that affects the vertex shader state
so the patch includes the boilerplate needed to get that to work.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:06 +00:00
Neil Roberts
5be5a03343 pipeline: Assume blend enabled when there are snippets
Whenever snippets are enabled we can't determine whether the final
color will be fully opaque so we just have to assume blending should
be enabled.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:06 +00:00
Neil Roberts
df0f9a862f pipeline: Add a snippet hook for the texture lookup
This adds a per-layer snippet hook for the texure lookup. Here the
snippet can modify the texture coordinates used for the lookup or
modify the texel resulting from the lookup. This is the first
per-layer hook so this also adds the
COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS state and all of the
boilerplate needed to make that work.

Most of the functions used by the pipeline state to manage the snippet
list has been moved into cogl-pipeline-snippet.c so that it can be
shared with the layer state.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:06 +00:00
Neil Roberts
d38ae0284b cogl-pipeline: Add two hook points for adding shader snippets
This adds two new public experimental functions for attaching
CoglSnippets to two hook points on a CoglPipeline:

void cogl_pipeline_add_vertex_hook (CoglPipeline *, CoglSnippet *)
void cogl_pipeline_add_fragment_hook (CoglPipeline *, CoglSnippet *)

The hooks are intended to be around the entire vertex or fragment
processing. That means the pre string in the snippet will be inserted
at the very top of the main function and the post function will be
inserted at the very end. The declarations get inserted in the global
scope.

The snippets are stored in two separate linked lists with a structure
containing an enum representing the hook point and a pointer to the
snippet. The lists are meant to be for hooks that affect the vertex
shader and fragment shader respectively. Although there are currently
only two hooks and the names match these two lists, the intention is
*not* that each new hook will be in a separate list. The separation of
the lists is just to make it easier to determine which shader needs to
be regenerated when a new snippet is added.

When a pipeline becomes the authority for either the vertex or
fragment snipper state, it simply copies the entire list from the
previous authority (although of course the shader snippet objects are
referenced instead of copied so it doesn't duplicate the source
strings).

Each string is inserted into its own block in the shader. This means
that each string has its own scope so it doesn't need to worry about
name collisions with variables in other snippets. However it does mean
that the pre and post strings can't share variables. It could be
possible to wrap both parts in one block and then wrap the actual
inner hook code in another block, however this would mean that any
further snippets within the outer snippet would be able to see those
variables. Perhaps something to consider would be to put each snippet
into its own function which calls another function between the pre and
post strings to do further processing.

The pipeline cache for generated programs was previously shared with
the fragment shader cache because the state that affects vertex
shaders was a subset of the state that affects fragment shaders. This
is no longer the case because there is a separate state mask for
vertex snippets so the program cache now has its own hash table.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:05 +00:00
Neil Roberts
da154b9a3b pipeline: Add a missing break for the uniforms state
_cogl_pipeline_init_multi_property_sparse_state was missing a break in
the case statement handling uniforms. This doesn't yet matter because
it is the last one handled anyway but it will bite someone later.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-29 13:03:25 +00:00
Neil Roberts
c269817edd cogl-pipeline: Use a hash table for faster uniform name lookup
The uniform names are now stored in a GPtrArray instead of a linked
list. There is also a hash table to speed up converting names to
locations.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 16:32:11 +00:00
Neil Roberts
4a7cd0d2ac cogl-pipeline: Store the uniform overrides in an array instead of list
Previously the uniform overrides were stored in a linked list. Now
they are stored in a g_malloc'd array. The values are still tightly
packed so that there is only a value for each uniform that has a
corresponding bit in override_mask. The allocated size of the array
always exactly corresponds to the number of bits set in the
override_mask. This means that when a new uniform value is set on a
pipeline it will have to grow the array and copy the old values
in. The assumption is that setting a value for a new uniform is much
less frequent then setting a value for an existing uniform so it makes
more sense to optimise the latter.

The advantage of using an array is that we can quickly jump to right
boxed value given a uniform location by doing a population count in
the bitmask for the number of bits less than the given uniform
location. This can be done in O(1) time whereas the old approach using
a list would scale by the number of bits set.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 16:32:11 +00:00
Neil Roberts
4553ca0695 cogl-pipeline: Add support for setting uniform values
This adds the following new public experimental functions to set
uniform values on a CoglPipeline:

void
cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline,
                              int uniform_location,
                              float value);
void
cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline,
                              int uniform_location,
                              int value);
void
cogl_pipeline_set_uniform_float (CoglPipeline *pipeline,
                                 int uniform_location,
                                 int n_components,
                                 int count,
                                 const float *value);
void
cogl_pipeline_set_uniform_int (CoglPipeline *pipeline,
                               int uniform_location,
                               int n_components,
                               int count,
                               const int *value);
void
cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline,
                                  int uniform_location,
                                  int dimensions,
                                  int count,
                                  gboolean transpose,
                                  const float *value);

These are similar to the old functions used to set uniforms on a
CoglProgram. To get a value to pass in as the uniform_location there
is also:

int
cogl_pipeline_get_uniform_location (CoglPipeline *pipeline,
                                    const char *uniform_name);

Conceptually the uniform locations are tied to the pipeline so that
whenever setting a value for a new pipeline the application is
expected to call this function. However in practice the uniform
locations are global to the CoglContext. The names are stored in a
linked list where the position in the list is the uniform location.

The global indices are used so that each pipeline can store a mask of
which uniforms it overrides. That way it is quicker to detect which
uniforms are different from the last pipeline that used the same
CoglProgramState so it can avoid flushing uniforms that haven't
changed. Currently the values are not actually compared which means
that it will only avoid flushing a uniform if there is a common
ancestor that sets the value (or if the same pipeline is being flushed
again - in which case the pipeline and its common ancestor are the
same thing).

The uniform values are stored in the big state of the pipeline as a
sparse linked list. A bitmask stores which values have been overridden
and only overridden values are stored in the linked list.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 16:32:11 +00:00
Neil Roberts
5369b3c601 pipeline: Make the backface culling experimental public
This adds two new experimental public functions to replace the old
internal _cogl_pipeline_set_cull_face_state function:

void
cogl_pipeline_set_cull_face_mode (CoglPipeline *pipeline,
                                  CoglPipelineCullFaceMode cull_face_mode);

void
cogl_pipeline_set_front_face_winding (CoglPipeline *pipeline,
                                      CoglWinding front_winding);

There are also the corresponding getters.

https://bugzilla.gnome.org/show_bug.cgi?id=663628

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-14 18:40:27 +00:00
Robert Bragg
b72f255c0a Start to reduce dependence on glib
Since we've had several developers from admirable projects say they
would like to use Cogl but would really prefer not to pull in
gobject,gmodule and glib as extra dependencies we are investigating if
we can get to the point where glib is only an optional dependency.
Actually we feel like we only make minimal use of glib anyway, so it may
well be quite straightforward to achieve this.

This adds a --disable-glib configure option that can be used to disable
features that depend on glib.

Actually --disable-glib doesn't strictly disable glib at this point
because it's more helpful if cogl continues to build as we make
incremental progress towards this.

The first use of glib that this patch tackles is the use of
g_return_val_if_fail and g_return_if_fail which have been replaced with
equivalent _COGL_RETURN_VAL_IF_FAIL and _COGL_RETURN_IF_FAIL macros.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-11-01 12:03:02 +00:00
Robert Bragg
5ab0b38657 pipeline: don't leak the layers_cache
When freeing a pipeline in _cogl_pipeline_free we weren't making sure to
free the layers_cache which was leading to a memory leak.

Thanks to Sunjin Yang for finding this.

https://bugzilla.gnome.org/show_bug.cgi?id=660986

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-10-12 15:29:07 +01:00
Robert Bragg
30f8521790 pipeline: optimize _compare_differences functions
This optimizes the layer and pipeline _compare_differences functions so
neither of them use the GArray api since building up the list of
ancestors by appending to a shared GArray was showing quite high on
profiles due to how frequently pipeline comparisons are made. Instead
we now build up a transient, singly linked list by allocating GList
nodes via alloca to build up the parallel lists of ancestors.

This tweaked approach actually ends up being a bit more concise than
before, we avoid the overhead of the GArray api and now avoid making any
function calls while comparing (assuming the _get_parent() calls always
inline), we avoiding needing to get the default cogl context.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-09-21 17:28:32 +01:00
Robert Bragg
f16d3756df pipeline: lazily get ctx in _get_layer
We only need a ctx pointer if we need to refer to the default_layer_x
layers to copy as templates so only call  _cogl_context_get_default()
once we need to copy a template. _cogl_context_get_default() was
starting to show up in profiles and this was the main cause.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-09-21 17:28:22 +01:00
Robert Bragg
d4459e2d42 pipeline: Split more code out from cogl-pipeline.c
This splits out the core CoglPipelineLayer support code from
cogl-pipeline.c into cogl-pipeline-layer.c; it splits out the debugging
code for dumping a pipeline to a .dot file into cogl-pipeline-debug.c
and it splits the CoglPipelineNode support which is shared between
CoglPipeline and CoglPipelineLayer into cogl-node.c.

Note: cogl-pipeline-layer.c only contains the layer code directly
relating to CoglPipelineLayer objects; it does not contain any
_cogl_pipeline API relating to how CoglPipeline tracks and manipulates
layers.
2011-09-21 17:03:10 +01:00
Robert Bragg
4c3dadd35e Add a strong CoglTexture type to replace CoglHandle
As part of the on going, incremental effort to purge the non type safe
CoglHandle type from the Cogl API this patch tackles most of the
CoglHandle uses relating to textures.

We'd postponed making this change for quite a while because we wanted to
have a clearer understanding of how we wanted to evolve the texture APIs
towards Cogl 2.0 before exposing type safety here which would be
difficult to change later since it would imply breaking APIs.

The basic idea that we are steering towards now is that CoglTexture
can be considered to be the most primitive interface we have for any
object representing a texture. The texture interface would provide
roughly these methods:

  cogl_texture_get_width
  cogl_texture_get_height
  cogl_texture_can_repeat
  cogl_texture_can_mipmap
  cogl_texture_generate_mipmap;
  cogl_texture_get_format
  cogl_texture_set_region
  cogl_texture_get_region

Besides the texture interface we will then start to expose types
corresponding to specific texture types: CoglTexture2D,
CoglTexture3D, CoglTexture2DSliced, CoglSubTexture, CoglAtlasTexture and
CoglTexturePixmapX11.

We will then also expose an interface for the high-level texture types
we have (such as CoglTexture2DSlice, CoglSubTexture and
CoglAtlasTexture) called CoglMetaTexture. CoglMetaTexture is an
additional interface that lets you iterate a virtual region of a meta
texture and get mappings of primitive textures to sub-regions of that
virtual region. Internally we already have this kind of abstraction for
dealing with sliced texture, sub-textures and atlas textures in a
consistent way, so this will just make that abstraction public. The aim
here is to clarify that there is a difference between primitive textures
(CoglTexture2D/3D) and some of the other high-level textures, and also
enable developers to implement primitives that can support meta textures
since they can only be used with the cogl_rectangle API currently.

The thing that's not so clean-cut with this are the texture constructors
we have currently; such as cogl_texture_new_from_file which no longer
make sense when CoglTexture is considered to be an interface.  These
will basically just become convenient factory functions and it's just a
bit unusual that they are within the cogl_texture namespace.  It's worth
noting here that all the texture type APIs will also have their own type
specific constructors so these functions will only be used for the
convenience of being able to create a texture without really wanting to
know the details of what type of texture you need.  Longer term for 2.0
we may come up with replacement names for these factory functions or the
other thing we are considering is designing some asynchronous factory
functions instead since it's so often detrimental to application
performance to be blocked waiting for a texture to be uploaded to the
GPU.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-09-21 15:27:03 +01:00
Neil Roberts
dbff3a357e Make backface culling be part of the legacy state
This adds an internal function to set the backface culling state on a
pipeline. This includes properties to set the culling mode (front,
back or both) and also to set which face is considered the front
(COGL_WINDING_CLOCKWISE or COGL_WINDING_COUNTER_CLOCKWISE). The actual
front face flushed to GL depends on whether we are rendering to an
offscreen buffer or not. This means that when changing between on- and
off- screen framebuffers it now checks whether the last flushed
pipeline has backface culling enabled and forces a reflush of the cull
face state if so.

The backface culling is now set on a pipeline as part of the legacy
state. This is important because some code in Cogl assumes it can
flush a temporary pipeline to revert to a known state, but previously
this wouldn't disable backface culling so things such as flushing the
clip stack could get confused.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-09-19 16:40:07 +01:00
Neil Roberts
f6ec6e2d0e pipeline-arbfp: Check for fog on the pipeline not the legacy state
The ARBfp backend can't handle fog so it tries to check for when it's
enabled and bails out. However it was checking using the global legacy
state value on the CoglContext but this doesn't necessarily reflect
the state that will actually be used by the pipeline because Cogl may
have internally pushed a different pipeline.

This patch adds an internal _cogl_pipeline_get_fog_enabled which the
ARBfp backend now uses.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-09-19 16:40:06 +01:00
Robert Bragg
db6c452aaa pipeline: split out all layer state apis
As part of an on-going effort to get cogl-pipeline.c into a more
maintainable state this splits out all the apis relating just to
layer state. This just leaves code relating to the core CoglPipeline
and CoglPipelineLayer design left in cogl-pipeline.c.

This splits out around 2k more lines from cogl-pipeline.c although we
are still left with nearly 4k lines so we still have some way to go!

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-09-19 16:40:00 +01:00
Robert Bragg
9b58b6f472 pipeline: split out all core state apis
Since cogl-pipeline.c has become very unwieldy this make a start at
trying to shape this code back into a manageable state. This patche
moves all the API relating to core pipeline state into
cogl-pipeline-state.c. This doesn't move code relating to layer state
out nor does it move any of the code supporting the core design
of CoglPipeline itself.

This change alone factors out 2k lines of code from cogl-pipeline.c
which is obviously a good start. The next step will be to factor
out the layer state and then probably look at breaking all of this
state code down into state-groups.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-09-19 16:35:59 +01:00
Robert Bragg
8b34a39319 Adds ColorMask support to Cogl
This adds CoglPipeline and CoglFramebuffer support for setting a color
mask which is a bit mask defining which color channels should be written
to the current framebuffer.

The final color mask is the intersection of the framebuffer color mask
and the pipeline color mask. The framebuffer mask affects all rendering
to the framebuffer while the pipeline masks can be used to affect
individual primitives.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-07-19 19:27:09 +01:00
Neil Roberts
d69d49fada pipeline: Unify how the backends store private data
Previously the fragends had a separate private data pointer which was
used by the GLSL and ARBfp fragends to store a tiny struct containing
a single pointer to the ref-counted shader state. The space for the
private data pointer is reserved in all of the pipelines for all of
the potential backends. The vertends and progends however did this
differently by directly storing the pointer to the ref counted data
using cogl_object_set_user_data. This patch unifies the different
methods so that they all use cogl_object_set_user_data and the
fragends don't bother with the separate tiny allocation for the
private data. The private data pointer array has been removed from
CoglPipeline and the corresponding fragend virtual to free the private
data has also been removed because this can instead be done with the
destroy notify from the object user data.

The variable names used have been unified so that all of the vertends
and fragends name their data struct CoglPipelineShaderState and use a
variable called shader_state to refer to it. The progend uses
CoglPipelineProgramState and a variable called program_state.

This should also fix two potential bugs. the ARBfp fragend was
apprently leaking a reference to the private state when it creates the
private data because it was adding a reference before stroring the
pointer to the newly allocated data but the ref count is already set
to 1 on creation. The other potential bug is that the free function
for CoglPipeline was only calling the free_priv virtual for the
currently used fragend of the pipeline. The design of the fragends is
meant to allow a pipeline to have multiple fragend priv datas because
a child pipeline could be attaching its fragend data to the ancestor
and its allowed to pick a different fragend.
2011-07-13 12:30:07 +01:00
Damien Lespiau
221850eca9 pipeline: NULLify deprecated_get_layers_list on copy
That list is tracking the layers for get_layers_list() and needs to be
freed later on. However _copy() did not initialize it and we ended up
trying to free some garbage pointer.
2011-07-12 14:49:21 +01:00
Damien Lespiau
711a817d8c pipeline: Plug a leak of GLists
_cogl_pipeline_get_layers() allocates a list on the pipeline to be able
to get the pointer valid as long as possible and store that list in the
pipeline object.

You need to free that list when freeing the pipeline.

Signed-off-by: Robert Bragg <robert@linux.intel.com>
2011-07-12 10:52:12 +01:00
Neil Roberts
b2e735ff7f Dynamically load the GL or GLES library
The GL or GLES library is now dynamically loaded by the CoglRenderer
so that it can choose between GL, GLES1 and GLES2 at runtime. The
library is loaded by the renderer because it needs to be done before
calling eglInitialize. There is a new environment variable called
COGL_DRIVER to choose between gl, gles1 or gles2.

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

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

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

Cogl-pango previously had a #ifdef to detect when the GL backend is
used so that it can sneakily pass GL_QUADS to
cogl_vertex_buffer_draw. This is now changed so that it queries the
CoglContext for the backend. However to get this to work Cogl now
needs to export the _cogl_context_get_default symbol and cogl-pango
needs some extra -I flags to so that it can include
cogl-context-private.h
2011-07-11 12:57:38 +01:00
Neil Roberts
17a558a386 cogl-pipeline: Fix reference counting on promoting weak parents
When a copy is made of a weak pipeline it tries to promote the weak
parent by taking a reference on that weak pipeline's parent. However
promote_weak_ancestors was instead always taking a reference on the
first parent, regardless of whether it was weak. The corresponding
revert_weak_ancestors function which is supposed to undo the effect of
promote_weak_ancestors only unref'd the parent if was weak. This meant
that any non-weak pipeline copy would end up leaking a reference on
its parent.

This patch changes both functions to have a similar loop. It loops
through all of the parents of the pipeline until it finds one that is
not weak and refs or unrefs the *parent* of that pipeline instead of
the pipeline itself.

Signed-off-by: Robert Bragg <robert@linux.intel.com>
2011-07-06 16:52:46 +01:00
Neil Roberts
b9b41723c1 cogl-pipeline: Use BSD lists for the list of pipeline children
Instead of having a separate GList for the children we can use the
linked list code from FreeBSD and store the list node directly in the
struct. That way we can avoid having a separate slice allocation for
the list node. It also means that we effectively have a pointer to the
list node given a pointer to the pipeline node. That means we can
unparent a pipeline without having to walk the entire list of
children. With this change there is no need to have the optimisation
to fast track a pipeline that only has one child which simplifies the
code somewhat.

With this patch we are removing a pointer and a gboolean from the
CoglPipeline struct and adding two pointers. On 32-bit architectures
this should end up exactly the same size because a gboolean is the
same size as a pointer. On 64-bit architectures I think it should end
up 4 bytes smaller because it also ends up removing two cases where a
pointer follows a gboolean which presumably would mean the compiler
would have to insert 4 bytes of padding to keep the pointer aligned to
8 bytes.

https://bugzilla.gnome.org/show_bug.cgi?id=652514
2011-07-01 17:58:59 +01:00
Robert Bragg
098a193802 pipeline: Avoid reseting texture target for NULL textures
When setting a NULL texture on a CoglPipeline we would also reset the
texture target to a dummy value of 0. Reseting the target also had the
effect of making fragends discard any associated program. In cases where
the NULL texture was only transient until a replacement texture could be
set we were re-running lots of redundant codegen and shader
compilations.

Signed-off-by: Neil Roberts <neil@linux.intel.com>
2011-06-30 14:33:13 +01:00
Robert Bragg
256274bfcc pipeline: fix layer change notify mutex rule
There is a documented rule that layer changes should only be notified to
the fragend once; either as a pipeline change or as a layer change. When
the number of layers associated with a material changes then that should
get notified against the pipeline. All other layer changes get notified
against the layer.

There was a mistake in the _cogl_pipeline_add/remove_layer_difference
functions, in that we weren't using the 'inc/dec_n_layers' boolean to
determine if the fragend should be notified of the change.

It was also noticed that the logic of _cogl_pipeline_prune_to_n_layers
would also break this rule, by failing to notify some changes at all.

Signed-off-by: Neil Roberts <neil@linux.intel.com>
2011-06-30 14:33:13 +01:00
Emmanuele Bassi
57db73873e pipeline: Fix argument checking in set_depth_state() 2011-05-18 11:50:56 +01:00
Robert Bragg
07c0b9f89f Add CoglDepthState API
Instead of simply extending the cogl_pipeline_ namespace to add api for
controlling the depth testing state we now break the api out. This adds
a CoglDepthState type that can be stack allocated. The members of the
structure are private but we have the following API to setup the state:

    cogl_depth_state_init
    cogl_depth_state_set_test_enabled
    cogl_depth_state_get_test_enabled
    cogl_depth_state_set_test_function
    cogl_depth_state_get_test_function
    cogl_depth_state_set_writing_enabled
    cogl_depth_state_get_writing_enabled
    cogl_depth_state_set_range
    cogl_depth_state_get_range

This removes the following experimental API which is now superseded:

    cogl_material_set_depth_test_enabled
    cogl_material_get_depth_test_enabled
    cogl_material_set_depth_test_function
    cogl_material_get_depth_test_function
    cogl_material_set_depth_writing_enabled
    cogl_material_get_depth_writing_enabled
    cogl_material_set_depth_range
    cogl_material_get_depth_range

Once a CoglDepthState structure is setup it can be set on a pipeline
using cogl_pipeline_set_depth_state().
2011-05-16 18:36:44 +01:00
Neil Roberts
184527580e cogl_pipeline_equal: Handle COGL_WRAP_MODE_AUTOMATIC better
When comparing the wrap modes of two pipeline layers it now considers
COGL_WRAP_MODE_AUTOMATIC to be equivalent to CLAMP_TO_EDGE. By the
time the pipeline is in the journal, the upper primitive code is
expected to have overridden this wrap mode with something else if it
wants any other behaviour. This is important for getting text to batch
together with textures because the text explicitly sets the wrap mode
to CLAMP_TO_EDGE on its pipeline.
2011-05-05 17:32:30 +01:00
Robert Bragg
fdbc741770 cogl: rename cogl-context.h cogl-context-private.h
Since we plan to add public cogl_context_* API we need to rename the
current cogl-context.h which contains private member details.
2011-04-11 15:18:12 +01:00
Neil Roberts
472e8e8f4e cogl-pipeline: Be careful not to take ownership of root layer
In _cogl_pipeline_prune_empty_layer_difference if the layer's parent
has no owner then it just takes ownership of it. However this could
theoretically end up taking ownership of the root layer because
according to the comment above in the same function that should never
have an owner. This patch just adds an extra check to ensure that the
unowned layer has a parent.

http://bugzilla.clutter-project.org/show_bug.cgi?id=2588
2011-04-05 18:24:09 +01:00
Robert Bragg
7de3655298 pipeline: reclaim ownership if reverting to layer ancestor
In _cogl_pipeline_prune_empty_layer_difference if we are reverting to
the immediate parent of an empty/redundant layer then it is not enough
to simply add a reference to the pipeline's ->layer_differences list
without also updating parent_layer->owner to point back to its new
owner.

This oversight was leading us to break the invariable that all layers
referenced in layer_differences have an owner and was also causing us to
break another invariable whereby after calling
_cogl_pipeline_layer_pre_change_notify the returned layer must always be
owned by the given 'required_owner'.

http://bugzilla.clutter-project.org/show_bug.cgi?id=2588
2011-04-05 18:24:09 +01:00
Neil Roberts
a866f2f4f4 cogl-pipeline: Fix comparing the color in set_layer_combine_constant
In cogl_pipeline_set_layer_combine_constant it was comparing whether
the new color is the same as the old color using a memcmp on the
constant_color parameter. However the combine constant is stored in
the layer data as an array of four floats but the passed in color is a
CoglColor (which is currently an array of four guint8s). This was
causing valgrind errors and presumably also the check for setting the
same color twice would always fail.

This patch makes it do the conversion to a float array upfront before
the comparison.
2011-02-01 17:50:10 +00:00
Robert Bragg
dc56d908ed pipeline: fix for _init_multi_property_sparse_state
When copying COMBINE state in
_cogl_pipeline_layer_init_multi_property_sparse_state we would read some
state from the destination layer (invalid data potentially), then
redundantly set the value back on the destination. This was picked up by
valgrind, and the code is now more careful about how it references the
src layer vs the destination layer.
2011-01-24 18:53:08 +00:00
Neil Roberts
c4a94439de cogl-debug: Split the flags to support more than 32
The CoglDebugFlags are now stored in an array of unsigned ints rather
than a single variable. The flags are accessed using macros instead of
directly peeking at the cogl_debug_flags variable. The index values
are stored in the enum rather than the actual mask values so that the
enum doesn't need to be more than 32 bits wide. The hope is that the
code to determine the index into the array can be optimized out by the
compiler so it should have exactly the same performance as the old
code.
2011-01-24 15:45:45 +00:00
Robert Bragg
1a5a4df326 journal: Support per-framebuffer journals
Instead of having a single journal per context, we now have a
CoglJournal object for each CoglFramebuffer. This means we now don't
have to flush the journal when switching/pushing/popping between
different framebuffers so for example a Clutter scene that involves some
ClutterEffect actors that transiently redirect to an FBO can still be
batched.

This also allows us to track state in the journal that relates to the
current frame of its associated framebuffer which we'll need for our
optimization for using the CPU to handle reading a single pixel back
from a framebuffer when we know the whole scene is currently comprised
of simple rectangles in a journal.
2011-01-21 16:18:10 +00:00