fix(graphics): retain Progressive difference tiles - #1698
fix(graphics): retain Progressive difference tiles#1698Marc-André Moreau (mamoreau-devolutions) wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds Progressive RemoteFX difference-tile decoding with retained per-context tile references.
Changes:
- Defines the difference-tile flag.
- Accumulates difference coefficients and rejects missing references.
- Adds difference-tile regression tests.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
crates/ironrdp-pdu/src/codecs/rfx/progressive.rs |
Defines and tests the difference flag. |
crates/ironrdp-graphics/src/progressive.rs |
Retains references and decodes difference tiles. |
There was a problem hiding this comment.
Adds decode support for RFX_TILE_DIFFERENCE in Progressive TILE_SIMPLE/TILE_FIRST tiles: retains a tile's quantized DWT coefficients as a reference, sums a difference tile's decoded delta onto it, and returns MissingTileReference instead of silently decoding against zero when no prior tile exists. Well-scoped, keeps the existing decode_first signature, and adds two targeted tests (cross-context accumulation, missing-reference error). Arithmetic and error logic match the supplied protocol handoff's conformance analysis for MS-RDPEGFX 3.2.8.1.4 and 3.3.8.2.1/.1. Two secondary handoff points (context- vs surface-scoped reference lifetime, saturating vs wrapping addition) are real but low-impact. One added point: a new variant on a non-exhaustive-unmarked public error enum is a legitimate but expected semver note.
Protocol analysis: accepted — Re-derived the mappings independently: TILE_FLAG_DIFFERENCE=0x01 matches the documented flags bit for TILE_SIMPLE/TILE_FIRST; the zero-then-add-back-reference sequence is algebraically equivalent to DecDwtQ = Ref + DecProgQ*PQF (difference) vs DecProgQ*PQF (original), with sign state always cleared; gating on pass != 0 (else MissingTileReference) defensibly enforces the encoder-side 'first send is always original' rule. The two potential_discrepancies are correctly low-confidence: context-vs-surface keying predates this diff, and saturating_add is a safe divergence from unspecified overflow behavior, not a wire defect.
5db30b5 to
b468942
Compare
Retain quantized DWT coefficients per Progressive tile so difference updates compose with their matching surface and codec-context reference. Reject difference tiles that lack a retained reference instead of decoding them against zeros.
Keep RFX Progressive DecDwtQ references on the surface after codec contexts are deleted and commit first-pass decode state only on success.
Keep sub-band difference references through codec grid replacement and ResetGraphics, releasing them only with their associated surface. This preserves valid difference-tile state per MS-RDPEGFX lifetime rules.
c0ad5bb to
b83275b
Compare
|
Same bug as #1701. Keying the reference by surface and keeping it across One substantive point: rejecting a difference tile that has no retained reference. 3.3.8.2.1 makes the zeroing conditional — "if the tile is an original tile (not a difference tile), then the tile MUST be zeroed out in the current frame" — but the add unconditional: "The result of the entropy decode operation MUST be added to the current frame." No error case is defined, and FreeRDP decodes against a zero-initialised Nit: Tests in #1701 you may want to lift: TILE_FIRST end to end (only TILE_SIMPLE is exercised here), the reduce-extrapolate band layout, and a difference tile arriving after an upgrade pass. |
Retain quantized DWT coefficients per Progressive tile so difference updates compose with their matching surface reference while progressive codec-context state remains isolated.
Reject difference tiles that lack a retained reference instead of decoding them against zeros.
Keep retained surface references across codec grid replacement and ResetGraphics; only deleting the surface releases them.