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

相关推荐
世微 如初13 天前
AP5125大功率LED恒流驱动实战:地摊灯项目从原理图到调试笔记
驱动开发·芯片·led电源驱动·降压恒流ic
ScilogyHunter13 天前
Zephyr串口驱动开发及构建完全指南
驱动开发·uart·zephyr
_Emma_13 天前
【DRM&Graphic】Linux图形与显示框架
linux·驱动开发·图形渲染·显示器
董厂长13 天前
Loop Engineering:停止手动提示,开始设计自动提示的系统
大数据·人工智能·驱动开发·llm
Saniffer_SH14 天前
【高清视频】Gen6 服务器还没到,Gen6 SSD 怎么测?Emily 现场演示三种测试环境
人工智能·驱动开发·测试工具·缓存·fpga开发·计算机外设·压力测试
暮云星影14 天前
全志linux开发屏幕适配(二)`HDMI`驱动适配说明
linux·arm开发·驱动开发
charlie11451419114 天前
嵌入式Linux驱动开发——从轮询到中断
linux·开发语言·驱动开发·嵌入式
暮云星影14 天前
瑞芯微rk3566开发FIT Secure Boot
linux·arm开发·驱动开发·安全
暮云星影14 天前
全志linux开发 USB接口设置
linux·arm开发·驱动开发
sukalot14 天前
windows显示驱动开发-CCD DDI的其它技术
windows·驱动开发