Refactor surface state handling in preparation for explicit sync
From #kde-kwin
5/3/2022, 11:50:11 AM - zzag: We could add support for explicit synchronization without changing how surface state is handled, but it won't bring significant improvements
5/3/2022, 11:51:05 AM - zamundaaa: It would probably at least fix a bunch of NVidia bugs
5/3/2022, 11:52:00 AM - zamundaaa: But yeah the surface state delaying is annoying. And the presentation timing stuff (whenever that gets worked on again) would require it as well
5/3/2022, 11:54:19 AM - zzag: Right, I have only two options - either queue state in extensions, i.e. SurfaceInterface, ConfinedPointerV1Interface, etc. or store it in a mega state
5/3/2022, 11:54:30 AM - zzag: Either solution is meh
5/3/2022, 11:59:03 AM - zzag: The first option is either add two signals or two hooks to get notified when state is committed and applied, i.e.
\`\`\`cpp
connect(surface, &Surface::stateCommitted, this, [this](quint32 serial) {
// queue my state
});
connect(surface, &Surface::stateApplied, this, [this](quint32 serial) {
// pick state with the given serial and apply it
});
\`\`\`
5/3/2022, 12:03:31 PM - zzag: ... with a mega state, `SurfaceInterface` would need to know how to move extension state between `SurfaceState`s
5/3/2022, 12:04:38 PM - zamundaaa: queue + commit seems like the easier solution to me
5/3/2022, 12:04:56 PM - zamundaaa: it doesn't need to have a serial though afaict
5/3/2022, 12:05:16 PM - zamundaaa: A stack would suffice. The state needs to be applied in order either way
5/3/2022, 12:05:34 PM - zamundaaa: s/stack/queue
5/3/2022, 12:08:53 PM - KDE Moderation changed the server ACLs for this room.
5/3/2022, 12:11:17 PM - zzag: <@zamundaaa:kde.org "A stack would suffice. The state..."> I don't think so. What if we have the following case:
1. initial state. surface state queue: [A, B, C]
2. extension is created
3. extension is initialized and the surface is committed; surface state queue: [A, B, C, D], extension state queue: [D']
4. state "A" is popped from the queue
5/3/2022, 12:11:42 PM - zzag: D' needs to be applied when D is applied
5/3/2022, 12:11:56 PM - zzag: without serials, it will be applied when state A is popped
5/3/2022, 12:16:26 PM - zamundaaa: Aren't the extensions part of the surface state queue? When state A is popped, the pointer in state A is nullptr, so nothing happens to the extension state
5/3/2022, 12:18:37 PM - zzag: Hmm, no, extension state queue will be inside the extension
5/3/2022, 12:18:48 PM - zzag: Or do you suggest to put attached extensions in the surface state
5/3/2022, 12:19:01 PM - zzag: and then explicitly call hooks when state is applied or committed?
5/3/2022, 12:19:25 PM - zzag: i.e.
5/3/2022, 12:22:14 PM - zzag: \`\`\`cpp
class SurfaceExtension
{
public:
virtual void surfaceStateCommitted(quint32 serial) {}
virtual void surfaceStateApplied(quint32 serial) {}
};
class ConfinedPointerV1Interface : public SurfaceExtension
{
};
in surface_interface.cpp, when state is committed
for (SurfaceExtension *extension : std::as_const(pending.extensions)) {
extension->surfaceStateCommitted(serial);
}
when applied
for (SurfaceExtension *extension : std::as_const(next.extensions)) {
extension->surfaceStateApplied(serial);
}
when a new extension is created, add it to `pending.extensions`
when an extension is destroyed, remove it from `pending.extensions` and all queued states
\`\`\`
5/3/2022, 12:46:48 PM - zamundaaa: Yes
5/3/2022, 1:17:36 PM - zzag: Sounds like we have a plan