window显示驱动开发—为头装载和专用监视器生成自定义合成器应用(三)

模式配置和枚举的原子状态

Windows.Devices.Display.Core API 旨在确保组合器能够以原子方式获取对各种系统显示状态的访问,并具有明确定义的过期行为。 这一点很重要,因为 GPU 是共享资源,带宽和电源约束非常紧张。 在现代系统中,设备可以随时到达/离开,其他内容可能会影响可用显示模式的列表(例如停靠/取消停靠、睡眠状态、另一个组件更改模式在另一条路径上)。 因此,组合器通过使用 Windows.Devices.Display.Core API 和以下用于配置状态的建议模式,对系统配置的更改具有复原能力非常重要。

因此,Windows.Devices.Display.Core API 提供了一个简单的事务性读取-修改-提交模型,类似于数据库。 客户端可以原子方式读取显示系统中设备的 DisplayState 对象。 所有对象都是不可变的,或者提供定义完善的 API,以便将/提交状态更新回系统。 在调用 DisplayState.TryApply 之前不会进行更改,这会对系统进行"提交"更改。 将更改 提交/应用于 DisplayState 失败,不会造成任何影响,或者应用完整更改成功。

若要利用 API 的原子性功能,请执行以下操作:

  • 在 重试循环中写入任何模式配置逻辑。
  • 请在 模式配置开始时在每个循环内创建新的 DisplayState。
  • 调用 DisplayState.TryApply 时,请使用 FailIfStateChanged 标志来检测系统状态不再与创建 DisplayState 时的状态相同。 这样,你就有机会重试该操作。 如果操作失败并出现 SystemStateChanged,请重试整个循环。

不要 将读取或更改状态的其他 API(DXGI、GDI 等)与使用 Windows.Devices.Display.Core API 混合使用,因为它们可能没有相同的原子性保证。

复制代码
#include <winrt\Windows.Devices.Display.Core.h>
using namespace winrt::Windows::Devices::Display::Core;
...

// Create a DisplayManager
DisplayManager manager = DisplayManager::Create(DisplayManagerOptions::EnforceSourceOwnership);

// Loop around trying to acquire a target and set a mode
bool shouldRetry;
do
{
    shouldRetry = false;

    // ... Find the target that you want to use
    auto targets = manager.GetCurrentTargets();
    DisplayTarget selectedTarget = ...;

    auto stateCreationResult = manager.TryAcquireTargetsAndCreateEmptyState(
        winrt::single_threaded_vector<DisplayTarget>({ selectedTarget }));

    if (stateCreationResult.ErrorCode() != DisplayManagerResult::Success)
    {
        winrt::check_hresult(stateCreationResult.ExtendedErrorCode());
    }

    auto state = stateCreationResult.State();
    DisplayPath newPath = state.ConnectTarget(selectedTarget);

    // ... Configure the path

    auto applyResult = state.TryApply(DisplayStateApplyOptions::FailIfStateChanged);

    if (applyResult.Status() == DisplayStateOperationStatus::SystemStateChanged)
    {
        shouldRetry = true;
    }
    else if (applyResult.Status() != DisplayStateOperationStatus::Success)
    {
        winrt::check_hresult(applyResult.ExtendedErrorCode());
    }

} while (shouldRetry);

以下 API 从系统原子读取状态:

  • DisplayManager
  1. GetCurrentTargets
  2. GetCurrentAdapters
  3. TryReadCurrentStateForAllTargets/TryAcquireTargetsAndReadCurrentState
  • DisplayState
  1. IsStale
  2. TryFunctionalize
  • DisplayPath
  1. FindAllModes
  • DisplayTarget
  1. DisplayTarget.IsStale

以下 API 将状态提交回系统:

  • DisplayManager
  1. TryAcquireTarget ReleaseTarget/ (并使用方法获取目标TryAcquireTargetsAnd*)从系统获取 DisplayTargets 的所有权。
  • DisplayState

TryApply 通过显示驱动程序在系统中所有拥有的目标上设置或清除模式来更新当前系统显示状态。

相关推荐
sukalot16 小时前
windows显示驱动开发-调试间接显示驱动程序(三)
windows·驱动开发
sukalot17 小时前
windows显示驱动开发-间接显示驱动程序
驱动开发
Saniffer_SH1 天前
【高清视频】CXL 2.0 over Fibre演示和答疑 - 将内存拉到服务器10米之外
运维·服务器·网络·人工智能·驱动开发·计算机外设·硬件工程
tt5555555555552 天前
Linux 驱动开发与内核通信机制——超详细教程
linux·驱动开发·b树
sukalot3 天前
windows显示驱动开发-调试间接显示驱动程序(一)
驱动开发
cellurw3 天前
Day52 串口通信原理与IMX6ULL UART驱动开发
驱动开发
深盾科技3 天前
Windows 驱动开发基础
windows·驱动开发·stm32
会跑的葫芦怪3 天前
Gin 框架令牌桶限流实战指南
驱动开发·gin
Nautiluss3 天前
WIN7下安装RTX3050 6GB显卡驱动
人工智能·驱动开发·opencv
小狗爱吃黄桃罐头3 天前
正点原子【第四期】Linux之驱动开发学习笔记-5.1 设备树下的LED驱动实验
linux·驱动开发·学习