2.9.2 wxGraphicsContext or wxDC better?

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
markm
Earned a small fee
Earned a small fee
Posts: 18
Joined: Mon Jun 07, 2010 10:07 pm

2.9.2 wxGraphicsContext or wxDC better?

Postby markm » Mon Sep 26, 2011 8:54 pm

I'm developing a program wxWidgets 2.9.2 on a program that needs to draw a lot of polygons to the screen, say ~500k polygons. I develop for OSX, Windows and Linux (say Ubuntu). I've noticed huge difference in both speed and stability between the three platforms depending on whether I use wxGraphicsContext or wxDC.

Does anybody know of a thread or link to some good information about the best recommended way to draw lots of polygons quickly on these three platforms? I've searched a fair bit, but everything seems out-of-date. Here's a few things that I've noticed by experimentation:

- wxGraphicsContext is about 10x faster than wxDC on OSX and is very stable (no crashes yet)
- wxGraphicsContext is about 2x slower than wxDC on Windows XP and even wxDC is pretty slow (I'm using Virtual Box to test Windows)
- wxDC is very very fast on Ubuntu, even when I'm using Virtual Box to run it. wxGraphicsContext is actually slower and crashes easily.

For testing purposes, I'm just rendering about 500k rectangles to the screen, so nothing fancy.

catalin
Moderator
Moderator
Posts: 1436
Joined: Wed Nov 12, 2008 7:23 am
Location: Romania

Re: 2.9.2 wxGraphicsContext or wxDC better?

Postby catalin » Mon Sep 26, 2011 9:11 pm

From what I know, see some comments beloow:

markm wrote:- wxGraphicsContext is about 10x faster than wxDC on OSX and is very stable (no crashes yet)
Under OSX wxDC is just a wrapper for wxGraphicsContext, so there should be no way for the latter to be slower. Could it be that you do something wrong in the test implementation?

markm wrote:- wxGraphicsContext is about 2x slower than wxDC on Windows XP and even wxDC is pretty slow (I'm using Virtual Box to test Windows)
When I tested it under msw wxGraphicsContext was "much" slower than wxDC, but the latter was pretty fast. Maybe buffered painting would help some more. See wx[Auto]BufferedPaintDc.

markm
Earned a small fee
Earned a small fee
Posts: 18
Joined: Mon Jun 07, 2010 10:07 pm

Re: 2.9.2 wxGraphicsContext or wxDC better?

Postby markm » Mon Sep 26, 2011 9:26 pm

catalin wrote:Under OSX wxDC is just a wrapper for wxGraphicsContext, so there should be no way for the latter to be slower. Could it be that you do something wrong in the test implementation?


That makes sense. When I first tried wxGraphicsContext in OSX, I rendered the polygons by one-by-one by repeated calls to StrokPath() with just a single polygon. Doing it this way was as slow as using wxDC. When I added all rectangles to a wxGraphicsPath first and then draw everything with a single call to StrokePath, then I get huge speedup. Perhaps I'm not even using wxDC in the best way possible. If you had to render 500k polygons, would you do something like

for (int i=0; i<500000, i++) dc->DrawRectangle(p[i].x, p[i].y, 2, 2)

I'm using the same code using a VM in Linux and Windows XP. On Linux, the above code takes about 700 ms, while on Windows it takes about 9000 ms. I assumed that the graphics drivers for Windows would be faster than Linux if anything.

User avatar
doublemax
Moderator
Moderator
Posts: 12507
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: 2.9.2 wxGraphicsContext or wxDC better?

Postby doublemax » Mon Sep 26, 2011 10:06 pm

Under Windows, wxGraphicscontext used GDI+ and it works with subpixel accuracy (aka antialiasing). AFAIK this is never hardware accelerated, so usually it's much slower than wxDC.

If performance is an issue, i'd use OpenGL, even if it means rewriting the whole rendering code. But if OpenGL is hardware accelerated, the speed improvement should be huge.
Use the source, Luke!

markm
Earned a small fee
Earned a small fee
Posts: 18
Joined: Mon Jun 07, 2010 10:07 pm

Re: 2.9.2 wxGraphicsContext or wxDC better?

Postby markm » Wed Sep 28, 2011 7:26 pm

OpenGL has it's advantages, but in the case of my project, I'm dealing with a lot of existing code that was written for the wxDC. Also, my program can easily have 20+ windows open at once with 500k polygons each, so I'm not sure how well OpenGL in wxWidgets would work for that.

I've done some more testing and have found the following results for this test loop on 2.9.2:

// dc is an instance of wxDC, say wxClientDC
for (int i=0; i<500000, i++) dc->DrawRectangle(p[i].x, p[i].y, 2, 2)

On Ubuntu 9 (running on a VM): < 2 seconds
Windows XP (not a VM and same hardware as above): > 10 seconds
OS X (not a VM and same hardware as above): > 10 seconds

The Linux (GTK) performance would be a good starting point. Any ideas on why the exact same drawing code is so much faster on just Linux than on Windows XP or OSX even though Linux is a VM? There seems to be so little documentation on these sorts of discrepancies for wxWidgets.

User avatar
doublemax
Moderator
Moderator
Posts: 12507
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: 2.9.2 wxGraphicsContext or wxDC better?

Postby doublemax » Wed Sep 28, 2011 8:00 pm

There seems to be so little documentation on these sorts of discrepancies for wxWidgets.
I don't believe wxWidgets is at fault here. I don't know the differences of the wxDC implementations on the three major platforms, but i'd guess that wxWidgets just passes the drawing commands to the underlying API, like GDI on Windows or Cairo on GTK.

Unless your real code actually draws 2x2 rectangles only, i'd suggest to make a test with more realistic drawing operations. Maybe the overhead on one platform is very big compared to the actual drawing so that this test gives unrealistic results.

Also, it might be interesting if using wxDC::DrawPolyPolygon() changes the performance, as it would be one function call only.
http://docs.wxwidgets.org/stable/wx_wxd ... olypolygon

Additionaly, if it's just Cairo that performs so much better than GDI, i think it's possible to use Cairo on Windows. There is an option for that in setup.h, but i can't give any assistance on how to make it work, i never tried that before. (And i doubt many people have ;) )
Use the source, Luke!

markm
Earned a small fee
Earned a small fee
Posts: 18
Joined: Mon Jun 07, 2010 10:07 pm

Re: 2.9.2 wxGraphicsContext or wxDC better?

Postby markm » Wed Sep 28, 2011 8:47 pm

I don't believe wxWidgets is at fault here.


I'm not saying there is any "fault" on wxWidgets part, I understand that drawing commands are just getting passed through. I know far less on the subject than you do, but now I know to look into Cairo on GTK and GDI on Windows, thanks. When I figure this out, I'd like to update the wxWidgets wiki pages to help out others.

My code needs to draw either tonnes of points or polygons (map data). I have tried working with real data, and and the performance differences are the same as I see for just simple rectangles. I know enough about graphics libraries to know that if drawing isn't optimized for a simple rectangle, it is highly unlikely to be optimized for more complicated shapes such as circles or general polygons.

Also, it might be interesting if using wxDC::DrawPolyPolygon() changes the performance, as it would be one function call only.


I tried this already and, disappointingly, it makes little difference in the run-times. It was after this failure that I decided to post to the forums because I was out of ideas.

i think it's possible to use Cairo on Windows.


Thanks for the lead! That's exactly the sort of help or ideas I was hoping somebody could give.

User avatar
doublemax
Moderator
Moderator
Posts: 12507
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: 2.9.2 wxGraphicsContext or wxDC better?

Postby doublemax » Fri Sep 30, 2011 12:40 am

I made a little benchmark myself and it seems there is something strange about your speed under XP.

500000 rectangles (2x2 pixels):

Code: Select all

                   wxDC       wxGraphicsContext

XP                 0.75s      22.9s
Fedora12 (VM)      1.24s      37.84s

My CPU is a Core2Duo E7300 (2x 2.66), so nothing extraordinary fast. All tests in Debug mode, without optimizations (i also made a test in release mode with optimizations, but the difference was hardly noticeable).

It seems that your speed when using wxGraphicsContext is similar to mine, but the standard wxDC under XP seems very slow. I have no explanation for that though. Have you tested your code on another machine?
Use the source, Luke!

markm
Earned a small fee
Earned a small fee
Posts: 18
Joined: Mon Jun 07, 2010 10:07 pm

Re: 2.9.2 wxGraphicsContext or wxDC better?

Postby markm » Fri Sep 30, 2011 2:35 pm

After seeing your results, I was inspired to do some more digging. It turns out that Windows was not using double buffering (doh!). I was just using wxClientDC, without wxBufferedDC. On Linux, this makes no difference to the speed (very fast either way), but on Windows, the speed difference is huge. On the other hand, it seems that I need to use wxGraphicsContext on OSX to get reasonable speed. It's too bad that wxGraphicsContext is only usable on OSX right now---it would be nice to have one solution that is reasonably fast on all platforms. I'm going to run some more tests and I'll report back with my results and the test code that I use. Thanks for not giving up on this one doublemax!

User avatar
doublemax
Moderator
Moderator
Posts: 12507
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: 2.9.2 wxGraphicsContext or wxDC better?

Postby doublemax » Fri Sep 30, 2011 2:50 pm

It's too bad that wxGraphicsContext is only usable on OSX right now---it would be nice to have one solution that is reasonably fast on all platforms.
Well, there is wxGCDC, which is a wxDC-compatible wrapper around wxDC.

This enables you to switch between both methods at run- or compile-time like the "drawing" sample does.

Here's a small (edited) code snippet from the "drawing" sample:

Code: Select all

void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event))
{
    wxPaintDC pdc(this);
    wxGCDC gdc( pdc ) ;

    wxDC &dc = m_useContext ? (wxDC&) gdc : (wxDC&) pdc ;

     // usual wxDC drawing code continues here...
Use the source, Luke!

markm
Earned a small fee
Earned a small fee
Posts: 18
Joined: Mon Jun 07, 2010 10:07 pm

Re: 2.9.2 wxGraphicsContext or wxDC better?

Postby markm » Fri Sep 30, 2011 3:17 pm

doublemax wrote:Well, there is wxGCDC, which is a wxDC-compatible wrapper around wxDC.


I did see that code, however according to my tests, for OSX you only get the reasonably fast speed if you use the wxGraphicsContext methods in the proper way, and I don't think you can do that using the wxGCDC methods. As I noted in my first post, just switching to the wxGraphicsContext in OSX doesn't immediately result in any speedup unless you package many drawing operations into a single drawing path followed by just a few "Stroke" operations. So, although everything will work, I still think OSX will be dog-slow. Are you able to see good performance in OSX using wxDC calls (although I'm guessing your primary work machine isn't a Mac)? When I have a bit more time I'll make a table like you did that summarizes my running times for each method. I prefer to have as little platform-specific code as possible, but at the moment this doesn't seem possible for reasonably fast graphics.

User avatar
doublemax
Moderator
Moderator
Posts: 12507
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: 2.9.2 wxGraphicsContext or wxDC better?

Postby doublemax » Fri Sep 30, 2011 3:35 pm

As I noted in my first post, just switching to the wxGraphicsContext in OSX doesn't immediately result in any speedup unless you package many drawing operations into a single drawing path followed by just a few "Stroke" operations.
Sorry, this must have slipped my mind ;)

Are you able to see good performance in OSX using wxDC calls (although I'm guessing your primary work machine isn't a Mac)?
i can only test Windows and Linux in a VM, but not OSX.
Use the source, Luke!

Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Re: 2.9.2 wxGraphicsContext or wxDC better?

Postby Auria » Fri Sep 30, 2011 4:36 pm

In my experience wxDC on OSX is reasonably fast but it of course depends on how much you're drawing, and probably what shape you're drawing

For ultimate speed OpenGL could be a solution, though it takes quite a bit more code to use.

Another solution, if you have some complex shapes that don't change much, you can draw them into a bitmap and them just paste the bitmap in the paint event.

Apart from that, I'm a little out of ideas
"Keyboard not detected. Press F1 to continue"
-- Windows

markm
Earned a small fee
Earned a small fee
Posts: 18
Joined: Mon Jun 07, 2010 10:07 pm

Re: 2.9.2 wxGraphicsContext or wxDC better?

Postby markm » Wed Oct 12, 2011 5:20 pm

Ok, I've now spent some considerable time running tests of wxDC vs wxGraphicsContext on OSX, Windows XP, and Linux GTK. The test consists of drawing 500k diamond-shaped polygon outlines to the screen as fast as possible. I've experimented with drawing directly to the screen, vs double buffering on all platforms. When drawing 500k polygons, the differences in time is negligible. By far, the majority of time is spent actually drawing the polygons.

