Skip to content
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

Gfx mainline merge work #2891

Merged
merged 21 commits into from
Feb 8, 2024
Merged

Gfx mainline merge work #2891

merged 21 commits into from
Feb 8, 2024

Conversation

Nexarian
Copy link
Contributor

No description provided.

Copy link
Member

@matt335672 matt335672 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks OK so far to me although I certainly can't say I understand all that is going on.

The GFX stuff appears pretty spread through the code. Is that just the way it is, or once we've got something going is there some scope for modularising it a bit more?

self->mm = mm;

if (client_info->jpeg_codec_id != 0)
{
LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_encoder_create: starting jpeg codec session");
LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_encoder_create: "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General thought: would it be useful to make these LOG() rather than LOG_DEVEL()? I'm thinking ahead to triaging user problem reports regarding which codec is being loaded.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this would be good to change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

(self->wm->client_info->rfx_codec_id != 0)))
{
self->encoder = xrdp_encoder_create(self);
}

Copy link
Member

@matt335672 matt335672 Jan 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need these tests before this call here? It looks like they're already in xrdp_encoder_create()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the only check that doesn't overlap here is the self->wm->client_info->gfx == 0 check, which I'm not sure is actually needed... Or rather, I'm not entirely certain what it does.

xrdp/xrdp_mm.c Show resolved Hide resolved
@Nexarian
Copy link
Contributor Author

Nexarian commented Jan 3, 2024

The GFX stuff appears pretty spread through the code. Is that just the way it is, or once we've got something going is there some scope for modularizing it a bit more?

I don't think we've thought much about how to modularize it or make it better. This code is largely a lift-and-shift from Jay's original prototypes that go back to 2017/2018. So if you have suggestions they'd be welcome. I think now is the time to think about how to re-flow the code. The good news with this code is it has been pretty thoroughly tested as people have been using variations of this in mainline_merge for years (though that's mostly been H264 a lot of the code such as the egfx_caps code is shared)

@Nexarian
Copy link
Contributor Author

Nexarian commented Jan 7, 2024

To respond further to why GFX is spread out throughout the code, there are several main things this change targets:

  • It adds the sec code to check for a GFX capable client. This seems fine to me.
  • It modifies the resize-on-the-fly code to be GFX compatible. This is awkward, and is the subject of that gigantic wiki post I wrote a few years ago. It could be improved, but I need another pair of eyes on it. All I know is it's stable and it works and has for years, but the fact that you need to delete the GFX session before resizing and reconstitute it is awkward and against what the MS specification says you need to do.
  • It makes some changes to the way painting is done because GFX modes require bitmap sizes of either 16x16 or 64x64 pixels, which means our dirty region detection logic can't do "only the pixels that changed." Instead, it has to do it block-wise.
  • It adds a few things, like changes to order processing, that will matter for H264 but we might as well get in now.
  • Due to a quirk of the way GFX is initialized, it changes the way login works with autologin. This is a necessary evil until we do a more aggressive refactoring of how [auto]login works.
  • Add RFX Progressive to the encoder facilities that already exist. I added Jay's changes to make this work to librfxcodec years ago and made sure they worked with mainline_merge, so tweaking is all that's needed.
  • Changes to how data is transmitted. In addition to fastpath, we now have xrdp_egfx_send_wire_to_surface1 and 2. Since those are fundamentally different, we have to break out conditional logic.
  • The most awkward part is probably the changes to xrdp_mm.c -- It's not clear that the functions with the prefix xrdp_mm_egfx belong there. They could go in a separate file.

After reading through the code I feel it's less "random" and more "invasive." GFX changes a lot of things from how capabilities are handled to how dirty regions are detected to how encoding works to how resizing works. It just touches a lot of stuff. There probably is room to simplify it. The FreeRDP codebase did a great job of this, but it's clear they've put a lot of effort into refactoring and code cleanup beyond what's probably worthwhile to do here.

Resizing and xrdp_mm would be targets for simplification, if any.

@matt335672
Copy link
Member

@Nexarian - Thanks for taking another look at it. I think we can look at re-simplifying later on. I'll happily pick up the xrdp_mm stuff.

@matt335672
Copy link
Member

Hi @Nexarian

I'm running your current merges as of 8th Jan. Configuring with ./configure --enable-devel-all --enable-ipv6

I'm using an xfreerdp client to control modes:-

xfreerdp /gfx /u:testuser /size:1280x1024 /v:xrdp-test.test.lan

I'm not having any session connection problems with a first connection, but I'm seeing the green banding you've mentioned elsewhere.

When I log out, I'm getting memory access errors. I've run with valgrind, and I'm attaching logs for xrdp and valgrind for the connection.
xrdp.log
valgrind.log

Before logging out there are no reported memory access violations, which is good.

@matt335672
Copy link
Member

FWIW, the valgrind issues are caused by the main xrdp process exiting while the encoder thread is still active.

This patch stops the valgrind errors:-

--- a/xrdp/xrdp_process.c
+++ b/xrdp/xrdp_process.c
@@ -306,6 +306,8 @@ xrdp_process_main_loop(struct xrdp_process *self)
     }
     /* Run end in module */
     xrdp_process_mod_end(self);
