Skip to content

Instantly share code, notes, and snippets.

@GeorgesStavracas
Created July 2, 2020 18:29
Show Gist options
  • Save GeorgesStavracas/a6abe7d7ccb4c59ea57586d854e4382c to your computer and use it in GitHub Desktop.
Save GeorgesStavracas/a6abe7d7ccb4c59ea57586d854e4382c to your computer and use it in GitHub Desktop.
frames.md

Splitting up the frame clock

Readers be advised, this is somewhat of a deep dive into the guts of mutter. With that out in the open, lets start! Not too long ago saw a merge request land, that has one major aim: split up the frame clock so that on the native backend, each CRTC is driven by its own clock. In effect the goal here is that e.g. a 144 Hz monitor and a 60 Hz monitor being active in the same session will not have to wait for each other to render, and that the space they occupy on the screen will draw at their own pace. A window on the 144 Hz monitor will paint at 144 Hz, and mutter will composite to the monitor at 144 Hz, while a window on the 60 Hz monitor will paint at 60 Hz and mutter will composite to the monitor at 60 Hz.

(Picture)

This is achieved by a number of changes.

Preface

In the beginning of times, Clutter was an application toolkit. As such, it assumed (1) the existence of a window compositor, and (2) the compositor is a different process. Back then, Wayland was still in its early infancy, and those assumptions wouldn't conflict with writing a X11 window manager. After all, a X11 window manager is pretty much just another client application.

Over time, however, Clutter started to grow Wayland integration in itself. Deeper and deeper surgeries were made to it to accomodate it being used by a Wayland compositor.

In 2016, the Cogl and Clutter codebases were merged with Mutter codebase, and they all live in the same repository now. However, to this day, relics from the time when Clutter was an application toolkit are still present in Mutter's Clutter. One such relic is ClutterMasterClock.

ClutterMasterClock

ClutterMasterClock was the main frame clock that drove Clutter painting. As an application toolkit, only a single, global frame clock was necessary; but as a compositor toolkit, this design does't fit the requirements for multi-monitor setups.

Over the last cycles, there has been some attempts to make it handle multiple monitors slightly better, but in general, the fundamental design of it has been incompatible with desired end goal.

Enters ClutterFrameClock.

ClutterFrameClock is the new frame clock object that aims to drive a single “output”. Right now, it has a fixed refresh rate, and a single “frame listener” and “presenter” notifying about frames being presented. It is also possible to have multiple frame clocks running in parallel.

However, ClutterFrameClock alone isn't enough to achieve independence of monitor redraws.

Stage Views

Mutter has a single stage that covers the union of all monitor rectangles. But how does it render different contents to each one of them?

That's one of the main responsibilities of ClutterStageView.

ClutterStageView was the answer to the need of drawing the stage at different framebuffers. ClutterStageView corresponds roughly to one monitor. Each ClutterStageView holds the on-screen framebuffer that the monitor displays; if using shadow framebuffers, ClutterStageView also handles them; and finally, it also handles the monitor rotation.

Now, ClutterStageView also handles the monitor's frame clock. By handling the frame clock, each view is also responsible of notifying about frames being presented, and handling the frame clock dispatching

All frame scheduling is moved from ClutterMasterClockDefault, ClutterStage, ClutterStageCogl, MetaRendererNative, MetaStageNative, MetaStageX11 to ClutterFrameClock and ClutterStageView. The logic dealing with scheduling frames (including flip counting, schedule time calculation, etc) was spread out to many places; the aim has been to concentrate all of it to two: the frame clock itself and frame clock driver (stage view).

Actors, Actors Everywhere

When animating interface elements, the core object that does that is ClutterTimeline and, thus, ClutterTransition.

Timelines and transitions saw frames whenever the master clock ticked. With the master clock gone, they need to find an appropriate frame clock to drive them. In most (and after this merge request all) cases a timeline was used to directly drive an animation related to an actor. This indirect relationship is now made explicit, and the timeline uses the actor to find what stage view it is being displayed on, and with that information, picks an appropriate frame clock to attach to.

If an actor moves to different stage view, the timeline will be notified about this and might migrate to a different frame clock.

What About X11?

In the X11 session, we composite the whole X11 screen at once, without any separation between monitors. This remains unchanged, with the difference being where scheduling takes place (as mentioned in an earlier point.)

Various minor API changes

Signals related to painting has seen ClutterStageView added as a signal parameter to let listeners know what is actually painted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment