[libbreezecommon] Use box blur instead of FFT blur
ClosedPublic

Authored by zzag on Sep 14 2018, 8:12 PM.

Details

Summary

Creation of shadows (especially for "Large" and "Very large" sizes) is
a computation expensive task because we have to blur alpha channel of a
shadow texture (which then will be tinted with desired shadow color).

Currently, we use the following approach:

  • for blur radius less than 64, use naive 2-pass algorithm;
  • for blur radius greater than or equal to 64, use FFT.

Even though the FFT approach is doing its the best, it still takes
impresive amount of time to blur the alpha channel.

What makes things even worse is that while we're blurring the alpha
channel, we're blocking the main thread of KWin (decorations are not
rendered in their own thread). This can result in frame drops (2 or 3
frames, something like that).

So, the only viable alternative is to use an approximation of the Gaussian
blur. As such an approximation, I picked the box blur because it's quite
simple, it's fast, and it takes small amount of iterations to have something
similar to the true Gaussian blur.

In general, there are no big differences between true gaussian shadows
and approximated shadows:

Before:

After:

Before:

After:

As a win, it takes much less time to generate decoration shadows.

Diff Detail

Repository
R31 Breeze
Branch
zzag/box-shadow-helper-box-blur
Lint
No Linters Available
Unit
No Unit Test Coverage
Build Status
Buildable 3655
Build 3673: arc lint + arc unit
zzag created this revision.Sep 14 2018, 8:12 PM
Restricted Application added a project: Plasma. · View Herald TranscriptSep 14 2018, 8:12 PM
Restricted Application added a subscriber: plasma-devel. · View Herald Transcript
zzag requested review of this revision.Sep 14 2018, 8:12 PM
zzag updated this revision to Diff 41663.Sep 14 2018, 8:35 PM

Edit comments

abetts added a subscriber: abetts.Sep 14 2018, 8:36 PM

Interesting, no big real differences visually IMHO

zzag updated this revision to Diff 41665.Sep 14 2018, 8:42 PM

Call reserve method

Yeah, I also can't tell the difference. If this new way is computationally cheaper, then +1 from me.

zzag added a comment.Sep 14 2018, 8:53 PM

Yeah, I also can't tell the difference. If this new way is computationally cheaper, then +1 from me.

I don't want to say numbers (because in order to have proper benchmark, I have to test it on variety of different hardware), but with the debug build (on my crappy 2012 laptop) + some load (Firefox), on average, it takes 10x less time to generate shadows.

zzag updated this revision to Diff 41666.Sep 14 2018, 8:56 PM

Code formatting

zzag planned changes to this revision.Sep 14 2018, 9:03 PM

Simplify it further.

zzag updated this revision to Diff 41667.Sep 14 2018, 9:23 PM

Simplify code, also delete unrelated changes

cfeck added a subscriber: cfeck.Sep 14 2018, 11:27 PM

I would even say 'after' looks better, because the bottom shadow isn't as strong as 'before'.

zzag edited the summary of this revision. (Show Details)Sep 23 2018, 6:11 PM
zzag added a comment.Sep 23 2018, 6:41 PM

I would even say 'after' looks better, because the bottom shadow isn't as strong as 'before'.

Hmm, yes, it's lighter a little bit. I think that's still fine because 'after' looks quite similar to what browsers render:

On the left hand side: what Firefox renders; On the right hand side: what we get with the box blur.

zzag retitled this revision from [libbreezecommon] Use box blur instead of FFT approach to [libbreezecommon] Use box blur instead of FFT blur.Sep 23 2018, 6:43 PM

Still +1, looks great!

zzag updated this revision to Diff 42295.Sep 25 2018, 10:11 AM

Comment on why shadows are a little bit lighter.

zzag updated this revision to Diff 42505.Sep 28 2018, 5:00 PM

Introduce BoxShadowRenderer helper

BoxShadowRenderer is a helper to render box shadows. The main benefit of
this class is that it takes care of allocating big enough shadow
texture, so the resulting shadows are not clipped, etc. Also, conceptually,
it makes sense to have it.

The box blur implementation is based on AlphaBoxBlur from Firefox, which means
that the resulting shadows look quite similar to what Firefox would render.

With debug build, opened web browser (Firefox), and a text editor (VS Code),
on average it takes less than 16ms to render decoration shadows for all sizes:

  • small: <1 ms
  • medium: 1-2ms
  • large: 5ms (+/- 1ms)
  • very large: 11ms (+/- 1ms)

Things to do:

  • revise shadow params (shadows are rendered slightly differently now)
  • clean up the code
zzag planned changes to this revision.Sep 28 2018, 5:01 PM
zzag edited the summary of this revision. (Show Details)Sep 28 2018, 6:47 PM
zzag updated this revision to Diff 43140.Oct 8 2018, 4:55 PM
  • Clean up code;
  • Revise shadow params: Because shadows are rendered slightly differently now, we have to revise params. For example, with the large size, shadows are not large, they are extremely large. I've tried to preserve the old look as much as possible;
  • Add explanation how shadow params are computed.
zzag edited the summary of this revision. (Show Details)Oct 8 2018, 4:57 PM
zzag added a comment.Oct 8 2018, 5:02 PM

Currently, it takes less than 5ms to generate shadows with the debug build.

  • small: < 1ms
  • medium: 1ms
  • large: 2ms
  • very large: 3ms
zzag edited the summary of this revision. (Show Details)Oct 8 2018, 5:38 PM
zzag updated this revision to Diff 43146.Oct 8 2018, 5:41 PM

Decrease the standard deviation scale constant

zzag updated this revision to Diff 43154.Oct 8 2018, 6:43 PM

Update copyright info

ngraham accepted this revision.Oct 8 2018, 7:31 PM
This revision is now accepted and ready to land.Oct 8 2018, 7:31 PM
zzag updated this revision to Diff 43161.Oct 8 2018, 7:42 PM

Adjust MDI shadows

zzag added a comment.Oct 27 2018, 12:35 PM

Landing it...

zzag closed this revision.Oct 27 2018, 12:47 PM
fvogt reopened this revision.Oct 27 2018, 2:05 PM
fvogt added a subscriber: fvogt.

Fails to build the KDE4 version here:

[   76s] /home/abuild/rpmbuild/BUILD/breeze-5.14.80git.20181027T152517~f1e4f103/libbreezecommon/breezeboxshadowrenderer.cpp:29:10: fatal error: QtMath: No such file or directory
[   76s]  #include <QtMath>
This revision is now accepted and ready to land.Oct 27 2018, 2:05 PM
zzag closed this revision.Oct 27 2018, 2:46 PM

It's fixed now.

abetts removed a subscriber: abetts.Oct 27 2018, 2:47 PM