【发布时间】:2011-05-15 21:53:21
【问题描述】:
我注意到在我正在开发的一个 MFC 应用程序中,当拖动滚动条以平滑地向下滚动文档时,当屏幕上显示一个包含大约一段文本的块时,帧速率会下降到断断续续的水平,但当它是丝滑的时候屏幕外。调查性能,我发现单个CDC::DrawText调用了负责文本的段落。这是一个优化的发布版本。
我使用QueryPerformanceCounter 获得了只是 DrawText 调用的高分辨率测量值,如下所示:
QueryPerformanceCounter(...);
pDC->DrawText(some_cstring, some_crect, DT_WORDBREAK);
QueryPerformanceCounter(...);
文本是 unicode,lorem-ipsum 样式填充符,865 个字符长,并在给定矩形和字体(Segoe UI,lfHeight = -12,标准正文文本大小)的情况下环绕 7 位行.根据我的测量,该调用单独平均需要 7.5 毫秒,奇数峰值为 21 毫秒。 (请注意,要跟上 60Hz 的显示器,每次更新需要大约 16 毫秒的时间来渲染。)
我尝试进行一些更改以提高性能:
- 删除
DT_WORDBREAK可将性能提高到大约 1 毫秒(大约快 7 倍),但考虑到只有一行文本出现在屏幕上,并且有超过 7 行断字,这似乎表明我的瓶颈在别处。 - 我在透明模式下绘制文本 (
SetBkMode(TRANSPARENT))。所以我尝试了使用纯色背景填充的不透明模式。没有改善。 - 我认为 ClearType 渲染可能是罪魁祸首。我将字体
lfQuality从CLEARTYPE_QUALITY更改为NONANTIALIASED_QUALITY。它看起来像废话,边缘很锋利,没有任何改进。 - 根据评论建议,我使用的是 CMemDC,但我摆脱了它并直接绘图。它像疯了一样闪烁,没有任何改善。
这是在配备 Intel Core 2 Duo P8400 @ 2.26 GHz 和 4 GB RAM 的 Windows 7 64 位笔记本电脑上运行的 - 我认为它不算是慢速系统。
我每次绘制时都会调用 DrawText(),这显然会影响性能如此缓慢的函数,尤其是当其中几个文本块同时可见时。这足以让体验变得迟缓。然而,Firefox 可以在 ClearType 中呈现这样的页面,其中包含更多文本,并且似乎处理得很好。我究竟做错了什么?如何解决实际 DrawText 调用的性能不佳问题?
【问题讨论】:
-
如果更改硬件加速会发生什么?
-
认为在 Win7 上使用老式 GDI(我认为是 MFC 内部使用)的方式根本不好。我的建议是转向 GDI+ 方式。 (msdn.microsoft.com/en-us/library/ms535991(v=VS.85).aspx)。您可以尝试告诉我们结果。
-
@Keynslug 我严重怀疑 GDI+ 会更好,因为它完全用软件实现,并且一次又一次地表明,它慢得要命。我的建议是更多地研究 Direct2D。那可能会更好。
-
你为什么要每帧都渲染字符串?内存 DC 建议意味着将文本一次渲染到内存 DC,然后每帧一次 blit。
标签: c++ windows performance mfc