fix(rdp6): use actual bitmap dimensions instead of rectangle dimensions#1398
fix(rdp6): use actual bitmap dimensions instead of rectangle dimensions#1398ArmConSol (armconsol) wants to merge 4 commits into
Conversation
|
Fixes #1399 |
There was a problem hiding this comment.
Pull request overview
This PR fixes rendering artifacts with RDP6-compressed (32bpp) bitmap updates where the decoded bitmap’s source dimensions (update.width/update.height) differ from the placement rectangle dimensions (update.rectangle). It updates the session image application logic so RGB24 row chunking can be based on the true decoded stride, improving correctness for tiled updates (e.g., NVIDIA DGX).
Changes:
- Added an RGB24 application API that accepts an explicit source width (stride) and updated the RDP6 fast-path bitmap handler to use
update.width. - Refactored BGR24 application to support configurable row order (bottom-up vs top-down).
- Expanded debug logging around RDP6 bitmap decode/placement to surface dimension mismatches.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| crates/ironrdp-session/src/image.rs | Adds stride-aware RGB24 application and introduces configurable row ordering for BGR24 application. |
| crates/ironrdp-session/src/fast_path.rs | Uses update.width/update.height for RDP6 decode/apply instead of rectangle dimensions and improves debug visibility. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Copilot Review AddressedThank you for the review! All three issues have been fixed: ✅ Issue #1: Box lifetime and performanceStatus: Fixed in commit Removed the
✅ Issue #2: Bounds checking for source_width > rectangle.width()Status: Fixed in commit Added comprehensive bounds checking in
This prevents out-of-bounds writes when the bitmap extends beyond the rectangle. ✅ Issue #3: Structured logging fieldsStatus: Fixed in commit Converted debug logs to use structured tracing fields per STYLE.md: debug!(
source_width,
source_height,
rect_width,
rect_height,
rect = ?update.rectangle,
data_len = update.bitmap_data.len(),
expected_len = source_width * source_height * 3,
"Compressed RDP6 bitmap stream (32 bpp)"
);This improves downstream filtering/aggregation and keeps messages concise. All changes verified:
|
|
@copilot |
PR #1398 submitted to Devolutions/IronRDP: Devolutions/IronRDP#1398
The RDP6 bitmap stream decoder outputs RGB24 data in top-to-bottom order, but apply_rgb24 was flipping rows (flip=true) causing horizontal striping artifacts. Changed to flip=false for RDP6 decoded bitmaps.
RDP6 compressed bitmaps can have different dimensions than the update rectangle. The decoder produces source_width × source_height pixels, but the rectangle specifies the placement coordinates. Previously, apply_rgb24() was chunking the decoded data using rectangle.width(), which caused pixel data to be read at the wrong stride when update.width != rectangle.width(). This manifested as horizontal striping and blur artifacts. Fix: Add apply_rgb24_with_dimensions() that accepts explicit source_width parameter, and use update.width (not rectangle.width()) for chunking.
1. Remove Box<dyn Iterator> in apply_bgr24_bitmap_with_order - Eliminates unnecessary heap allocation and dynamic dispatch - Fixes lifetime issues by using direct if/else branches - Keeps hot pixel-copy path monomorphized for performance 2. Add bounds checking in apply_rgb24_with_dimensions - Clamp copy dimensions to min(source, rectangle) to prevent OOB writes - Guard against source_width == 0 to avoid chunks_exact(0) panic - Only copy the overlapping region when source > rectangle 3. Use structured tracing fields in debug logs - Convert formatted strings to structured fields per STYLE.md - Improves downstream filtering and aggregation - Keeps log messages concise All issues identified by Copilot review now resolved.
07a0a89 to
b0cac43
Compare
Resolves password-prompt-loop and striping artifacts on DGX connections. Changes: - Updated Cargo.toml to use patched IronRDP (path dependencies) - Added CI step to clone IronRDP patch before builds - Documented patch in IRONRDP_PATCH.md - Contributed fix upstream: Devolutions/IronRDP#1398
Problem
When connecting to servers that send RDP6 compressed bitmaps with tiled updates (e.g., NVIDIA DGX), the rendered display shows horizontal striping and blur artifacts.
Root Cause
RDP6
BitmapUpdatePDUs can have different dimensions than their placement rectangles:update.width×update.height= actual decoded bitmap sizeupdate.rectangle= where to place the bitmap on screenThe current implementation of
apply_rgb24()chunks the decoded RGB24 data usingrectangle.width(), but the decoder produces data withupdate.widthpixels per row. When these values differ, it causes stride mismatches and pixel data misalignment.Example from Real Traffic
Connecting to NVIDIA DGX server at 1920x1080:
The decoder produces 348 pixels/row, but
apply_rgb24()chunks at 345 pixels/row → pixel misalignment → horizontal stripes.Changes
apply_rgb24_with_dimensions()that accepts explicitsource_widthparameterfast_path.rsto useupdate.width(notrectangle.width()) for chunkingapply_rgb24()for backward compatibility (delegates to new function)Testing