Graphics.Draw*, AutoScroll & Culling - c#

I've implemented a custom control in C#/Winforms which does things like syntax highlighting & autocomplete. I'm using AutoScroll to manage scrolling and it works nicely.
Currently I have not optimized at all (sure optimization is important, but I'm doing that last; functionality is what I'm after first), I am rendering huge documents, and each keypress will re-parse the affected line to make sure syntax highlighting is consistent.
Right now in my big meaty paint method, I am painting every string, keyword, etc, even if it is outside of the clip region. But regardless of how big the document is & how many combinations of keywords/highlighted bits & pieces I have, it still runs bloody fast with not much memory & CPU overhead.
So my question - do the Graphics.Draw* methods do any kind of culling? Eg: If the AutoScrollPosition is way down the document & I Graphics.DrawString(insert some coordinates outside the draw region), is any actual work being done? Also note I'm running VS on Win 7 inside a VM, and it is still running fast. Not that it's an issue now, but it would be nice to keep in mind for later when it comes to the optimization phase. :D
Cheers,
Aaron

From personal experience writing games that use Graphics.Draw* methods, you will notice a speed increase if you perform your own bounds checking before calling the drawing methods.
Attempting to draw things offscreen is faster than drawing things onscreen, but its still noticeably slower than not drawing them at all.

Related

Displaying bitmaps rapidly

I have a WPF application where I need to add a feature that will display a series of full screen bitmaps very fast. In most cases it will be only two images, essentially toggling the two images. The rate they are displayed should be constant, around 10-20ms per image. I tried doing this directly in WPF using a timer, but the display rate appeared to vary quit a bit. I also tried using SharpGL (a .Net wrapper on OpenGL), but it was very slow when using large images (I may not have been doing the best way). I will have all the bitmaps upfront, before compile time, so the format could be changed as long as the pixels are not altered.
What would be the best way to do this?
I'm already behind schedule so I don't have time to learn lots of APIs or experiment with lots of options.
"I tried doing this directly in WPF using a timer, but the display rate appeared to vary quit a bit."
Instead of using a Timer, use Thread.Sleep(20) as it wont hog as many system resources. This should give you an immediate improvement.
It also sounds as though there will be user interaction with the application while the images are rapidly toggling, in this case put the code that toggles the images in a background thread. Remember though that the UI- is not thread safe.
These are just quick wins, but you might need to use DirectX for Hardware Acceleration to get around HAL:
The Windows' Hardware Abstraction Layer (HAL) is implemented in
Hal.dll. The HAL implements a number of functions that are
implemented in different ways by different hardware platforms, which
in this context, refers mostly to the Chipset. Other components in the
operating system can then call these functions in the same way on all
platforms, without regard for the actual implementation.

High performance graphics using the WPF Visual layer

