Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » Community » U++ community news and announcements » Painter refactored/optimized
Painter refactored/optimized [message #50488] Sun, 11 November 2018 13:47 Go to next message
mirek is currently offline  mirek
Messages: 11991
Registered: November 2005
Ultimate Member
After upgrading to 8C/16T machine, I was ashamed by pitiful gains (and terrible losses in some cases) of Painter performance in MT mode.

Which lead me to spending about 80 hours trying to optimize it. The result is about 10% improvement in ST performance and substantial improvements in MT - usually about 50%, but in some cases 200%. In some cases MT is now 6x faster than ST (on 8C/16T AMD 2700X).

Enjoy Smile

Mirek
Re: Painter refactored/optimized [message #50492 is a reply to message #50488] Sun, 11 November 2018 18:06 Go to previous messageGo to next message
Tom1
Messages: 635
Registered: March 2007
Contributor
Hi Mirek!

Absolutely great news! I just can't wait to get to the office tomorrow morning to test this!

Thanks and best regards,

Tom
Re: Painter refactored/optimized [message #50493 is a reply to message #50488] Sun, 11 November 2018 18:15 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 2980
Registered: August 2008
Veteran
Thank you Mirek.

Best regards
IƱaki
Re: Painter refactored/optimized [message #50495 is a reply to message #50488] Sun, 11 November 2018 19:55 Go to previous messageGo to next message
Novo is currently offline  Novo
Messages: 878
Registered: December 2006
Experienced Contributor
Thank you!
Could you please fix this:
uppsrc/Painter/BufferPainter.h:325:82: warning: control reaches end of non-void function [-Wreturn-type]
        BufferPainter&     NoImageCache(bool b = true)             { ImageCache(false); }
                                                                                        ^


Regards,
Novo
Re: Painter refactored/optimized [message #50497 is a reply to message #50488] Mon, 12 November 2018 09:25 Go to previous messageGo to next message
Tom1
Messages: 635
Registered: March 2007
Contributor
Hi Mirek,

It is faster indeed, but now some segments of strokes drop out on the right edge of the view if they are partially clipped by the right edge of the view. I think the 'blanking distance' from the right edge is erroneously dependent on the scaling in the transformation being used. (I use the scaling and transformation to implement zooming, rotation and panning of vector maps.)

Another issue is that Filled text drops out in the top edge when the text touches or crosses the edge of the view. The outline (Stroked) text gets drawn until half of it is clipped from the top. (They should obviously both be drawn as long as there are any pixels visible.)

Best regards,

Tom
Re: Painter refactored/optimized [message #50498 is a reply to message #50497] Mon, 12 November 2018 09:35 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11991
Registered: November 2005
Ultimate Member
Tom1 wrote on Mon, 12 November 2018 09:25
Hi Mirek,

It is faster indeed, but now some segments of strokes drop out on the right edge of the view if they are partially clipped by the right edge of the view. I think the 'blanking distance' from the right edge is erroneously dependent on the scaling in the transformation being used. (I use the scaling and transformation to implement zooming, rotation and panning of vector maps.)

Another issue is that Filled text drops out in the top edge when the text touches or crosses the edge of the view. The outline (Stroked) text gets drawn until half of it is clipped from the top. (They should obviously both be drawn as long as there are any pixels visible.)

Best regards,

Tom


Well, thanks for testing, in fact I was hoping you will test this and half expected that there will be issues.

Do you think it would be possible to provide screenshots and/or testcase?

Are this issue apparent both in ST and MT?

Also: In Render.cpp, line 142, there is

if(pathattr.mtx_serial != preclip_mtx_serial) {

try to change that to

if(pathattr.mtx_serial != preclip_mtx_serial || 1) {

Thanks, I will try hard to resolve this as soon as possible... (if you provide testcase, it should be really soon Smile

Mirek
Re: Painter refactored/optimized [message #50499 is a reply to message #50498] Mon, 12 November 2018 09:39 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11991
Registered: November 2005
Ultimate Member
One last thing, does it show these problems without preclip?
Re: Painter refactored/optimized [message #50500 is a reply to message #50498] Mon, 12 November 2018 09:55 Go to previous messageGo to next message
Tom1
Messages: 635
Registered: March 2007
Contributor
Mirek,

MT/ST does not have any effect on this.

You are absolutely right: Not using painter.PreClipDashed(); fixes both issues. (I do not use the old PreClip anymore after PreClipDashed was introduced.)

Using:
if(pathattr.mtx_serial != preclip_mtx_serial || 1) {

Fixes both issues too. Smile

Best regards,

Tom
Re: Painter refactored/optimized [message #50501 is a reply to message #50500] Mon, 12 November 2018 09:59 Go to previous messageGo to next message
Tom1
Messages: 635
Registered: March 2007
Contributor
As for a testcase, my (commercial) code is complex and figuring out a testcase will take a while. I'll see what I can do. Anyway, please let me know if the above already helped you on the track...

Thanks and best regards,

Tom
Re: Painter refactored/optimized [message #50503 is a reply to message #50501] Mon, 12 November 2018 10:08 Go to previous messageGo to next message
Tom1
Messages: 635
Registered: March 2007
Contributor
Hi,

After all, the test case was easy: Just use PainterExamples and add sw.PreClipDashed(); right after constructing the BufferPainter in App::Paint() in main.cpp.

Then compile and run PainterExamples, select Stroke example and drag the right edge of the window to gradually cover the the contents of the example. Both the line and the stroked text will disappear before they are fully covered by the window edge.

I'll stay tuned for the fix to test. Smile

Best regards,

Tom
Re: Painter refactored/optimized [message #50505 is a reply to message #50503] Mon, 12 November 2018 11:15 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11991
Registered: November 2005
Ultimate Member
Found and fixed 3 issues, can you test please?
Re: Painter refactored/optimized [message #50512 is a reply to message #50505] Mon, 12 November 2018 11:53 Go to previous messageGo to next message
Tom1
Messages: 635
Registered: March 2007
Contributor
Mirek,

As far as I can see, everything renders perfectly now.

Thank you very much for your excellent work on Painter again!!

Best regards,

Tom

Re: Painter refactored/optimized [message #50514 is a reply to message #50512] Mon, 12 November 2018 11:59 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11991
Registered: November 2005
Ultimate Member
BTW, preclipping is optimized as well. As long as you do not change transformation matrix too often, it should be significantly faster.
Re: Painter refactored/optimized [message #50516 is a reply to message #50514] Mon, 12 November 2018 12:39 Go to previous messageGo to next message
Tom1
Messages: 635
Registered: March 2007
Contributor
Hi,

I cannot confirm any change in PreClip() or PreClipDashed() performance with my usage profile. But it is true that my program tries really hard to not pass Painter anything that would not be visible at least partially. So, this may be the reason I'm not seeing the improvement here.

Importantly, both PreClip() and PreClipDashed() still improve rendering speed of a _very_ long partially visible horizontal dashed line from e.g. 10 seconds to about 0.9 seconds. I guess the only way to dramatically improve this is to clip the line before dashing it.

Is there any difference between the two preclip functions anymore?

Best regards,

Tom
Re: Painter refactored/optimized [message #50519 is a reply to message #50516] Mon, 12 November 2018 13:25 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11991
Registered: November 2005
Ultimate Member
Tom1 wrote on Mon, 12 November 2018 12:39
Hi,

I cannot confirm any change in PreClip() or PreClipDashed() performance with my usage profile. But it is true that my program tries really hard to not pass Painter anything that would not be visible at least partially. So, this may be the reason I'm not seeing the improvement here.

Importantly, both PreClip() and PreClipDashed() still improve rendering speed of a _very_ long partially visible horizontal dashed line from e.g. 10 seconds to about 0.9 seconds. I guess the only way to dramatically improve this is to clip the line before dashing it.

Is there any difference between the two preclip functions anymore?


Yes, they basically behave the same. What is new is that inverse matrix is now calculated only if transformation matrix changes.

Mirek
Re: Painter refactored/optimized [message #50522 is a reply to message #50519] Mon, 12 November 2018 16:15 Go to previous messageGo to next message
Tom1
Messages: 635
Registered: March 2007
Contributor
OK, that sounds logical. Smile

Thanks and best regards,

Tom
Re: Painter refactored/optimized [message #50523 is a reply to message #50522] Mon, 12 November 2018 23:42 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11991
Registered: November 2005
Ultimate Member
After integrating new Painter with the target application, I have initially noticed that performance is not so great.

Investigation revealed that the problem was the app was creating BufferPainter several times per 'frame'. So in order to achive good perfromance, it is advisable to limit the number of BufferPainter destructors called. I have ended with single BufferPainter as member variable that exists for the whole lifetime of the application.

There is now new method "BufferPainter::Create" that allow it to "rebind" to another ImageBuffer, keeping as much initialized internal data as possible.
Re: Painter refactored/optimized [message #50530 is a reply to message #50523] Tue, 13 November 2018 09:14 Go to previous messageGo to next message
Tom1
Messages: 635
Registered: March 2007
Contributor
Hi Mirek,

Here's the test result from this morning.

If I replace the following in my Paint() method:
BufferPainter painter(ib);

With the following:
painter.Create(ib);

And add a class variable 'BufferPainter painter;', The rendering will seemingly randomly drop various elements, especially texts, from the result when using MT. It does not matter if I have PreClip()/PreClipDashed() enabled or not. When using ST, everything works fine even with this new Create() mechanism. Also, if I use the traditional 'BufferPainter painter(ib);' on each Paint(), everything works fine with both MT and ST.

Best regards,

Tom
Re: Painter refactored/optimized [message #50531 is a reply to message #50530] Tue, 13 November 2018 09:18 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11991
Registered: November 2005
Ultimate Member
You have to call "Finish" at the end of rendering (that is also called by destructor). It waits for thread "pipeline" to finish the work.

Anyway, if you create single BufferPainter per render and you have thousands of polygons to render, you are probably fine. My problem was that my original code was creating like 30 BufferPainters...

Mirek
Re: Painter refactored/optimized [message #50532 is a reply to message #50531] Tue, 13 November 2018 09:35 Go to previous messageGo to previous message
Tom1
Messages: 635
Registered: March 2007
Contributor
Hi,

OK, I added 'sw.Finish();' in the end. There is still something strange with it.

Please add 'BufferPainter csw;' to PainterExamples App and Change the App::Paint() in main.cpp:
void App::Paint(Draw& w)
{
	Size sz = GetSize();
	if(ctrl.transparent) {
		for(int y = 0; y < sz.cy; y += 32)
			for(int x = 0; x < sz.cx; x += 32)
				w.DrawRect(x, y, 32, 32, (x ^ y) & 32 ? Color(254, 172, 120) : Color(124, 135, 253));
	}
	ImageBuffer ib(sz);
	{
		//BufferPainter sw(ib, ctrl.quality); // Removed
		csw.Create(ib, ctrl.quality); // Added
		
		BufferPainter &sw=csw;
		
		if(ctrl.transparent)
			sw.Clear(RGBAZero());
		else
			sw.Clear(White());
		sw.Co(ctrl.mt);
		DoPaint(sw);
		
		sw.Finish(); // Added
	}
	w.DrawImage(0, 0, ib);
	
}


Just scaling causes strange behavior.

Best regards,

Tom

EDIT: My own code worked fine again after adding the 'sw.Finish();'. However, it feels like the transformations do not get reset to default identity transformation in PainterExamples. Maybe this should be part of Create()...?
EDIT2: This appears to solve the issue with PainterExamples. Add the following in the end of BufferPainter::Create():
pathattr.mtx = attr.mtx = Xform2D::Identity();

However, I'm not sure if this breaks something else instead...

[Updated on: Tue, 13 November 2018 10:05]

Report message to a moderator

Previous Topic: Jsonize/Xmlize with lambda (and common template example)
Next Topic: Critical issues to resolve for U++ 2018.1 - please suggest
Goto Forum:
  


Current Time: Tue Aug 20 15:44:11 CEST 2019

Total time taken to generate the page: 0.01227 seconds