Bug 84410 - Terrible performance on http://alliances.commandandconquer.com/ and http://www.lordofultima.com/
Summary: Terrible performance on http://alliances.commandandconquer.com/ and http://ww...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Layout and Rendering (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Simon Fraser (smfr)
URL: http://alliances.commandandconquer.co...
Keywords: InRadar
Depends on: 84393 87080 87212
Blocks:
  Show dependency treegraph
 
Reported: 2012-04-19 18:13 PDT by Simon Fraser (smfr)
Modified: 2012-05-25 17:07 PDT (History)
6 users (show)

See Also:


Attachments
Part 1: use a geometry map to optimize absolute layer bounds (68.06 KB, patch)
2012-05-22 19:02 PDT, Simon Fraser (smfr)
no flags Details | Formatted Diff | Diff
Patch (75.68 KB, patch)
2012-05-24 16:53 PDT, Simon Fraser (smfr)
hyatt: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Simon Fraser (smfr) 2012-04-19 18:13:33 PDT
From <http://code.google.com/p/chromium/issues/detail?id=120871>

URLs (if applicable):
http://alliances.commandandconquer.com/en/
http://www.lordofultima.com/en/

Other browsers tested:
Add OK or FAIL after other browsers where you have tested this issue:
Safari 5:
     Firefox 4.x: OKAY (far better)
     IE 7/8/9: OKAY (far better)

What steps will reproduce the problem?
1. go to a page mentioned above
2. start a game
3. ingame performance is really bad while IE and FF have solid 40 to 60 fps

What is the expected result?

Good performance with at least 30 fps. With the behaviour at this moment the games mentioned above cannot be played with Chrome,


What happens instead?

