<div dir="ltr"><div><div><div>Hi, Stefano!<br><br></div>Short answer:<br></div><div><ul><li>If I were you I would take the following plan:</li></ul><ol style="margin-left:40px"><li>Port image color space conversion to the strokes framework as it is now. That is one layer --- one thread provided by the framework.</li><li>Then talk to the painters and ask them to test. Given that most of the painters have i5 (4 cores) and work with images that have more than 4 layers, it is highly probable (thought should be measured, of course) that no further steps will be needed. If measurements show that we still underutilize CPU power (using VTune for example), we can always implement further optimizations using QtConcurrent framework (we already use it in KisAutoBrush). Or we can improve KisProcessingApplicator class to handle that case if we end-up over-utilize CPU. All such optimization work should be always controlled by very tight measurements. Otherwise we can end up spending a month of work on making it 5-10% faster :)</li></ol><ul><li>Yes, you were right about the two-stage openGL update. I almost forgot about out talk. It should be done like resizing of the image, so KisCanvas2 should handle colorSpaceChanged() signal.<br></li></ul></div></div><div><div><div>Long answer:<br></div><div><div><div><div class="gmail_extra"><br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>Not everyone has a processor that can overclock one core to speed up applications with few threads, moreover threads are quite underutilized in Krita (or basicly there are very few if none operations that uses all the cores), and this will become worse when using even bigger images.</div></div></div></div></blockquote><div><br></div><div>When one is using KisProcessingApplicator, every layer is processed in a separate thread. That is if the number of layers is higher than the number of cores you have, the CPU will be fully loaded.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div></div><div>Also the idea is not to split the image whatever dimension it has, clearly a certain minimum rect dimension has to be chosen to be fed to a thread and also the number of cores will dictate how much parallelization has to be done (this if the multithreaded way needs any special code that may slow the single/few core way).</div></div></div></div></blockquote><div><br></div><div>And yes, KisUpdatesScheduler uses the number of cores to optimize the number of threads used.<br></div><div><br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><span class=""></span><div class="gmail_quote"><div>Here we agree, in fact i said that i didn't wanted to spawn threads from the thread dealing with processing and the current node visited, but it would make sense something like TBB or C# TPL does: you have a "generic" scheduler (in Krita we have it already, and it doesn't have to be that generic) where you can enqueue tasks/jobs from a job thread that is executed and those jobs are marked to be run as childs of the job thread they are launched in, so that they are actually part of the work the parent job has to do and the parent also waits on them (a parallel for on the rects to convert, and some could be processed by the caller so that the thread doesn't get unused).</div></div></div></div></blockquote><div><br></div><div>KisUpdatesScheduler is much higher level of abstraction than a "generic scheduler". It should know quite a lot about how the image should be processed and how jobs interfere each. The thing you are talking about is already implemented in Qt, it is called QtConcurrent framework. And you can use it. Though there are risks that the CPU will be saturated. But we have it in KisAutoBrush and it seems to work quite fine.<br></div><div><br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra">ColorSpaceChangedSignal is not handled by KisImage or any other class (a part from the signal rerouter), why shouldn't i handle it and do something with it?<div class="gmail_quote"><div>If you recall we talked about color conversion and there's a problem with the OpenGL texture bit format that is not updated when you do a conversion. </div></div></div></div></blockquote><div><br></div><div>Yes, you were totally right. KisCanvas2 should handle this event in exactly the same way resizing is done. And the processing should have KisProcessingApplicator::NO_UI_UPDATES flag as well.<br><br></div><div>It algorithm is like:<br><br></div><div>1) KisProcessingApplicator processes everything with  KisProcessingApplicator::NO_UI_UPDATES. That is it merges the image, but doesn't send any results to KisCanvas2.<br></div><div>2) Then it emits Qt::DirectConnection call to KisCanvas2::startConvertColorSpace (the stroke is still active, so the problem of thread safety is resolved)<br>3) startConvertColorSpace() will emit Qt::AutoConnection, which will be enqueued by Qt, whose handler will reset openGL texture format.<br>4) startConvertColorSpace() will do startUpdateInPatches() which would do two things: 1) fetch the image from the image into temporary objects (remember about thread-safety!); 2) enqueue these objects into the Qt's queue to update the newly generated textures after their format is change.<br></div><br></div><br>-- <br><div class="gmail_signature">Dmitry Kazakov</div>
</div></div></div></div></div></div></div>