This document compares NVIDIALibrary and IntelLibrary in terms of orchestration style, object model shape, and settings-application flow. It intentionally focuses on structure and behavior patterns, not vendor-specific API calls.
IntelLibrary is already close to NVIDIALibrary in lifecycle shape (CreateDefaultConfig, UpdateActiveConfig, GetActiveConfig, SetActiveConfig, SetActiveConfigOverride) and logging style.
The major remaining gap is model normalization:
NVIDIALibrarypersists mostly capability-gated DTO settings.IntelLibrarystill persists a mixed model (DTOs plus many native interop structs) inINTEL_DISPLAY_WITH_SETTINGS.
The IGCLWrapper library has been completely rewritten with a three-layer DTO-first facade: IGCLApi (low-level native interop) → IGCLApiHelper / IGCLAdapterHelper (mid-level adapter facades) → IGCLDisplayHelper and per-feature helpers (display and feature operations). All public wrapper methods now return DTOs; native structs are confined to private helper methods and explicitly-named *Native() overloads for advanced callers.
IntelLibrary has been updated to use this wrapper hierarchy for all IGCL operations. No direct IGCL native calls remain in IntelLibrary; all access is through IGCLApiHelper, IGCLAdapterHelper, and IGCLDisplayHelper.
The adapter/display enumeration and stable-key lookup pipeline in SetActiveConfigOverride has also been implemented. The remaining gaps — inline per-feature apply blocks, mixed native struct persistence in INTEL_DISPLAY_WITH_SETTINGS, and initialization/error policy alignment — are still open.
NVIDIA pattern:
- Per-display config is capability-gated (
HasX) plus typed setting payload (XData). - Adapter-level and display-level data are clearly separated.
- Top-level config includes global profile domains (for example Mosaic and DRS).
Intel pattern:
- Per-display config includes both business settings and many native transport/intermediate structs.
- Adapter/display separation exists, but display struct still carries boundary-level native fields.
- Combined display is handled, but there is no generalized top-level profile bucket like NVIDIA's Mosaic/DRS split.
Impact:
- Intel serialization and equality are heavier and less stable than NVIDIA's DTO-first approach.
NVIDIA pattern:
- Build helper lookups once.
- For each target display: fetch active, compare target vs active, apply only diffs.
- Uses consistent per-feature "is supported / is different / apply / log" blocks.
Intel pattern:
- Enumeration and helper creation use the
IGCLApiHelper/IGCLAdapterHelper/IGCLDisplayHelperwrapper chain; no direct IGCL native calls remain inIntelLibrary. - Adapter/display lookup in
SetActiveConfigOverridebuilds a stable display device ID key per display (VEN_xxxx&DEV_xxxx&REV_xx-PORT_xx), then usesTryGetValueagainst both stored and current config snapshots. - Application logic remains fully inline per-feature in
SetActiveConfigOverride; no extracted helper methods exist yet. - An inline local function
IsUnsupportedResult()consistently classifies unsupported IGCL result codes within the apply loop.
Impact:
- Intel behavior is functional and the enumeration/lookup pipeline is clean, but per-feature apply blocks are still inline and not reusable.
NVIDIA pattern:
- In non-initialized paths, often logs and returns false.
Intel pattern:
- In some non-initialized set paths, throws
IntelLibraryException.
Impact:
- Cross-vendor behavior diverges for callers that rely on consistent failure semantics.
NVIDIA pattern:
- Uses DTO/value-object comparisons and capability flags to limit comparisons to meaningful domains.
Intel pattern:
- Equality and hash include many native/native-array fields in
INTEL_DISPLAY_WITH_SETTINGS.
Impact:
- Higher chance of noisy profile mismatch and brittle persistence behavior in Intel.
Target pattern per setting:
IsSupportedXXSettingsDto
Keep native structs only at call boundaries (local variables used to call IGCL), not in persisted display config structs.
Current progress:
DisplayTimingis now DTO-based (DisplayTimingDto).- The
IGCLWrapperpublic API is fully DTO-first; all get/set operations return or accept DTOs. - Most settings domains in
INTEL_DISPLAY_WITH_SETTINGSnow have DTO-based fields (ScalingSettingsDto,SharpnessSettingsDto,RetroScalingSettingsDto,DceArgsDto,PowerOptimizationSettingsDto,LaceConfigDto,SwPsrSettingsDto,WireFormatConfigDto,DisplaySettingsDto,DisplayPropertiesDto,AdapterDisplayEncoderPropertiesDto,IntelArcSyncMonitorParamsDto,GenlockArgsDto).
Next goal:
- Remove the remaining native struct fields that are still persisted in
INTEL_DISPLAY_WITH_SETTINGS:ctl_scaling_caps_t ScalingCaps,ctl_sharpness_caps_t SharpnessCaps,ctl_sharpness_filter_properties_t[] SharpnessFilterProperties,ctl_retro_scaling_caps_t RetroScalingCaps,ctl_power_optimization_caps_t PowerOptimizationCaps,ctl_intel_arc_sync_profile_params_t IntelArcSyncProfile,ctl_get_set_custom_mode_args_t CustomModeArgs,ctl_custom_src_mode_t[] CustomModes,ctl_lda_args_t LinkedDisplayAdaptersArgs,IntPtr[] LinkedDisplayAdapters,ctl_mux_properties_t MuxProperties,IntPtr[] MuxDisplayOutputs,ctl_vblank_ts_args_t VblankTimestamp,ctl_get_brightness_t Brightness. - Move these to transient runtime variables only (not persisted in the display config struct).
Steps 1–3 are now implemented in SetActiveConfigOverride:
- ✓ Build adapter/display helper map — uses
IGCLApiHelper.EnumerateAdapters()andadapter.EnumerateDisplayOutputs(). - ✓ Resolve stored config entry by stable key — constructs a
VEN_xxxx&DEV_xxxx&REV_xx-PORT_xxkey and usesTryGetValue. - ✓ Resolve current config entry — snapshots
currentDisplayConfigviaGetIntelDisplayConfig()at method entry and resolves per display viaTryGetValue. - ✗ Apply per-feature through a common extracted helper pattern — all feature apply blocks are still inline; extracting these into private helper methods remains to be done.
This mirrors NVIDIA's maintainable "lookup then apply" orchestration.
Centralize result handling for:
- unsupported feature
- unsupported version
- invalid operation
- invalid arguments
Use a single helper for consistent skip/log behavior across all feature blocks.
Pick one policy and apply consistently:
- either return false and log
- or throw for all set/apply entry points
Recommended for alignment with NVIDIA style: return false + log in operational methods.
For profile matching behavior, prefer comparing persisted capability-gated settings rather than internal/native transport details.
- Model cleanup pass
- Keep only persisted settings domains in
INTEL_DISPLAY_WITH_SETTINGS. - Move native-only transport fields behind runtime helper methods or transient locals.
- Apply-flow helper extraction pass
- Extract repeated compare/apply blocks into private methods with a consistent signature.
- Unsupported-result policy pass
- An inline local function
IsUnsupportedResult()already handles detection and skip logging withinSetActiveConfigOverride. Promote it to a class-level private helper so it can be reused bySetActiveConfigand any future apply methods.
- Initialization/failure policy pass
- Normalize return/throw behavior in
SetActiveConfigandSetActiveConfigOverride.
- Equality/hash stabilization pass
- Align comparisons with persisted settings semantics.
- Final consistency pass
- Ensure logging conventions, naming, and per-setting gating follow one pattern end to end.
- This comparison deliberately excludes vendor API parity concerns.
- The goal is operational similarity in structure, call flow, object modeling, and maintainability.
Status legend:
- completed
- not started
- Fix CombinedDisplay child list usage to match DTO list shape.
- Fix OsDisplayEncoderIdentifierDto property naming usage (WindowsDisplayEncoderId).
- Convert DisplayTiming persistence to DisplayTimingDto.
- Rewrite IGCLWrapper with DTO-first public API (IGCLApi / IGCLApiHelper / IGCLAdapterHelper / IGCLDisplayHelper three-layer hierarchy).
- Update IntelLibrary to use IGCLWrapper helper hierarchy for all IGCL operations; no direct native IGCL calls remain.
- Define a persisted-settings-only target shape for INTEL_DISPLAY_WITH_SETTINGS.
- Mark native-only fields as runtime/transient concerns (no profile persistence intent).
- Keep capability gates consistent per setting domain (IsSupportedX + X settings).
- Ensure constructor defaults align to the normalized model.
- Build a reusable display-helper lookup step in SetActiveConfigOverride.
- Standardize stored/current lookup and skip rules per display.
- Extract per-feature apply blocks into private helper methods.
- Keep one compare/apply flow shape for all settings domains.
- Centralize unsupported-result classification helper (currently an inline local function in
SetActiveConfigOverride; needs promotion to a class-level private method for broader reuse). - Use shared unsupported handling in every feature apply block.
- Keep unsupported outcomes as skip + trace unless severity requires warning/error.
- Decide cross-vendor policy for non-initialized set paths.
- Apply the same policy across SetActiveConfig and SetActiveConfigOverride.
- Align logging level and message format with chosen policy.
- Restrict equality/hash to persisted, meaningful settings domains.
- Avoid transport-only/native state creating false mismatch noise.
- Verify profile matching behavior remains deterministic after reboot/apply cycles.
- Ensure naming and per-feature gating are uniform across Intel paths.
- Remove duplicated compare/apply patterns no longer needed after helper extraction.
- Final pass on trace/warn/error consistency.
Suggested branch name:
- develop/intel-alignment-with-nvidia-flow
Suggested commit plan:
- Commit: Intel DTO baseline alignment ✓ COMPLETE
- IGCLWrapper rewritten with DTO-first public API (three-layer hierarchy).
- IntelLibrary updated to use IGCLWrapper helper hierarchy; no direct native calls remain.
- Baseline fixes (list shape, encoder id property, DisplayTiming DTO) also complete.
- Adapter/display enumeration and stable-key lookup pipeline in SetActiveConfigOverride complete.
- Commit: Intel model normalization scaffold
- Remove remaining native struct fields from INTEL_DISPLAY_WITH_SETTINGS.
- Move caps and transport-only structs (ScalingCaps, SharpnessCaps, SharpnessFilterProperties, RetroScalingCaps, PowerOptimizationCaps, IntelArcSyncProfile, CustomModeArgs, CustomModes, LinkedDisplayAdaptersArgs, LinkedDisplayAdapters, MuxProperties, MuxDisplayOutputs, VblankTimestamp, Brightness) to transient runtime variables only.
- Commit: Intel apply pipeline helpers
- Helper lookup and stored/current key resolution are complete.
- Remaining: extract inline per-feature apply blocks into private helper methods with a consistent signature.
- Commit: Intel unsupported result normalization
- Unsupported-result handling is already consistent across all feature blocks via inline local function.
- Remaining: promote inline
IsUnsupportedResult()to a class-level private helper for broader reuse.
- Commit: Intel initialization/error policy alignment
- Unify non-initialized behavior and logging strategy in apply entry points.
- Commit: Intel equality and hash stabilization
- Refocus equality/hash to persisted settings semantics.
- Commit: Intel final consistency cleanup
- Naming, logging consistency, and duplicate code cleanup pass.
- PR 1: Model + constructor normalization only.
- PR 2: Apply helper extraction only.
- PR 3: Error-policy and unsupported handling alignment.
- PR 4: Equality/hash stabilization and cleanup.
This sequence keeps risk lower by separating data-model changes from application-flow refactors.