我们如何确定WPF使用的是硬件还是软件渲染?
我正在对各种平台上的WPF应用程序进行基准测试,并且我需要一种简单的方法来确定WPF是使用硬件渲染还是软件渲染。
我似乎想起一个确定此问题的电话,但现在无法动手。
另外,是否有一种简单的,基于代码的方法来强制一个渲染管线超过另一个渲染管线?
解决方案
检查RenderCapability.Tier
- http://msdn.microsoft.com/library/ms742196(v=vs.100).aspx
- http://msdn.microsoft.com/zh-CN/library/system.windows.media.rendercapability_members.aspx
[更新]
- RenderCapability.IsPixelShaderVersionSupported-获取一个值,该值指示是否支持指定的像素着色器版本。
- RenderCapability.IsShaderEffectSoftwareRenderingSupported-获取一个值,该值指示系统是否可以在软件中渲染位图效果。
- RenderCapability.Tier-获取一个值,该值指示当前线程的渲染层。
- RenderCapability.TierChanged-在更改当前线程的Dispatcher对象的呈现层时发生。
RenderCapability.Tier >> 16
- 渲染层0-没有图形硬件加速。 DirectX版本级别低于7.0版。
- 渲染层1-部分图形硬件加速。 DirectX版本级别大于或者等于7.0版,并且小于9.0版。
- 渲染层2-大多数图形功能使用图形硬件加速。 DirectX版本级别大于或者等于9.0版本。
或者使用分析工具...
New checkbox was added to tint the target application elements that use SW rendered legacy Bitmap Effects.
基于RenderingTier链接,下面是一些代码:
logger.InfoFormat("WPF Tier = {0}",RenderCapability.Tier / 0x10000); RenderCapability.TierChanged += (sender, args) => logger.InfoFormat("WPF Tier Changed to {0}", RenderCapability.Tier / 0x10000);
我仍在对此进行测试和工作。查看以后的修改/答案,以了解我的发现。
要回答问题的下半部分,我相信没有任何办法真的可以强迫另一种方法。如果可用,将自动使用硬件渲染,否则使用软件。
如果需要在"软件"模式下进行测试,则需要使用规格较低的计算机或者"远程桌面"来查看在另一台计算机上运行的应用程序。除了降低性能/帧率外,两者之间在外观上不应有任何明显的差异。使用RenderCapability类来了解是否应禁用动画或者效果之类的东西以提高性能。
也许以下内容可以帮助解决问题的第二部分,即可以将一个渲染管道强加于另一个管道吗?
我们可以更改注册表设置以禁用硬件加速并强制始终进行软件渲染。我们经常使用它来查看我们遇到的特定问题是否与视频驱动程序有关。作为我正在谈论的示例,请参见WPF论坛帖子。
不过,这里要注意的一件事是……这会影响所有WPF应用程序,实际上仅应将其用于测试目的。
要禁用硬件加速:
[HKEY_CURRENT_USER\Software\Microsoft\Avalon.Graphics] "DisableHWAcceleration"=dword:00000001
要启用硬件加速:
[HKEY_CURRENT_USER\Software\Microsoft\Avalon.Graphics] "DisableHWAcceleration"=dword:00000000
查看此MSDN链接以获取更多信息。
我同意第二个答案,但这只是说一说关于使用硬件渲染运行机器的能力,而不是如果应用程序实际上是硬件渲染的。
我使用画布制作了一个简单的应用程序,然后使用RotateTransform旋转了一个矩形,从而为硬件渲染的应用程序使用了占用大量CPU的方式。该值和" RenderCapability.Tier"值为2,因此有足够的硬件功能可以做到这一点。
那为什么不呢?
.NET 4.0提供了强制使用代码进行软件渲染的功能:
public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { if (WeThinkWeShouldRenderInSoftware()) RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly; } }
有关更多信息,请参见此帖子。