2010-11-25 20 views
8

MFC 응용 프로그램에서 스크롤 막대를 드래그하여 문서를 부드럽게 스크롤하는 동안 텍스트 단락이 들어있는 블록이 켜지면 프레임 속도가 고르지 못한 수준으로 떨어집니다. 스크린이지만, 화면이 꺼지면 부드럽습니다. 퍼포먼스를 조사한 결과, 단 하나의 텍스트 단락이 발생했음을 알게되었습니다. CDC::DrawText. 이것은 최적화 된 릴리스 빌드입니다.Win7 x64의 DrawText 성능이 좋지 않음

나는 다음과 같이 단지 DrawText에 호출의 고해상도 측정을 얻기 위해 QueryPerformanceCounter을 사용 :

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

텍스트 유니 코드,가 lorem-ipsum의 스타일 필러, 긴 865 자이며 (7)을 통해 랩 사각형 및 글꼴 (Segoe UI, lfHeight = -12, 표준 본문 텍스트 크기)이 주어진 비트 라인. 내 측정에서 만 전화하면은 평균 7.5ms, 홀수 피크는 21ms입니다. (당신은 약 16ms 각 업데이트를 렌더링을 얻을 60Hz의 모니터를 계속합니다.)

나는 성능 향상을 위해 몇 가지 변화를 시도 :

  • DT_WORDBREAK 약이 1ms (약 7 성능을 향상 제거를 시간이 빠름). 단 한 줄의 텍스트 만 화면에 표시되고 단어 분리가 7 줄이 넘는 경우 병목 현상이 다른 곳에서 발생한다는 것을 알 수 있습니다.
  • 텍스트를 투명 모드 (SetBkMode(TRANSPARENT))로 그렸습니다. 그래서 단색 배경 채우기로 불투명 모드를 시도했습니다. 개선 없음.
  • ClearType 렌더링이 문제가 될 수 있다고 생각했습니다. 글꼴 lfQualityCLEARTYPE_QUALITY에서 NONANTIALIASED_QUALITY으로 변경했습니다. 날카로운 모서리와 모든 것, 그리고 아무런 개선이없는 쓰레기처럼 보였습니다.
  • 의견 제안에 따라 CMemDC를 사용하고 있었지만이를 제거하고 직접 그리기를 수행했습니다. 그것은 미친 듯이 깜박이며 개선되지 않았습니다.

이것은 Intel Core 2 Duo P8400 @ 2.26GHz 및 4GB RAM이 장착 된 Windows 7 64 비트 노트북에서 실행됩니다. 느린 시스템으로 간주되지 않습니다.

DrawText()를 호출 할 때마다 DrawingText()가 호출되므로 느린 함수로 성능이 저하됩니다. 특히 여러 텍스트 블록이 동시에 표시되는 경우에는 더욱 그러합니다. 경험을 부진하게 만드는 것으로 충분합니다. 그러나 파이어 폭스는 훨씬 더 많은 텍스트를 가진 ClearType에서 이와 같은 페이지를 렌더링 할 수 있습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? 어떻게하면 실제 DrawText 호출의 성능 저하를 피할 수 있습니까?

+0

하드웨어 가속을 변경하면 어떻게됩니까? – Dialecticus

+0

