We don't need to generate a new ARBfp program for every material created
if we can find an ancestor whos state will result in the same program
being generated.
The more code we can have adopt the coding pattern of deriving their
materials from other similar materials using cogl_material_copy() the
more likely this metric will be good enough on its own to minimize the
set of arbfp programs necessary to support a given application.
Previously in _cogl_material_pre_change_notify we manually freed the
layer caches of a material if we caused a reparent, but it makes more
sense to have _cogl_material_set_parent do this directly instead.
This adds a _cogl_material_weak_copy() function that can be used to
create materials that don't count as strong dependants on their parents.
This means the parent can be modified without worrying about how it will
affect weak materials. The material age of the parent can potentially be
queried to determine if a weak material might need to be re-created.
When we add support for weak materials it's expected that Clutter will
want to attach them as private data to other materials and it needs a
mechanism to determine when a weak material should be re-created because
its parent has changed somehow.
This adds the concept of a material age (internal only currently) which
increments whenever a material is modified. Clutter can then save the
age of the material which its weak materials are derived from and later
determine when the weak material may be invalid.
In _cogl_texture_quad_multiple_primitives we weren't memsetting the
CoglMaterialWrapModeOverrides structure we were memsetting
&state.wrap_mode_overrides where state.wrap_mode_overrides is just a
pointer that might potentially later point to the
CoglMaterialWrapModeOverrides structure.
In _cogl_material_equal we were repeating the same code pattern to
compare several of the state groups so this just adds
simple_property_equal function that's now used instead.
This redirects the legacy depth testing APIs through CoglMaterial and
adds a new experimental cogl_material_ API for handling the depth
testing state.
This adds the following new functions:
cogl_material_set_depth_test_enabled
cogl_material_get_depth_test_enabled
cogl_material_set_depth_writing_enabled
cogl_material_get_depth_writing_enabled
cogl_material_set_depth_test_function
cogl_material_get_depth_test_function
cogl_material_set_depth_range
cogl_material_get_depth_range
As with other experimental Cogl API you need to define
COGL_ENABLE_EXPERIMENTAL_API to access them and their stability isn't
yet guaranteed.
cogl_ortho is one of those APIs whos style was, for better or worse,
copied from OpenGL and for some inexplicable reason the near and far
arguments are inconsistent with the left, right, top, bottom arguments
because they don't take z coordinates they take a "distance" which
should be negative for a plane behind the viewer.
This updates the documentation to explain this.
The internal CoglMaterialLayer pointers associated with a material may
change whenever layer properties are modified so it's no longer ok to
assume that a list of layers returned by cogl_material_get_layers
remains valid if the layers have been changed.
Since it can sometimes be awkward to figure out where a particular
material came from when debugging, this adds a breadcrumb mechanism that
lets you associate a const string with a material that may give a clue
about its origin.
As a follow on to using cogl_material_copy instead of flush options this
patch now removes the ability to pass flush options to
_cogl_material_equal which is the final reference to the
CoglMaterialFlushOptions mechanism.
Since cogl_material_copy should now be cheap to use we can simplify
how we handle fallbacks and wrap mode overrides etc by simply copying
the original material and making our override changes on the new
material. This avoids the need for a sideband state structure that has
been growing in size and makes flushing material state more complex.
Note the plan is to eventually use weak materials for these override
materials and attach these as private data to the original materials so
we aren't making so many one-shot materials.
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.
We were incorrectly guarding the use of GL_TEXTURE_RECTANGLE_ARB with
ifdef ARB_texture_rectangle instead of ifdef GL_ARB_texture_rectangle
which broke test-cogl-texture-rectangle.
This was mistakenly added some time ago because at some point when we
were discussing how to handle premultiplied alpha in Clutter/Cogl we
were considering having a magic "just do the right thing" option which
was later abandoned.
This is to try and improve API consistency. Simple cogl structures that
don't derive from CoglObject and which can be allocated on the stack,
such as CoglColor and CoglMatrix should all have "_init" or
"_init_from" functions to initialize all the structure members. (As
opposed to a cogl_xyz_new() function for CoglObjects). CoglColor
previously used the naming scheme "_set_from" for these initializers but
"_set" is typically reserved for setting individual properties of a
structure/object.
This adds three _init functions:
cogl_color_init_from_4ub
cogl_color_init_from_4f
cogl_color_init_from_4fv
The _set_from functions are now deprecated but only with a gtk-doc
annotation for now. This is because the cogl_color_set_from API is quite
widely used already and so were giving a grace period before enabling a
GCC deprecated warning just because otherwise the MX maintainers will
complain to me that I've made their build logs look messy.
The journal logs colors as 4bytes into a vertex array and since we are
planning to make CoglMaterial track its color using a CoglColor instead
of a byte array this convenience will be useful for re-implementing
_cogl_material_get_colorubv.
When converting the floating point allocation width to an integer
multiple of PANGO_SCALE to give to the PangoLayout it can sometimes
end up slightly short of the allocated size due to rounding
errors. This can cause some of the lines to be wrapped differently
when a non-integer-aligned position is used (such as when animating
text). It works better to round the number to the nearest integer by
adding 0.5 instead of letting the default float cast truncate it
downwards.
http://bugzilla.openedhand.com/show_bug.cgi?id=2170
Both ::drag-begin and ::drag-end have a "button" argument - even though
we assume internally, and externally, that dragging can only be the
result of a primary button operation.
* wip/deform-effect:
docs: Add DeformEffect and PageTurnEffect to the API reference
effect: Add PageTurnEffect
effect: Add DeformEffect
offscreen-effect: Traslate the modelview with the offsets
docs: Fix Effect subclassing section
The marshallers we use for the signals are declared in a private header,
and it stands to reason that they should also be hidden in the shared
object by using the common '_' prefix. We are also using some direct
g_cclosure_marshal_* symbol from GLib, instead of consistently use the
clutter_marshal_* symbol.
Some internal symbols used for the GLES 2 wrapper were accidentally
being exported. This prepends an underscore to them so they won't
appear in the shared library.
It is often useful to determine if one actor is an ancestor of
another. Add a method to do that.
http://bugzilla.openedhand.com/show_bug.cgi?id=2162
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
By default, ShaderEffect creates a fragment shader; in order to be able
to deprecate ClutterShader we need a way for ShaderEffect sub-classes to
create a vertex shader if needed - By using a write-only, constructor
only property.
ClutterShader has, internally, a ClutterShaderType enumeration that can
be used exactly for this. We just need to expose it and create a GObject
property for ClutterShaderEffect.
Whenever a path or a rectangle is added to the clip stack it now also
stores a screen space bounding box in the entry. Then when the clip
stack is flushed the bounding box is first used to set up the
scissor. That way when we eventually come to use the stencil buffer
the clear will be affected by the scissor so we don't have to clear
the entire buffer.
_cogl_path_get_bounds is no longer static and is exported in
cogl-path-private.h so that it can be used in the clip stack code. The
old version of the function returned x/y and width/height. However
this was mostly used to call cogl_rectangle which takes x1/y1
x2/y2. The function has been changed to just directly return the
second form because it is more useful. Anywhere that was previously
using the function now just directly looks at path->path_nodes_min and
path->path_nodes_max instead.
The transform_point function takes a modelview matrix, projection
matrix and a viewport and performs all three transformations on a
point to give a Cogl window coordinate. This is useful in a number of
places in Cogl so this patch moves it to cogl.c and adds it to
cogl-internal.h
For sliced 2D textures, _cogl_texture_2d_sliced_get_data() uses the
bitmap width, instead of the rowstride, when memcpy()ing into the
dest buffer.
Signed-off-by: Robert Bragg <robert@linux.intel.com>
We only had getters for the red, green, blue and alpha channels of a
color. This meant that, if you wanted to change, say, the alpha
component of a color, one would need to query the red, green and blue
channels and use set_from_4ub() or set_from_4f().
Instead of this, just provide some setters for CoglColor, using the same
naming scheme than the existing getters.
For some operations on pre-multiplied colors (say, replace the alpha
value), you need to unpremultiply the color.
This patch provides the counterpart to cogl_color_premultiply().
The place where we actually change the framebuffer is
_cogl_framebuffer_flush_state(), so if we changed to a new frame buffer
we need to initialize the color bits there.
http://bugzilla.openedhand.com/show_bug.cgi?id=2094
OpenGL 3.0 deprecated querying of the GL_{RED,GREEN,BLUE}_BITS
constants, and the FBO extension provides a mechanism to query for the
color buffer sizes which *should* work even with the default
framebuffer. Unfortunately, this doesn't seem to hold for Mesa - so we
just use this for the offscreen CoglFramebuffer type, and we fall back
to glGetIntegerv() for the onscreen one.
http://bugzilla.openedhand.com/show_bug.cgi?id=2094
DeformEffect is an abstract class that should be used to write effects
that change the geometry of an actor before submitting it to the GPU.
Just like the ShaderEffect class, DeformEffect renders the actor to
which it has been applied into an FBO; then it creates a mesh and stores
it inside a VBO. Sub-classes can control vertex attributes like
position, texel coordinates and the color.
Instead of using the stage offsets when painting we can simply traslate
the current modelview. This allows sub-classes to fully override the
paint_target() virtual function without chaining up.
This function had two problems. Firstly it would clear the enable
blend flag before calling pre_change_notify so that if blending was
previously enabled the journal would end up being flushed while the
flag was still cleared. Secondly it would call the pre change notify
whenever blending is needed regardless of whether it was already
needed previously.
This was causing problems in test-depth.
This adds a _cogl_bind_gl_texture_transient function that should be used
instead of glBindTexture so we can have a consistent cache of the
textures bound to each texture unit so we can avoid some redundant
binding.