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.
* clutter/clutter-actor.c:
(clutter_actor_set_min_width),
(clutter_actor_set_min_height),
(clutter_actor_set_natural_width),
(clutter_actor_set_natural_height): Ignore any override of the
minimum and natural size of the stage on backends that only
support static stages.
* clutter/clutter-stage.c (clutter_stage_allocate): Use the
preferred size of the ClutterStage implementation instead of
the display size.
* clutter/clutter-backend.[ch]: Remove get_display_size() and
clutter_backend_get_display_size().
* clutter/eglnative/clutter-backend-egl.c:
* clutter/fruity/clutter-backend-fruity.c:
* clutter/osx/clutter-backend-osx.c:
* clutter/sdl/clutter-backend-sdl.c:
* clutter/win32/clutter-backend-win32.c:
* clutter/x11/clutter-backend-x11.c: Remove get_display_size()
implementations.
* clutter/clutter-backend.c:
(clutter_backend_get_display_size): Provide a fallback for
backends not implementing get_display_size().
* clutter/clutter-stage.c:
(clutter_stage_allocate): Add debug messages.
* clutter/sdl/clutter-backend-sdl.c:
(clutter_backend_sdl_get_display_size),
(clutter_backend_sdl_class_init): Implement get_display_size()
on the SDL backend.
* clutter/clutter-backend.c:
(_clutter_backend_create_stage): Call _clutter_stage_set_window()
ourselves, thus removing yet another action that backends must
implement and might get wrong; also cuts a backend-agnostic piece
of code duplication.
* clutter/eglnative/clutter-backend-egl.c:
(clutter_backend_egl_create_stage): Update the EGL native backend.
* clutter/eglx/clutter-backend-egl.c:
(clutter_backend_egl_create_stage): Update the EGLX backend.
* clutter/fruity/clutter-backend-fruity.c:
(clutter_backend_egl_create_stage): Update the fruity backend
* clutter/glx/clutter-backend-glx.c:
(clutter_backend_glx_create_stage): Update the GLX backend.
* clutter/sdl/clutter-backend-sdl.c:
(clutter_backend_sdl_create_stage): Update the SDL backend.
* HACKING.backends: Update the ::create_stage() description.
Rework the stage wrapper/implementation relation: remove
duplicated code and all the bookkeeping from the backends into
ClutterStage whenever possible, to reduce the amount of work a
backend must do (and possibly get wrong). Thanks to Tommi
Komulainen.
* clutter/clutter-main.c:
(clutter_init_with_args), (clutter_init): Realize the default
stage after creation. The default stage is special, because we
use it in the initialization sequence. This removes the burden
from the backends and reduces the things a backend can get
wrong.
* clutter/clutter-stage.c:
(clutter_stage_show): Make sure to realize the implementation if
it hasn't been realized yet.
(clutter_stage_realize): Set the REALIZED flag and call
clutter_stage_ensure_current() if the implementation was
successfully realized.
(clutter_stage_unrealized): Call clutter_stage_ensure_current()
on unrealize.
* clutter/glx/clutter-backend-glx.c:
(clutter_backend_glx_create_stage): Do not realize the stage anymore
when creating it, and let the normal realization sequence take
place.
(clutter_backend_glx_ensure_context): Trap for X11 errors.
* clutter/glx/clutter-stage-glx.c:
(clutter_stage_glx_realize): Chain up to the X11 implementation
so that we can set up the window state (title, cursor visibility)
when we actually have a X window. Also, do not call
clutter_stage_ensure_current(), and rely on the wrapper to do
it for us. This means we can drop setting the REALIZED flag on
the wrapper.
(clutter_stage_glx_unrealize): Do not call
clutter_stage_ensure_current() ourselves, and rely on the wrapper
to do it for us.
* clutter/x11/clutter-stage-x11.c:
(set_wm_title), (set_cursor_visible): Move the WM title and
cursor visibility code inside their own functions.
(clutter_stage_x11_realize): Set the window title and whether the
cursor is visible or not after realizing the stage.
(clutter_stage_x11_set_cursor_visible),
(clutter_stage_x11_set_title): Call set_wm_title() and
set_cursor_visible().
(clutter_stage_x11_finalize): Free the title string.
* clutter/x11/clutter-stage-x11.h: Save more of the stage state,
so that we can set it even when the stage hasn't been realized
yet.
* clutter/eglnative/clutter-backend-egl.c:
(clutter_backend_egl_create_stage):
* clutter/eglnative/clutter-stage-egl.c:
(clutter_stage_egl_unrealize),
(clutter_stage_egl_realize): Update the eglnative backend.
* clutter/eglx/clutter-backend-egl.c:
(clutter_backend_egl_ensure_context),
(clutter_backend_egl_create_stage):
* clutter/eglx/clutter-stage-egl.c:
(clutter_stage_egl_unrealize),
(clutter_stage_egl_realize): Update the eglx backend.
* clutter/sdl/clutter-backend-sdl.c:
(clutter_backend_sdl_create_stage):
* clutter/sdl/clutter-stage-sdl.c:
(clutter_stage_sdl_realize): Update the sdl backend.
* clutter/fruity/clutter-backend-fruity.c:
(clutter_backend_fruity_create_stage):
* clutter/sdl/clutter-stage-fruity.c:
(clutter_stage_fruity_realize): Update the fruity backend.
* tests/test-multistage.c (on_button_press): Bail out if
clutter_stage_new() returns NULL.
* HACKING.backends: Update backend writing documentation.
* clutter/sdl/clutter-backend-sdl.c:
(clutter_backend_sdl_dispose): Destroy the timer that we created...
(clutter_backend_sdl_init): ... here.
* clutter/sdl/clutter-backend-sdl.h: Add a GTimer for time-based
operations, like the event time.
* clutter/sdl/clutter-event-sdl.c:
(get_backend_time): Get the elapsed milliseconds for the SDL
backend.
(_clutter_events_init): Start the timer provided by the backend...
(_clutter_events_uninit): ... and the stop it.
(key_event_translate), (event_translate): Use the backend time
to fill out the time field of the event structures. This fixes
the motion notification throttling on the SDL backend.
Build fixes for the SDL flavour.
* clutter/sdl/clutter-backend-sdl.c: Remove an unused function.
* clutter/sdl/clutter-event-sdl.c:
(clutter_event_dispatch): Properly cast the stage pointer.
* clutter/sdl/clutter-stage-sdl.c:
(clutter_stage_window_iface_init): Remove the draw_to_pixbuf()
stub and assignment.
* clutter/sdl/clutter-stage-sdl.[ch]: Port the SDL stage to
the new stage implementation API.
* clutter/sdl/clutter-backend-sdl.[ch]: Port the SDL backend
to the new backend API.
* clutter/sdl/clutter-event-sdl.c:
(clutter_event_dispatch): Assign the default stage as the
origin of the event.
* clutter/clutter-actor.c (clutter_actor_destroy): Bail out
if clutter_actor_destroy() was called on the stage: the stage
is not for the user to destroy.
* clutter/x11/clutter-backend-x11.c:
* clutter/eglnative/clutter-backend-egl.c:
* clutter/sdl/clutter-backend-sdl.c:
* clutter/osx/clutter-backend-osx.c: Unset the top-level private
flag on the stage when disposing it, so the backends can safely
call clutter_actor_destroy().
* clutter/clutter-private.h: Tweak the private flags accessors,
to avoid the typecheck.
* clutter/eglnative/clutter-backend-egl.c:
* clutter/eglx/clutter-backend-egl.c:
* clutter/sdl/clutter-backend-sdl.c: Set the default resolution
as 96.0 dpi for every backend (we already were under this
assumption anyway, and this makes it easier to change this
setting per-backend).
* clutter/pango/pangoclutter-fontmap.c:
* clutter/pango/pangoclutter.h: Allow setting the resolution
for the PangoClutterFontMap object and provide the implementation
for the PangoFcFontMap::get_resolution() virtual function. This
allows to set the resolution of the PangoContext when retrieving
it.
* clutter/clutter-label.c (clutter_label_init): Set the
resolution of the font map with the one the backend gives us.
* clutter/clutter-entry.c (clutter_entry_init): Ditto.
* clutter/clutter-feature.h:
Add new stage feature flags and document.
* clutter/eglnative/clutter-backend-egl.c:
* clutter/eglx/clutter-backend-egl.c:
* clutter/sdl/clutter-backend-sdl.c:
Set new feature flags.
* clutter/glx/clutter-backend-glx.c:
* clutter/glx/clutter-stage-glx.c:
* clutter/clutter-stage.c:
* clutter/clutter-stage.h:
Add a 'user_resizeable' setting to the backend and implement
for glx backend.
* clutter/eglx/clutter-backend-egl.c:
* clutter/eglnative/clutter-backend-egl.c:
* clutter/sdl/clutter-backend-sdl.c: Destroy the stage in every
backend.
* clutter/clutter-backend.c:
* clutter/clutter-backend.h:
* clutter/glx/clutter-stage-glx.c:
* clutter/glx/clutter-backend-glx.c:
Fix up rendering pipeline removing clutter_backend_XXX_stage_paint
and adding clutter_backend_XXX_redraw instead. Duplicates less
code in backends, avoids clutter_actor_paint() getting called
before stage is set up (viewport wise) and unbreaks things like
picking.
* clutter/clutter-actor.c:
* clutter/clutter-actor.h:
* clutter/clutter-main.c:
* clutter/clutter-private.h:
* clutter/clutter-stage.c: (clutter_stage_get_actor_at_pos):
Redo picking functionality a different way (via color indexing)
as to provide more flexibility, possibly speed and more likely
work with GL/ES (doesn't currently however - not sure why).
* clutter/clutter-group.c:
Add groups own 'pick' method.
* clutter/cogl/cogl.h:
* clutter/cogl/gl/cogl.c:
* clutter/cogl/gles/cogl.c:
Move clipping funtionality into cogl.
* clutter/cogl/gles/cogl-defines.h:
Hack around missing BGR format in GL/ES.
* clutter/egl/clutter-backend-egl.c:
* clutter/egl/clutter-backend-egl.h:
* clutter/egl/clutter-stage-egl.c:
* clutter/sdl/clutter-backend-sdl.c:
* clutter/sdl/clutter-backend-sdl.h:
* clutter/sdl/clutter-event-sdl.c:
* clutter/sdl/clutter-stage-sdl.c:
Update backends to newer API.
Add basic mouse event translation to SDL.
* clutter/Makefile.am:
* clutter/clutter-stage.c:
* clutter/sdl/Makefile.am:
* clutter/sdl/clutter-backend-sdl.c:
* clutter/sdl/clutter-backend-sdl.h:
* clutter/sdl/clutter-event-sdl.c:
* clutter/sdl/clutter-sdl.h:
* clutter/sdl/clutter-stage-sdl.c:
* clutter/sdl/clutter-stage-sdl.h:
* configure.ac:
Add a basic SDL based backend. Lacks real input event handling
(translation) as yet.
Also allows for clutter to be built against dgles.