WinAPIのExtTextOutW関数を呼び出すと、クリップされたテキストを高解像度ビットマップ(2560x1440/3840x2160)に描画すると、Windowsの更新後に〜x50のパフォーマンスが得られます10のクリエイター版のアップデート。私のユーザーのテストとデバッグログからは、ビットマップやフォントサイズのわずかな違いがパフォーマンスヒットを引き起こす可能性があります。ここでWindowsクリエーター版更新後のQHD/4K画面でのExtTextOutW x50パフォーマンスの低下
はパフォーマンスヒットを示すデバッグログです:
10/05/2017 15:51:50 [ 63227,186] : Calculate Rect
10/05/2017 15:51:50 [ 63227,190] : Rect : Left=263, Top=504, Right=3561, Bottom=2155
10/05/2017 15:51:50 [ 63227,193] : Set Shadow Color
10/05/2017 15:51:50 [ 63227,198] : Render Text Shadow
10/05/2017 15:51:50 [ 63236,650] : Set Text Color
10/05/2017 15:51:50 [ 63236,661] : Render Text "Kingdom come Deliverance"
10/05/2017 15:51:50 [ 63246,062] : Rendering complete
ログから見ることができるように、この同じコールの前クリエイターに1msの下にもかかっている間、ExtTextgOutWへの単一の呼び出しが〜の9.5msを取ります更新。このコードは、Y-のわずかな違いで二回同じテキストを描画することにより、非常に単純なドロップシャドウ効果を行い
{$IFDEF TEXTRENDERTRACE}DebugMsgFT('c:\log\.TextRender.txt','Calculate Rect');{$ENDIF}
cRect := Rect(X,Y,Width+X,MainForm.Monitor.Height-(1+(MainForm.Monitor.Height div 540)));
{$IFDEF TEXTRENDERTRACE}DebugMsgFT('c:\log\.TextRender.txt','Rect : Left='+IntToStr(cRect.Left)+', Top='+IntToStr(cRect.Top)+', Right='+IntToStr(cRect.Right)+', Bottom='+IntToStr(cRect.Bottom));{$ENDIF}
{$IFDEF TEXTRENDERTRACE}DebugMsgFT('c:\log\.TextRender.txt','Set Shadow Color');{$ENDIF}
srcColor := txtCanvas.Font.Color;
txtCanvas.Font.Color := OutLineColor;
{$IFDEF TEXTRENDERTRACE}DebugMsgFT('c:\log\.TextRender.txt','Render Text Shadow');{$ENDIF}
Windows.ExtTextOutW(txtCanvas.Handle,X ,Y+(MainForm.Monitor.Height div 540),ETO_CLIPPED,@cRect,@S[1],I,nil);
{$IFDEF TEXTRENDERTRACE}DebugMsgFT('c:\log\.TextRender.txt','Set Text Color');{$ENDIF}
txtCanvas.Font.Color := srcColor;
{$IFDEF TEXTRENDERTRACE}DebugMsgFT('c:\log\.TextRender.txt','Render Text "'+S+'"');{$ENDIF}
Windows.ExtTextOutW(txtCanvas.Handle,X ,Y ,ETO_CLIPPED,@cRect,@S[1],I,nil);
{$IFDEF TEXTRENDERTRACE}DebugMsgFT('c:\log\.TextRender.txt','Rendering complete'+CRLF);{$ENDIF}
:ここ
を使用すると、上記のデバッグ出力に比較することができ、実際のコードですオフセットと色。 http://forum.inmatrix.com/index.php?showtopic=14995&page=2私たちは、DPIでテスト100に設定します。ここでは
は、(追加のデバッグログがポストに含まれている)私たちは、ハードウェアの多種多様な問題をデバッグしようとする私のフォーラムのユーザーとの完全な説明であります%をクリックして、トリガがクリエイターエディションで導入されたDPIの変更に関連していないことを確認します。これをトリガーするものは誰でも知っていますか?回避策がありますか?
*****更新1 *****
少なくとも最初のテストでは、「DrawTextExW」も性能低下の影響を受けているようです。テスト中に使用されているフォントはArialであり、パフォーマンス問題はフォントのサイズに関連しているように見えます。ユーザーが画面にサイズの小さい行を追加するとテキストがより低い解像度でレンダリングされるためパフォーマンスが大幅に向上します。
*****更新2 *****
私はあなたがこのGitHubのリポジトリに見つけることができますこの問題をプロファイリングするための小さなツールを書いた: https://github.com/bLightZP/WindowsTextRenderingProfiler
問題が依存しているようですたとえば、2560x1440スクリーン上のフォントサイズを「Arial」フォントテキストのサイズを「35」21msにレンダリングし、「34」サイズでレンダリングするには2msを要した。
これは32ビットピクセル形式のDelphi TBitmapのHDCにレンダリングされ、クリッピングを無効にするだけでパフォーマンスにはほとんど影響しません。以下
*****更新3 *****
セバスチャンZの答えは、パフォーマンスの前クリエイター版の水準を回復し、私は彼の答えを反映するためのGitHub上のサンプルコードを更新しましたが、私は持っていますWindows 7の64ビット版と1920×1080の画面で問題を再現できたため、Windows 10のクリエイター版や高解像度のディスプレイに限定されず、フォント品質が[ANTIALIASED]に設定されている場合はトリガーのしきい値が高くなります。私のWindows 7でのテストでは、フォントArialを使用して、トリガーポイントは "109"(高速)のフォントサイズと "110"(低速または悪いパフォーマンス)のフォントサイズでした。また、Sebastian Zの答えを使ってcleartypeを無効にした後も、Windows 10にこの同じトリガーしきい値が存在します。
ETO_CLIPPEDフラグを削除すると、同じパフォーマンス低下がありますか?ビットマップ(つまり、24bppまたは32bpp)はどのような色深度ですか?それはDIBかDDBですか? SOユーザーが再現しようとするように[mcve]を追加するのが最もよいでしょう。 – zett42
元の投稿に、ソースコードとこれをテストするために使用できる実行可能ファイルを含むGitHubプロジェクトへのリンクを更新しました。更新には他の詳細も含まれます。 – bLight