thread crashes in wxGDIPlusContext::DrawLines Topic is solved

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.
Post Reply
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

thread crashes in wxGDIPlusContext::DrawLines

Post by mael15 »

I have one of these crashes in a thread with none of the usual debug info. How can I get to the bottom of this?
this is the call stack:
[Externer Code]
> wxmsw31ud_core_vc_x64_custom.dll!GdipDrawLines(Gdiplus::GpGraphics * graphics, Gdiplus::GpPen * pen, const Gdiplus::PointF * points, int count) Zeile 916 C++
[Externer Code]
wxmsw31ud_core_vc_x64_custom.dll!wxGDIPlusContext::DrawLines(unsigned __int64 n, const wxPoint2DDouble * points, wxPolygonFillMode __formal) Zeile 1564 C++
ecInspector.exe!PaintPlotterXYThread::Entry() Zeile 1841 C++
wxbase31ud_vc_x64_custom.dll!wxThread::CallEntry() Zeile 356 C++
wxbase31ud_vc_x64_custom.dll!wxThreadInternal::DoThreadStart(wxThread * thread) Zeile 551 C++
wxbase31ud_vc_x64_custom.dll!wxThreadInternal::WinThreadStart(void * param) Zeile 583 C++
[Externer Code]
all of the parameters seem fine, although the point array is 44300 points big and I cannot check them all. there is no output in the debug output window, the thread just froze there. there is no reason to suspect any of the usual thread problems, no other thread accessing the same data.

could this be problematic somehow? it is for preparing the context just before DrawLines:

Code: Select all

graphCtxt->SetBrush(wxBrush(backCol));
graphCtxt->SetPen(wxPen()/*wxPen(255, 0 ,0)*/);
double wid, hei;
graphCtxt->GetSize(&wid, &hei);
graphCtxt->DrawRectangle(0, 0, wid, hei);

graphCtxt->SetPen(pltCfgXY->getSignalColor());
preparing, because i set the mask color to backCol later...

Thanks for your thoughts!
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: thread crashes in wxGDIPlusContext::DrawLines

Post by doublemax »

Are you saying this code runs in a secondary thread?

If yes, try the same code from the main thread. If it works there, you have your answer.

If it crashes there too, try decreasing the number of points. Although i couldn't find any documentation that mentions a limit like that in GDI+, i wouldn't be surprised if there is one.
Use the source, Luke!
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: thread crashes in wxGDIPlusContext::DrawLines

Post by mael15 »

doublemax wrote: Thu Jul 04, 2019 1:35 pm Are you saying this code runs in a secondary thread?

If yes, try the same code from the main thread. If it works there, you have your answer.

If it crashes there too, try decreasing the number of points. Although i couldn't find any documentation that mentions a limit like that in GDI+, i wouldn't be surprised if there is one.
Yes, this was from a secondary thread. The code still freezes when called from the main thread, of course now freezing the whole app. It also has nothing to do with what I do before drawing, it stays the same when reducing it to

Code: Select all

graphCtxt = wxGraphicsContext::Create(*getTempImage());
graphCtxt->SetPen(wxColor(200, 35, 0));
graphCtxt->DrawLines(numPntsToPaint, &doubleVec[0]);
so not a thread problem, also stays the same when I eliminate that getTempImage() pointer and use a stack wxImage instead. what else is possible?
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: thread crashes in wxGDIPlusContext::DrawLines

Post by doublemax »

What's the size of the image and the range of coordinates?

Does it work if you replace DrawLines with StrokeLines? Drawing a filled polygon with that many points must require a lot of calculations and internal buffers. Have you tried reducing the number of points?

Code: Select all

&doubleVec[0];
If this is allocated on the stack, try allocating on the heap.
Use the source, Luke!
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: thread crashes in wxGDIPlusContext::DrawLines

Post by mael15 »

doublemax wrote: Thu Jul 04, 2019 2:53 pm What's the size of the image and the range of coordinates?
image size 724x724, the extreme values of the coodinates are:
x: 99,26|477,08 y:-153,42|1310,00
doublemax wrote: Thu Jul 04, 2019 2:53 pm Does it work if you replace DrawLines with StrokeLines?
It does not work either.
doublemax wrote: Thu Jul 04, 2019 2:53 pm Have you tried reducing the number of points?
Yes! It actually works if I paint only 1000 instead of 44300 with this one signal. and it works but takes a couple of seconds when painting 10000.
is there any way to determine if drawing is still in progress (but very slow) or if it has crashed altogether?
doublemax wrote: Thu Jul 04, 2019 2:53 pm try allocating on the heap.
It still crashed.

Thank you very much for taking the time!
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: thread crashes in wxGDIPlusContext::DrawLines

Post by mael15 »

i have watched the windows 10 ressource monitor, it seems to freeze when when the amount of "zugesichert" ram exceeds about 60000 kB. does that make sense?!

EDIT: when i wrote this the drawing finished after one minute, so it probably is not a freeze but a very slow drawing.
Last edited by mael15 on Thu Jul 04, 2019 4:29 pm, edited 1 time in total.
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: thread crashes in wxGDIPlusContext::DrawLines

Post by doublemax »

It looks like it's a GDI+ problem/limit.

Does it work to draw direct to screen instead of into an image?

Code: Select all

x: 99,26|477,08 y:-153,42|1310,00 
The only other thing i would try is to make sure that all coordinates are inside the image and that there are no negative coordinates.

Code: Select all

and it works but takes a couple of seconds when painting 10000. 
it would be interesting to see where the tipping point is, e.g. maybe at 16383/16384 or 32767/32768?
Use the source, Luke!
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: thread crashes in wxGDIPlusContext::DrawLines

Post by doublemax »

when i wrote this the drawing finished after one minute, so it probably is not a freeze but a very slow drawing.
Ok. So everything is solved then ;)
Use the source, Luke!
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: thread crashes in wxGDIPlusContext::DrawLines

Post by doublemax »

Apparently you were using the default GDIPlus backend. Try the Direct2D one. Maybe it's faster.

-> wxGraphicsRenderer::GetDirect2DRenderer()
Use the source, Luke!
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: thread crashes in wxGDIPlusContext::DrawLines

Post by mael15 »

Thank you for your feedback!
doublemax wrote: Thu Jul 04, 2019 4:35 pm Apparently you were using the default GDIPlus backend. Try the Direct2D one. Maybe it's faster.

-> wxGraphicsRenderer::GetDirect2DRenderer()
I could not find this, could you post a link to the documentation please?

I actually do not remember why I used a wxGraphicsContext in the first place. Was it because I draw in a thread? Why not use a wxMemoryDC, if that would make a difference anyway?
doublemax wrote: Thu Jul 04, 2019 4:28 pm Does it work to draw direct to screen instead of into an image?
Yes, drawing to a wxClientDC works fine and fast, but I would rather draw to an image for when the number of points gets really high. Just to paint as little as possible.
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: thread crashes in wxGDIPlusContext::DrawLines

Post by doublemax »

https://docs.wxwidgets.org/trunk/classw ... 3591b9d4ef
You need wx 3.1.x for this. The "drawing" sample shows how to use this.
I actually do not remember why I used a wxGraphicsContext in the first place.
Maybe you needed anti-aliasing?
Yes, drawing to a wxClientDC works fine and fast
Interesting. I wouldn't have expected a big performance difference.
Use the source, Luke!
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: thread crashes in wxGDIPlusContext::DrawLines

Post by mael15 »

I cannot remember needing anti-alias, so I will try drawing without wxGraphicsContext, also try the 2DRenderer you mentioned.
One big difference is using wxPoint in the "normal" drawing and wxPoint2DDouble in the problematic one.
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: thread crashes in wxGDIPlusContext::DrawLines

Post by mael15 »

Problem solved by using good old wxMemoryDC instead of wxGraphicsContext. Thanx for your thoughts, they helped me figuring it out!
Post Reply