本文为个人博客备份文章,原文地址:
http://validvoid.net/win2d-handling-device-lost/
“设备丢失”是指 GPU 设备失效无法继续进行渲染的情况。GPU 硬件故障、驱动程序缺陷、驱动程序软件更新或者从一个 GPU 切换到另一个都可能导致此问题。丢失的设备无法使用,此时任何尝试使用设备的 Win2D 都会引发异常。要解决这一问题,应用必须创建新设备再重新创建所有图形资源。
并非所有应用都需要操心如何解决设备丢失的情况。设备丢失是一种比较少见的情况(但愿如此),所以某些开发者就任由应用在此类情况发生时崩溃了。而本文正是为另一些希望应用足够健壮,能够处理设备丢失问题的开发者准备的。
使用 XAML 控件时设备丢失的处理
Win2D (CanvasControl, CanvasVirtualControl and CanvasAnimatedControl)控件能够代替应用自动应对设备丢失的情况。
当检测到设备丢失,这些控件会重建它们的 CanvasDevice
并触发 CreateResources
事件,传递值为 NewDevice 的 CanvasCreateResourcesReason 类型枚举作为参数。应用应当在该事件的处理逻辑中使用新的设备重建所有图形资源,并更新任何可能包含对旧有失效资源引用的数据结构。
Win2D 控件能够自动捕获并处理在其 CreateResources
、Update
或 Draw
事件处理逻辑中抛出的设备丢失异常。如果你在其它位置调用了 Win2D 绘图 API (比如在鼠标或键盘输入事件处理程序中),请参阅下一节的内容。
手动处理设备丢失
如果你并没有使用 Win2D 的内建控件,或在 CreateResources
、Update
或 Draw
事件处理逻辑之外调用了 Win2D 绘图 API,那么你就需要手动捕获并报告设备丢失异常。这可以通过 IsDeviceLost(Int32) and RaiseDeviceLost() 方法实现:
try { DrawStuff(); } catch (Exception e) where canvasDevice.IsDeviceLost(e.ErrorCode) { canvasDevice.RaiseDeviceLost(); }
调用 RaiseDeviceLost
方法会通知所有使用当前设备的控件启动设备丢失处理逻辑。如果你是从别的某个地方获取的该设备,你需要通过 DeviceLost 事件在设备丢失时进行响应。
如何测试设备丢失的处理情况
要检测你的应用是否正确处理了设备丢失的情况,最简单的办法就是在应用运行期间关闭你的硬件 GPU:
- 打开
设备管理器
(桌面 -> 右键单击此电脑
->属性
->设备管理器
) - 展开
显示适配器
节点 - 右键单击你的 GPU 设备条目,选择
禁用
这样 Windows 就会绕过你的 硬件 GPU,切换到 WARP1 软件渲染设备进行显示渲染,而这期间所有活动应用都会遭遇设备丢失的情况。
别忘记在测试完成后重新启用你的 GPU!如果你想要多次测试设备丢失的情况,最好每次测试都重启应用(启动时确保 GPU 开启)。在应用运行期间反复开关 GPU 并不一定会反复引发设备丢失,因为在此期间系统可能持续使用 WARP 软件设备进行渲染。
在测试应用处理设备丢失的同时,最好也确保应用能够正确处理显示设备 DPI 的动态改变。
- 译注:WARP 全拼 Windows Advanced Rasterization Platform,即Windows 高级光栅化平台,详情可参阅"Windows Advanced Rasterization Platform (WARP) Guide" ?