Laggy/choppy performance
Comment 1 Radar WebKit Bug Importer 2012-04-19 18:14:17 PDT
<rdar://problem/11286123>
Comment 2 Simon Fraser (smfr) 2012-04-19 18:27:22 PDT
Adding a single 3D transform to the page (to turn off overlap testing) takes the CPU usage from 100% to 30% on my machine, using the CC reduction in the chromium bug.
Comment 3 Simon Fraser (smfr) 2012-05-17 14:31:41 PDT
My plans here are to avoid O(N^2) behavior when computing absolute layer bounds to add to the overlap map by storing some data as we walk the layer tree that allows us to map to absolute coords more efficiently.
Comment 4 Adrienne Walker 2012-05-17 14:34:36 PDT
(In reply to comment #3)
> My plans here are to avoid O(N^2) behavior when computing absolute layer bounds to add to the overlap map by storing some data as we walk the layer tree that allows us to map to absolute coords more efficiently.

That sounds great.  I've been having similar thoughts.

As you modify what's going into the overlap map, can you see if this fixes the issue in bug 64201?
Comment 5 Simon Fraser (smfr) 2012-05-18 22:13:14 PDT
Ugh, layer->backgroundClipRect(rootRenderLayer(), 0, true) is also super-expensive.
Comment 6 Simon Fraser (smfr) 2012-05-19 07:56:33 PDT
That was added in http://trac.webkit.org/changeset/91114
Comment 7 Adrienne Walker 2012-05-19 14:25:56 PDT
(In reply to comment #6)
> That was added in http://trac.webkit.org/changeset/91114

In retrospect, I'm pretty sure that we don't need to use temp clip bounds there, which would help immensely.
Comment 8 Simon Fraser (smfr) 2012-05-20 21:56:44 PDT
We do, because the cache rects are cached for painting (relative to repaint containers), and this rect is root-relative.
Comment 9 Simon Fraser (smfr) 2012-05-21 10:56:39 PDT
I think the best option here will be to cache both clipRects for painting, and absolute clip rects.
Comment 10 Adrienne Walker 2012-05-21 11:04:50 PDT
(In reply to comment #8)
> We do, because the cache rects are cached for painting (relative to repaint containers), and this rect is root-relative.

You said you were planning to store some transform data as you walked the tree; would be possible to reuse some of that data to transform cached clip rects into the right space?

Alternatively, RenderLayer::localClipRect gets reused when calculating composited bounds, so maybe that's the extra one to cache.
Comment 11 Simon Fraser (smfr) 2012-05-22 19:02:47 PDT
Created attachment 143434 [details]
Part 1: use a geometry map to optimize absolute layer bounds
Comment 12 Dave Hyatt 2012-05-23 10:48:36 PDT
Comment on attachment 143434 [details]
Part 1: use a geometry map to optimize absolute layer bounds

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

Overall looks nice. I'd like a bit of an explanation regarding why flipped blocks writing modes can't be dealt with. I'm a bit confused about that part. I thought offsetFromContainer did the right thing for those.

> Source/WebCore/rendering/RenderGeometryMap.cpp:157
> +            // The root get special treatment for fixed position

Should be "The root gets"

> Source/WebCore/rendering/RenderInline.cpp:1148
> +    if (container->isBox() && container->style()->isFlippedBlocksWritingMode())
> +        offsetDependsOnPoint = true;

Confused regarding why you can't just flip (somewhere) to handle this.

> Source/WebCore/rendering/RenderLayerCompositor.cpp:725
> +//        absBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();

Probably shouldn't leave commented out code in.

> Source/WebCore/rendering/RenderLayerCompositor.cpp:734
> -    
> +

Whitespace.

> Source/WebCore/rendering/RenderObject.cpp:2060
> +    LayoutSize offset;
> +    if (container->hasOverflowClip())
> +        offset = -toRenderBox(container)->scrolledContentOffset();

I'm a little confused about why this has to be special cased.

> Source/WebCore/rendering/RenderObject.cpp:2062
> +    bool isNonUniform = hasColumns() || (container->isBox() && container->style()->isFlippedBlocksWritingMode());

Is it really that hard to deal with flipped blocks? Don't you just have to flipForWritingMode along the correct axis?

> Source/WebCore/rendering/RenderObject.h:885
> +    // Pushes state onto RenderGeometryMap about how to map coordinates from this renderer to its condtainer, or ancestorToStopAt (whichever is encountered first).

Typo. "condtainer" should be "container"
Comment 13 Simon Fraser (smfr) 2012-05-23 13:53:09 PDT
(In reply to comment #12)

> > Source/WebCore/rendering/RenderObject.cpp:2060
> > +    LayoutSize offset;
> > +    if (container->hasOverflowClip())
> > +        offset = -toRenderBox(container)->scrolledContentOffset();
> 
> I'm a little confused about why this has to be special cased.

I was following the code in RenderObject::mapLocalToContainer(). However, now I see that RenderObject::offsetFromContainer() takes the scroll offset into account, so perhaps we're doing it twice.
Comment 14 Simon Fraser (smfr) 2012-05-24 16:53:14 PDT
Created attachment 143929 [details]
Patch
Comment 15 Simon Fraser (smfr) 2012-05-24 16:54:20 PDT
Fixed the patch in response to comments.

The RenderObject mapping methods appear to never be called (because they are always overidden. Maybe they should ASSERT_NOT_REACHED?
Comment 16 Dave Hyatt 2012-05-25 11:14:36 PDT
Comment on attachment 143929 [details]
Patch

r=me. Should follow up with ASSERT_NOT_REACHED and clean those methods up in RenderObject in a future patch.
Comment 17 Simon Fraser (smfr) 2012-05-25 11:18:50 PDT
Followups: bug 87516, bug 87517.
Comment 18 Simon Fraser (smfr) 2012-05-25 14:43:01 PDT
http://trac.webkit.org/changeset/118567
Comment 19 Simon Fraser (smfr) 2012-05-25 15:56:32 PDT
The reduced testcase in the cr bug takes 25% CPU after fixes for this and bug 87212. It used to be 100%.
Comment 20 Adrienne Walker 2012-05-25 16:27:48 PDT
Comment on attachment 143929 [details]
Patch

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

> Source/WebCore/rendering/RenderGeometryMap.cpp:149
> +        if (currStep->m_hasTransform) {
> +            // If this box has a transform, it acts as a fixed position container for fixed descendants,
> +            // and may itself also be fixed position. So propagate 'fixed' up only if this box is fixed position.
> +            inFixed &= currStep->m_isFixedPosition;

How does this assignment work if inFixed starts false (which it's initialized to), but this layer has both a transform and is fixed position? Shouldn't inFixed be true in that case? I wonder if this should be "=" instead of "&=".

This causes the test in the patch on bug 64201 to break.
Comment 21 Simon Fraser (smfr) 2012-05-25 16:45:00 PDT
(In reply to comment #20)
> (From update of attachment 143929 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=143929&action=review
> 
> > Source/WebCore/rendering/RenderGeometryMap.cpp:149
> > +        if (currStep->m_hasTransform) {
> > +            // If this box has a transform, it acts as a fixed position container for fixed descendants,
> > +            // and may itself also be fixed position. So propagate 'fixed' up only if this box is fixed position.
> > +            inFixed &= currStep->m_isFixedPosition;
> 
> How does this assignment work if inFixed starts false (which it's initialized to), but this layer has both a transform and is fixed position? Shouldn't inFixed be true in that case? I wonder if this should be "=" instead of "&=".

That does look wrong. Please file a new bug.

> This causes the test in the patch on bug 64201 to break.

Yay, a testcase!
Comment 22 Adrienne Walker 2012-05-25 17:07:30 PDT
(In reply to comment #21)
> (In reply to comment #20)
> > (From update of attachment 143929 [details] [details])
> > View in context: https://bugs.webkit.org/attachment.cgi?id=143929&action=review
> > 
> > > Source/WebCore/rendering/RenderGeometryMap.cpp:149
> > > +        if (currStep->m_hasTransform) {
> > > +            // If this box has a transform, it acts as a fixed position container for fixed descendants,
> > > +            // and may itself also be fixed position. So propagate 'fixed' up only if this box is fixed position.
> > > +            inFixed &= currStep->m_isFixedPosition;
> > 
> > How does this assignment work if inFixed starts false (which it's initialized to), but this layer has both a transform and is fixed position? Shouldn't inFixed be true in that case? I wonder if this should be "=" instead of "&=".
> 
> That does look wrong. Please file a new bug.

Bug 64201 covers this.  See the updated patch there.