Home » Community » U++ community news and announcements » Painter refactored/optimized
|
|
|
|
|
|
| Re: Painter refactored/optimized [message #50495 is a reply to message #50488] |
Sun, 11 November 2018 19:55   |
Novo
Messages: 1432 Registered: December 2006
|
Ultimate 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   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate 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   |
 |
mirek
Messages: 14291 Registered: November 2005
|
Ultimate Member |
|
|
Tom1 wrote on Mon, 12 November 2018 09:25Hi 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 
Mirek
|
|
|
|
|
|
|
|
| Re: Painter refactored/optimized [message #50501 is a reply to message #50500] |
Mon, 12 November 2018 09:59   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate 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 #50516 is a reply to message #50514] |
Mon, 12 November 2018 12:39   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate 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 #50530 is a reply to message #50523] |
Tue, 13 November 2018 09:14   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate 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:
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 #50532 is a reply to message #50531] |
Tue, 13 November 2018 09:35   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate 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
|
|
|
|
|
|
| Re: Painter refactored/optimized [message #50535 is a reply to message #50534] |
Tue, 13 November 2018 11:52   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate Contributor |
|
|
Yes. Begin()/End() around DoPaint(); equally fixes the issue with PainterExamples. But I think it would be nice to have a clean table after BufferPainter::Create()... Of course, I understand that each re-initialized variable increases the cost towards full constructor/destructor pair.
Best regards,
Tom
|
|
|
|
|
|
|
|
| Re: Painter refactored/optimized [message #50538 is a reply to message #50537] |
Tue, 13 November 2018 12:50   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate Contributor |
|
|
The issue is still there in SVN 12531 if you do my above changes to PainterExamples. (Obviously, adding Begin/End will still remove the issue.)
I can't figure out what exactly you changed in Create though. Or am I working on a completely wrong SVN version?
Best regards,
Tom
|
|
|
|
|
|
| Re: Painter refactored/optimized [message #50540 is a reply to message #50539] |
Tue, 13 November 2018 14:06   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate Contributor |
|
|
OK, the file was correctly updated. (Reverting my changes simultaneously slightly misguided me to believe otherwise.)
Anyway the problem is still there: The transformation matrix does not get reset to identity in Create.
Best regards,
Tom
|
|
|
|
|
|
|
|
| Re: Painter refactored/optimized [message #50546 is a reply to message #50542] |
Wed, 14 November 2018 10:57   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate Contributor |
|
|
Hi Mirek,
As of r12533 Create now works as expected 
However, there seems to be a severe performance issue with MT. In some cases MT can be three times slower than MT before this optimization round. E.g. a vector map rendering in 20 ms with previous MT and in 40 ms with ST now takes 60 ms with new MT.
This is somehow related to changing transformations (of course within Begin/End pairs) which is now extremely expensive, especially when using MT.
Thanks and best regards,
Tom
EDIT: I created a transformation intensive view that shows a matrix of just 90 symbols. Each of the symbols are drawn with strokes and fills using a different translation for each within a Begin/End pair. Rendering of this same view takes only 2.2 ms with ST but a whopping 45 ms with MT! Using PreClip or not does not have any observable effect on the result.
[Updated on: Wed, 14 November 2018 11:37] Report message to a moderator
|
|
|
|
|
|
| Re: Painter refactored/optimized [message #50548 is a reply to message #50547] |
Wed, 14 November 2018 13:39   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate Contributor |
|
|
Hi,
You can test with PainterExamples by enabling MT and running Benchmark with OnPath and OnTextPath examples.
Best regards,
Tom
EDIT: 'Pythagoras Tree Image' example portrays this slowdown too. Every other PainterExamples example running MT is on par or faster compared to ST. With my 4C8T Intel Core i7 the best MT gain is about 4x compared to ST. This is common with images and fills. Narrow geometries do not gain so much boost from MT landing at 1x-2x speed improvement.
[Updated on: Wed, 14 November 2018 14:03] Report message to a moderator
|
|
|
|
| Re: Painter refactored/optimized [message #50549 is a reply to message #50548] |
Wed, 14 November 2018 14:38   |
 |
mirek
Messages: 14291 Registered: November 2005
|
Ultimate Member |
|
|
Tom1 wrote on Wed, 14 November 2018 13:39Hi,
You can test with PainterExamples by enabling MT and running Benchmark with OnPath and OnTextPath examples.
Best regards,
Tom
EDIT: 'Pythagoras Tree Image' example portrays this slowdown too. Every other PainterExamples example running MT is on par or faster compared to ST. With my 4C8T Intel Core i7 the best MT gain is about 4x compared to ST. This is common with images and fills. Narrow geometries do not gain so much boost from MT landing at 1x-2x speed improvement.
I have found that BeginOnPath was conservatively flushing rendering pipeline for no good reason, so that is now optimized out. TextOnPath is still slower if you fill the letters, that will have to wait till next batch of optimization I am afraid.
In fact, what is slow is alternating solid color / non-solid color fills - that is the case for both Pythagoras Tree Image and TextOnPath... Will have to think if there is anything I can do there...
[Updated on: Wed, 14 November 2018 14:40] Report message to a moderator
|
|
|
|
|
|
| Re: Painter refactored/optimized [message #50551 is a reply to message #50550] |
Wed, 14 November 2018 14:56   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate Contributor |
|
|
Hi,
Absolutely! I'm extremely motivated to help you squeeze every single extra millisecond out of the rendering times in Painter!
OnPath show now 1.4x improvement over ST and OnTextPath about 2.3x improvement... And these were over ST not over previous MT where improvement is 5x that. Well done Mirek!
A question --- removed ---
Best regards,
Tom
EDIT: Removing question. Something else is now slowing down my code. It may be related to translations (Xform2D).
[Updated on: Wed, 14 November 2018 15:07] Report message to a moderator
|
|
|
|
|
|
| Re: Painter refactored/optimized [message #50553 is a reply to message #50552] |
Wed, 14 November 2018 15:55   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate Contributor |
|
|
Hi,
My translated symbols are simply solid black over white background. The ST vs. MT speed ratio is about 15..20x in favor of ST. They were about equally fast when compiled against r.11960.
I need to find a pattern here. There is no clear Begin/End dependency as far as I can see. I'm trying to narrow down the code to find a test case.
Best regards,
Tom
|
|
|
|
|
|
| Re: Painter refactored/optimized [message #50557 is a reply to message #50554] |
Thu, 15 November 2018 10:14   |
Tom1
Messages: 1319 Registered: March 2007
|
Ultimate Contributor |
|
|
Hi,
I finally figured out a way to share this test case. I send you code and a Serialized Painting to test. (Actually, this can be quite handy for any Painter performance issue testing in general.) Here's the code:
#include <CtrlLib/CtrlLib.h>
#include <Painter/Painter.h>
using namespace Upp;
class PainterBench : public TopWindow {
public:
Painting p;
FileSel fs;
void Open(){
if(fs.ExecuteOpen("Select a painting to view")){
p.Clear();
p.Serialize(FileIn(fs.Get()));
}
}
virtual bool Key(dword key, int count){
switch(key){
case K_CTRL_O:
Open();
return true;
}
return false;
}
typedef PainterBench CLASSNAME;
PainterBench(){
Sizeable();
}
virtual void Paint(Draw &draw){
int64 STtiming=0;
int64 MTtiming=0;
ImageBuffer ib(GetSize());
{
BufferPainter bpainter(ib);
bpainter.Co(true);
bpainter.PreClipDashed();
bpainter.Clear(White());
bpainter.EvenOdd();
int64 t0=usecs();
bpainter.Paint(p);
int64 t1=usecs();
MTtiming=t1-t0;
}
{
BufferPainter bpainter(ib);
bpainter.Co(false);
bpainter.PreClipDashed();
bpainter.Clear(White());
bpainter.EvenOdd();
int64 t0=usecs();
bpainter.Paint(p);
int64 t1=usecs();
STtiming=t1-t0;
}
SetSurface(draw,Rect(ib.GetSize()),ib,ib.GetSize(),Point(0,0));
double gain=(double)STtiming/(double)(0.1+MTtiming); // Avoid div by zero
Title(Format("Rendering MT took %lld us, ST took %lld us, MT gain is %.2f",MTtiming,STtiming,gain));
}
};
GUI_APP_MAIN
{
PainterBench().Run();
}
There are two Serialized painting files to test with: SomeRocks.painting exhibits the MT slowdown issue dramatically. The other file is just for checking how fast a typical map view renders.
Best regards,
Tom
|
|
|
|
|
|
Goto Forum:
Current Time: Fri Jun 19 07:36:18 GMT+2 2026
Total time taken to generate the page: 0.01671 seconds
|