Bug 22102 - -webkit-box-shadow causes awful scroll/resize/redraw performance
Summary: -webkit-box-shadow causes awful scroll/resize/redraw performance
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: CSS (show other bugs)
Version: 528+ (Nightly build)
Hardware: Mac OS X 10.5
: P2 Normal
Assignee: Simon Fraser (smfr)
URL:
Keywords: InRadar
: 27505 39601 41031 (view as bug list)
Depends on: 14606 51420
Blocks:
  Show dependency treegraph
 
Reported: 2008-11-06 09:03 PST by Will Will
Modified: 2013-07-09 22:31 PDT (History)
32 users (show)

See Also:


Attachments
Testcase (378 bytes, text/html)
2008-11-06 12:13 PST, Anthony Ricaud
no flags Details
Another example of awful performance (495 bytes, text/html)
2009-02-16 23:56 PST, Eric Seidel (no email)
no flags Details
Testcase #3 (4.22 KB, application/zip)
2009-04-20 18:52 PDT, Mike Wille
no flags Details
Test Case (Box shadow over a fixed background image). (16.81 KB, text/html)
2010-05-27 01:09 PDT, Richard Connamacher
no flags Details
Test of box-shadows with animation (33 bytes, text/plain)
2010-09-07 17:32 PDT, white.mans.fire
no flags Details
Patch (883.04 KB, patch)
2010-12-23 20:59 PST, Simon Fraser (smfr)
no flags Details | Formatted Diff | Diff
Patch (948.58 KB, patch)
2010-12-24 11:15 PST, Simon Fraser (smfr)
no flags Details | Formatted Diff | Diff
Patch (1.17 MB, patch)
2011-01-30 19:15 PST, Simon Fraser (smfr)
mitz: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Will Will 2008-11-06 09:03:06 PST
Drop shadows on large DIV's cause scroll performance to decrease dramatically. Specifically, scrolling a large container DIV will make the scrolled document jump instead of scrolling smoothly. The document I used a drop shadow on was of low complexity. I believe this is a severe problem that needs to be addressed before the drop shadow feature is released. 

CSS used: 

-webkit-box-shadow: 0 8px 64px #000; 	
-webkit-border-radius: 5px; 

Performance seems to improve when the spread (64px) of the shadow is decreased, e.g. to 10px. This must have to do with the underlying rendering algorithms.

