Weak materials are ones that don't take a reference on their parent and
they are associated with a callback that notifies when the material is
destroyed, because its parent was freed or modified.
More details can be found at:
http://wiki.clutter-project.org/wiki/CoglDesign/CoglMaterial
For now the concept is internal only but the plan is to make this public
at some point once we have tested the design internally.
Following the commits:
c03544da - clutter-shader: use cogl_program_set_uniform_xyz API
a26119b5 - tests: Remove use of cogl_program_use
Remove the users of cogl_program_uniform_* and cogl_program_use() in the
shader-based effects.
In the case where there is no error log for arbfp we were returning a
"" string literal. The other paths were using g_strdup to return a
string that could be freed with g_free. This makes the arbfp path return
g_strdup ("") instead.
There are quite a few if {} else {} blocks for dealing with arbfp else
glsl and the first block is guarded with #ifdef HAVE_COGL_GL. In this
case though the #endif was before the else so it wouldn't compile for
gles.
We need to include cogl-shader-private.h to have the
COGL_SHADER_TYPE_GLSL define. When building for opengl this wasn't
noticed probably because some other header indirectly includes this
file. It was a problem when building for gles2 though.
Instead of using the deprecated cogl_program_uniform_xyz functions we
now use the cogl_program_set_uniform methods. It looks like this should
also fix a problem with clutter-shader too in that previously we weren't
calling cogl_program_use before cogl_program_uniform_xyz so setting
uniforms would only work while the shader is enabled.
Instead of exposing an API that provides an OpenGL state machine style
where you first have to bind the program to the context using
cogl_program_use() followed by updating uniforms using
cogl_program_uniform_xyz we now have uniform setter methods that take an
explicit CoglHandle for the program.
This deprecates cogl_program_use and all the cogl_program_uniform
variants and provides the following replacements:
cogl_program_set_uniform_1i
cogl_program_set_uniform_1f
cogl_program_set_uniform_int
cogl_program_set_uniform_float
cogl_program_set_uniform_matrix
--quiet has been added to g-ir-scanner in the 0.9.1 cycle. We really
want to be able to compile clutter with 0.6.14 to be able to reuse
gir files that are distributed in current distributions.
Use the INTROSPECTION_SCANNER_ARGS (previously unused) variable to
convey --quiet when necessary.
Fixes: http://bugzilla.clutter-project.org/show_bug.cgi?id=2265
CoglAtlas chooses a fairly large default initial size of either
512x512 or 1024x1024 depending on the texture format. There is a
chance that this size will not be supported on some platforms which
would be catastrophic for the glyph cache because it would mean that
it would always fail to put any glyphs in the cache so text wouldn't
work. To fix this the atlas code now checks whether the chosen initial
size is supported by the texture driver and if not it will get halved
until it is supported.
Previously when creating a new rectangle map it would try increasingly
larger texture sizes until GL_MAX_TEXTURE_SIZE is reached. This is bad
because it queries state which should really be owned by the texture
driver. Also GL_MAX_TEXTURE_SIZE is often a conservative estimate so
larger texture sizes can be used if the proxy texture is queried
instead.
Previously each node in the rectangle map tree would store the total
remaining space in all of its children to use as an optimization when
adding nodes. With this it could skip an entire branch of the tree if
it knew there could never be enough space for the new node in the
branch. This modifies that slightly to instead store the largest
single gap. This allows it to skip a branch earlier because often
there would be a lot of small gaps which would add up to enough a
space for the new rectangle, but the space can't be used unless it is
in a single node.
The rectangle map still needs to keep track of the total remaining
space for the whole map for the debugging output so this has been
added back in to the CoglRectangleMap struct. There is a separate
debugging function to verify this value.
Previously when the atlas needs to be migrated it would start by
trying with the same size as the existing atlas if there is enough
space for the new texture. However even if the atlas is completely
sorted there will always be some amount of waste so when the atlas
needs to grow it would usually end up redundantly trying the same size
when it is very unlikely to fit. This patch changes it so that there
must be at least 6% waste available after the new texture is added
otherwise it will start with the next atlas size.
When iterating over the rectangle map a stack is used to implement a
recursive algorithm. Previously this was slice allocating a linked
list. Now it uses a GArray which is retained with the rectangle map to
avoid frequent allocations which is a little bit faster.
Previously the remaining space was managed as part of the
CoglRectangleMap struct. Now it is stored per node so that at any
point in the hierarchy we can quickly determine how much space is
remaining in all of the node's children. That way when adding a
rectangle we can miss out entire branches more quickly if we know that
there is no way the new rectangle would fit in that branch.
This also adds a function to recursively verify the cached state in
the nodes such as the remaining space and the number of
rectangles. This function is only called when the dump-atlas-image
debug flag is set because it is potentially quite slow.
The glyph cache is now stored in a CoglAtlas structure instead of the
custom atlasing code. This has the advantage that it can share code
with the main texture atlas and that it supports reorganizing the
atlas when it becomes full. Unlike the texture atlas, the glyph cache
can use multiple atlases which would be neccessary if the maximum
texture size is reached and we need to create a second
texture. Whenever a display list is created it now has to register a
callback with the glyph cache so that the display list can be
recreated whenever any of the atlases are reorganized. This is needed
because the display list directly stores texture coordinates within
the atlas texture and they would become invalid when the texture is
moved.
The ensure_glyphs_for_layout now works in two steps. First it reserves
space in the atlas for all of the glyphs. The atlas is created with
the DISABLE_MIGRATION flag so that it won't actually copy any textures
if any rearranging is needed. Whenever the position is updated for a
glyph then it is marked as dirty. After space for all of the glyphs
has been reserved it will iterate over all dirty glyphs and redraw
them using Cairo. The rendered glyph is then stored in the texture
with a sub texture update.
The glyphs need to all be set at the right location before starting to
create the display list because the display list stores the texture
coordinates of the glyph. If any of the glyphs were moved around then
the parts of the display list that was created already would become
invalid. To make this work, ensure_glyphs_for_layout is now always
called before rendering a layout or a layout line.
_cogl_atlas_new now has two extra parameters to specify the format of
the textures it creates as well as a set of flags to modify the
behavious of the atlas. One of the flags causes the new textures to be
cleared and the other causes migration to avoid actually copying the
textures. This is needed to use CoglAtlas from the pango glyph cache
because it needs to use COGL_PIXEL_A_8 and to clear the textures as it
does not fill in the gaps between glyphs. It needs to avoid copying
the textures so that it can work on GL implementations without FBO
support.
Instead of storing a pointer to the CoglRectangleMap and a handle to
the atlas texture in the context, there is a now a separate data
structure called a CoglAtlas to manage these two. The context just
contains a pointer to this. The code to reorganise the atlas has been
moved from cogl-atlas-texture.c to cogl-atlas.c
This adds an internal CoglCallbackList type which is just a GSList of
of function pointers along with a data pointer to form a
closure. There are functions to add and remove items and to invoke the
list of functions. This could be used in a number of places in Cogl.
This simply renames CoglAtlas to CoglRectangleMap without making any
functional changes. The old 'CoglAtlas' is just a data structure for
managing unused areas of a rectangle and it doesn't neccessarily have
to be used for an atlas so it wasn't a very good name.
Textures within a layer were compared for equality by comparing their
texture handle. However this means that sub textures and atlas
textures which may be internally using the same GL handle would not be
batched together. Instead it now tries to determine the underlying GL
handle using either the slice override or _cogl_texture_get_gl_texture
and then compares those.
When filtering on allowed formats for atlas textures, it now masks out
the BGR and AFIRST bits in addition to the premult bit. That way it
will accept RGB and RGBA formats in any component order.
In theory it could also accept luminance and alpha-only textures but I
haven't added this because presumably if the application has requested
these formats then it has some reason not to use a full RGB or RGBA
texture and we should respect that.
See commits:
7daeb217 blur-effect: Do not inherit from ShaderEffect
1ec57743 desaturate-effect: Do not inherit from ShaderEffect
We might avoid using shaders at all in the future for simple effects.
Since BlurEffect and DesaturateEffect are using the shader API
implicitly and not using ClutterShaderEffect, we need to check if the
underlying GL implementation supports the GLSL shading language and warn
if not.
Hide the fact that we're using a fragment shader, in case we're able in
the future to use a material layer combine function when painting the
offscreen target texture.
We might want to switch the BlurEffect from a box-blur to a
super-sampling of the texture target, in order to make it cheap(er).
If we inherit from ShaderEffect, though, we're setting in stone the
fact that we are going to use a fragment shader for blurring.
Since there is not parametrization of the blur, the code necessary
to implement effect is pretty small, and we can use the Cogl API
directly.
Instead of calling cogl_program_use() around the paint_target()
chain-up, we can use the newly added API in CoglMaterial to attach
user-defined shaders to the offscreen target material.
* wip/table-layout:
Add ClutterTableLayout, a layout showing children in rows and columns
box-layout: Use allocate_align_fill()
bin-layout: Migrate to allocate_align_fill()
actor: Add allocate_align_fill()
test-flow-layout: Use BindConstraints
A TableLayout is a layout manager that allocates its children in rows
and columns. Each child is assigned to a cell (or more if a cell span
is set).
The supported child properties are:
• x-expand and y-expand: if this cell with try to allocate the
available extra space for the table.
• x-fill and y-fill: if the child will get all the space available in
the cell.
• x-align and y-align: if the child does not fill the cell, then
where the child will be aligned inside the cell.
• row-span and col-span: number of cells the child will allocate for
itself.
Also, the TableLayout has row-spacing and col-spacing for specifying
the space in pixels between rows and between columns.
We also include a simple test of the layout manager, and the
documentation updates.
The TableLayout was implemented starting from MxTable and
ClutterBoxLayout.
http://bugzilla.clutter-project.org/show_bug.cgi?id=2038
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Layout managers are using the same code to allocate a child while taking
into consideration:
• horizontal and vertical alignment
• horizontal and vertical fill
• the preferred minimum and natural size, depending
on the :request-mode property
• the text direction for the horizontal alignment
• an offset given by the fixed position properties
Given the amount of code involved, and the amount of details that can go
horribly wrong while copy and pasting such code in various classes - let
alone various projects - Clutter should provide an allocate() variant
that does the right thing in the right way. This way, we have a single
point of failure.
This adds a wrapper macro to clutter-private that will use
g_object_notify_by_pspec if it's compiled against a version of GLib
that is sufficiently new. Otherwise it will notify by the property
name as before by extracting the name from the pspec. The objects can
then store a static array of GParamSpecs and notify using those as
suggested in the documentation for g_object_notify_by_pspec.
Note that the name of the variable used for storing the array of
GParamSpecs is obj_props instead of properties as used in the
documentation because some places in Clutter uses 'properties' as the
name of a local variable.
Mose of the classes in Clutter have been converted using the script in
the bug report. Some classes have not been modified even though the
script picked them up as described here:
json-generator:
We probably don't want to modify the internal copy of JSON
behaviour-depth:
rectangle:
score:
stage-manager:
These aren't using the separate GParamSpec* variable style.
blur-effect:
win32/device-manager:
Don't actually define any properties even though it has the enum.
box-layout:
flow-layout:
Have some per-child properties that don't work automatically with
the script.
clutter-model:
The script gets confused with ClutterModelIter
stage:
Script gets confused because PROP_USER_RESIZE doesn't match
"user-resizable"
test-layout:
Don't really want to modify the tests
http://bugzilla.clutter-project.org/show_bug.cgi?id=2150
The special handling for texture unit 1 caught the case where unit
1 was changed for transient purposes, but didn't properly handle
the case where the actual non-transient texture was different between
two materials with no transient binding in between.
If the actual texture has changed when flushing, mark unit 1 as dirty
and needing a rebind.
http://bugzilla.clutter-project.org/show_bug.cgi?id=2261
This makes CoglProgram/Shader automatically detect when the user has
given an ARBfp program by checking for "!!ARBfp1.0" at the beginning of
the user's source.
ARBfp local parameters can be set with cogl_program_uniform_float
assuming you pass a @size of 4 (all ARBfp program.local parameters
are vectors of 4 floats).
This doesn't expose ARBfp environment parameters or double precision
local parameters.
Previously we had an internal only _cogl_material_set_user_program to
redirect legacy usage of cogl_program_use() through CoglMaterial. This
instead makes the API public because until we implement our planned
"snippet" framework we need a stop-gap solution for using shaders in
Cogl.
The plan is to also support ARBfp with the cogl_program/shader API so
this API will also allow clutter-gst to stop using direct OpenGL calls
that conflict with Cogl's state tracking.
A change to a layer is also going to be a change to its owning material
so we have to chain up in _cogl_material_layer_pre_change_notify and
call _cogl_material_pre_change_notify. Previously we were only
considering if the owning material was referenced in the journal but
that ignores that it might also have dependants. We no longer need to
flush the journal directly in layer_pre_change_notify.
In _cogl_material_layer_pre_change_notify when we see that a layer has
dependants and it can't be modified directly then we allocate a new
layer. In this case we also have to link the new layer to its required
owner. If the immutable layer we copied had the same owner though we
weren't unlinking that old layer.