Page 1 of 1

thread crashes in wxGDIPlusContext::DrawLines

Posted: Thu Jul 04, 2019 12:52 pm
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!

Re: thread crashes in wxGDIPlusContext::DrawLines

Posted: Thu Jul 04, 2019 1:35 pm
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.

Re: thread crashes in wxGDIPlusContext::DrawLines

Posted: Thu Jul 04, 2019 2:37 pm
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?

Re: thread crashes in wxGDIPlusContext::DrawLines

Posted: Thu Jul 04, 2019 2:53 pm
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.

Re: thread crashes in wxGDIPlusContext::DrawLines

Posted: Thu Jul 04, 2019 4:19 pm
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!

Re: thread crashes in wxGDIPlusContext::DrawLines

Posted: Thu Jul 04, 2019 4:27 pm
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.

Re: thread crashes in wxGDIPlusContext::DrawLines

Posted: Thu Jul 04, 2019 4:28 pm
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?

Re: thread crashes in wxGDIPlusContext::DrawLines

Posted: Thu Jul 04, 2019 4:32 pm
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 ;)

Re: thread crashes in wxGDIPlusContext::DrawLines

Posted: Thu Jul 04, 2019 4:35 pm
by doublemax
Apparently you were using the default GDIPlus backend. Try the Direct2D one. Maybe it's faster.

-> wxGraphicsRenderer::GetDirect2DRenderer()

Re: thread crashes in wxGDIPlusContext::DrawLines

Posted: Fri Jul 05, 2019 8:45 am
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.

Re: thread crashes in wxGDIPlusContext::DrawLines

Posted: Fri Jul 05, 2019 9:21 am
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.

Re: thread crashes in wxGDIPlusContext::DrawLines

Posted: Fri Jul 05, 2019 11:55 am
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.

Re: thread crashes in wxGDIPlusContext::DrawLines

Posted: Sat Jul 06, 2019 10:44 am
by mael15
Problem solved by using good old wxMemoryDC instead of wxGraphicsContext. Thanx for your thoughts, they helped me figuring it out!