Avoid double argument checking, and a deprecation warning when
implementing create() as a wrapper around create_region(), by using
a simple internal function.
Keeping the backing Cairo surface of a CairoTexture canvas in sync with
the actor's allocation is tedious and prone to mistakes. We can
definitely do better by simply exposing a property that does the surface
resize and invalidation automagically on ::allocate.
The current "create context/draw/destroy context" pattern presents
various problems. The first issue is that it defers memory management to
the caller of the create() or create_region() methods, which makes
bookkeeping of the cairo_t* harder for language bindings and third party
libraries. The second issue is that, while it's easier for
draw-and-forget texturs, this API is needlessly complicated for contents
that have to change programmatically - and it introduces constraints
like calling the drawing code explicitly after a surface resize (e.g.
inside an allocate() implementation).
By using a signal-based approach we can make the CairoTexture actor
behave like other actors, and like other libraries using Cairo as their
2D drawing API.
The semantics of the newly-introduced ::draw signal are the same as the
one used by GTK+:
- the signal is emitted on invalidation;
- the cairo_t* context is owned by the actor;
- it is safe to have multiple callbacks attached to the same
signal, to allow composition;
- the cairo_t* is already clipped to the invalidated area, so
that Cairo can discard geometry immediately before we upload
the texture data.
There are possible future improvements, like coalescing multiple
invalidations inside regions, and performing clipped draws during
the paint cycle; we could even perform clipped redraws if we know the
extent of the invalidated area.
It stands to reason that any piece of code using Cairo and Cogl at the
same time, and dealing with texture data, will want to use the same
logic Clutter uses to determine the compatible pixel format between the
two.
https://bugzilla.gnome.org/show_bug.cgi?id=647875
By using a new signal, ::create-surface (width, height), it should be
possible for third party code and sub-classes to override the default
surface creation code in CairoSurface.
This commit takes a bit of the patch from:
http://bugzilla.clutter-project.org/show_bug.cgi?id=1878
which cleans up CairoTexture; the idea, mutuated from that bug, is that
the CairoTexture actor checks whether the surface it has it's an image
one, and in that case it uses a Cogl texture as the backing store. In
case the surface is not an image one we assume that the surface itself
has some way of updating the GL state and flush the surface.
There are too many examples where the default assumption that an actor
paints inside its allocation isn't true, so we now return FALSE in the
base implementation instead. This means that by default we are saying
"we don't know the paint volume of the actor", so developers need to
implement the get_paint_volume virtual to take advantage of culling and
clipped redraws with their actors.
This patch provides very conservative get_paint_volume implementations
for ClutterTexture, ClutterCairoTexture, ClutterRectangle and
ClutterText which all explicitly check the actor's object type to avoid
making any assumptions about subclasses.
Comprehensively add (out) annotations to functions parameters
returning int/float/double.
Not handled here: structure out returns like ClutterColor or
ClutterPerspective or GValue that should get (out caller-allocates).
Not handled here: Cogl
http://bugzilla.clutter-project.org/show_bug.cgi?id=2302
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 :sync-size property of ClutterTexture should be set to FALSE by
default by ClutterCairoTexture. The preferred size of the
ClutterCairoTexture is already the size of the internal Cairo surface,
and we override the preferred width/height getters to that effect.
The :sync-size property is also responsible of changing the size of
the Texture actor when changing the texture handle - but since we
encourage that to happen during the CairoTexture allocation, we get a
queue_relayout() invocation (and a warning) when we change the size
of the Cairo image surface.
Since GObject doesn't make it easy to override the default value of the
:sync-size property in sub-classes, we should simply call the setter
function during the ClutterCairoTexture instance initialization.
We should also change one of the interactive tests using a CairoTexture
to rebuild the contents of the actor in response to an allocation.
This reverts commit 716ec82db8.
The Cogl pixel buffer API currently has problems if an atlas texture
is created or the format needs to be converted. The atlas problem
doesn't currently show because the atlas rejects BGR textures anyway
but we may want to change this soon. The problem with format
conversion would happen under GLES because that does not support BGR
textures at all so Cogl has to do the conversion. However it doesn't
currently show either because GLES has no support for buffer objects
anyway.
It's also questionable whether the patch would give any performance
benefit because Cairo needs read/write access which implies the buffer
can't be put in write-optimised memory.
Conflicts:
clutter/clutter-cairo-texture.c
http://bugzilla.openedhand.com/show_bug.cgi?id=1982
In clutter_cairo_texture_create_region it tries to destroy the old
texture before mapping the PBO by setting the texture on the first
layer of the material to COGL_INVALID_HANDLE. However it was using the
material API incorrectly so it ended up showing a warning and doing
nothing.
ClutterCairoTexture now stores the surface image data in a Cogl pixel
buffer object. When clutter_cairo_texture_create is called the buffer
is mapped and a new Cairo surface is created to render directly to the
PBO. When the surface is destroyed the buffer is unmapped and a Cogl
texture is recreated from the buffer. This should enable slightly
faster uploads when using Cairo because it avoids having to copy the
surface data to the texture.
http://bugzilla.openedhand.com/show_bug.cgi?id=1982
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Since using addresses that might change is something that finally
the FSF acknowledge as a plausible scenario (after changing address
twice), the license blurb in the source files should use the URI
for getting the license in case the library did not come with it.
Not that URIs cannot possibly change, but at least it's easier to
set up a redirection at the same place.
As a side note: this commit closes the oldes bug in Clutter's bug
report tool.
http://bugzilla.openedhand.com/show_bug.cgi?id=521
Cairo stores the image data in ARGB native byte order so we need to
upload this as BGRA on little endian architectures and ARGB on big
endian. ClutterTexture doesn't currently expose any flags to describe
ARGB format so until we can fix the Clutter API it now uses the Cogl
API directly.
Instead of unpremultiplying the Cairo data, pass it directly to Cogl
in premultiplied form; we now *prefer* premultiplied data.
http://bugzilla.openedhand.com/show_bug.cgi?id=1406
Signed-off-by: Robert Bragg <robert@linux.intel.com>
Document that repeated calls to clutter_cairo_texture_create()
continue drawing on the same cairo_surface_t. Add
clutter_cairo_texture_clear() for when you don't want that behavior.
http://bugzilla.openedhand.com/show_bug.cgi?id=1599
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
With the recent change to internal floating point values, ClutterUnit
has become a redundant type, defined to be a float. All integer entry
points are being internally converted to floating point values to be
passed to the GL pipeline with the least amount of conversion.
ClutterUnit is thus exposed as just a "pixel with fractionary bits",
and not -- as users might think -- as generic, resolution and device
independent units. not that it was the case, but a definitive amount
of people was convinced it did provide this "feature", and was flummoxed
about the mere existence of this type.
So, having ClutterUnit exposed in the public API doubles the entry
points and has the following disadvantages:
- we have to maintain twice the amount of entry points in ClutterActor
- we still do an integer-to-float implicit conversion
- we introduce a weird impedance between pixels and "pixels with
fractionary bits"
- language bindings will have to choose what to bind, and resort
to manually overriding the API
+ *except* for language bindings based on GObject-Introspection, as
they cannot do manual overrides, thus will replicate the entire
set of entry points
For these reason, we should coalesces every Actor entry point for
pixels and for ClutterUnit into a single entry point taking a float,
like:
void clutter_actor_set_x (ClutterActor *self,
gfloat x);
void clutter_actor_get_size (ClutterActor *self,
gfloat *width,
gfloat *height);
gfloat clutter_actor_get_height (ClutterActor *self);
etc.
The issues I have identified are:
- we'll have a two cases of compiler warnings:
- printf() format of the return values from %d to %f
- clutter_actor_get_size() taking floats instead of unsigned ints
- we'll have a problem with varargs when passing an integer instead
of a floating point value, except on 64bit platforms where the
size of a float is the same as the size of an int
To be clear: the *intent* of the API should not change -- we still use
pixels everywhere -- but:
- we remove ambiguity in the API with regard to pixels and units
- we remove entry points we get to maintain for the whole 1.0
version of the API
- we make things simpler to bind for both manual language bindings
and automatic (gobject-introspection based) ones
- we have the simplest API possible while still exposing the
capabilities of the underlying GL implementation
It is possible to change the surface size after construction with
clutter_cairo_texture_set_surface_size so it doesn't seem right to
restrict changing the properties.
clutter_cairo_texture_resize_surface_internal is called in a handler
for the notify signal. It is called there rather than directly in the
set_property handler so that changing both properties in a single
g_object_set will only cause one resize. The constructed override is
no longer needed.
resize_surface_internal will now bail out if the size of the surface
is already the right size.
The current CairoTexture can be created with a surface size of 0
by 0 pixels, but a warning will be printed.
Worse, the surface can be resized to be 0 by 0 pixels without a
warning. The :surface-width and :surface-height properties accept
a minimum value of 0, and not check is performed on either the
constructor or set_surface_size() parameters to enforce the "greater
than zero" rule.
The correct and consistent behaviour is to allow a 0 by 0 pixels
surface size everywhere; inside surface_resize_internal(), the
current surface will be destroyed and if either :surface-width or
:surface-height are set to 0, the resizing terminates.
Attempting to create a Cairo context from a CairoTexture with
either :surface-width or :surface-height set to 0 will result in
a warning.
This allows:
- creating a CairoTexture with :surface-width or :surface-height
set to zero and delaying the surface resize at a later point;
- resizing the surface to 0 by 0 pixels to destroy the image
surface used internally;
- increase the consistency in the usage of CairoTexture.
Fix the CairoTexture description, and some of the comments inside
the code, especially with regards to the alpha channel unpremultiplication
that we have to perform each time we upload the image surface to
GL.
If you create a Cairo context in the middle of a paint run and then
you destroy it, the CairoTexture will have to upload the contents of
the image surface to the GL pipeline. This usually leads to slow
downs and general performance degradation.
ClutterCairoTexture will warn to the console if Clutter has been
compiled with the debug messages and if create() or create_region()
are called while an actor is in the middle of a paint.
Move the ClutterCairo actor from a separate library to an in-tree
actor.
ClutterCairoTexture is a simple texture subclass that allows you
to retrieve a Cairo context for a private image surface. When the
Cairo context is destroyed it will cause the image surface
contents to be uploaded to a GL texture.
The image surface used is not hardware accelerated.