Skip to content

fix(egfx): use exclusive AVC region bounds - #1788

Open
Marynych Oleksandr (maryny4) wants to merge 3 commits into
Devolutions:masterfrom
maryny4:fix/egfx-region-bounds
Open

fix(egfx): use exclusive AVC region bounds#1788
Marynych Oleksandr (maryny4) wants to merge 3 commits into
Devolutions:masterfrom
maryny4:fix/egfx-region-bounds

Conversation

@maryny4

@maryny4 Marynych Oleksandr (maryny4) commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

MS-RDPEGFX 2.2.1.2 defines RDPGFX_RECT16 with exclusive right and bottom, and 2.2.4.4.1 gives regionRects in RFX_AVC420_METABLOCK that same type. Avc420Region documented its edges as inclusive, full_frame() built width - 1 / height - 1, and to_rectangle() handed those to an InclusiveRectangle that encoded them unchanged, so every regionRects entry went out a pixel short on the right and bottom edge. GraphicsPipelineServer::compute_dest_rect(), used for the WireToSurface1 destination, does add that pixel back: the two call sites disagreed about whether the conversion had already happened.

Avc420Region is exclusive throughout now and to_rectangle produces an ExclusiveRectangle, so the asymmetric adjustment disappears. fix(egfx): bound both AVC444 streams then computes the destination rectangle from both streams rather than from the luma one, so a chroma region larger than luma is no longer cut short. feat(egfx): add explicit AVC444v2 frame sender separates the AVC444v2 path from AVC444; both fixes build on it.

What the defect costs: with ironrdp-server on master, Windows App on macOS drops the connection right after the encoder starts, the server reporting peer closed connection without sending TLS close_notify. Pinning the session resolution, so that no deactivation-reactivation happens at all, changes nothing. With these three commits the same server build and the same client run normally. FreeRDP-based clients accept the frames either way, which is why this shows only against the Microsoft client. That is not proof this field is the trigger - 2.2.4.4.1 also calls the metablock informational - only that the field is wrong on the wire and that these commits make that client work.

avc.rs lost its inline test module to #1736 while these sat in a fork, so the full_frame expectation is updated in testsuite-core/tests/egfx/avc.rs instead.

Please rebase-merge rather than squash. The three commits are MuNeNiCK (@MuNeNiCK)'s with his authorship intact, and the breaking change is confined to the middle one; squashing would collapse both.

BREAKING CHANGE: Avc420BitmapStream::rectangles is now Vec<ExclusiveRectangle>, and Avc420Region::to_rectangle returns ExclusiveRectangle. Callers that build or match InclusiveRectangle there have to switch, and a region built with Avc420Region::full_frame no longer subtracts one from the width and height.

Issue: #1712

@github-actions github-actions Bot added maintainer-required Maintainer review or intervention is required risk/unknown Risk could not be determined automatically; needs maintainer-level scrutiny scope/core Touches the core architectural tier size/M Size: up to 449 counted lines and 10 files; exceeds S in either measure labels Aug 23, 2026
@MuNeNiCK

Copy link
Copy Markdown

Thank you for taking the time to validate these changes and submit them upstream. Sorry I missed your earlier messages. I’m happy for these changes to be upstreamed through this PR.

@glamberson

Copy link
Copy Markdown
Contributor

Thanks for filing this, and glad to see MuNeNiCK confirm he's happy for it to go through this PR. Good fix.

@maryny4

Copy link
Copy Markdown
Contributor Author

Context that does not belong in the commit message.

Authorship. These three commits are MuNeNiCK (@MuNeNiCK)'s, cherry-picked onto master with his authorship intact; I am the committer only. I asked him twice whether he would rather send them himself before opening this, and he has since confirmed here that he is happy for them to go upstream through this PR. That is the reason for the rebase-merge request in the body: a squash would put my name on his work.

Provenance of the analysis. The exclusive/inclusive mismatch was diagnosed by Greg Lamberson (@glamberson) in #1712. I checked each step of it against master before sending this rather than taking it on trust.

What I ran locally. cargo xtask check fmt is clean. ironrdp-egfx is 46 passed / 0 failed and the egfx part of the testsuite is 52 passed / 0 failed. I could not run cargo xtask ci in full on this machine: the repo pins toolchain 1.94.1 and the installed one is 1.98.0, under which cargo clippy --workspace -- -D warnings fails in ironrdp-bulk and ironrdp-str - crates this PR does not touch, and it fails there on unmodified master too - and typos-cli is not installed here. The CI on this head is green: 35 passed, 8 skipped, none failed.

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

Labels

maintainer-required Maintainer review or intervention is required risk/unknown Risk could not be determined automatically; needs maintainer-level scrutiny scope/core Touches the core architectural tier size/M Size: up to 449 counted lines and 10 files; exceeds S in either measure

Development

Successfully merging this pull request may close these issues.

3 participants