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.
I've found this is something I do quite often when debugging rendering
problems since its a simple way to wipe out lots of geometry and removes a
lot of unpredictable noise when logging geometry passing through the Cogl
journal.
The _clutter_context_get_default() function will automatically
create the main Clutter context; if we just want to check whether
Clutter has been initialized this will complicate matters, by
requiring a call to g_type_init() inside the client code.
Instead, we should simply provide an internal API that checks
whether the main Clutter context exists and if it has been
initialized, without any side effect.
The input device API is split halfway thorugh the backends in a very
weird way. The data structures are private, as they should, but most
of the information should be available in the main API since it's
generic enough.
The device type enumeration, for instance, should be common across
every backend; the accessors for device type and id should live in the
core API. The internal API should always use ClutterInputDevice and
not the private X11 implementation when dealing with public structures
like ClutterEvent.
By adding accessors for the device type and id, and by moving the
device type enumeration into the core API we can cut down the amount
of symbols private and/or visible only to the X11 backends; this way
when other backends start implementing multi-pointer support we can
share the same API across the code.
The clutter_context_get_default() function is private, but shared
across Clutter. For this reason, it should be prefixed by '_' so
that the symbol is hidden from the shared object.
The clutter_redraw() function is used by embedding toolkits to
force a redraw on a stage. Since everything is performed by
toggling a flag inside the Stage itself and then letting the
master clock advance, we need a ClutterStage method to ensure
that we start the master clock and redraw.
clutter-master-clock.c clutter-master-clock.h: When the
SYNC_TO_VBLANK feature is not available, wait for 1/frame_rate
seconds since the start of the last frame before drawing the next
frame. Add _clutter_master_clock_start_running() to abstract
the usage of g_main_context_wakeup()
clutter-stage.c: Add _clutter_master_clock_start_running()
clutter-main.c: Update docs for clutter_set_default_frame_rate()
clutter_get_default_frame_rate() to no longer talk about timeline
frame rates.
test-text-perf.c test-text.c: Set a frame rate of 1000fps so that
frame-rate limiting doesn't affect the result.
http://bugzilla.openedhand.com/show_bug.cgi?id=1637
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Instead of trying to guess about which motion events are
extraneous, queue up all events until we process a frame.
This allows us to look ahead and reliably compress consecutive
sequence of motion events.
clutter-main.c: Feed received events to the stage for queueing.
Remove old compression code. Remove clutter_get_motion_events_frequency()
clutter_set_motion_events_frequency()
clutter-stage.c: Keep a queue of pending events.
clutter-master-clock.c: Add processng of queued events to the
clock source dispatch function.
http://bugzilla.openedhand.com/show_bug.cgi?id=1637
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Remove code to advance the master clock after drawing a frame; if
there are any running timelines the master clock will do another
frame by itself, and the clock will be advanced before running
that frame.
With this change, there is no point in queueing an extra frame
redraw after completing a timeline, since we are always advancing
the timeline *before* redrawing, so remove that code as well.
(This does mean that calling clutter_timeline_stop() won't implicitly
cause the stage to be redrawn; this doesn't seem like something
an app should rely on in any case.)
http://bugzilla.openedhand.com/show_bug.cgi?id=1637
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
The clutter_redraw() function is used by libraries embedding
Clutter inside another toolkit, instead of queueing a redraw
on the embedded stage. This means that clutter_redraw() should
perform the same sequence of actions done by the redraw idle
callback.
Instead of passing a boolean value, the ::allocate virtual function
should use a bitmask and flags. This gives us room for expansion
without breaking API/ABI, and allows to encode more information to
the allocation process instead of just changes of absolute origin.
The setup_viewport() function should only be used by Clutter and
not by application code.
It can be emulated by changing the Stage size and perspective and
requeueing a redraw after calling clutter_stage_ensure_viewport().
Sometimes it is necessary for third party code to have a
function called during the redraw process, so that you can
update the scenegraph before it is painted.
cogl_clip_push_window_rect is implemented using GPU scissoring which allows
the GPU to cull anything that falls outside a given rectangle. Since in the
case of picking we only ever care about a single pixel we can get the GPU to
ignore all geometry that doesn't intersect that pixel and only rasterize for
one pixel.
The stencil buffer is always cleared the first time a clip is used
that needs it and the stencil test is disabled otherwise so there is
no need to clear before a paint.
Calling glReadPixels is bad enough in forcing us to synchronize the CPU with
the GPU, but glFinish has even stronger synchonization semantics than
glReadPixels which may negate some driver optimizations possible in
glReadPixels.
The master clock is currently advanced using a frame source driven
by the default frame rate. This breaks the sync to vblank because
the vblanking rate could be different than 60 Hz -- or it might be
completely disabled (e.g. with CLUTTER_VBLANK=none).
We should be using the main loop to check if we have timelines
playing, and if so queue a redraw on the stages we own.
We should also prepare the subsequent frame at the end of the redraw
process, so if there are new redraw we will have the scene already
in place.
This makes Clutter redraw at the maximum frame rate, which is
limited by the vblanking frequency.
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
Redundant clearing of depth and stencil buffers every render can be very
expensive, so cogl now gives control over which auxiliary buffers are
cleared.
Note: For now clutter continues to clear the color, depth and stencil buffer
each paint.
Currently, all timelines install a timeout inside the TimeoutPool
they share. Every time the main loop spins, all the timeouts are
updated. This, in turn, will usually lead to redraws being queued
on the stages.
This behaviour leads to the potential starvation of timelines and
to excessive redraws.
One lesson learned from the games developers is that the scenegraph
should be prepared in its entirety before the GL paint sequence is
initiated. This means making sure that every ::new-frame signal
handler is called before clutter_redraw() is invoked.
In order to do so a TimeoutPool is not enough: we need a master
clock. The clock will be responsible for advancing all the active
timelines created inside a scene, but only when the stage is
being redrawn.
The sequence is:
+ queue_redraw() is invoked on an actor and bubbles up
to the stage
+ if no redraw() has already been scheduled, install an
idle handler with a known priority
+ inside the idle handler:
- advance the master clock, which will in turn advance
every playing timeline by the amount of milliseconds
elapsed since the last redraw; this will make every
playing timeline emit the ::new-frame signal
- queue a relayout
- call the redraw() method of the backend
This way we trade multiple timeouts with a single frame source
that only runs if a timeline is playing and queues redraws on
the various stages.
If we need to check that the layout sequence is correct in
terms of order of execution and with respect to caching, then
having a CLUTTER_DEBUG_LAYOUT debug flag would make things
easier.
Bug 1495 - Timelines run 4% short
Previously the timelines were timed by calculating the interval
between each frame stored as an integer number of milliseconds so some
precision is lost. For example, requesting 60 frames per second gets
converted to 16 ms per frame which is actually 62.5 frames per
second. This makes the timeline shorter by 4%.
This patch merges the common code for timing from the timeout pools
and frame sources into an internal clutter-timeout-interval file. This
stores the interval directly as the FPS and counts the number of
frames that have been reached instead of the elapsed time.
The fog and perspective API is currently split in two parts:
- the floating point version, using values
- the fixed point version, using structures
The relative properties are using the structure types, since they
are meant to set multiple values at the same time. Instead of
using bare values, the whole API should be coalesced into two
simple calls using structures to match the GObject properties.
Thus:
clutter_stage_set_fog (ClutterStage*, const ClutterFog*)
clutter_stage_get_fog (ClutterStage*, ClutterFog*)
clutter_stage_set_perspective (ClutterStage*, const ClutterPerspective*)
clutter_stage_get_perspective (ClutterStage*, ClutterPerspective*)
Which supercedes the fixed point and floating point variants.
More importantly, both ClutterFog and ClutterPerspective should
using floating point values, since that's what get passed to
COGL anyway.
ClutterFog should also drop the "density" member, since ClutterStage
only allows linear fog; non-linear fog distribution can be achieved
using a signal handler and calling cogl_set_fog() directly; this keeps
the API compact yet extensible.
Finally, there is no ClutterStage:fog so it should be added.
Grabs are an entirely evil way to override the whole event delivery
machinery that Clutter has in place.
A pointer grab can be effectively replaced by a much more reliable
::captured-event signal handler, for instance.
Sometimes, grabs are a necessary evil -- and that is why Clutter
exposes them in the API; that should not fool anyone into thinking
that they should be used unless strictly necessary.
When event delivery is invoked by synthetic events through
clutter_do_event from inside an event handler clutter was silently
ignoring it, this warning will hopefully help resolving some issues.
The font options accessors in ClutterBackend only deal with const
cairo_font_options_t values, since:
- set_font_options() will copy the font options
- get_font_options() will return a pointer to the internal
font options
Not using const in these cases makes the API confusing and might lead
to erroneous calls to cairo_font_options_destroy().
Instead of using a fixed size array for storing the scenegraph sub-node
during event delivery we should use a GPtrArray. The benefits are:
- a smaller allocation
- no undocumented yet binding constraint on the scenegraph size
The environment variable to disable mipmapping should also be
a command line switch, and be handled like the rest of Clutter's
environment variables/command line switches.
Clutter is able to show debug messages written using the CLUTTER_NOTE()
macro at runtime, either by using an environment variable:
CLUTTER_DEBUG=...
or by using a command line switch:
--clutter-debug=...
--clutter-no-debug=...
Both are parsed during the initialization process by using the
GOption API.
COGL would benefit from having the same support.
In order to do this, we need a cogl_get_option_group() function in
COGL that sets up a GOptionGroup for COGL and adds a pre-parse hook
that will check the COGL_DEBUG environment variable. The OptionGroup
will also install two command line switches:
--cogl-debug
--cogl-no-debug
With the same semantics of the Clutter ones.
During Clutter initialization, the COGL option group will be attached
to the GOptionContext used to parse the command line options passed
to a Clutter application.
Every debug message written using:
COGL_NOTE (SECTION, "message format", arguments);
Will then be printed only if SECTION was enabled at runtime.
This whole machinery, like the equivalent one in Clutter, depends on
a compile time switch, COGL_ENABLE_DEBUG, which is enabled at the same
time as CLUTTER_ENABLE_DEBUG. Having two different symbols allows
greater granularity.
Mipmapped text is enabled by default in Clutter but it can cause
problems on some drivers so it is convenient to have an environment
variable to disable it for all apps.
Add annotations such as (transfer-none) (out) (element-type ClutterActor),
and so forth to the doc comments as appropriate.
The annotations added here are a combination of the annotations previously
in gir-repository for Clutter and annotations found in a review of all
return values with that were being parsed with a transfer of "full".
http://bugzilla.openedhand.com/show_bug.cgi?id=1452
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
cogl_paint_init was a bit too miscellaneous; it mainly cleared the color, depth
and stencil buffers but arbitrarily it also disabled fogging and lighting.
It no longer disables lighting, since we know Cogl never enables lighting and
disabling of fog is now handled with a seperate function.
Since I noticed cogl_set_fog was taking a density argument documented as
"Ignored" I've also added a mode argument to cogl_set_fog which exposes the
exponential fog modes which can make use of the density.
In generate_enter_leave_events it passes the device pointer from the
event to set_motion_last_actor but it was reading it directly from
event->motion.device. However the function is also used to process
button events so it would read from the wrong location in this case.
The device location in the union happened to be in the same place as
the click_count field of ClutterButtonEvent so it only mattered if the
click_count is non-zero. The X11 backend doesn't set this but
Clutter-GTK does so it was causing a crash.
Bug 1178 - No enter / leave events on actors when pointer leaves the
stage window
The patch is mostly thanks to Johan Bilien with small modifications
based on suggestions by Owen Taylor.
The X11 backend now listens for enter and leave notifications. Leave
notifications get translated directly to a CLUTTER_LEAVE
event. Clutter can detect these special events because the source
actor is NULL in which case it sets the source actor to the last known
actor and then sets the last known actor to NULL.
Enter notifications just get translated to CLUTTER_MOTION events which
will cause Clutter to generate an enter event through the usual code
path.
Moved clutter_stage_set_title() before call to clutter_actor_realize()
to ensure _NET_WM_NAME is set early enough for use by interested WM's,
Signed-off-by: Shane Bryan <shane.bryan@linux.intel.com>
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
The clutter_get_current_event_time() is a global function for
retrieving the timestamp of the current event being propagated
by Clutter. Such function avoids the need to propagate the
timestamp from within user code.
Instead of having a separate set of font options that override the
backend options when clutter_set_font_flags is called, it now just
directly sets the backend font options. So now the font flags are just
a convenience wrapper around the backend font options.
This also makes the ClutterText labels automatically update when the
font flags are changed because they will respond to the 'font-changed'
signal from the backend.
Conflicts:
clutter/cogl/gl/cogl-texture.c
clutter/cogl/gles/cogl-primitives.c
* cogl-material:
clutter-{clone-,}texture weren't updating their material opacity.
Updates GLES1 support for CoglMaterial
Normalizes gl vs gles code in preperation for synching material changes
Removes cogl_blend_func and cogl_alpha_func
Fully integrates CoglMaterial throughout the rest of Cogl
[cogl-material] Restore the GL_TEXTURE_ENV_MODE after material_rectangle
[cogl-material] Make the user_tex_coords parameter of _rectangle const
[test-cogl-material] Remove return value from material_rectangle_paint
Add cogl-material.h and cogl-matrix.h to libclutterinclude_HEADERS
[cogl-material] improvements for cogl_material_rectangle
[cogl-material] Adds a cogl_material_set_color function
[cogl-material] Some improvements for how we sync CoglMaterial state with OpenGL
[cogl-material] Converts clutter-texture/clutter-clone-texture to the material API
[doc] Hooks up cogl-material reference documentation
Updates previous GLES multi-texturing code to use CoglMaterial
Adds a CoglMaterial abstraction, which includes support for multi-texturing
[doc] Hooks up cogl-matrix reference documentation
Adds CoglMatrix utility code
[tests] Adds an interactive unit test for multi-texturing
[multi-texturing] This adds a new cogl_multi_texture API for GL,GLES1 + GLES2
The hope is that this function makes it easier to extend the font
settings with more flags without having to add a function for every
setting.
A new flag for enabling hinting has been added. If set, this changes
the font options on the global PangoContext and any newly created
PangoContexts. The options are only set if the flag is changed from
the default so it won't override any detailed setting chosen by the
backend.
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.
Continuation of the fix in commit 00a3c69868.
Instead of using a separate flag for the resize process, just
delay the setting of the CLUTTER_ACTOR_SYNC_MATRICES flag on the
stage to the point when we receive a ConfigureNotify event from
X11.
This commit will break the stage embedding into other toolkits.
There is a race condition when we resize a stage before showing
it on X11.
The race goes like this:
- clutter_init() creates the default stage and realize it, which
will cause a 640x480 Window to be created
- call set_size(800, 600) on the stage will cause the Window to be
resized to 800x600
- call show() on the stage for the first time will cause COGL
to set up an 800 by 600 GL viewport
- the Window will be mapped, which will cause X to notify the
window manager that the Window should be resized to 800x600
- the window manager will approve the resize
- X resizes the drawable to 800x600
To fix the race, we need to defer COGL from setting up the viewport
until we receive a ConfigureNotify event and the X server has resized
the Drawable.
In order to defer the call to cogl_setup_viewport() we add a new
private flag, CLUTTER_STAGE_IN_RESIZE; the flag is checked whenever
we need to change the viewport size along with the SYNC_MATRICES
private flag. Thus, cogl_setup_viewport() will be called only if
SYNC_MATRICES is set and IN_RESIZE is not set.
Merge branch 'text-actor'
* text-actor: (108 commits)
Re-align ClutterText header file
[text] Fix cursor sizing
Comments and whitespace fixes to ClutterText
[docs] Add newly added :single-line-mode accessors
Update the ignore file
[tests] Add text field interactive test
[text] Add single-line-mode to ClutterText
[text] Fix the deletion actions
[text] Use cached length when possible
[tests] Add unit for the ClutterText:password-char property
[docs] Update the Text section
[text] Coalesce text visibility and password character
Allow localizations to change the text direction
Clean up the update_pango_context() function
Pass the PangoContext, not the MainContext
Revert the logic of the PangoContext check
Remove the binding pool entry from the list
Remove BindingPool::list_actions()
Add ClutterActor::create_pango_context()
Rename the PangoContext creation functions
...
The locale translators of Clutter are also the ones that should set
the default direction of the text in a Clutter user interface.
This commit adds a translatable string that defines the direction
of the text; the translation authors will change it to the correct
value and that will determine the default direction.
The default text direction can be overridden by using the
CLUTTER_TEXT_DIRECTION environment variable, or by using the
--clutter-text-direction command line switch. In any other case,
the locale will determine the text direction, as it should.
Clutter has a set of command line options that are added to every
application by means of clutter_init() or by obtaining the Clutter
GOptionGroup and using g_option_context_parse(). Thus, every Clutter
application will automatically have an --help command line switch
showing the list of options and their description.
At the moment, Clutter does not enable localization of the help,
thus making it less than useful on non-English locales.
This patch enables the machinery to create a localization file and
load it when initializing Clutter, by means of the GLib macros and
locale.h API we already use.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
When updating the PangoContext with the current options (font name,
options, resolution) pass the PangoContext instead of the Clutter
MainContext structure pointer.