Is rendering a lot of repeated images more or less performant than using brushes in WPF?
Asked Answered
G

2

6

An application our company is working on currently displays many rectangle shapes with gradients to draw 'Tiles'. An internal discussion came about that posed a question of performance. These tiles are about 100 pixels by 200 pixels, and are either gradient shaded red, yellow, or green. At any given time, there could be up to 100 of these tiles on screen. Would it be more performant for us to create an image for each (red, yellow, green) and repeat it when needed, or would it be better for us to continue drawing them using standard WPF brushes?

EDIT: To clarify, the gradient brush we're using is a LinearGradientBrush.

Glassine answered 13/1, 2010 at 18:38 Comment(6)
What performance metric are you most concerned with? Speed, memory usage, cpu usage, etc.Ghostly
Graphics performance, cpu utilization, etc. When I scroll through a list of hundreds of such gradient tiles, I witness screen flicker and high cpu utilization. We've tried a few things to help performance, but with no luck. I was wondering if using rasterized images would help instead.Glassine
Flicker and high CPU utilization for only a a few hundred of these tiles? What kind of objects are you creating for the tiles? Are you creating full-fledged FrameworkElements or UIElements or are you working with the lower-level Visual class?Rosenkranz
UIElements. Mostly user controls and data templates made up of UIElements.Glassine
That's one major aspect to your performance problem. UIElements provide support for a broad feature set- layout, input, focus, and events. But I'm willing to bet you don't need any of those things (or not as rich of support). You should drop down in the hierarchy to the Visual layer. Create custom objects that inherit from Visual, and handle their own drawing by overriding OnRender. You can then draw them using brushes and a drawing context. This will result in far better performance than UIElements, and is more critical than how you render your UIElements (with images or brushes).Rosenkranz
Very nice. Results of many profiling sessions all point toward the creation of these UIElements, especially while scrolling through a list. Your comments are right in line with what I'm seeing. Do you mind summarizing this in your original answer? The bounty is yours, my friend!Glassine
R
1

From experience, drawing them using brushes will have far better performance. The overhead of loading up the tile images and rendering them is large compared to rendering filled rectangles.

Rosenkranz answered 5/3, 2010 at 18:12 Comment(5)
Can you tell me technical reasons of why gradient brushesperform better? If so, the bounty is all yours.Glassine
Technical reasons are pretty basic. IO is always one of the most costly operations you can do. Reading images from files is going to take time; rendering something without that overhead is going to take less time. Once you hit the actual rendering code it's going to boil down to the same thing (highly optimized DirectX), but the difference is the brush approach doesn't have any overhead to create the image.Rosenkranz
Sorry, I should have mentioned this in my post. I'll edit accordingly. There are only 3 images that would be repeated. The only IO is reading them for the first time. After that, they're cached resources.Glassine
So rendering gradient brushes is handled by DirectX, but rendering of rasterized images are not?Glassine
Actually all rendering is DirectX. The performance difference between drawing filled rectangles and drawing cached images is minimal- I don't even think you would notice a difference. The real performance gain you could get is from stepping down to the Visual layer and overriding OnRender. See my comment on your original question for more information.Rosenkranz
P
1

The only way to clear this up would be to try it both ways and measure the performance of each approach.

You'd need to add code to time the render loop and log the result to file, then force a 1000 (or even 100,000) redraws to be able to get a realistic figure.

My gut feeling is that the LinearGradientBrush would be quicker than loading an image (even from resources) - but I'm willing to be proved wrong.

Pytlik answered 13/1, 2010 at 19:55 Comment(0)
R
1

From experience, drawing them using brushes will have far better performance. The overhead of loading up the tile images and rendering them is large compared to rendering filled rectangles.

Rosenkranz answered 5/3, 2010 at 18:12 Comment(5)
Can you tell me technical reasons of why gradient brushesperform better? If so, the bounty is all yours.Glassine
Technical reasons are pretty basic. IO is always one of the most costly operations you can do. Reading images from files is going to take time; rendering something without that overhead is going to take less time. Once you hit the actual rendering code it's going to boil down to the same thing (highly optimized DirectX), but the difference is the brush approach doesn't have any overhead to create the image.Rosenkranz
Sorry, I should have mentioned this in my post. I'll edit accordingly. There are only 3 images that would be repeated. The only IO is reading them for the first time. After that, they're cached resources.Glassine
So rendering gradient brushes is handled by DirectX, but rendering of rasterized images are not?Glassine
Actually all rendering is DirectX. The performance difference between drawing filled rectangles and drawing cached images is minimal- I don't even think you would notice a difference. The real performance gain you could get is from stepping down to the Visual layer and overriding OnRender. See my comment on your original question for more information.Rosenkranz

© 2022 - 2024 — McMap. All rights reserved.