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 通过显示驱动程序在系统中所有拥有的目标上设置或清除模式来更新当前系统显示状态。

相关推荐
进击的小头20 小时前
20_第20篇:嵌入式外设驱动开发基础:寄存器级开发与库函数开发对比实战
arm开发·驱动开发·单片机
低调小一20 小时前
BDD(行为驱动开发)入门:把“测试”写成“行为”,把“需求”写成“场景”
驱动开发·tdd·bdd
charlie11451419121 小时前
嵌入式Linux驱动开发(7) 从虚拟设备到真实硬件 —— LED驱动硬件基础
linux·开发语言·驱动开发·内核·c
莎士比亚的文学花园1 天前
Linux驱动开发(2)——驱动编程
linux·运维·驱动开发
2601_949695591 天前
开源AI智能体OpenClaw接入DeepSeek V4全流程:从配置到成本
人工智能·驱动开发·ai·电脑
枳实-叶1 天前
【Linux驱动开发】第二天:内核模块生命周期+内存分配全解
linux·驱动开发
嵌入式小企鹅1 天前
CPU需求变化、RISC-V安全方案、DeepSeek V4适配、太空算力动态
人工智能·驱动开发·华为·开源·算力·risc-v
智者知已应修善业2 天前
【触发器种类和真值表】2023-7-5
驱动开发·经验分享·笔记·硬件架构·硬件工程
枳实-叶2 天前
【Linux驱动开发】第一天:用户态与内核态通俗讲解+最简字符设备驱动实战
linux·驱动开发·学习
nix.gnehc3 天前
读懂 OpenSpec:AI 编码时代的规范驱动开发新范式
人工智能·驱动开发·sdd·openspec