2017-05-10 3 views
8

WinAPI의 ExtTextOutW 함수를 호출하여 클리핑 된 텍스트를 고해상도 비트 맵 (2560x1440/3840x2160)에 그리면 Windows 업데이트 후 ~ x50 성능이 저하됩니다 10 크리에이터 에디션 업데이트. 내 사용자의 테스트 및 디버그 로그에서 비트 맵 또는 글꼴 크기의 약간의 차이로 인해 성능이 저하 될 수 있습니다. 여기 Windows 크리에이터 에디션 업데이트 후 QHD/4K 화면에서 ExtTextOutW x50 성능 저하

가 성능 저하 보여주는 디버그 로그입니다 :이 같은 호출은 제작자 이전에이 1ms에서 잘했다 동안

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 

로그에서 볼 수 있듯이을 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이고 사용자가 화면에 더 작은 크기의 선을 추가하면 텍스트가 낮은 해상도로 렌더링됨에 따라 성능이 크게 향상된다는보고에 따라 성능 문제가 글꼴 크기와 관련이있는 것처럼 보입니다. 문제가에 따라 https://github.com/bLightZP/WindowsTextRenderingProfiler

것 같다 :

는 ***** 업데이트 2 *****는

난 당신이 GitHub의 저장소에서 찾을 수있는이 문제를 프로필에 작은 도구를 작성 예를 들어 2560x1440 화면에서 글꼴 크기를 "Arial"글꼴 텍스트의 크기를 "35"21ms로 렌더링하고 "34"크기에서 렌더링하는 데 2ms가 걸립니다.

이것은 32 비트 픽셀 형식의 Delphi TBitmap의 HDC로 렌더링되며 클리핑을 비활성화하면 성능에 약간의 영향을 미칩니다.

***** 업데이트 3 *****

아래

세바스찬 Z의 대답은 사전 제작자에게 성능 에디션의 수준을 회복합니다 나는 그의 대답을 반영하기 위해 GitHub의에 샘플 코드를 업데이트,하지만 난이 Windows 7 64 비트 및 1920x1080 화면에서 문제를 재현 할 수 있으므로 Windows 10 작성자 에디션이나 고해상도 디스플레이에만 국한되지 않습니다. 폰트 품질을 ANTIALIASED로 설정하면 트리거 임계 값이 높아집니다. Windows 7에서의 테스트에서, 글꼴 Arial을 사용하여 트리거 포인트는 "109"(빠름)의 글꼴 크기와 "110"(느리게 또는 더 나쁜 성능)의 글꼴 크기를가집니다. 그리고 Clebype을 비활성화하기 위해 Sebastian Z의 대답을 사용한 후 Windows 10에도이 같은 트리거 임계 값이 있습니다.

+4

ETO_CLIPPED 플래그를 제거 할 때 동일한 성능 저하가 발생합니까? 비트 맵 (즉, 24bpp 또는 32bpp)은 어떤 색 깊이입니까? DIB 또는 DDB입니까? SO 사용자가 재현을 시도 할 수 있도록 [mcve]를 추가하는 것이 가장 좋습니다. – zett42

+0

원래의 게시물을 테스트하기 위해 사용할 수있는 소스 코드와 실행 파일이 포함 된 GitHub 프로젝트에 대한 링크가 업데이트되었습니다. 업데이트에는 다른 세부 정보가 포함됩니다. – bLight

답변

4

델파이는 lfQuality := DEFAULT_QUALITY;으로 글꼴을 만듭니다. 기본 품질은 안티 앨리어싱 품질이었습니다. 그러나 Windows 10 크리에이터가 지금이 기본값을 cleartype으로 업데이트하기 때문에. 그리고 이것은 매우 느립니다. 따라서 해결책은 안티 앨리어싱 된 품질을 수동으로 강제하는 것입니다.

당신은 당신이 단순히 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; 

이 : 그것은 더 복잡 조금이다 오래된 델파이 버전의

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 크리에이터 업데이트에서 상당히 어려움을 겪고 있습니다.

+0

답변이 작동하고 제작 전 제작진 수준의 성능을 반환하지만보다 심층적 인 테스트를 거친 후에도 Windows 7과 같은 수준이지만 임계 값이 높은 문제는 업데이트 3 (약 5 분 후)을 참조하십시오. – bLight