+    xrdp_wm_delete(self->wm);
+    self->wm = NULL;
     libxrdp_exit(self->session);
     self->session = 0;
     self->status = -1;

@Nexarian
Copy link
Contributor Author

Nexarian commented Jan 8, 2024

Thanks, I incorporated your PR! I've also noticed that resize-on-the-fly appears to be broken, so I'll dig into that tonight.

@Nexarian
Copy link
Contributor Author

Nexarian commented Jan 8, 2024

As you can see from the commit, fixed it. I missed when lifting-and-shifting the code from mainline_merge_shm that we need to process the "memory allocation complete" event regardless of whether the helper is enabled. This means that the changes I added to xorgxrdp are also important and this PR does not stand alone.

@metalefty
Copy link
Member

I'll test it.

@metalefty
Copy link
Member

@Nexarian Does this PS includes 20 commits included in gfx_mainline_merge_work branch?

@Nexarian
Copy link
Contributor Author

@metalefty I'm confused. There are only 7 commits beyond devel?

@metalefty
Copy link
Member

Ah, sorry. My head was messed up due to a lack of sleep. Just ignore it.

BTW, did you talk something about multimon with Jay?

@Nexarian
Copy link
Contributor Author

Nexarian commented Jan 11, 2024

Jay's multimon work is here:

What I can do is work on integrating these into this branch. The only bug I'm aware of in the gfx_mainline_merge_work is the graphical corruption with RFX PRO that we need to hunt down, but I agree with you the next priority should be pulling in the multimon work if you and Matt can investigate the corruption.

@metalefty
Copy link
Member

Then, could you go on multimon work? I will look into the graphical corruption.

@matt335672
Copy link
Member

The corruption is going to be a tough one to find. I spent a couple of hours playing with it on Monday and got nowhere - it's certainly not related to out-of-bounds memory accesses. It might be necessary to put a test program together which illustrates the fault and look at the resulting PDUs. Anyone got any other ideas?

@Nexarian
Copy link
Contributor Author

Nexarian commented Jan 11, 2024 via email

@jsorg71
Copy link
Contributor

jsorg71 commented Jan 11, 2024

The GFX decoder does not like rects in the list that contain tiles that didn't change. I older RemoteFX decoder was ok with that. I don't see my patch for rdpCapture2 that fixes that in gfx_mainline_merge_work. Also, the frame ack is used to 'lock' the shared memory. I think some of the dynamic monitor changes violate this assumption. For debugging, we can change xorgxrdp to always allocate a new shared memory so they can't both be using it at the same time.

@Nexarian
Copy link
Contributor Author

Nexarian commented Jan 12, 2024 via email

@jsorg71
Copy link
Contributor

jsorg71 commented Jan 12, 2024

No I think it's this one.

