-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resize state machine: A fix and a question #2929
Resize state machine: A fix and a question #2929
Conversation
At present the EGFX state is destroyed by states WMRZ_EGFX_DELETE_SURFACE through WRMZ_EGFX_DELETE. This means that at WMRZ_EGFX_INITIALIZE we cannot distinguish between EGFX not being ever used, and EGFX having been torn down. Consequently, when running non-GFX, we don't correctly recover the session.
PS: I've got pretty much a full day available on Wednesday to look at this. I imagine you'll be rather busy doing other things. |
Small update - it's looking like we can make use of the suppress_output mechanism to prevent us sending screen updates to the client during deactivation-reactivation. That's removed a lot of the warnings from FreeRDP, but I've only get a prototype in place so far. |
Sorry for the delayed response. In reference to the concern about not knowing whether not to create the encoder, I thought I solved this by making use of the state machine itself.. If GFX isn't initialized, we just skip the entirety of the GFX shutdown/restart workflow... But maybe this isn't quite good enough? As to the FreeRDP error. Yes, it's been known for some time but I hadn't invested in fixing it because as best I could tell it was only a warning and didn't break anything. It was a low-priority "to fix" but if we are fixing spec conformance, yes, great idea. Yes, according to the spec you don't need to reset everything in order for GFX resizing to work. You're supposed to be able to simply delete surfaces and re-create them at the new size. I was never able to get this to work with the Mac OS client, which seemed to require that the entire thing be shutdown and rebuilt. Microsoft insists that this is not true. So we have an issue where my tested experience conflicts directly with the spec, which is why I've always asserted that "I need someone else to sanity check this." Also yes to suppress_output. I was never able to get it work to utilize it to prevent errant signals from being sent when we didn't want them. If you notice there are a lot of checks to make sure things are "up" so an errant video frame doesn't slip through before everything is re-initialized. Also to installing FreeRDP -- Any variation of V2 or V3 should work for our purposes here, we really only need GFX/RFX Pro and resizing, which has been stable in FreeRDP for a long time. Building FreeRDP from scratch is always difficult for me, but installing any production version from the last few years is likely fine for our purposes. |
Would be funny, if you run here into the pitfall of |
Thanks @Nexarian. In reference to the state machine line you reference, that bit's fine. The problem is later on. This As I said, I've got a bit of time tomorrow (I'm on UTC+0 at the mo'), so I'll try to get the latest The reason I want to use 3.2.0 is that the FreeRDP team have been pushing to get their stuff as standards compliant as it can be. That's been good for us too - see #2839. @pnowack - that's a great call. I'll look into it tomorrow. For reference, here's the section:-
|
I'm embarrassed that I missed that. There was a time where I was SURE I'd tested this case. Ah well. In any case, let's get this merged and then we can continue to test. |
Thanks. I suggest you do the merge since you're in charge of the branch! |
Replaces the single boolean for suppress_output with a bitmask, to allow output to be suppressed for more than one reason
Adds states to the dynamic resize state machine so we wait for a Deactivation-Reactivation sequence to finish before sending pointer updates, etc.
xrdp_mm needs to be informed when a resize has been performed so that the resize stte machine can be updsate.
I've added a bunch of commits around the dynamic resize state machine. With these commits dynamic resize works with GFX and non-GFX clients and Xorg and VNC backends. I've tested with FreeRDP 3.2.0. This is now warning-free for the dynamic resize codepaths. Some points:-
|
On the corrupted screens, the problem seems to be down to a corrupted framebuffer in the X server. This happens for both Xvnc and Xorg backends. I've no idea why this should be happening. |
Do you want me to hold off on merging this until you look into it further? Or is this still a major improvement from where things were? |
It's a big step forward, certainly. Probably worth merging despite the wrinkles. |
PS: Please check with MacOS if you get time. There should be no regressions here though. |
If you're not moving backward, you're moving fowards, will do :) |
Validated that it doesn't break resizing on Mac OS under basic stress tests (Resizing whilst playing a YouTube video, multiple resizes queued up at once, switching from the smallest possible to the largest possible size multiple times). Great work, I'll merge it and we can continue testing/iterating! |
9753559
into
neutrinolabs:gfx_mainline_merge_work
* Store EGFX state before entering resize state machine At present the EGFX state is destroyed by states WMRZ_EGFX_DELETE_SURFACE through WRMZ_EGFX_DELETE. This means that at WMRZ_EGFX_INITIALIZE we cannot distinguish between EGFX not being ever used, and EGFX having been torn down. Consequently, when running non-GFX, we don't correctly recover the session. * Allow multiple reasons for suppress_output Replaces the single boolean for suppress_output with a bitmask, to allow output to be suppressed for more than one reason * Disable output during resize * Add states to dynamic resize Adds states to the dynamic resize state machine so we wait for a Deactivation-Reactivation sequence to finish before sending pointer updates, etc. * suppress module output during the dynamic resize * Add support for dynamic resize to VNC backend xrdp_mm needs to be informed when a resize has been performed so that the resize stte machine can be updsate.
* Store EGFX state before entering resize state machine At present the EGFX state is destroyed by states WMRZ_EGFX_DELETE_SURFACE through WRMZ_EGFX_DELETE. This means that at WMRZ_EGFX_INITIALIZE we cannot distinguish between EGFX not being ever used, and EGFX having been torn down. Consequently, when running non-GFX, we don't correctly recover the session. * Allow multiple reasons for suppress_output Replaces the single boolean for suppress_output with a bitmask, to allow output to be suppressed for more than one reason * Disable output during resize * Add states to dynamic resize Adds states to the dynamic resize state machine so we wait for a Deactivation-Reactivation sequence to finish before sending pointer updates, etc. * suppress module output during the dynamic resize * Add support for dynamic resize to VNC backend xrdp_mm needs to be informed when a resize has been performed so that the resize stte machine can be updsate.
* Store EGFX state before entering resize state machine At present the EGFX state is destroyed by states WMRZ_EGFX_DELETE_SURFACE through WRMZ_EGFX_DELETE. This means that at WMRZ_EGFX_INITIALIZE we cannot distinguish between EGFX not being ever used, and EGFX having been torn down. Consequently, when running non-GFX, we don't correctly recover the session. * Allow multiple reasons for suppress_output Replaces the single boolean for suppress_output with a bitmask, to allow output to be suppressed for more than one reason * Disable output during resize * Add states to dynamic resize Adds states to the dynamic resize state machine so we wait for a Deactivation-Reactivation sequence to finish before sending pointer updates, etc. * suppress module output during the dynamic resize * Add support for dynamic resize to VNC backend xrdp_mm needs to be informed when a resize has been performed so that the resize stte machine can be updsate.
The commit is the easy bit.
This commit allows non-GFX sessions to resize.
At present the EGFX state is destroyed by states WMRZ_EGFX_DELETE_SURFACE through WRMZ_EGFX_DELETE. This means that at WMRZ_EGFX_INITIALIZE we cannot distinguish between EGFX not being ever used, and EGFX having been torn down. Consequently, when running non-GFX, we don't correctly recover the session.
Now for the question.
With FreeRDP 3.2.0 the non-GFX codepath is working, but I get a lot of messages of this form:-
These are generated after we start a Deactivation-Reactivation sequence with
libxrdp_reset()
and before we callxrdp_rdp_send_synchronise()
There seem to be a couple of problems with this area of the state machine:-libxrdp_reset()
. From [MS-RDPEDISP] 1.3 :-So it seems to me that both the GFX and non-GFX resize codepaths need some work here to be conformant to the specification.
@Nexarian - I'd very much appreciate your comments on the above.