Oh, CPU/Model was as follows (~1 year old MacBook Pro 15") :   
  Model Name:	MacBook Pro
  Model Identifier:	MacBookPro3,1
  Processor Name:	Intel Core 2 Duo
  Processor Speed:	2.4 GHz
  Number Of Processors:	1
  Total Number Of Cores:	2
  L2 Cache:	4 MB
  Memory:	2 GB
  Bus Speed:	800 MHz
Comment 1 Anthony Ricaud 2008-11-06 12:13:41 PST
Created attachment 24950 [details]
Testcase

Here is a testcase adapted from the one found in bugzilla : https://bugzilla.mozilla.org/show_bug.cgi?id=458031
Comment 2 Eric Seidel (no email) 2009-02-16 23:55:42 PST
This is probably a dupe of bug 14606.  I also noticed this was *awful* tonight, and made a test case, which I've attached.
Comment 3 Eric Seidel (no email) 2009-02-16 23:56:11 PST
Created attachment 27719 [details]
Another example of awful performance
Comment 4 David Kilzer (:ddkilzer) 2009-04-18 18:58:31 PDT
Please retest on a recently WebKit nightly build.
Comment 5 Gavin Sherlock 2009-04-18 19:45:23 PDT
Testing with r42583, the test case is still pretty darned slow for window resizing.  Better than 3.2.1, but still obviously slower than resizing a regular window.
Comment 6 Mike Wille 2009-04-20 18:52:20 PDT
Created attachment 29636 [details]
Testcase #3

Testcase #3 has an example that shows the scrolling performance severely degraded Safari 3, 4, and the latest webkit nightly.  I believe the two triggers are a fixed position div over a div with rounded corners, drop shadow, and a background image.
Comment 7 Mike Wille 2009-04-21 12:29:49 PDT
That last comment was a little off.  I was a bit tired.  I forgot to mention that the earlier mentioned fix by comment #4, showed little difference between r415something and r42662.  There was a barely perceptible improvement.
Comment 8 Tom Brearley 2009-09-17 08:31:14 PDT
I've recently been having the same issues. However, i was using

	-webkit-box-shadow: 0px 0px 200px #000;

when i reduced it to:

	-webkit-box-shadow: 0px 0px 125px #000;

I found that a lot of the issues went. Similar to "Will Will".

I've tested on the latest WebKit nightly (r48454), and i have the same issues there also.
Comment 9 Richard Connamacher 2010-05-27 01:09:01 PDT
Created attachment 57207 [details]
Test Case (Box shadow over a fixed background image).

Test case showing very poor performance scrolling a long page where the main content div has a box shadow and the background is a fixed image.
Comment 10 mitz 2010-05-27 01:14:18 PDT
I am pretty sure there is an older bug about this in the database but I cannot find it at the moment.
Comment 11 Richard Connamacher 2010-05-27 01:17:34 PDT
I ran into this bug today while working on a site design. My design has a fixed background image and the main content in a DIV with a CSS box shadow behind it. Firefox handles it well, but WebKit stutters awfully while scrolling.

(The above test case I posted was distilled from that design.)
Comment 12 Richard Connamacher 2010-05-27 01:18:15 PDT
Comment on attachment 57207 [details]
Test Case (Box shadow over a fixed background image).

Includes both WebKit and Mozilla styles so performance can be compared.
Comment 13 Richard Connamacher 2010-06-03 13:27:57 PDT
I found that Safari performs far better when I recreate the box shadow using translucent PNGs. This is for the same page design: scrollable main box against a fixed background image.

So compositing speed can't be the main problem, since it has to re-composite my translucent PNGs just as it's doing with the shadow.

Is WebKit recalculating the shadow itself every time the user scrolls? If so then this bug could be fixed by calculating the shadow once and reusing it whenever the page is scrolled or resized. The shadow itself should only be recalculated when the dimensions of its box changes.
Comment 14 Simon Fraser (smfr) 2010-06-03 13:38:24 PDT
> The shadow itself should only be recalculated when the dimensions of its box changes

What's slow is painting the shadow (it involves a gaussian blur). To speed this up, we'd have to cache a bitmap for the shadow.
Comment 15 Simon Fraser (smfr) 2010-08-21 13:29:01 PDT
*** Bug 27505 has been marked as a duplicate of this bug. ***
Comment 16 white.mans.fire 2010-09-07 17:32:49 PDT
Created attachment 66800 [details]
Test of box-shadows with animation

I noticed this bug when I was working with floating windows and scriptaculous. The shadows cause poor animation performance when fading in and out the floating windows.
Comment 17 Simon Fraser (smfr) 2010-10-07 10:39:12 PDT
*** Bug 39601 has been marked as a duplicate of this bug. ***
Comment 18 Simon Fraser (smfr) 2010-10-07 10:39:50 PDT
<rdar://problem/8447138>
Comment 19 Alejandro G. Castro 2010-10-08 01:02:57 PDT
The solution we used with ContextShadow and tiling helped to solve this issue for us, the integration is in bug 46475.
Comment 20 Simon Fraser (smfr) 2010-12-19 13:32:19 PST
*** Bug 41031 has been marked as a duplicate of this bug. ***
Comment 21 Simon Fraser (smfr) 2010-12-23 20:59:55 PST
Created attachment 77399 [details]
Patch
Comment 22 Simon Fraser (smfr) 2010-12-23 21:29:13 PST
<rdar://problem/5687101>
Comment 23 mitz 2010-12-23 21:58:18 PST
Comment on attachment 77399 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=77399&action=review

> LayoutTests/ChangeLog:37
> +        * platform/mac/fast/transforms/shadows-expected.checksum:
> +        * platform/mac/fast/transforms/shadows-expected.png:

The shadows in the third and fourth column in the new results look wrong. They appear to be clipped.
Comment 24 Simon Fraser (smfr) 2010-12-24 08:41:49 PST
(In reply to comment #23)
> (From update of attachment 77399 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=77399&action=review
> 
> > LayoutTests/ChangeLog:37
> > +        * platform/mac/fast/transforms/shadows-expected.checksum:
> > +        * platform/mac/fast/transforms/shadows-expected.png:
> 
> The shadows in the third and fourth column in the new results look wrong. They appear to be clipped.

I'll take a look.
Comment 25 Simon Fraser (smfr) 2010-12-24 11:15:42 PST
Created attachment 77421 [details]
Patch
Comment 26 Dirk Schulze 2011-01-02 04:07:19 PST
I think it is better to make the tilling code platform independent, than adapting the same code for every port. So we may get rid of most of the #if PLATFORM's and minimize the separation of the code.

Just one notice. Simon, if you use ContextShadow for -webkit-svg-shadow as well in the future, you'll also change the behavior. CG supports group shadow, while ContextShadow doesn't:

<g style="-webkit-svg-shadow_...">
   <rect x="10" y="10" width="100" height="100"/>
   <rect x="30" y="30" width="100" height="100"/>
   <rect x="50" y="50" width="100" height="100"/>
</g>

for CG you'll get one common shadow for all three rects, for ContextShadow every rect gets it's own shadow.
Comment 27 Simon Fraser (smfr) 2011-01-02 11:12:54 PST
(In reply to comment #26)
> I think it is better to make the tilling code platform independent, than adapting the same code for every port. So we may get rid of most of the #if PLATFORM's and minimize the separation of the code.

That's covered by bug 51312.

> Just one notice. Simon, if you use ContextShadow for -webkit-svg-shadow as well in the future, you'll also change the behavior. CG supports group shadow, while ContextShadow doesn't:
> 
> <g style="-webkit-svg-shadow_...">
>    <rect x="10" y="10" width="100" height="100"/>
>    <rect x="30" y="30" width="100" height="100"/>
>    <rect x="50" y="50" width="100" height="100"/>
> </g>
> 
> for CG you'll get one common shadow for all three rects, for ContextShadow every rect gets it's own shadow.

Right, but that should be possible to fix by choosing when to start and end the shadow layer.
Comment 28 Dirk Schulze 2011-01-13 10:32:07 PST
Comment on attachment 77421 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=77421&action=review

Looks great in general, but please share the code of drawRectShadow() as much as possible with other platforms. r- because of the duplication.

> WebCore/platform/graphics/cg/ContextShadowCG.cpp:141
> +        // FIXME: can't get at the ImageBuffer bits directly, so we have to copy.

We have a bug report for this (not sure about the bug id right now), can you add the link to this bug here please?

> WebCore/platform/graphics/cg/ContextShadowCG.cpp:145
> +                       IntSize(layerData->width(), layerData->height()),

ImageData has size() now, please use this.

> WebCore/platform/graphics/cg/ContextShadowCG.cpp:369
> +
> +    // Draw the bottom left corner.
> +    tileRect = FloatRect(0, shadowTemplateSize.height() - radiusTwice - bottomLeftRadius.height(),
> +                         radiusTwice + bottomLeftRadius.width(), radiusTwice + bottomLeftRadius.height());
> +    destRect = tileRect;
> +    destRect.move(shadowRect.x(), shadowRect.y() + shadowedRect.height() - shadowTemplateSize.height() + radiusTwice);
> +    graphicsContext->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, destRect, tileRect);

Most of 60 lines above look similar of identical to the code in ContextShadowCairo. We don't need to share the complete function, but at least this code should be shared. If you want you can drop this function into a follow up patch. I'm very interested in ContexShadow for CG, since it is ideal for a sample implementation of feDropShadow. Something I'm working on ;-)
Comment 29 Simon Fraser (smfr) 2011-01-30 19:15:39 PST
Created attachment 80611 [details]
Patch
Comment 30 Simon Fraser (smfr) 2011-01-30 19:36:44 PST
http://trac.webkit.org/changeset/77101
Comment 31 Build Bot 2011-01-30 19:51:19 PST
Attachment 80611 [details] did not build on win:
Build output: http://queues.webkit.org/results/7584892
Comment 32 WebKit Review Bot 2011-01-30 20:31:06 PST
Attachment 80611 [details] did not build on chromium:
Build output: http://queues.webkit.org/results/7681074
Comment 33 WebKit Review Bot 2011-01-31 04:14:31 PST
http://trac.webkit.org/changeset/77101 might have broken GTK Linux 32-bit Release
The following tests are not passing:
fast/js/toInt32UInt32.html