diff --git a/module/rdpCapture.c b/module/rdpCapture.c
index 94f16aa..8ebfa66 100644
--- a/module/rdpCapture.c
+++ b/module/rdpCapture.c
@@ -1170,7 +1170,14 @@ rdpCapture2(rdpClientCon *clientCon, RegionPtr in_reg, BoxPtr *out_rects,
             rcode = rdpRegionContainsRect(in_reg, &rect);
             LLOGLN(10, ("rdpCapture2: rcode %d", rcode));

-            if (rcode != rgnOUT)
+            if (rcode == rgnOUT)
+            {
+                LLOGLN(0, ("rdpCapture2: rgnOUT"));
+                rdpRegionInit(&tile_reg, &rect, 0);
+                rdpRegionSubtract(in_reg, in_reg, &tile_reg);
+                rdpRegionUninit(&tile_reg);
+            }
+            else
             {
                 crc = crc_start();
                 if (rcode == rgnPART)```

@Nexarian
Copy link
Contributor Author

That didn't seem to help unfortunately :/

@Nexarian
Copy link
Contributor Author

I also tried changing the rdpCapture2 to the "wyhash" variation that I have in mainline_merge_shm, no luck either.

@matt335672
Copy link
Member

This may be subjective, but after merging @Nexarian's last two commits, I'm finding it harder to generate green areas on the display. That's good in a way, but I've yet to come up with some way of reproducing the problem effectively which allows for testing. I've knocked up some X11 drawing programs, but these all seem to be working perfectly.

How are the rest of you reproducing the screen corruption?

@Nexarian
Copy link
Contributor Author

Here's what I do:

  • Open a terminal, drag it to the middle of the screen.
  • Run glxgears
  • Click between activating the glx window and the terminal window

It will eventually create spots within the terminal window that, if you only move the window slightly, will not disappear. This is, presumably, because of the CRC check algorithm that doesn't update tiles that aren't changing. However, on screen they're corrupt so it's very interesting. If the edges of the terminal go over those tiles, they will be corrected.

Not a very thorough set of instructions to reproduce, but it works consistently for me.

@matt335672
Copy link
Member

With the latest gfx_mainline_merge_work commits 06e8303 and neutrinolabs/xorgxrdp@8519407 I'm still getting the occasional green banding.

A couple of observations:-

  1. It seems that xup doesn't need write access to the shared memory area. It would be reasonable to disable this to prevent a stray pointer in xrdp causing issues with the display:-
--- a/xup/xup.c
+++ b/xup/xup.c
@@ -1275,7 +1275,7 @@ process_server_set_pointer_shmfd(struct mod *amod, struct stream *s)
         {
             Bpp = (bpp == 0) ? 3 : (bpp + 7) / 8;
             shmembytes = width * height * Bpp + width * height / 8;
-            if (g_file_map(fd, 1, 1, shmembytes, &shmemptr) == 0)
+            if (g_file_map(fd, 1, 0, shmembytes, &shmemptr) == 0)
             {
                 cur_data = (char *)shmemptr;
                 cur_mask = cur_data + width * height * Bpp;
@@ -1368,7 +1368,7 @@ process_server_paint_rect_shmfd(struct mod *amod, struct stream *s)
     {
         if (num_fds == 1)
         {
-            if (g_file_map(fd, 1, 1, shmem_bytes, &shmem_ptr) == 0)
+            if (g_file_map(fd, 1, 0, shmem_bytes, &shmem_ptr) == 0)
             {
                 bmpdata = (char *)shmem_ptr;
                 bmpdata += shmem_offset;
  1. I'm wondering if this is down to syncing issues between xorgxrdp and xup. I'm running a VM which is logging to a hard drive array, and as the file is opened with O_SYNC xup is a bit laggy. Enabling more logging seems to make the problem worse. In fact if I add this delay, I see it a lot more:-
--- a/xup/xup.c
+++ b/xup/xup.c
@@ -1715,6 +1715,7 @@ lib_mod_process_message(struct mod *mod, struct stream *s)
     {
         LOG_DEVEL(LOG_LEVEL_INFO,
                   "lib_mod_process_message: type 3 len %d", len);
+        g_sleep(100);
         for (index = 0; index < num_orders; index++)
         {
             phold = s->p;

How is the syncing supposed to work? If a crect (say) is sent over the link, how does xup know how when the client has read the crect data so the source can be overwritten in the server? I'm sure I'm misunderstanding something here, but I can't see what.

@jsorg71
Copy link
Contributor

jsorg71 commented Jan 16, 2024

@matt335672 Here is what I did on higher latency connection to get rid of xorgxrdp overwriting the shared memory before the encoder is done.
This breaks something in dynamic resize though.

diff --git a/module/rdpClientCon.c b/module/rdpClientCon.c
index 2cfebf4..ca9a285 100644
--- a/module/rdpClientCon.c
+++ b/module/rdpClientCon.c
@@ -2753,12 +2753,12 @@ rdpScheduleDeferredUpdate(rdpClientCon *clientCon)
     uint32_t msToWait;
     uint32_t minNextUpdateTime;
 
-    if (clientCon->updateRetries > UPDATE_RETRY_TIMEOUT) {
-        LLOGLN(10, ("rdpScheduleDeferredUpdate: clientCon->updateRetries is %d"
-                    " and has exceeded the timeout of %d retries."
-                    " Overriding rect_id_ack to INT_MAX.", clientCon->updateRetries, UPDATE_RETRY_TIMEOUT));
-        clientCon->rect_id_ack = INT_MAX;
-    }
+    //if (clientCon->updateRetries > UPDATE_RETRY_TIMEOUT) {
+    //    LLOGLN(10, ("rdpScheduleDeferredUpdate: clientCon->updateRetries is %d"
+    //                " and has exceeded the timeout of %d retries."
+    //                " Overriding rect_id_ack to INT_MAX.", clientCon->updateRetries, UPDATE_RETRY_TIMEOUT));
+    //    clientCon->rect_id_ack = INT_MAX;
+    //}
 
     curTime = (uint32_t) GetTimeInMillis();
     /* use two separate delays in order to limit the update rate and wait a bit

mstsc.exe indicates it supports GFX in the early capability flags, even
if it not able to support 32 BPP. This results in a session failure
if a RDPGFX_CAPS_CONFIRM_PDU is sent on the EGFX virtual channel.
Since v0.9.9, xrdp has assumed that the "drdynvc" static virtual
channel is available for its exclusive use. With GFX support, it
is necessary to codify this to prevent this sequence of operations:-

- NeutrinoRDP target sends DVC Capabilities Request PDU
- target responds wih DVC Capabilities Response PDU
- xrdp processes this, starting the GFX virtual channel again

In the future, if NeutrinoRDP requires access to virtual channels,
data may somehow need to be passed through to the target while being
parsed and handled appropriately within xrdp.
* 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.
@metalefty
Copy link
Member

I'm testing GFX multimon at the following versions but I got "protocol error" on mstsc. Is something missed to cherry-pick?

@Nexarian
Copy link
Contributor Author

Nexarian commented Feb 1, 2024

I haven't merged Jay's changes as I haven't had a chance to test it. I suppose now is the time. I'll just send it, I'm realistically not going to have much time in the next week.

* GFX: work on multimon

* fix for non GFX multimon
@Nexarian
Copy link
Contributor Author

Nexarian commented Feb 1, 2024

I merged in Jay's work and did a quick test on my M1 MacBook with 3x 4k monitors, it works! 👍

@Nexarian
Copy link
Contributor Author

Nexarian commented Feb 1, 2024

Hmm, now dynamic resizing for a single monitor appears to be broken :/. We can investigate.

@matt335672
Copy link
Member

I can look at the resizing early next week.

@Nexarian
Copy link
Contributor Author

Nexarian commented Feb 1, 2024

Stack trace. Seems the mechanism to use multi monitor doesn't like when something changes via the virtual channel.

  #0  0x000055b99bc9887d server_egfx_cmd (xrdp + 0x1287d)
  #1  0x00007f069043d363 process_server_egfx_shmfd (libxup.so + 0x2363)
  #2  0x00007f069043d7c8 lib_mod_process_orders (libxup.so + 0x27c8)
  #3  0x00007f069043e996 lib_mod_process_message (libxup.so + 0x3996)
  #4  0x00007f0691438bc4 trans_check_wait_objs (libcommon.so.0 + 0x15bc4)
  #5  0x000055b99bc9c8ed xrdp_mm_check_wait_objs (xrdp + 0x168ed)
  #6  0x000055b99bca05ce xrdp_process_main_loop (xrdp + 0x1a5ce)
  #7  0x000055b99bc92f1b xrdp_process_run (xrdp + 0xcf1b)
  #8  0x000055b99bc9421a xrdp_listen_fork (xrdp + 0xe21a)
  #9  0x000055b99bc8b106 main (xrdp + 0x5106)
  #10 0x00007f069114e083 __libc_start_main (libc.so.6 + 0x24083)
  #11 0x000055b99bc8b90e _start (xrdp + 0x590e)

@matt335672
Copy link
Member

I've had a quick look at the single monitor resizing. What seems to be happening is when the encoder and the EGFX surface have been removed, xorgxrdp is sending an orders command even though output is suppressed. That's causing a SEGV due to the missing encoder. I'll look into it in more detail tomorrow - not sure where the best place to fix this is.

@matt335672
Copy link
Member

To add more detail to the stack trace:-

hread 1 "xrdp" received signal SIGSEGV, Segmentation fault.
server_egfx_cmd (mod=0x55a087f290a0, cmd=0x55a087f2c574 "\v", cmd_bytes=85, data=0x7f256bc5b000 "", data_bytes=3244032) at xrdp_mm.c:4144
4144	    tc_mutex_lock(mm->encoder->mutex);
(gdb) where
#0  server_egfx_cmd (mod=0x55a087f290a0, cmd=0x55a087f2c574 "\v", cmd_bytes=85, 
    data=0x7f256bc5b000 "", data_bytes=3244032) at xrdp_mm.c:4144
#1  0x00007f256da6f70b in process_server_egfx_shmfd (
    amod=amod@entry=0x55a087f290a0, s=s@entry=0x55a087f24a90) at xup.c:1279
#2  0x00007f256da710e2 in lib_mod_process_orders (mod=mod@entry=0x55a087f290a0, 
    type=type@entry=62, s=s@entry=0x55a087f24a90) at xup.c:1670
#3  0x00007f256da7179e in lib_mod_process_message (mod=mod@entry=0x55a087f290a0, 
    s=s@entry=0x55a087f24a90) at xup.c:1778
#4  0x00007f256da6980b in lib_data_in (trans=0x55a087f249d0) at xup.c:132
#5  0x00007f256db13c10 in trans_check_wait_objs (self=0x55a087f249d0)
    at trans.c:442
#6  0x00007f256da71c75 in lib_mod_check_wait_objs (mod=0x55a087f290a0)
    at xup.c:1899
#7  0x000055a087507289 in xrdp_mm_check_wait_objs (self=0x55a087e6bed0)
    at xrdp_mm.c:3668
#8  0x000055a087519f53 in xrdp_wm_check_wait_objs (self=0x55a087b983e0)
    at xrdp_wm.c:2351
#9  0x000055a08750de85 in xrdp_process_main_loop (self=self@entry=0x55a087b20480)
    at xrdp_process.c:287
#10 0x000055a0874f6067 in xrdp_process_run (in_val=in_val@entry=0x0)
    at xrdp_listen.c:152
#11 0x000055a0874f76cc in xrdp_listen_fork (self=self@entry=0x55a087b1f180, 
    server_trans=server_trans@entry=0x55a087b20850) at xrdp_listen.c:802
#12 0x000055a0874f7c81 in xrdp_listen_main_loop (self=0x55a087b1f180)
    at xrdp_listen.c:987

@jsorg71
Copy link
Contributor

jsorg71 commented Feb 1, 2024

Oh, sorry guys, I didn't test resize much. I'll check why suppress is not working.

@matt335672
Copy link
Member

I can see what's happening on the resize.

The encoder is now responsible for GFX surface management - it is instructed what to do by xorgxrdp.

The resize logic isn't expecting this. The first thing is does is to stop the encoder and manually delete surfaces. When we send the mod_server_version message, xorgxrdp sends the GFX monitor layout back. We then try to pass this to the encoder which isn't there and get the SEGV.

I think the solution is going to be to not stop the encoder as part of the GFX resize. We'll then end up with the version message being processed normally. All the surface management for the resize can be driven from xorgxrdp.

We'll probably need to solve the issue with the MacOS client as well. I've managed to get a VM running Monterey to check this out.

I'm out of time today to try things today, but I've got all day Monday to spend on this.

@Nexarian
Copy link
Contributor Author

Nexarian commented Feb 2, 2024

I think the solution is going to be to not stop the encoder as part of the GFX resize.

This might be hard. In order to change the size of the encoders, you have to delete and re-create them. This is true from what I understand for RFX, but also for the upcoming X264, NVENC, and YAMI encoders (the width and height of all of them are read-only properties set as an argument to the constructor). However, we might be able to get away with doing it in one step of the state machine, or eliminate the state machine entirely, which leads to...

We'll probably need to solve the issue with the MacOS client as well

As I wrote here, the entire reason the state machine exists is because of the fact that I couldn't figure out how to not shut down the GFX channel and re-create it in order to have a stable resize with the Mac OS client. If that requirement goes away, then we can collapse a lot of this into a single atomic step that doesn't require a lot of "waiting until something is done" including re-creating the encoder at a different size.

@Nexarian
Copy link
Contributor Author

Nexarian commented Feb 2, 2024

Another potential way to solve this that is probably too much work, is to queue up any surface commands from xorgxrdp until the state machine finishes what it needs to, then replay those commands back to the client after the encoder and the channel are back...

@jsorg71
Copy link
Contributor

jsorg71 commented Feb 2, 2024

rdpSendGfxMonitors does not look at suppress. Maybe it should. Anyway, just comment out the call to rdpSendGfxMonitors seems to fix it. If surface 0 is first monitor and 1 is second one etc we should be ok.

@Nexarian
Copy link
Contributor Author

Nexarian commented Feb 2, 2024

That almost fixes this. But the following test case is still broken with that command commented:

  1. Connect with one monitor
  2. [Optional] Resize the session (this works)
  3. Disconnect
  4. Connect with > 1 monitors
    Result: The other monitors are black, the first monitor is the resolution that you left it when you disconnected.

@Nexarian
Copy link
Contributor Author

Nexarian commented Feb 2, 2024

This change 75b41af has the same net effect, but it simply blocks a crash if the encoder isn't there. It doesn't fix the bug I outlined earlier.

@matt335672
Copy link
Member

I've had a look at the latest xorgxrdp merges, and I'm getting an idea of what's going on. I can see that for GFX and H.264 we're sending the GFX graphics messages directly from rdpClientConSendPaintRectShmFd() to the encoder, which makes a certain amount of sense and is fairly readable. We only do this when the client advertises itself as GFX capable. This happens when the version message is received, so we should be able to handle connecting to the same session from both GFX and non-GFX clients.

The bit I'm confused about is why we need to create and map the surfaces from within xorgxrdp. It's going to be harder to support [MS-RDPEGFX] 3.3.5.19 behaviour. This is probably going to have to be done in xrdp_mm.c, so we'll end up duplicating code between these two locations.

Can anyone help me with why this approach has been taken?

@jsorg71
Copy link
Contributor

jsorg71 commented Feb 4, 2024

Yea, I was talking with Nex. Xorgxrdp odes not need to reset. As long as the surface ID can be predicable for each monitor. I'll do a PR to remove that.

@metalefty
Copy link
Member

Let's merge into devel.

@metalefty metalefty marked this pull request as ready for review February 8, 2024 12:49
@metalefty metalefty merged commit 45fd497 into devel Feb 8, 2024
25 checks passed
@metalefty metalefty deleted the gfx_mainline_merge_work branch February 8, 2024 14:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants