문제 설명
WPF ‑ ScreenSaver 그래픽 성능 향상 (WPF ‑ ScreenSaver graphics performance improvements)
WPF‑VS2008 ScreenSaver 템플릿을 만들고 새로운 화면 보호기를 만들기 시작했습니다. winForms‑platform(GDI+) 화면 보호기에 대한 약간의 경험이 있으므로 WPF에서 약간 길을 잃었습니다.
- 내 화면 보호기의 배경 요소는 Canvas입니다.
- DispatcherTimer 틱은 33msec로 설정되어 있으며 이는 ~30FPS입니다.
- 배경 ‑color는 하나의 거대한 LinearGradientBrush입니다.
- 화면에는 무작위로 계산된(초기화) 배경색 + 알파 채널로 그려진 n‑타원(사용 가능한 화면당, 내 로컬 컴퓨터에 2개)이 있습니다. 모두 Canvas의 Children 컬렉션에 있습니다.
- 일부 논리(모든 DispatcherTimer 틱)를 사용하여 화면에서 타원을 이동하고 있습니다. 타원별로 이동한 다음 각 타원에 대해 Canvas.SetLeft(...) 및 Canvas.SetTop(...)을 호출합니다.
- N(타원의 수)이 더 높은 경우 > 70‑80, 그래픽이 느려지는 것을 느끼기 시작했습니다.
이제, 더 높은 N 값을 선택할 때 그래픽의 부드러움을 개선하기 위해 내가 할 수 있는 일이 있는지 궁금합니다. 타원을 이동하기 전에 "고정" "무언가"를 수행하고 완료되면 "고정 해제" "무언가"를 할 수 있습니까? 아니면 내가 할 수 있는 다른 트릭이 있습니까?
내가 언급한 성능 드롭다운에 대해 너무 까다롭지는 않습니다. N==50일 때 모든 것이 원활하게 작동하기 때문입니다.
## 참조 솔루션 #### 방법 1:
Have you tried rendering in the CompositionTarget.Rendering event, rather than in a timer? I've gotten impressive performance in a 3D screen saver when using the Rendering event and doing my own double buffering. (See http://stuff.seans.com/2008/08/21/simple‑water‑animation‑in‑wpf/ , http://stuff.seans.com/2008/08/24/raindrop‑animation‑in‑wpf/ , and http://stuff.seans.com/2008/09/01/writing‑a‑screen‑saver‑in‑wpf/ )
방법 2:
It is not possible to unfreeze something once it has been frozen (although a copy of the object is unfozen by default). Double buffering is also enabled by default in WPF so you cannot gain here.
Once way to improve performance if not already done is to use geometry objects such as Ellipse Geometry rather than shapes if you do not need to the all of the events as these are lighter weight.
I also have found this MSDN Article Optimizing Performance: 2D Graphics and Imaging that suggests a CachingHint may help along with some other tips.
Finally ensure that you are using the latest service pack one as it has many performance improvements outlined here
방법 3:
You will improve performance if you call the Freeze method on objects that inherit from Freezable ‑ brushes for example.
The reason is that Freezable supports extra change notifications that have to be handled by the graphics system, when you call Freeze the object can no longer change and so there are no more change notifications.
For an example of this notification system, if you create a brush, use it to paint a rectangle (for example) and then change the brush the on‑screen rectangle will change color.
(by sabiland、Sean Sexton、John、Nir)