我正在阅读Larry Osterman关于debugging a flickering problem in the Windows Vista/7 volume control的最新博客文章,我突然意识到我记不起在我的OS X笔记本电脑上看到应用程序闪烁了。即使是看起来写得不好的应用程序也可以避免我的经验中的闪烁问题。如果没有这个转变为Apple vs Windows辩论(请),为什么OS X应用程序似乎没有同样的闪烁问题?
我很难相信Apple开发人员在编程无闪烁的GUI时非常惊人,而Windows程序员很糟糕,所以原因是什么? OS X API是否需要所有GUI来实现双缓冲?虽然有些应用程序具有稍微缓慢的双缓冲调整大小行为,但许多应用程序没有,并且它们仍然避免闪烁。 OS X重绘流程是否与Windows有根本的不同,完全避免了WM_ERASEBKGRND
问题?还是有其他可能性,我没有看到?
更新:感谢您的回答。我希望我能同时选择ken和cb160的答案,因为它们都很有帮助。
答案 0 :(得分:16)
Mac OS X有double buffered windows。
您无需做任何事情来实现它。它在幕后。
当某些内容发生变化时,你(几乎总是)没有明确地绘制到Cocoa中的窗口,这会使窗口区域无效。该框架稍后将下降视图的层次结构,并将窗口的脏区域绘制到辅助缓冲区中。然后它交换缓冲区。
你可以选择做一些允许框架在重绘时采用快捷方式的承诺,但它们都是选择加入的。只有精明的观点才会受到影响。
如果NSView的子类实现isOpaque
方法返回YES,那么框架将永远不会清除视图后面的任何内容或绘制其下的任何视图。
实现preservesContentDuringLiveResize
以返回YES会给您一些额外的责任,但可以在窗口大小调整期间提高性能。
10.6添加了另外两种新的此类API layerContentsRedrawPolicy
和layerContentsPlacement
。
最后,自定义绘图不如Windows上常见。您看到的大多数视图都是框架提供的而不是子类。框架提供的方法是通过apple优化的。
答案 1 :(得分:10)
Windows Vista / 7和OSX都使用合成引擎在屏幕上绘制光栅化的位图。这些合成引擎负责处理所有窗口的输出并绘制最终的屏幕图像。这种合成方法是OSX能够在最小化码头时使用精灵效果以及航空器如何绘制半透明边界。它们还可以防止闪烁,就像填充屏幕特定区域的位图不可用一样,它将使用已经存在的图像而不是绘制空白区域。
自首次发货以来,OSX已经有了一个合成引擎。当时很多人虽然这是一个疯狂的appraoch,因为当时出货的所有视频卡都经过优化以绘制位图(即窗口按钮和边框)而不是合成图像。在OSX的后续版本中,合成被推送到GPU(在Quartz Extreme中),因此大大减轻了CPU的负担并使更多的效果成为可能。
因为Windows合成器只是在Windows Vista中添加,然后才有可用的GPU并且你拥有正确版本的操作系统,所以它并不像OSX中的Quartz Compositer那样具有普遍性。由于合成器并不总是在Windows中使用,因此当区域被消隐并且负责绘图的应用程序无法足够重新绘制区域时会发生闪烁。
答案 2 :(得分:1)
是的,它都是自动双缓冲的。当然,如果你在跑 来自mac os 9的遗留代码,或者从windoze移植的代码,这意味着你是 可能三倍缓冲而不知道它。嘿,周期很便宜!