I am creating a WPF mapping program which will potentially load and draw hundreds of files to the screen at any one time, and a user may want to zoom and pan this display. Some of these file types may contain thousands of points, which would most likely be connected as some kind of path. Other supported formats will include TIFF files.
Is it better for performance to have a single DrawingVisual to which all data is drawn, or should I be creating a new DrawingVisual for each file loaded?
If anyone can offer any advice on this it would be much appreciated.
You will find lots of related questions on Stack Overflow, however not all of them mention that one of the most high-performance ways to draw large amounts of data to the screen is to use the WriteableBitmap API. I suggest taking a look at the WriteableBitmapEx open source project on codeplex. Disclosure, I have contributed to this once, but it is not my library.
Having experimented with DrawingVisual, StreamGeometry, OnRender, Canvas, all these fall over once you have to draw 1,000+ or more "objects" to the screen. There are techniques that deal with the virtualization of a canvas (there' a million items demo with Virtualized Canvas) but even this is limited to the ~1000 visible at one time before slow down. WriteableBitmap allows you to access a bitmap directly and draw on that (oldskool style) meaning you can draw tens of thousands of objects at speed. You are free to implement your own optimisations (multi-threading, level of detail) but do note you don't get much frills with that API. You literally are doing the work yourself.
There is one caveat though. While WPF uses the CPU for tesselation / GPU for rendering, WriteableBitmap will use CPU for everything. Therefore the fill-rate (number of pixels rendered per frame) becomes the bottleneck depending on your CPU power.
Failing that if you really need high-performance rendering, I'd suggest taking a look at SharpDX (Managed DirectX) and the interop with WPF. This will give you the highest performance as it will directly use the GPU.
Using many small DrawingVisuals with few details rendered per visual gave better performance in my experience compared to less DrawingVisuals with more details rendered per visual. I also found that deleting all of the visuals and rendering new visuals was faster than reusing existing visuals when a redraw was required. Breaking each map into a number of visuals may help performance.
As with anything performance related, conducting timing tests with your own scenarios is the best way to be sure.

What is the most suitable method for implementing heavy graphix in windows?

hello i m using c# and suffering with delay problem. i want to change the technique for handling the graphics before this i want to know what will be the most efficient method for implementing heavy graphics,
i started making bmp files for each dynamic and static module and at the end i updates the whole GUI by pasting this bmps as layers after this i do double buffering but still not getting the required results i am thinking for using Direct-X ??
help required thanx in advance
Microsoft XNA is a managed environment for doing extensive graphics. It's mainly used for Game development.
IMHO. Worth a look in your case.
What exactly are you trying to draw? DirectX may be a good solution but it does depend on what you want to draw.
I've done some quite heavy updating of windows by doing the updates inside a thread. Once the thread has finished doing its processing then the window gets updated. This gives good results for my case (calculating and drawing a spectrogram that can be moved around). It would, however, depend on how heavy what you want to draw is.

XOR Drawing in C#

I am a trying to learn C# .Net.
I had written small (hobby) Analog Clock application in VB sometime ago(edit: VB6, to be precise), and I thought I will rewrite in C#.NET, as part of my learning process.
In the VB application, I drew the hands of the clock in XOR Drawmode, so that I have to move the second hand, I just had to redraw it in the previous position and then draw the current position - I need not refresh the whole Form. All I did was
Me.DrawMode = vbNotXorPen
and then
Me.Line...
on a VB Form
In C# I don't find an equivalent Xor Pen Draw mode.
I found
ControlPaint.DrawReversibleLine
somewhere on the net, but I am not sure whether ControlPaint is meant for such purposes (and I don't understand based on what co-ordinate system ControlPaint is drawing)
Is there an equivalent to XOR drawing in C#.NET?
Or is there a better way to do what I am doing (with the best performance)
(Both VB and C# are my hobbies. So feel free to correct me wherever I am wrong)
.NET/GDI+ does not support XOR drawing. You'll have to workaround it by using p/invoke calls of several native functions.
See the link below for more information
http://www.vbaccelerator.com/home/net/code/libraries/Graphics/ZoomIn/article.asp
IMHO, until and unless you are targeting some really slow computers, you don't need to optimize performance by using XOR technique.
Since you'd be drawing the second hand only once in a second, a complete redraw of the clock would be much better. Also, the second hand will "look" good if drawn directly, and use smoothing mode set to Anti alias for a more cleaner look.
To optimize performance, you can create a bmp for clock every one minute and then draw the second hand upon it.

How to design a high performance grid with VS 2005(specifically C#)

I need to build a high performance winforms data grid using Visual Studio 2005, and I'm at a loss with where to start. I've build plenty of data grid applications, but none of those were very good when the data was constantly refreshing.
The grid is going to be roughly 100 rows by 40 columns, and each cell in the grid is going to update between 1 and 2 times a second(some cells possibly more). To me, this is the biggest drawback of the out of the box data grid, the repainting isn't very efficient.
Couple caveats
1) No third party vendors. This grid is backbone of all our applications, so while XCeed or Syncfusion or whatever might get us up and running faster, we'd slam into its limitations and be hosed. I'd rather put in the extra work up front, and have a grid that does exactly what we need.
2) I have access to Visual Studio 2008, so if it would be much better to start this in 2008, then I can do that. If its a tossup, I'd like to stick with 2005.
So whats the best approach here?
I would recommend the following approach if you have many cells that are updating at different rates. Rather than try to invalidate each cell each time the value changes you would be better off by limiting the refresh rate.
Have a timer that fires at a predefined rate, such as 4 times per second, and then each time it fires you repaint the cells that have changed since the last time around. You can then tweak the update rate in order to find the best compromise between performance and usability with some simple testing.
This has the advantage of not trying to update too often and so killing your CPU performance. It batches up changes between each refresh cycle and so two quick changes to a value that occur fractions of a second apart do not cause two refreshes when only the latest value is actually worth drawing.
Note this delayed drawing only applies to the rapid updates in value and does not apply to general drawing such as when the user moves the scroll bar. In that case you should draw as fast as the scroll events occur to give a nice smooth experience.
We use the Syncfusion grid control and from what I've seen it's pretty flexible if you take the time to modify it. I don't work with the control myself, one of my co-workers does all of the grid work but we've extended it to our needs pretty well including custom painting.
I know this isn't exactly answering your question, but it writing a control like this from scratch is going always going to be much more complicated than you anticipate, regardless of your anticipations. Since it'll be constantly updating I assume it's going to be databound which will be a chore in itself, especially to get it to be highly performant. Then there's debugging it.
Try the grid from DevExpress or ComponentOne. I know from experience that the built-in grids are never going to be fast enough for anything but the most trivial of applications.
I am planning to build a grid control to do the same as pass time, but still haven't got time. Most of the commercial grid controls have big memory foot print and update is typically an issue.
My tips would be (if you go custom control)
1. Extend a Control (not UserControl or something similar). It will give you speed, without losing much.
2. In my case I was targeting the grid to contain more data. Say a million row with some 20-100 odd columns. In such scenarios it usually makes more sense to draw it yourself. Do not try to represent each cell by some Control (like say Label, TextBox, etc). They eat up a lot of resources (window handles, memory, etc).
3. Go MVC.
The idea is simple: At any given time, you can display limited amount of data, due to screen size limitations, Human eye limitation, etc
So your viewport is very small even if you have gazillion rows and columns and the number of updates you have to do are no more than 5 per second to be any useful to read even if the data behind the grid id being updated gazillion times per second. Also remember even if the text/image to be displayed per cell is huge, the user is still limited by the cell size.
Caching styles (generic word to represent textsizes, fonts, Colors etc), also help in such scenario depending on how many of them you will be using in your grid.
There will be lot more work in getting some basic drawing (highlights, grid, boundaries, borders, etc) done to get various effects.
I don't recall exactly, but there was a c# .net grid on sourceforge, which can give you a good idea of how to start. That grid offered 2 options, VirtualGrid where the model data is not held by the grid making it very lightweight, and a Real grid (traditional) where the data storage is owned by the grid itself (mostly creating a duplicate, but depends on the application)
For a super-agile (in terms of updates), it might just be better to have a "VirtualGrid"
Just my thoughts

Categories