我有一个Win32非游戏窗口应用程序,该应用程序使用Direct2D设备上下文/ HWND渲染目标绘制窗口。当前,它使用具有DXGI_SWAP_EFFECT_DISCARD
交换效果的DXGI交换链。
微软建议使用新的翻盖机型交换效果,无论是DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
或DXGI_SWAP_EFFECT_FLIP_DISCARD
。我对使用它们感兴趣,主要是因为它们允许我在调用时指定脏矩形列表Present1()
,这将改善性能/功耗。
只需将其更改为SwapEffect
新的翻转模型值中的任意一个,就会产生奇怪的(但实际上是预期的)结果,即每隔一帧绘制一个黑色窗口,并且在屏幕上可见先前帧的伪像。
所以问题是:在这种情况下是否可以使用新的翻转模型交换效果?如果是,应该如何设置?
鉴于应用程序需要将脏矩形绘制到其他有效缓冲区中,因此似乎正确的方法将涉及维护两个内容基本相同的缓冲区(一个用于绘制,一个用于提供给DWM进行合成),因此不确定在没有完全重画每一帧的应用中是否可以通过这种方式获得任何性能提升。但是也许我错过了一些重要的事情。
交换链当前设置如下:
swapChainDesc.Width = ...;
swapChainDesc.Height = ...;
swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
swapChainDesc.Stereo = false;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 1;
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
swapChainDesc.Flags = 0;
编辑1
事实证明,DXGI_SWAP_EFFECT_DISCARD
强制BufferCount
为1,所以我的初始值2有点误导,因为只使用了一个缓冲区。来源(第三评论)。
此外该文档的DXGI_SWAP_EFFECT
说不说UWP应用被迫进入翻转模式,所以这应该是一个可以解决的问题。
有两种方法可以做到这一点。
第一种方法是增加能源使用量。您可以将内容绘制到中间缓冲区/渲染纹理中,然后在每次出现之前将其复制到swapchain。这样,您实际上只能渲染中间缓冲区中已更改的部分,而不必关心交换链的状态是什么。
第二种方法较为复杂,但可以产生最佳的能源使用。您可以直接绘制到交换链缓冲区中,而不是使用中间缓冲区并仅绘制自上一帧以来的变化。为了使它正常工作,您不需要重绘当前帧与最后一帧之间的变化,而是重绘当前帧与(当前-BufferCount)帧之间的变化。例如:
框架1-在(200 x 200)处绘制尺寸为(150 x 150)的绿色矩形。脏区是整个帧,因为它是第一帧。
框架2-您在(250 x 250)处绘制了一个尺寸为(50 x 50)的蓝色矩形。脏区是(250、250、300、300)。
框架3-在(225 x 225)处绘制尺寸为(50 x 50)的红色矩形。脏区是(225、225、50、50)。
如果您的缓冲区数为2,则意味着绘制第3帧时,不仅需要重绘(225,225,50,50)的脏区域,而且还需要重绘(250,250,300,300)的脏区域。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句