Win7에서 오래된 학교 GDI (MFC에서 내부적으로 사용되는 것으로 추정 됨)를 사용하는 방법을 생각하면 좋지 않습니다. 내 조언은 GDI + 방식으로 전환하는 것입니다. (http://msdn.microsoft.com/en-us/library/ms535991(v=VS.85).aspx). 시도해보고 결과를 알려줄 수 있습니다. – Keynslug

+0

본 적이 있나요? http://blog.m-ri.de/index.php/2009/02/15/slow-drawtext-performance-in-vista-and-windows-7-please-comment/ –

답변

6

새로 고침 할 때마다 텍스트를 그리는 것은 낭비입니다. 더블 버퍼링을 사용하십시오. 즉, 오프 스크린 비트 맵을 그려 화면에 블릿합니다. 그런 다음 스크롤을하려면 필요에 따라 대부분의 비트 맵을 위/아래 또는 옆으로 복사 한 다음 결과를 화면에 표시하기 전에 무효화 된 영역 만 그립니다.

너무 느리다는 사실이 밝혀지면 그려진 텍스트도 화면 외부 비트 맵에 유지하고 그리기 대신 blit을 사용하십시오.

건배 & HTH.,

2

this german blogpost에 따르면이 문제는 아시아 언어 글꼴 지원과 관련이 있습니다. XP에서 이들을 활성화하면 동일한 성능 저하가 발생합니다. Vista/7에서는 기본적으로 사용하도록 설정되어 있으며 사용하지 않도록 설정할 수 없습니다.

편집 : 그냥 다른 글꼴을 사용하면 도움이 될 수 있습니다. (아시아 문자가 포함되지 않은 글꼴 일 수도 있습니다.)

+0

블로그 게시물은 실제로 텍스트를 렌더링하지 않는 DT_CALCRECT 플래그를 사용하는 것으로 나타납니다. 렌더링에 대해 이야기하고 있습니다. 참고로 DT_CALCRECT를 사용하면 약 7 배 빨라집니다. 예상대로 렌더링 범위가 계산 범위보다 훨씬 느립니다. 또한 최선의 국제 지원을 유지할 수 있다면 더 좋을 것입니다! – AshleysBrain

+0

@AshelysBrain : 예, 시나리오가 다릅니다. 그러나 근본 원인이 동일한 지 쉽게 판단 할 수 있습니다. XP 시스템에서이 두 확인란을 활성화하고 테스트 코드를 실행하면 성능과 어떤 관련이 있습니까? –

2

사용자는 7 밀리 초 안에 7 줄의 텍스트를 읽을 수 없으므로 호출 자체가 빠릅니다.

모니터의 60Hz 재생 빈도는 전적으로 관련이 없습니다. 모든 프레임에 대해 동일한 텍스트를 다시 렌더링 할 필요가 없습니다. 비디오 카드는 행복하게 동일한 픽셀을 다시 화면에 보냅니다.

그래서 나는 thibk에 또 다른 문제가 있습니다.텍스트 스크롤에 대해 궁금 하신가요? DrawText가 범인이라고 가정하는 대신 실제로 갖고있는 문제에 대해 물어보십시오.

+0

질문에서 스크롤 막대를 드래그하는 동안 성능에 대해 이야기하고 있으므로 스크롤하는 문서를 부드럽게 표시하기 위해 텍스트를 항상 새로 고침 빈도로 이상적으로 다시 그리는 중입니다. – AshleysBrain

+0

아 맞아. XY 문제가 있다는 느낌이 들었어. 그래서, 예,'DrawText'는 실제로 충분히 빠릅니다. 그러나 이제 화면에서 몇 픽셀 낮추어야하기 때문에 텍스트를 다시 렌더링하면 안됩니다. 다른 오프셋에서 (수정되지 않은!) CMemDC를 재사용하고 새로 표시되는 부분에 대해 추가 CMemDC를 추가하는 것이 트릭을 수행해야합니다. 이 설명은 모든 세부 사항을 다루기에 조금 작습니다. – MSalters

1

단어 분리에서 텍스트를 분리하려면 DrawText가 텍스트 블록 너비를 가져 와서 맞는지 알아보기 위해 반복적으로 시도한 다음 나머지를 가져 와서 끝내야합니다. 모든 통화에서이 작업을 수행해야합니다. 텍스트가 변경되지 않으면 불필요한 오버 헤드입니다. 임시 해결 방법으로 텍스트를 직접 측정하고 임시 줄 바꿈을 삽입하고 DT_WORDBREAK 플래그를 제거 할 수 있습니다.

0

당신은 Direct2D의 /의 DirectWrite를 생각 해 봤나?

어쨌든 텍스트를 한 번만 자체 mem DC로 그리면 모든 반복문에 그려지는 dc를 blit하는 것이 좋습니다.

관련 문제