2010-11-25 62 views
8

我在MFC應用程序中注意到我正在開發一個拖動滾動條以平滑向下滾動文檔的框架,當包含一段文本的塊打開屏幕,但在屏幕外光滑柔滑。調查的性能,我發現單一的CDC::DrawText要求負責文本的段落。這是一個優化的發佈版本。使用Win7 x64上的DrawText性能不佳

我用QueryPerformanceCounter得到的只是的DrawText的通話高分辨率測量,像這樣:

QueryPerformanceCounter(...); 
pDC->DrawText(some_cstring, some_crect, DT_WORDBREAK); 
QueryPerformanceCounter(...); 

文本是unicode,LOREM-存有風格填料,865個字符長,包過7 (Segoe UI,lfHeight = -12,一個標準的正文文本大小)的矩形和字體。從我的測量結果來看,單獨的單獨的平均需要7.5毫秒,而單峯值爲21毫秒。 (注意跟上60Hz的顯示器,你得到約16毫秒,從而使得各更新。)

我試圖做一些改變,以提高性能:

  • 卸下DT_WORDBREAK提高性能,以約1毫秒(約7時間更快),但由於只有一行文本正在屏幕上顯示,並且有超過7行的文字中斷,這似乎暗示了其他地方的瓶頸。
  • 我在透明模式下繪製文本(SetBkMode(TRANSPARENT))。所以我嘗試了一種不透明的模式,用一個堅實的背景填充。沒提升。
  • 我以爲ClearType渲染可能是怪罪。我將字體lfQualityCLEARTYPE_QUALITY更改爲NONANTIALIASED_QUALITY。它看起來像帶有鋒利邊緣的廢物,沒有任何改進。
  • 根據評論建議,我使用的是CMemDC,但是我擺脫了它並做了直接繪圖。它像瘋了一樣閃爍,沒有改善。

這是運行在Windows 7 64位筆記本電腦與英特爾酷睿2雙核P8400 @ 2.26 GHz和4 GB的RAM - 我不認爲它算作一個緩慢的系統。

每次繪製時我都會調用DrawText(),這顯然會影響性能,因爲這樣的函數很慢,尤其是如果幾個文本塊可以同時顯示的話。這足以讓體驗感到呆滯。然而,Firefox可以使用更多的文本在ClearType中呈現像這樣的頁面,並且似乎應對得很好。我究竟做錯了什麼?我如何解決實際DrawText調用的糟糕表現?

+0

如果更改硬件加速,會發生什麼情況? – Dialecticus 2010-11-25 21:15:21

+0

想想在Win7上使用老派GDI(我認爲MFC內部使用)的方式根本就不好。我的建議是轉向GDI +的方式。 (http://msdn.microsoft.com/en-us/library/ms535991(v=VS.85).aspx)。你可以試着告訴我們結果。 – Keynslug 2010-11-25 21:18:34

+0

看過這個嗎? http://blog.m-ri.de/index.php/2009/02/15/slow-drawtext-performance-in-vista-and-windows-7-please-comment/ – 2010-11-25 21:21:10

回答

6

在每次刷新時繪製文本都很浪費。使用雙緩衝,也就是說,繪製一個離屏位圖,然後將其閃爍到屏幕上。然後,對於滾動,只需要根據需要向上或向下複製大部分位圖,然後僅繪製無效區域(在將結果傳送到屏幕之前)。

如果事實證明速度太慢,請將繪製的文本保留在離屏位圖中,然後使用blit而不是繪製。

乾杯&心連心,

2

根據this german blogpost,問題與支持亞洲語言字體有關。如果你在XP中啓用它們,你會得到同樣的perf命中。在Vista/7中,它們默認啓用,您不能關閉它們。

編輯:也許,使用不同的字體可能會有所幫助..(一個不包含亞洲字符)。

2

用戶無法在7毫秒內讀取7行的文本,因此通話本身足夠快。

顯示器的60 Hz刷新率完全不相關。您不需要爲每個幀重新渲染相同的文本。視頻卡會很高興地再次將相同的像素髮送到屏幕上。

所以,我thibk你有另一個問題。你是否想知道滾動文字?請問你真的有問題,而不是假設DrawText是罪魁禍首。

1

爲了打破單詞中斷的文字,DrawText需要反覆嘗試獲取文本塊的寬度,以查看它是否合適,然後取出餘數並完成。每次通話都需要這樣做。如果你的文本不變,這是不必要的開銷。作爲解決方法,您可以自行測量文本並插入臨時換行符,並刪除DT_WORDBREAK標誌。

0

你有沒有考慮的Direct2D/DirectWrite的?

無論如何,它應該更好地工作,如果你只是將文本一次繪製到它自己的內存dc和blit上,直到你想在每次迭代時繪製的dc。