Closed
Bug 841192
Opened 12 years ago
Closed 12 years ago
Remove nsDisplayClip(RoundedRect) and attach explicit Clip objects to every display item
Categories
(Core :: Layout, defect)
Core
Layout
Tracking
()
RESOLVED
FIXED
mozilla23
People
(Reporter: roc, Assigned: roc)
References
(Depends on 1 open bug)
Details
Attachments
(20 files, 1 obsolete file)
55.22 KB,
patch
|
mattwoodrow
:
review+
|
Details | Diff | Splinter Review |
21.88 KB,
patch
|
mattwoodrow
:
review+
|
Details | Diff | Splinter Review |
6.40 KB,
patch
|
mattwoodrow
:
review+
|
Details | Diff | Splinter Review |
1.95 KB,
patch
|
mattwoodrow
:
review+
|
Details | Diff | Splinter Review |
3.59 KB,
patch
|
mattwoodrow
:
review+
|
Details | Diff | Splinter Review |
2.07 KB,
patch
|
mattwoodrow
:
review+
|
Details | Diff | Splinter Review |
7.30 KB,
patch
|
mattwoodrow
:
review+
|
Details | Diff | Splinter Review |
9.96 KB,
patch
|
mattwoodrow
:
review+
|
Details | Diff | Splinter Review |
8.07 KB,
patch
|
mattwoodrow
:
review+
|
Details | Diff | Splinter Review |
3.32 KB,
patch
|
mattwoodrow
:
review+
|
Details | Diff | Splinter Review |
7.85 KB,
patch
|
mattwoodrow
:
review+
|
Details | Diff | Splinter Review |
6.89 KB,
patch
|
mattwoodrow
:
review+
|
Details | Diff | Splinter Review |
Part 14: Convert all usage of nsDisplayClip(RoundedRect) to use DisplayListClipState/DisplayItemClip
148.31 KB,
patch
|
mattwoodrow
:
review+
|
Details | Diff | Splinter Review |
46 bytes,
text/html
|
Details | |
271 bytes,
text/html
|
Details | |
5.52 KB,
patch
|
MatsPalmgren_bugz
:
review+
|
Details | Diff | Splinter Review |
344 bytes,
text/html
|
Details | |
33.51 KB,
patch
|
mattwoodrow
:
review+
|
Details | Diff | Splinter Review |
4.26 KB,
patch
|
mattwoodrow
:
review+
|
Details | Diff | Splinter Review |
62.09 KB,
image/png
|
Details |
In some display lists (e.g. in bug 840372) a lot of nested nsDisplayClips are created. Constructing these, and processing them in FrameLayerBuilder is expensive and unnecessary. nsDisplayClip also adds a lot of complications to display lists because unlike all other display items, they may not have a specific "underlying frame". Also, FrameLayerBuilder eventually constructs explicit Clip objects for each (post-optimization) display item anyway.
So, assigning explicit Clip objects during display list construction should save a lot of work and simplify the code.
Assignee | ||
Comment 1•12 years ago
|
||
Plan of attack:
1) Move mozilla::FrameLayerBuilder::Clip to mozilla::DisplayItemClip.
2) Instead of wrapping up display items after we've constructed them, we'll keep "current clip" state in nsDisplayListBuilder with an Auto class to save and restore that state. When a display item is created, the current clip in the nsDisplayListBuilder will be copied to a new DisplayItemClip in the displaylist arena and a pointer to that DisplayItemClip will be put in the new display item. We can cache this pointer so that display items allocated with the same current clip state share the same DisplayItemClip object (keeping display list size down).
3) The "current clip" state is a bit complex. It can't just be a DisplayItemClip, because for 'overflow' clipping the container needs to clip the child items that it is the containing block for, and *not* clip the other child items. So we're actually going to need one DisplayItemClip which "clips everything" and a separate stack of (DisplayItemClip, containing block) pairs which clip the display items whose frame has the given containing block. For efficiency we probably should store all three of:
a) DisplayItemClip that clips everything
b) Stack of (DisplayItemClip, containing block) with the conditional clips in effect. When we follow placeholders through BuildDisplayListForChild we'd remove any clips that are no longer containing-block ancestors for the out-of-flow frame. And each clip on the stack would include the clips below it on the stack.
c) A pointer to an arena-allocated DisplayItemClip which is the intersection of a) and the clip at the top of stack b), if one has been allocated.
Assignee | ||
Comment 2•12 years ago
|
||
Assignee | ||
Comment 3•12 years ago
|
||
Attachment #722458 -
Flags: review?(matspal)
Assignee | ||
Comment 4•12 years ago
|
||
Attachment #722459 -
Flags: review?(matt.woodrow)
Assignee | ||
Comment 5•12 years ago
|
||
Attachment #722461 -
Flags: review?(matt.woodrow)
Assignee | ||
Comment 6•12 years ago
|
||
Attachment #722467 -
Flags: review?(matt.woodrow)
Assignee | ||
Comment 7•12 years ago
|
||
Attachment #722468 -
Flags: review?(matt.woodrow)
Assignee | ||
Comment 8•12 years ago
|
||
Attachment #722471 -
Flags: review?(matt.woodrow)
Assignee | ||
Comment 9•12 years ago
|
||
Attachment #722472 -
Flags: review?(matt.woodrow)
Assignee | ||
Comment 10•12 years ago
|
||
Attachment #722473 -
Flags: review?(matt.woodrow)
Assignee | ||
Comment 11•12 years ago
|
||
Attachment #722474 -
Flags: review?(matt.woodrow)
Assignee | ||
Comment 12•12 years ago
|
||
Attachment #722475 -
Flags: review?(matt.woodrow)
Assignee | ||
Comment 13•12 years ago
|
||
Attachment #722476 -
Flags: review?(matt.woodrow)
Assignee | ||
Comment 14•12 years ago
|
||
Attachment #722477 -
Flags: review?(matt.woodrow)
Assignee | ||
Comment 15•12 years ago
|
||
Attachment #722479 -
Flags: review?(matt.woodrow)
Assignee | ||
Comment 16•12 years ago
|
||
Attachment #722480 -
Flags: review?(matt.woodrow)
Updated•12 years ago
|
Attachment #722459 -
Flags: review?(matt.woodrow) → review+
Updated•12 years ago
|
Attachment #722461 -
Flags: review?(matt.woodrow) → review+
Comment 17•12 years ago
|
||
Comment on attachment 722467 [details] [diff] [review]
Part 4: Create DisplayListClipState
Review of attachment 722467 [details] [diff] [review]:
-----------------------------------------------------------------
::: layout/base/DisplayItemClip.h
@@ +57,5 @@
>
> // Construct as the intersection of aOther and aClipItem.
> DisplayItemClip(const DisplayItemClip& aOther, nsDisplayItem* aClipItem);
>
> + void IntersectWith(const DisplayItemClip& aOther);
Is this meant to be here? I don't see an implementation of it
::: layout/base/DisplayListClipState.h
@@ +36,5 @@
> + {
> + return mClipContentDescendants;
> + }
> +
> + void SetClipForContainingBlockDescendants(const DisplayItemClip* aClip)
Should these two not have the 'Get' prefix since they are just getters without side effects?
Attachment #722467 -
Flags: review?(matt.woodrow) → review+
Updated•12 years ago
|
Attachment #722468 -
Flags: review?(matt.woodrow) → review+
Comment 18•12 years ago
|
||
Comment on attachment 722471 [details] [diff] [review]
Part 6: Save and restore DisplayListClipState when we start building display lists for a frame
Review of attachment 722471 [details] [diff] [review]:
-----------------------------------------------------------------
::: layout/base/nsDisplayList.h
@@ +488,5 @@
> class AutoBuildingDisplayList {
> public:
> AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder, bool aIsRoot)
> : mBuilder(aBuilder),
> + mPrevClipState(aBuilder->mClipState),
It's a bit scary to me that we just copy the raw pointers within DisplayListClipState and trust that nothing will delete them. I realise that the arena allocations make this true, but we should document it somewhere.
Attachment #722471 -
Flags: review?(matt.woodrow) → review+
Updated•12 years ago
|
Attachment #722472 -
Flags: review?(matt.woodrow) → review+
Updated•12 years ago
|
Attachment #722473 -
Flags: review?(matt.woodrow) → review+
Updated•12 years ago
|
Attachment #722474 -
Flags: review?(matt.woodrow) → review+
Comment 19•12 years ago
|
||
(In reply to Matt Woodrow (:mattwoodrow) from comment #17)
> ::: layout/base/DisplayListClipState.h
> @@ +36,5 @@
> > + {
> > + return mClipContentDescendants;
> > + }
> > +
> > + void SetClipForContainingBlockDescendants(const DisplayItemClip* aClip)
>
> Should these two not have the 'Get' prefix since they are just getters
> without side effects?
"GetFoo()" means the functions can return null, "Foo()" means it cannot.
Comment 20•12 years ago
|
||
Comment 21•12 years ago
|
||
Comment 22•12 years ago
|
||
Comment on attachment 722458 [details] [diff] [review]
Part 1: Instead of making nsSubDocumentFrame::Reflow enforce that HTML <frame> elements have no padding, do that in ua.css so that all our code agrees on what the content box is
It sounds as if you intended this change to be idempotent?
Can you explain why I now see a left and top padding in Testcase #1
with the Part 1 patch applied?
Fwiw, Trident and Webkit appears to implement padding for <frame>,
I tend to think we should too.
Attachment #722458 -
Flags: review?(matspal) → review-
Assignee | ||
Comment 23•12 years ago
|
||
(In reply to Matt Woodrow (:mattwoodrow) from comment #17)
> Comment on attachment 722467 [details] [diff] [review]
> Part 4: Create DisplayListClipState
>
> Review of attachment 722467 [details] [diff] [review]:
> -----------------------------------------------------------------
>
> ::: layout/base/DisplayItemClip.h
> @@ +57,5 @@
> >
> > // Construct as the intersection of aOther and aClipItem.
> > DisplayItemClip(const DisplayItemClip& aOther, nsDisplayItem* aClipItem);
> >
> > + void IntersectWith(const DisplayItemClip& aOther);
>
> Is this meant to be here? I don't see an implementation of it
The implementation's in part 9. Sorry, I'll move it down.
(In reply to Matt Woodrow (:mattwoodrow) from comment #18)
> It's a bit scary to me that we just copy the raw pointers within
> DisplayListClipState and trust that nothing will delete them. I realise that
> the arena allocations make this true, but we should document it somewhere.
Actually there is something here which makes me a bit uncomfortable: we require that ClipContainingBlockDescendants/ClipContentDescendants and SetClipForContainingBlockDescendants/SetClipForContentDescendants take parameters that will stay alive (on the stack, typically) until the old clip state is restored.
I can probably fix that unsafeness by requiring all DisplayListClipState modification be done through DisplayListClipState::AutoSaveRestore, which would actually contain the temporary DisplayItemClip that gets used for setting. I'll try that.
Assignee | ||
Comment 24•12 years ago
|
||
(In reply to Mats Palmgren [:mats] from comment #22)
> Fwiw, Trident and Webkit appears to implement padding for <frame>,
> I tend to think we should too.
OK.
Updated•12 years ago
|
Attachment #722475 -
Flags: review?(matt.woodrow) → review+
Comment 25•12 years ago
|
||
>
> Actually there is something here which makes me a bit uncomfortable: we
> require that ClipContainingBlockDescendants/ClipContentDescendants and
> SetClipForContainingBlockDescendants/SetClipForContentDescendants take
> parameters that will stay alive (on the stack, typically) until the old clip
> state is restored.
>
> I can probably fix that unsafeness by requiring all DisplayListClipState
> modification be done through DisplayListClipState::AutoSaveRestore, which
> would actually contain the temporary DisplayItemClip that gets used for
> setting. I'll try that.
Sounds good.
Updated•12 years ago
|
Attachment #722476 -
Flags: review?(matt.woodrow) → review+
Updated•12 years ago
|
Attachment #722477 -
Flags: review?(matt.woodrow) → review+
Updated•12 years ago
|
Attachment #722479 -
Flags: review?(matt.woodrow) → review+
Comment 26•12 years ago
|
||
Comment on attachment 722480 [details] [diff] [review]
Part 14: Convert all usage of nsDisplayClip(RoundedRect) to use DisplayListClipState/DisplayItemClip
Review of attachment 722480 [details] [diff] [review]:
-----------------------------------------------------------------
Looks really good! Might be worth getting someone else to double check the nsSubDocumentFrame etc stuff, I don't know that code all that well.
::: layout/base/FrameLayerBuilder.cpp
@@ +3242,5 @@
> + tmpClip.RemoveRoundedCorners();
> + clip = &tmpClip;
> + }
> + if (currentClipIsSetInContext != clip->HasClip() ||
> + (clip->HasClip() && *clip != currentClip)) {
Items with the same clip should compare true with just a pointer comparison, right?
Can we make currentClip a pointer and just do that instead here? I guess we might still need to do both (nsDisplayItem::SetClip allocates new memory), but it should be faster in the common case.
::: layout/base/nsDisplayList.cpp
@@ -974,5 @@
> - item->GetType() != nsDisplayItem::TYPE_TRANSFORM ||
> - item->GetUnderlyingFrame() != aForItem->GetUnderlyingFrame() ||
> - aForItem->ReferenceFrame() != aForItem->GetUnderlyingFrame(),
> - "If we have an nsDisplayTransform child (for the same frame),"
> - "then we shouldn't be our own reference frame!");
Why is this going?
@@ +1636,5 @@
> nscoord radii[8];
> return !aFrame->GetBorderRadii(radii) ||
> + nsLayoutUtils::RoundedRectIntersectsRect(nsRect(aFrameToReferenceFrame,
> + aFrame->GetSize()),
> + radii, aTestRect);
Probably should be part of the previous patch, doubt it matters though.
::: layout/base/nsLayoutDebugger.cpp
@@ +159,5 @@
> + const DisplayItemClip& clip = i->GetClip();
> + nsCString clipString;
> + if (clip.HasClip()) {
> + clipString = clip.ToString();
> + }
ToString already handles the !HasClip() case
Attachment #722480 -
Flags: review?(matt.woodrow) → review+
Assignee | ||
Updated•12 years ago
|
Version: 18 Branch → Trunk
Assignee | ||
Comment 27•12 years ago
|
||
Webkit supports both border and padding on <frame> elements, and it turns out to be trivial for us to support both, so why not?
Attachment #722458 -
Attachment is obsolete: true
Attachment #726966 -
Flags: review?(matspal)
Assignee | ||
Comment 28•12 years ago
|
||
(In reply to Matt Woodrow (:mattwoodrow) from comment #26)
> Items with the same clip should compare true with just a pointer comparison,
> right?
Not necessarily.
> Can we make currentClip a pointer and just do that instead here? I guess we
> might still need to do both (nsDisplayItem::SetClip allocates new memory),
> but it should be faster in the common case.
We could use a pointer comparison as a shortcut but in the common (non-roundedrect) case comparing clips is already just comparing the rects and checking that both rounded-rect arrays are empty, so really cheap.
> ::: layout/base/nsDisplayList.cpp
> @@ -974,5 @@
> > - item->GetType() != nsDisplayItem::TYPE_TRANSFORM ||
> > - item->GetUnderlyingFrame() != aForItem->GetUnderlyingFrame() ||
> > - aForItem->ReferenceFrame() != aForItem->GetUnderlyingFrame(),
> > - "If we have an nsDisplayTransform child (for the same frame),"
> > - "then we shouldn't be our own reference frame!");
>
> Why is this going?
Because we're passing aForItem just for this assertion, which seems not worthwhile.
> @@ +1636,5 @@
> > nscoord radii[8];
> > return !aFrame->GetBorderRadii(radii) ||
> > + nsLayoutUtils::RoundedRectIntersectsRect(nsRect(aFrameToReferenceFrame,
> > + aFrame->GetSize()),
> > + radii, aTestRect);
>
> Probably should be part of the previous patch, doubt it matters though.
Will fix.
> ::: layout/base/nsLayoutDebugger.cpp
> @@ +159,5 @@
> > + const DisplayItemClip& clip = i->GetClip();
> > + nsCString clipString;
> > + if (clip.HasClip()) {
> > + clipString = clip.ToString();
> > + }
>
> ToString already handles the !HasClip() case
Will fix.
Comment 29•12 years ago
|
||
Comment on attachment 726966 [details] [diff] [review]
Part 1 v2
> + // XUL <iframe> or <browser>, or HTML <iframe>, <object> or <embed>
or <frame> :-)
Seriously though, it seems a bit odd now to list the potential elements
this frame class deals with here, since they are all handled the same.
If anywhere, the comment at the top of nsSubDocumentFrame.cpp seems more
appropriate, and/or in the header file somewhere.
Anyway, r=mats, as you see fit.
Attachment #726966 -
Flags: review?(matspal) → review+
Comment 30•12 years ago
|
||
For the record, I noticed a couple of details where rendering differs
between UAs. <frameset> background propagates to the viewport in IE10,
not in Chrome (27) or Firefox. <frameset> margins seems mostly compatible
in IE10/FF (top,left,bottom seems correct, but the right margin is zero
in IE and 20px in FF (size of vertical borders?). Chrome only has a top
margin. Not sure if this is worth filing bugs on, unless there actually
is a spec for <frameset> / <frame> rendering somewhere.
Assignee | ||
Comment 31•12 years ago
|
||
(In reply to Mats Palmgren [:mats] from comment #30)
> For the record, I noticed a couple of details where rendering differs
> between UAs. <frameset> background propagates to the viewport in IE10,
> not in Chrome (27) or Firefox.
I believe we're correct per spec. The <frameset> is not the document's root element, nor is it the document's <body> element, so nothing says its background should propagate.
> <frameset> margins seems mostly compatible
> in IE10/FF (top,left,bottom seems correct, but the right margin is zero
> in IE and 20px in FF (size of vertical borders?).
How margins work on <frameset> is not specified anywhere as far as I know. Frameset layout is specified here: http://www.whatwg.org/specs/web-apps/current-work/multipage/rendering.html#frames-and-framesets but that doesn't handle margins (or CSS padding or borders either).
If we had to deal with this I'd be tempted to just force all margins to 0 for <frame> and <frameset> elements, and force borders and padding to 0 for <frameset>s, using !important rules in html.css. But really I don't care.
Assignee | ||
Comment 32•12 years ago
|
||
Attachment #733261 -
Flags: review?(matt.woodrow)
Updated•12 years ago
|
Attachment #733261 -
Flags: review?(matt.woodrow) → review+
Assignee | ||
Comment 33•12 years ago
|
||
Attachment #733724 -
Flags: review?(matt.woodrow)
Assignee | ||
Comment 34•12 years ago
|
||
Updated•12 years ago
|
Attachment #733724 -
Flags: review?(matt.woodrow) → review+
Assignee | ||
Comment 35•12 years ago
|
||
Assignee | ||
Comment 36•12 years ago
|
||
https://hg.mozilla.org/integration/mozilla-inbound/rev/1740631994da
https://hg.mozilla.org/integration/mozilla-inbound/rev/698d23ec564b
https://hg.mozilla.org/integration/mozilla-inbound/rev/fb7633e8733e
https://hg.mozilla.org/integration/mozilla-inbound/rev/ec3f4cfe3866
https://hg.mozilla.org/integration/mozilla-inbound/rev/d6f4ddf03ffb
https://hg.mozilla.org/integration/mozilla-inbound/rev/dc2f8190c7dd
https://hg.mozilla.org/integration/mozilla-inbound/rev/a9214f38c73e
https://hg.mozilla.org/integration/mozilla-inbound/rev/b16876942c8d
https://hg.mozilla.org/integration/mozilla-inbound/rev/30928f33d63f
https://hg.mozilla.org/integration/mozilla-inbound/rev/072417fd4d8e
https://hg.mozilla.org/integration/mozilla-inbound/rev/c9583f064a2d
https://hg.mozilla.org/integration/mozilla-inbound/rev/54952cb8f869
https://hg.mozilla.org/integration/mozilla-inbound/rev/00fdcb8176a7
https://hg.mozilla.org/integration/mozilla-inbound/rev/5f7f4e26d4a9
https://hg.mozilla.org/integration/mozilla-inbound/rev/3396e302a1e4
https://hg.mozilla.org/integration/mozilla-inbound/rev/1e958f7224a7
Comment 37•12 years ago
|
||
I tried out cset 1e958f7224a7 on m-c inbound which seems to only include this patch and I see an anomaly in my sidebars. I've attached a screenshot of it. The previous cset 905671d954c5 worked OK.
Comment 38•12 years ago
|
||
Comment 39•12 years ago
|
||
about:addons also shows the same sort of thing.
Comment 40•12 years ago
|
||
https://hg.mozilla.org/mozilla-central/rev/1740631994da
https://hg.mozilla.org/mozilla-central/rev/698d23ec564b
https://hg.mozilla.org/mozilla-central/rev/fb7633e8733e
https://hg.mozilla.org/mozilla-central/rev/ec3f4cfe3866
https://hg.mozilla.org/mozilla-central/rev/d6f4ddf03ffb
https://hg.mozilla.org/mozilla-central/rev/dc2f8190c7dd
https://hg.mozilla.org/mozilla-central/rev/a9214f38c73e
https://hg.mozilla.org/mozilla-central/rev/b16876942c8d
https://hg.mozilla.org/mozilla-central/rev/30928f33d63f
https://hg.mozilla.org/mozilla-central/rev/072417fd4d8e
https://hg.mozilla.org/mozilla-central/rev/c9583f064a2d
https://hg.mozilla.org/mozilla-central/rev/54952cb8f869
https://hg.mozilla.org/mozilla-central/rev/00fdcb8176a7
https://hg.mozilla.org/mozilla-central/rev/5f7f4e26d4a9
https://hg.mozilla.org/mozilla-central/rev/3396e302a1e4
https://hg.mozilla.org/mozilla-central/rev/1e958f7224a7
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla23
Assignee | ||
Comment 41•12 years ago
|
||
I don't see that on Linux, probably because the theme background isn't different.
Comment 42•12 years ago
|
||
You need to log in
before you can comment on or make changes to this bug.
Description
•