Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 启用桌面合成时是否需要双缓冲?_Windows_Composition_Aero_Double Buffering - Fatal编程技术网

Windows 启用桌面合成时是否需要双缓冲?

Windows 启用桌面合成时是否需要双缓冲?,windows,composition,aero,double-buffering,Windows,Composition,Aero,Double Buffering,启用桌面合成时是否仍需要双缓冲 在微软的: 图形设备界面(GDI) Windows Vista和Windows之前的版本 服务器2008,一个窗口句柄(HWND) 直接画在屏幕上, 这有一定的好处,但是 限制了Windows的显示和 管理顶级窗口。在窗户里 Vista和Windows Server 2008,全部 顶级窗口渲染为 屏幕外位图(类似于 WS_EX_LAYERED)和桌面窗口 Manager将图像组合在一起 绘制桌面 听起来所有渲染现在都是对屏幕外位图进行的: 窗口渲染为屏幕外位图

启用桌面合成时是否仍需要双缓冲

在微软的:

图形设备界面(GDI)

Windows Vista和Windows之前的版本 服务器2008,一个窗口句柄(HWND) 直接画在屏幕上, 这有一定的好处,但是 限制了Windows的显示和 管理顶级窗口。在窗户里 Vista和Windows Server 2008,全部 顶级窗口渲染为 屏幕外位图(类似于 WS_EX_LAYERED)和桌面窗口 Manager将图像组合在一起 绘制桌面

听起来所有渲染现在都是对屏幕外位图进行的:

窗口渲染为屏幕外位图

这是正确的吗

我询问的原因是,在标准绘制周期中,我仍然看到闪烁:

  • WM_擦除BKGND
  • WM_涂料
启用桌面合成时:

我想在打电话给

   BeginPaint(hWnd, paintStructure);
   ...
   EndPaint(hWnd, paintStructure);
所有绘画都会发生在后缓冲区:

窗口渲染为屏幕外位图


同时,前端缓冲区将不受影响。

好的,绘制屏幕外位图只会使DWM按自己喜欢的方式合成窗口,而无需等待应用程序重新绘制(例如,在XP中将窗口移到另一个窗口上时就是这种情况)

这并不意味着绘制到屏幕外表面会自动减少闪烁。如果您擦除窗口,然后重新绘制,并且在两个操作之间DWM会重新绘制屏幕(大约每秒60次),那么您当然会看到闪烁

当应用程序重新绘制的速度不够快时,它确实解决了“白色窗口”问题,而且它还减少了由于窗口重叠而导致的重新绘制。但这无助于防止闪烁。DWM无法知道您的绘制操作尚未完成,您希望在再次绘制内容之前显示窗口的旧图像

这是正确的吗

是的(这就是缩略图如何显示当前被遮挡的窗口部分)


DWM对屏幕的渲染是双缓冲的。然而,如果它在擦除和绘制之间占据了缓冲区。。。它将以可见的人工制品的形式出现。所以你仍然需要加倍缓冲。双缓冲发生在桌面上(即,它完全绘制下一个桌面视图,然后翻转),而不是在每个窗口所绘制的屏幕外缓冲区上。

这在Windows 10中发生了变化(至少1903年)

启用DWM后,默认情况下,现在所有内容都正确地进行双缓冲。即使以最基本的方式移动和调整控件大小,重新绘制/调整大小时也不会闪烁


DWM现在似乎只在绘制完成后才显示一个新位图,而不是之前。

你们都指出了同样的问题:这可能使它成为正确的答案。我直接在用于绘画的缓冲区上绘画。如果DWM在我画一半的时候抓住了缓冲区,我会看到画一半的内容。鉴于windows上的画在调用BeginPaint和EndPaint之间被很好地分隔开,你会认为DWM可以知道何时可以安全地抓取更新。它必须跟踪这一点。我怀疑,性能方面的考虑可能放在半绘制内容之上。@Chris:应用程序不需要调用
BeginPaint
EndPaint
。你在描述,一个系统如何在一个完美的世界中实现。这个世界不是这样的。如果你不调用BeginPaint/EndPaint来响应WM_PAINT,事情就会变得很不正常。@Chris:不,它们不会。只要确保通过调用验证脏区域。