IddCx 1.4 updates for remote IDDs
The following updates to IddCx version 1.4 apply to remote indirect display drivers (IDDs) only.
Remote IDD developers should also see IddCx 1.4 updates for console and remote IDDs for additional updates.
Declare a remote IDD for remote sessions
An IDD declares it wants to create a remote ID adapter by setting the IDDCX_ADAPTER_FLAGS_REMOTE_SESSION_DRIVER bit in the IDDCX_ADAPTER_CAPS.Flags field when calling IddCxAdapterInitAsync. The OS tracks whether the IDD is being loaded due the remote desktop stack connecting to a remote session and will fail the IddCxAdapterInitAsync call in the following two cases:
- The IDD did not set IDDCX_ADAPTER_FLAGS_REMOTE_SESSION_DRIVER for a device that was create by the OS remote desktop stack for a remote session
- The IDD set IDDCX_ADAPTER_FLAGS_REMOTE_SESSION_DRIVER for a device that was not created by the OS remote desktop stack
Installation recommendations for remote IDDs
UMDF allows drivers to control the device pooling option in their INF files, using directives such as UmdfHostProcessSharing and DeviceGroupId. Due to some lock contention issues, it is highly recommended that remote IDDs set the UmdfHostProcessSharing directive to ProcessSharingDisabled and remove any DeviceGroupId directives. This setting will configure the remote IDD for each session to be in its own process.
Additional restrictions on existing IddCx features for remote IDDs
Remote IDDs are required to set IDDCX_ADAPTER_FLAGS_USE_SMALLEST_MODE in the IDDCX_ADAPTER_CAPS.Flags field. This ensures that virtual modes are not used and hence the swapchain size will always match the desktop resolution. IddCxAdapterInitAsync will fail if this flag is not set.
Only progressive target modes are supported for remote IDDs, so IDDCX_TARGET_MODE.TargetVideoSignalInfo.targetVideoSignalInfo.scanLineOrdering must be set to DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE. IddCxMonitorArrival will fail if this value is not set.
Set the display configuration for the remote session
As the remote IDDs control all the monitors in a remote session, and the remote session display configuration should mirror that of the client, a remote IDD needs the ability to specify the display configuration that the OS will set in the remote session. This display configuration needs to be set when the session is either created as a remote session or transitioned to a remote session.
The remote IDD can update the display configuration during a remote session to either:
- Change the setting for current monitors (for example, change desktop position, orientation, physical size or DPI)
- Set the desktop configuration after monitors are added/removed, by calling IddCxMonitorArrival/IddCxMonitorDeparture. Remote IDDs use IddCxMonitorArrival and IddCxMonitorDeparture in the same way as console IDDs to inform the OS about monitor arrivals and departures.
Below is the logic the OS uses to process monitor arrivals, departures, and desktop configuration changes. For each remote session, the OS will store a single current desktop configuration provided by the remote IDD. This desktop configuration will start empty and will be updated every time a remote IDD successfully calls IddCxDisplayConfigUpdate.
When the driver receives a new display configuration
If all monitors in the new display configuration are present in the system
If new display configuration is supported by driver (eg resolutions)
Store new display configuration
Set new display configuration (this will disable any active monitors
that are not part of new configuration)
If all monitors in the new display config are not currently present in the system
Store new display configuration
Disable all active paths and wait for the correct set of monitors to arrive
When a monitor is removed
If removed monitor is not in the current display configuration
Remove the monitor and do not change the current desktop configuration
If removed monitor is part of the current display configuration
Remove the monitor
Disable all active paths and wait for the correct set of monitors to arrive
When a monitor arrives
If added monitor is not part of current display configuration
Do not change the display configuration
If added monitor is part of the current display configuration
If now all the monitors in the current display configurations are present
Set the new display configuration
Below are some simple scenarios to illustrate how IddCxDisplayConfigUpdate can be used.
Scenario 1: A new session starts with two monitors connected
Driver action | Current display topology | Currently connected monitor | Currently active monitors | Notes |
---|---|---|---|---|
None | None | None | Session start configuration | |
IddCxMonitorArrival(Mon1) | None | Mon1 | None | No active display configuration, so nothing changes |
IddCxMonitorArrival(Mon2) | None | Mon1, Mon2 | None | Still no change in display config |
IddCxDisplayConfigUpdate | Mon1, Mon2 | Mon1, Mon2 | Mon1, Mon2 | As all monitors are connected, set the configuration |
NOTE: The driver could have called IddCxDisplayConfigUpdate before adding the monitors for the same result.
Scenario 2: Add a third monitor to Scenario 1 and make it active
Driver action | Current display topology | Currently connected monitor | Currently active monitors | Notes |
---|---|---|---|---|
IddCxMonitorArrival(Mon3) | Mon1, Mon2 | Mon1, Mon2, Mon3 | Mon1, Mon2 | No change to display configuration |
IddCxDisplayConfigUpdate | Mon1, Mon2, Mon3 | Mon1, Mon2, Mon3 | Mon1, Mon2, Mon3 | New configuration set |
Scenario 3: Remove a monitor from an active configuration
Driver action | Current display topology | Currently connected monitor | Currently active monitors | Notes |
---|---|---|---|---|
Mon1, Mon2 | Mon1, Mon2 | Mon1, Mon2 | Starting configuration | |
IddCxDisplayConfigUpdate() | Mon1 | Mon1, Mon2 | Mon1 | Change configuration to use Mon1 only first |
IddCxMonitorDeparture(Mon2) | Mon1 | Mon1 | Mon1 |
Scenario 4: Changing the mode of a path when the driver only supports a single mode
Driver action | Current display topology | Currently connected monitor | Currently active monitors | Notes |
---|---|---|---|---|
Mon1 10x7 , Mon2 19x10 | Mon1, Mon2 | Mon1, Mon2 | Starting configuration | |
IddCxMonitorUpdateModes(Mon1 supports 16x9) | None | Mon1, Mon2 | None | Updated mode list for Mon1 to 16x9 |
IddCxDisplayConfigUpdate() | Mon1 16x9, Mon2 19x10 | Mon1, Mon2 | Mon1, Mon2 | Set config for Mon1 to 16x9 |
Handling IddCxDisplayConfigUpdate errors
The remote driver needs to handle errors from IddCxDisplayConfigUpdate. Some errors are expected; for example, when the connection was using a temporary session.
In unexpected cases in the initial configuration, the driver has options such as:
- Call IddCxReportCriticalError to terminate the driver process and disconnect the user session. It is recommended that the driver use a unique major/minor combination so these cases can be identified in crashes and Watson reports.
- Retry the configuration again in the event that it was a transient error.
- Try a different configuration.
A remote driver might decide that mid-session configuration change failures are not as critical as initial configuration failures, and hence might never call IddCxReportCriticalError mid-session.
The driver should not call IddCxReportCriticalError if IddCxDisplayConfigUpdate returns STATUS_GRAPHICS_INDIRECT_DISPLAY_DEVICE_STOPPED as a result of the OS detecting that the target session is being disconnected or the IddCx adapter for that session is being stopped, because this is expected.
Display API changes in an indirect display remote session
In a remote XDDM session, the OS display control panel does not provide the user with any controls to change the display configuration. This is primarily because the remote session desktop configuration is controlled by the connecting client system, and not by applications running in the session. For example, supporting the Win+P projection user interface does not make sense in a remote session.
In general for remote ID sessions:
- Display enumeration APIs work, including QueryDisplayConfig
- Display setting APIs do not function. For example, it is not desirable for an application running in the remote session to call ChangeDisplaySettings/SetDisplayConfig to change the desktop configuration (for example, change the desktop position or topology).
Interestingly, remote XDDM solutions use ChangeDisplaySetting to change modes and desktop positions as that is the only way changes from the client can be applied. Since remote ID solutions have IddCxDisplayConfigUpdate functionality, ChangeDisplaySetting is no longer required to function in remote ID sessions.
The following table shows the APIs and display control panel (CPL) functionality in a XDDM remote session and a WDDM remote session.
API/CPL | XDDM remote session | WDDM remote session |
---|---|---|
Display CPL | No information is displayed and a message saying 'The Display Settings cannot be changed from a remote session' is issued. | Same behavior as an XDDM remote session. |
Win+P UI and functionality | The UI is not shown and API fails. | Same behavior as an XDDM remote session. |
Legacy display enum APIs (such as EnumDisplaySettings & EnumDisplayDevices) | The API works as expected and returns relevant information. | Same behavior as an XDDM remote session. |
Legacy ChangeDisplaySetting | Works and is used to reflect desktop changes from the client. | Returns success for application compatibility reasons, but ignores the call and does not change any display configuration. The IDD will use IddCxDisplayConfigUpdate to change the desktop configuration. |
QueryDisplayConfig | Fails. | Works as expected. |
DisplayConfigGetDeviceInfo | Fails. | Works and reports the expected information. |
SetDisplayConfig and DisplayConfigSetDeviceInfo | Fails. | Same behavior as an XDDM remote session. |
Monitor idle behavior in an ID remote session
When the protocol stack calls IWRdsProtocolConnectionCallback::StopScreenUpdates to stop updating the client screen, the OS destroys the swapchains and makes all the paths for that session inactive, resulting in the IDD's EVT_IDD_CX_ADAPTER_COMMIT_MODES callback being called with IDDCX_PATH_FLAGS_NONE set in IDDCX_PATH.Flags for all the paths.
When the protocol stack calls IWRdsProtocolConnectionCallback::RedrawWindow to enable updates again, the OS sets new active paths using the IDD's EVT_IDD_CX_ADAPTER_COMMIT_MODES callback, and new swapchains will be created.
Disconnect behavior in an ID remote session
When the user disconnects from a remote session, the OS destroys the devnode hosting the remote ID device for that session, resulting in the remote ID adapter for that session being PnpStopped. UMDF will call the remote IDD's EVT_WDF_DEVICE_D0_EXIT callback.
If the session is connected to again remotely, the OS will create a new devnode for the remote IDD for that session. The remote IDD should go through the normal start-up sequence again, initialization the adapter and then adding monitors etc.