GNOME Bugzilla – Bug 780859
Brush hardness blur is slow
Last modified: 2018-05-24 17:40:12 UTC
Created attachment 349155 [details] Samples and duration estimated for each case brush How demonstrate the freezing: 1) Use two kind of brushes, raster and parametric. 2) Begins paint a line with the Paintbrush (recommended with Ctrl+Shift) with the parametric brush with a linear curve on hardness paint dynamic; 3) After, paint another line with Paintbrush (is very recommended with Ctrl+Shift) using the same linear curve on hardness paint dynamic (is necessary circa 150 seconds in my computer*); 4) Modify the paint dynamic curve from linear to a fast curve, see my figure, and apply again the brushes (parametric and after the raster brush). Is necessary circa 100 seconds to finish the stroke with raster brush. 5) I have a final test with a slow curve to hardness on paint dynamics, see my figure. In this case was necessary also 150 seconds as the linear curve. On Tool Options were used: Opacity: 100% Size: 50 pixels Hardness: as default of parametric = 100% Force: 50% Computer* --- ubuntu gnome 14.04 GNOME 3.10 Intel® Core™ i5-3570K CPU @ 3.40GHz × 4 | 8GB memory Video cart | Gallium 0.4 on AMD CAICOS, 1GB -- GIMP 2.9.5 Git Master commit 79a0ca5
Created attachment 349156 [details] Brushes used in this Test Parametric and Raster brush designed with same size, shape and hardness.
The blurring we're doing when hardness < 1 is simply that slow, that's pretty much it :P When the hardness changes dynamically, so that caching doesn't save us, it shows. The convolution kernel we're using for this blur is a little weird (not d8 symmetric, for example); not sure why we're using this specific kernel, and not, say, a more conventional blur, like gaussian or even box. Anyway, we're currently using a generic convolution algorithm, that, for an n-by-n kernel, has a complexity of O(n^2) per pixel. With a bit of cunning, I think we can actually do this kernel in O(1) pp. There's definitely room for improvement.
I have made tests, and I have prepared some figures about this hardness behavior on raster brushes. Is useful create attachments of these figures in this bug report? Between the raster brushes (.gbr and .gih), the .gbr brush has this bug with hardness. The .gih are acceptable, not optimal, the behavior... because is not producing the freezing of GIMP ;-). I have made some tests how the blur is working, and is very strange its behavior: with same shape of a .vbr brush... the blur aspect of the .gbr brush is very different. The .vbr are working well with hardness instances on tool options and with paint dynamics curves. I am not sure... but this issue could have relationship with the #780337.
I'm repurposing this bug as a general "hardness is slow" bug, since this is the actual issue here.
(In reply to jose americo gobbo from comment #3) > I have made tests, and I have prepared some figures about this hardness > behavior on raster brushes. Is useful create attachments of these figures in > this bug report? Yes, figures would be useful as a benchmark against future improvements, especially if you could run the same tests again in the future. > Between the raster brushes (.gbr and .gih), the .gbr brush has this bug with > hardness. The .gih are acceptable, not optimal, the behavior... because is > not producing the freezing of GIMP ;-). Pipe brushes (.gih) shouldn't be any faster here. The difference is probably due to bug 780337. > I have made some tests how the blur is working, and is very strange its > behavior: with same shape of a .vbr brush... the blur aspect of the .gbr > brush is very different. There's no direct relation between how hardness affects generated and raster brushes, but, yeah, the blur amount is qualitatively very different. This can be improved, but that's another issue. > I am not sure... but this issue could have relationship with the #780337. These bugs are not directly related, but if we can make hardness faster, caching blurred versions of brushes might become less critical.
(In reply to Ell from comment #5) > > I have made some tests how the blur is working, and is very strange its > > behavior: with same shape of a .vbr brush... the blur aspect of the .gbr > > brush is very different. > > There's no direct relation between how hardness affects generated and raster > brushes, but, yeah, the blur amount is qualitatively very different. This > can be improved, but that's another issue. Interesting, so what you suggest me as a good title to report this bug? The blur effect on the .gbr is creating an effect is very similar of two ovals superposed... I have all figures ready.
(In reply to jose americo gobbo from comment #6) > Interesting, so what you suggest me as a good title to report this bug? > The blur effect on the .gbr is creating an effect is very similar of two > ovals superposed... I have all figures ready. Oh, I thought you were talking about performance figures. Well, these are useful too :)
(In reply to Ell from comment #7) > (In reply to jose americo gobbo from comment #6) > > Interesting, so what you suggest me as a good title to report this bug? > > The blur effect on the .gbr is creating an effect is very similar of two > > ovals superposed... I have all figures ready. > > Oh, I thought you were talking about performance figures. Well, these are > useful too :) So, I have open a bug report about these tests here: https://bugzilla.gnome.org/show_bug.cgi?id=780950 See, if is useful ;-)
Things should be much faster now. Could you run the same tests from the original comment, and report how long it takes with the commit below? New blur implementation in master: commit da30b86ffc01ffd809a025290f20951d8269e401 Author: Ell <ell_se@yahoo.com> Date: Fri Apr 7 10:14:05 2017 -0400 Bug 780859 - Brush hardness blur is slow Add a specialized convolution algorithm for the hardness blur. It uses the same kernel as before, but performs the convolution in (amortized) O(1)-per-pixel time, instead of O(n^2), where n is the size of the kernel (or the blur radius). Note that the new code performs the convolution in the input color space, instead of always using a linear space. Since our brush pixmaps (but the not masks) are currently perceptual, the result is a bit different. app/core/gimpbrush-transform.c | 257 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------- 1 file changed, 171 insertions(+), 86 deletions(-)
(In reply to Ell from comment #9) > Things should be much faster now. Could you run the same tests from the > original comment, and report how long it takes with the commit below? I have problems with the 'make' on GEGL... and with the 'git pull -r' on gimp clone. I have solved the issue around the dependencies some days ago with harfbuzz and all OK apparently.
So the behavior is better if we do a comparison with previous time values. Now the parametric is with same, apparently value, below of 0,1 seconds, and the .gbr brushes with 1 second circa.
Created attachment 349487 [details] Samples and duration estimated for each case brush - after commit-da30b86-ell Test 2 after commit-da30b86 by ell.
I have tested to see the behavior in relation of bug #780337. This the bug doesn't have anything with the current bug.
So, ~100x speedup, not too shabby :) I think we're within the acceptable range now. This particular case can be much faster still by disabling blur caching, since we're blurring the brush at its original size (256x256), instead of its applied size (50x50), so we have ~25x more pixels to process.
Thanks Ell to the efforts in this case! In fact, I will made a test with full size and with spacing=1 to have how the blur chaching is working in this case... of my fast-tests now... is a bit bad. So, my questions are: 1) what happens if is disabled the blur? 2) is possible to increase the performance of blur caching, modifying how the blur is applied on the brush? See my notes on bug #780950.
Created attachment 349498 [details] Performance of Hardness curves on parametric brush > size=257px, Spacing=1 Around 3 seconds for all curve cases.
Created attachment 349499 [details] Performance of Hardness curves on raster brush (.gbr) > size=256px, Spacing=1 All curve cases around 4 sec.
Comment on attachment 349499 [details] Performance of Hardness curves on raster brush (.gbr) > size=256px, Spacing=1 Correct description, instead 257px, 256px.
A few improvements, in master: commit 257504cbc2d1f87611351eaa002de780bdcd873c Author: Ell <ell_se@yahoo.com> Date: Sat Apr 8 04:30:35 2017 -0400 Bug 780859 - Brush hardness blur is slow A few additional minor speedups. Also, make sure we don't overflow for large blur radii. Not a problem yet, since the blur radius is capped, but soon... app/core/gimpbrush-transform.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------- 1 file changed, 51 insertions(+), 33 deletions(-) I've disabled blur caching for now, which should also give a nice speed bump in many cases: commit 810f1fc72219c64685c24b016a1584b991704aad Author: Ell <ell_se@yahoo.com> Date: Sat Apr 8 04:59:51 2017 -0400 app: disable brush blur caching Blurring is much faster now, and the cache mostly gets in the way. This is a quick hack to disable blur caching for now. app/core/gimpbrush.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
We must decide if this approach is definitive or could be improved, so we needinfo.
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/gimp/issues/1080.