2017-05-10 3 views
8

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にこの同じトリガーしきい値が存在します。

+4

ETO_CLIPPEDフラグを削除すると、同じパフォーマンス低下がありますか?ビットマップ(つまり、24bppまたは32bpp)はどのような色深度ですか?それはDIBかDDBですか? SOユーザーが再現しようとするように[mcve]を追加するのが最もよいでしょう。 – zett42

+0

元の投稿に、ソースコードとこれをテストするために使用できる実行可能ファイルを含むGitHubプロジェクトへのリンクを更新しました。更新には他の詳細も含まれます。 – bLight

答えて

4

デルファイはlfQuality := DEFAULT_QUALITY;でフォントを作成します。デフォルトの品質はアンチエイリアスされた品質でした。しかし、Windows 10のクリエイターはこれをデフォルトにするので、クリアタイプに更新します。そして、これはかなり遅いです。ですから、アンチエイリアシングされた品質を手動で強制することです。

あなたは現在のDelphiのバージョンを使用している場合、あなたは単にFont.Qualityプロパティを設定することができます

var 
    lf: TLogFont; 
begin 
    if GetObject(oBitmap.Canvas.Font.Handle, SizeOf(TLogFont), @lf) = sizeof(TLogFont) then 
    begin 
    lf.lfQuality := ANTIALIASED_QUALITY; 
    oBitmap.Canvas.Font.Handle := CreateFontIndirect(lf); 
    end; 

この:それは少し複雑です古いDelphiのバージョンでは

Procedure RenderText(oBitmap : TBitmap; X,Y : Integer; cRect : TRect; S : WideString; testFunction : Integer; TxtEffect : Integer; EffectColor : TColor; Clipping : Boolean); 
// [...] 
begin 
    obitmap.Canvas.Font.Quality := fqClearType; 

ClearTypeテキストは常に適切ではないので、予期せぬ結果が生じる可能性があるため、Windows 10 Creators Updateではかなりの問題があります。

+0

あなたの回答はうまくいって、プレ作成者版のパフォーマンスレベルを返しますが、深いテストでは、Windows 7と同じくらい遠いところに問題は残っていますが、より高いレベルのしきい値があります。アップデート3を参照してください(約5分後) – bLight

関連する問題