= A Year of Clutter = Gran Canaria Desktop Summit, 2009 == Introduction == in the past 12 months I've been giving four talks about Clutter. they were all at least two hours slots, and in one case it was a four days, six hours per day training. after the third talk I came to the realization that I *hate* talking that much. the one time I actually enjoyed it was when I gave the training sessions, because I did not have to talk all the time: I had to make questions at the end of each section, and I had to explain specific bits and pieces of API, implementation, design decision. In short, I had to establish a connection with my audience. on the other hand, at last year's GUADEC in Istanbul I gave a lightning talk about the toy toolkit we wrote on top of Clutter, called Tidy. I enjoyed writing and talking for those five minutes much more than any other talk I gave since I started doing them. since this time I only have 30 minutes, I decided to take a completely different route. I never tried it, and it might be the one and only time I give this talk. I'm going to play it by ear. I wanted to avoid the "Big Clutter Talk" and instead I tried to recapture the "five minutes talk" experience. so I wrote four, five minutes each, lightning talks about Clutter to fill a 30 minutes slot, plus this introduction and a conclusion. to lay down the groud rules: * slides will only contain one or two words * unless it's a complicated slide * but if the slide gets too complicated, I'll use an image * at some point, I'll blatantly try to elicit a laugh * and when I say "blatantly" I really mean it * at any given point I could throw in a kitten anyway, this was the introduction, so that we're on the same page. == Clutter 1.0 == where were we last year? Clutter 0.8 was released at GUADEC 2009. we were happy, we were having fun; then something happened. that something was OpenedHand being acquired by Intel. after some weeks spent trying to readjust ourselves to the new corporate hive mind and the convalescence period following the removal of our souls, we sat down and started working on the 0.9 development cycle for Clutter - which was meant to end on January. then in February. then in March. then in April. then in May. then in June. but now it's done. I swear. I rolled the release candidate tarballs. obviously, the extra long development cycle was driven by the Moblin 2.0 netbook user experience, but we had lots of input (and patches) from the GNOME Shell project, as well as lots of input, bug reports and patches from other companies and projects using Clutter. so, what changed? * performance * API consolidation * vblank-driven updates * new animation framework what 1.0 means? * the minimal amount of API we feel confident * API and ABI stability * full documentation some metrics: * 70 kSLOC codebase, +20 kSLOC since 0.8 * 12+ kSLOC test suite * 1600+ symbols in Clutter (99% documented) * ~300 symbols in COGL (90% documented) * 1200+ single commits since master was branched for 0.8 * 29 single authors, 14 non-Intel [5:00] == Implicit Animations == when creating user interfaces that incorporate animations to transition between states you usually have two choices: either you know exactly the initial state and the final state and both are independent of the state of the animated elements; or you want the final state to be the result of an operation on the current state of the animated element. for the first kind of animations, Clutter provided since the 0.2 version the Behaviours; for the second kind Clutter provided the "effects" API. unfortunately, the effects API proved themselves to be too simple and a lot less flexible than expected. extending the number of effects to cover all the animatable properties and third party actors was very kludgy at best. after various experiments, Clutter 1.0 added the Animations API. it's based on base classes like the Timeline and the Alpha, to share as much as possible with the Behaviours; it adds a new Interval class which is responsible of interpolating between two values; and also adds the Animation class which is responsible of binding any GObject property to an Interval. whilst the Animation class can be used to animate any GObject, there is a simple function call that will: * create the Animation * bind the specified animated properties * set the state of the specified non-animated properties * connect to the specified Animation signals * manage the lifetime of the Animation object there are caveats for all this automagic handling: concatenating animations through clutter_actor_animate() requires using g_signal_connect_after(), and you cannot keep the internal Animation instance around and connected to the animated actor. [5:00] == Clutter's Master Clock == when something changes in the Clutter scenegraph then you, the toolkit or Clutter itself will queue a redraw. up until 0.8, queueing a redraw meant installing and idle handler in the main loop and, when the handler was called, relayout the stage and paint it on the front back buffer of the drawable then swap the buffer to front. this cycle was disjoint from the timelines, which were mostly glorified timeout sources, and from the event processing queue. such system is inherently prone to the possibility of starvation of one of the sources, especially if you start throwing things in like video playback, or you want to perform animations during event processing, like drag and drop. for these reasons, during the 0.9 cycle we decided to rework the way Clutter schedules the various operations during a paint cycle. the important thing in order to make this whole machinery work is using the sync-to-vblank rate of the screen, in order to avoid doing more work than necessary. when you queue a redraw on any stage, a flag will be set; Clutter uses the main loop to check for that flag and, if it is set, it will advance all the timelines by the same amount of milliseconds elapsed since the previous paint cycle. once all the timelines have been advanced, Clutter will process all the events queued on each stage, compressing motion events if they are coming in faster than the refresh rate. once that is done, and if it is needed, the layout will be refreshed and the stages will be painted to the back buffer, and then swapped to front. since timelines are not timeout sources anymore, and since events are processed within the master clock iteration, there is no possibility of two different sources starving the main loop anymore. [5:00] == COGL, the Clutter OpenGL Abstraction Library == for the past year and a half a lot of our resources have been concentrated on the COGL abstraction library. COGL started out as an API abstracting the differences between GL, GL|ES 1.1 and GL|ES 2.0, but it steadily grew into a proper low level API that allows Clutter to efficiently use GL. during the 0.9 cycle there has been an ongoing effort to make COGL faster; a lot of development time went into making it cache as much as possible to avoid costly state changes. COGL provides "materials", an API tra allows the developer to describe a geometry, its color, whether it should be painted with a texture, etc. if the GPU supports it, it's possible to add multiple layers inside a material and have multi-texturing; and it's possible to define the blend functions and the texture combines using a simple string definition. another object provided by COGL is the Vertex Buffer Object, mapping to the VBOs on the GPU if available. by using VBOs it's possible to efficiently upload geometries to the GPU, complete with color informations. as I mentioned before, COGL tries to cache as much as possible to avoid needlessly resubmitting geometries to the GPU; for this reason, there is a internal "journal" that stores all the rectangles defined by the scenegraph inside Clutter. COGL will combine all the geometry, color and texture information and submit it in one pass to simplify the number of validations, modelview matrix changes and state changes. this makes Clutter use GL better, and thus makes Clutter draw faster. as before, it's possible to break out of COGL and into raw GL. even more than before, though, breaking out might hurt your performance since all the state maintained by COGL must be submitted before you can drop into GL. for this reason, we'd prefer to make COGL better and avoid the need to use GL indiscriminately instead. [5:00] == The Future == we talked a bit about the past, we talked some more about the present. the future for Clutter means continuation of the 1.0 API, with six months release cycles tracking the GNOME development process in a Cairo-like way. it means at least a couple of years of API stability of the 1.0 branch for OSVs and ISVs. it also means, though, that the work towards 2.0 starts now. the future of COGL is to be a GPU programming library, exposing many more features of modern, programmable hardware in an efficient and object oriented way. it means tracking OpenGL and its changes. the future of Clutter is a review of how the scenegraph is constructed and how (and when) its geometry is sent to the GPU. how the actor that received an event is identified and how events are delivered to that actor. it means that changes that do not imply an API change will be backported and made available to the 1.x branch, but that API and ABI stability must not stop evolution and experimentation. the future of Clutter is not going to be ponies and unicorns, so we're sorry about that. but we promise to do our best. the most important thing for us is that you have fun with Clutter. thanks.