So, here's a question:
Is there a good reason to make framerate changes be totally in-order?
Currently, FPS throttling is done statelessly. Once you call SetFrameRate, the framerate is changed atomically and immediately--no matter what the current relationship is between the render thread and the engine thread.
So, let's say you draw some frames (just worrying about actual FlipScreens in the pipeline), and you've set the FPS to 30 beforehand:
Draw Queue:
[Frame 0|Frame 1|Frame 2|Frame 3]
Engine:
[Frame 4]
So right now, we've sent four frames to the draw queue that aren't drawn yet. The engine has no idea, it's working on the fifth frame, and doesn't care what's happening in the render thread (or that the render thread is behind). All those frames will be drawn at 30 FPS (30-ish ms between each one).
[Frame 0 | 30 ms interval | Frame 1 | 30 ms interval | Frame 2 | 30 ms interval | Frame 3]
Then you change the frame rate to 60 FPS.
Ideally (theoretical ideally), if you then submitted two more frames, it would look like this:
[Frame 0 | 30 ms interval | Frame 1 | 30 ms interval | Frame 2 | 30 ms interval | Frame 3 | FPS Change Operation | 16 ms interval | Frame 4 | 16 ms interval | Frame 5]
Right now, what would happen is this:
The second you change the FPS:
[Frame 0 | 16 ms interval | Frame 1 | 16 ms interval | Frame 2 | 16 ms interval | Frame 3]
Then, with two more frames:
[Frame 0 | 16 ms interval | Frame 1 | 16 ms interval | Frame 2 | 16 ms interval | Frame 3 | 16 ms interval | Frame 4 | 16 ms interval | Frame 5]
And so, in once sense, you've interfered with past events. But you've also performed the action immediately, and applied it based on real time rather than on synchronous timings.
This is actually really different from how Sphere and other totally synchronous engines would do it--you can affect the FPS of frames you submitted in the past! This sounds like kind of a bad idea, because it introduces a certain amount of unpredictable behaviour (how many, if any, frames have their resulting intervals changed). But on the other hand, it is much lighter weight than sending a message through the render queue to make it happen in-order, and I also can't especially think of a reason why you would want to be 100% sure that it executed in order.