Here's a comparison of times on all three platforms, for wxDC vs wxGraphicsContext. Times are all in milliseconds.

Code: Select all

            wxGraphicsContext  wxDC
OSX               597          2154
XP (VM)         76298           231
Ubuntu 9 (VM)   16570           358

The relative time differences between XP and Linux are similar to those given by doublemax. Note that XP and Ubuntu are both running as 32-bit virtual machines on OSX. It's pretty amazing that even the best time for OSX is slower than both XP and Linux. In case you are wondering, I've tried all sorts of alternative drawing methods for both wxDC and wxGraphicsContext. The above times are the best I could achive for both. Also, I've disabled anti-aliasing for OSX, and this gives about a 20% speed improvement. I believe that the above is the current state-of-the art for simple ploygon drawing speed in 2.9.2 using either wxDC or wxGraphicsContext. I know that OpenGL will be faster, but I don't think it's practical for my project. It's a bit disappointing that OSX is currently so slow, even when using the fastest methods available. It's also too bad that I'll have to use both wxDC and wxGraphicsContext in order to get reasonably similar speeds on all three platforms.

I'm happy to post or send the complete testing code I if anybody is interested.

The inner loop for my wxGraphicsContext test is:

Code: Select all

wxGraphicsPath path = gc->CreatePath();
for (int i=0; i<num_obj_to_draw; i++) {
    path.MoveToPoint(pt[0].x, pt[0].y);
    path.AddLineToPoint(pt[1].x, pt[1].y);
    path.AddLineToPoint(pt[2].x, pt[2].y);
    path.AddLineToPoint(pt[3].x, pt[3].y);
    path.AddLineToPoint(pt[0].x, pt[0].y);
    path.CloseSubpath();
}
gc->StrokePath(path);

The inner loop for my wxDC test is:

Code: Select all

for (int i=0; i<num_obj_to_draw; i++) {
    dc.DrawLines(5, pt);
}


Return to “C++ Development”

Who is online

Users browsing this forum: No registered users and 44 guests