Skip to content

feat(activex): present EGFX dirty regions - #1874

Open
Marc-André Moreau (mamoreau-devolutions) wants to merge 6 commits into
masterfrom
copilot/activex-accelerated-graphics
Open

feat(activex): present EGFX dirty regions#1874
Marc-André Moreau (mamoreau-devolutions) wants to merge 6 commits into
masterfrom
copilot/activex-accelerated-graphics

Conversation

@mamoreau-devolutions

@mamoreau-devolutions Marc-André Moreau (mamoreau-devolutions) commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Propagate validated ResetGraphics extents into the session framebuffer and deliver exact packed desktop damage to ActiveX without rebuilding full image snapshots.

Coalesce only fully covered regions, preserve sparse updates with a 64-event and 256 MiB pixel-data budget, and backpressure without evicting accepted frame or static-channel payloads. Update retained GDI and RPC surfaces in place. Reuse framebuffer storage with fallible growth, and retain software cursor shape, position, visibility, and clipping across graphics resets. Keep V8 non-AVC negotiation and full-frame output fallback unchanged. Rejected oversized resets still destroy prior surfaces and are reported as unsupported without allocating a session framebuffer.

Copilot AI balanced review requested due to automatic review settings September 1, 2026 18:36
@github-actions github-actions Bot added kind/protocol Affects RDP or related protocol behavior maintainer-required Maintainer review or intervention is required risk/medium Behavioral change that does not substantially alter a core public API scope/core Touches the core architectural tier scope/cross-cutting Spans multiple architectural boundaries scope/ffi Affects native or .NET bindings size/XL Size: up to 1299 counted lines and 49 files; exceeds L in either measure labels Sep 1, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds dirty-region delivery for ActiveX while retaining full-frame fallback.

Changes:

  • Propagates validated EGFX reset extents into session framebuffers.
  • Adds packed desktop updates and retained partial-frame presentation.
  • Introduces bounded damage queuing and related tests/documentation.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
crates/ironrdp-testsuite-extra/tests/client/output_channel.rs Tests desktop-update validation.
crates/ironrdp-session/src/active_stage.rs Resizes framebuffers after EGFX resets.
crates/ironrdp-egfx/src/compositor.rs Validates output dimensions and memory limits.
crates/ironrdp-egfx/src/client.rs Reports validated reset extents.
crates/ironrdp-client/src/rdp.rs Adds packed dirty-region delivery.
crates/ironrdp-activex/src/rpc.rs Applies partial updates to retained RPC frames.
crates/ironrdp-activex/src/control.rs Queues, merges, presents, and invalidates dirty regions.
crates/ironrdp-activex/README.md Documents the dirty-region pipeline.

Comment thread crates/ironrdp-activex/src/control.rs
Comment thread crates/ironrdp-client/src/rdp.rs Outdated
Comment thread crates/ironrdp-session/src/active_stage.rs Outdated
@github-actions github-actions Bot added breaking-change Includes a breaking change, and requires special scrutiny at the boundaries risk/high Substantial core public API impact, or fail-closed triage; needs maintainer-level scrutiny risk/unknown Risk could not be determined automatically; needs maintainer-level scrutiny size/XXL Size: 1300 or more counted lines or 50 or more files and removed risk/medium Behavioral change that does not substantially alter a core public API size/XL Size: up to 1299 counted lines and 49 files; exceeds L in either measure breaking-change Includes a breaking change, and requires special scrutiny at the boundaries risk/high Substantial core public API impact, or fail-closed triage; needs maintainer-level scrutiny labels Sep 1, 2026
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

This pull request is size/XXL, so automated review is disabled for it: a change this large is hard to review well in one piece, whether by a human or a model.

Please split it into focused pull requests that can each be reviewed on their own. When the parts build on each other, stacked pull requests let you open each one on top of the last without waiting for the one below to merge. Stacks require every branch to live in this repository, so from a fork, please open separate pull requests instead.

Automated review resumes once the change is below the size/XXL threshold.

@mamoreau-devolutions

Copy link
Copy Markdown
Contributor Author

The size/XXL warning is acknowledged. The diff has two conceptual review boundaries—EGFX reset/session propagation and ActiveX packed-damage presentation—but they form the end-to-end graphics path validated by this PR. This recovery was explicitly constrained to the existing PR branch and to preserving valid pushed work, so I did not create stacked branches, discard either boundary, or rewrite the existing commits. Both boundaries received separate protocol, implementation, documentation, and skeptical review passes; the retained findings are fixed at 82d445e88.

Note

Human-tuned, LLM-assisted content.

Propagate validated ResetGraphics extents into the session framebuffer and deliver packed desktop damage to ActiveX without rebuilding full image snapshots.

Coalesce only fully covered regions, preserve disjoint updates with bounded backpressure, and update retained GDI and RPC surfaces in place. Keep V8 non-AVC negotiation and full-frame output fallback unchanged.
Destroy prior surfaces when a ResetGraphics output exceeds local allocation limits, matching protocol reset semantics.

Notify handlers about the rejected output so capture replay retains its unsupported-path classification and fuzz models stay synchronized.
Preserve exact compositor regions so sparse updates do not expand into full bounding-box copies, and cap queued pixel payloads at 256 MiB with backpressure.

Retain software cursor shape, position, and visibility when ResetGraphics replaces the session framebuffer.
Invalidate retained RPC frames when a resized desktop exceeds the screenshot budget, and consume the EGFX client's accepted reset state directly during capture replay.
Keep exact frame and static-channel updates ordered when the UI queue is saturated, and make dispatch recovery fail instead of waiting without an outstanding message.

Reuse framebuffer storage across graphics resets and clip retained software cursors without source-rectangle underflow.
Integrate partial frame presentation with the modern screen-update suspension contract by snapshotting one bounded full-frame base and applying every suspended dirty region before resume.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Direct frame dispatch can violate lifecycle ordering, and differing framebuffer extents still evict accepted updates.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 11/11 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment on lines +12030 to +12035
let client = RdpClient::new(config, output_sender).with_desktop_update_handler(move |update| {
let _ = queue_worker_event(
&desktop_update_events,
&desktop_update_posted,
HWND(desktop_update_hwnd as *mut c_void),
WorkerEvent::Image {
Comment on lines +17007 to +17009
if !same_extent {
queue[index] = event;
true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-review/allow-oversized Allows normal automated review of an oversized pull request kind/protocol Affects RDP or related protocol behavior 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 scope/cross-cutting Spans multiple architectural boundaries scope/ffi Affects native or .NET bindings size/XXL Size: 1300 or more counted lines or 50 or more files

Development

Successfully merging this pull request may close these issues.

3 participants