Closed Bug 119311 Opened 23 years ago Closed 12 years ago

Reconsider line-level invalidation

Categories

(Core :: Layout: Block and Inline, defect)

defect
Not set
normal

Tracking

()

RESOLVED DUPLICATE of bug 539356

People

(Reporter: bryner, Unassigned)

References

(Depends on 1 open bug)

Details

(Keywords: perf)

Attachments

(1 file, 4 obsolete files)

Steps to reproduce: - Turn on XBL form controls by setting the pref "nglayout.debug.enable_xbl_forms" to true in all.js - Go to a page with a listbox, such as http://bugzilla.mozilla.org/query.cgi - Scroll one of the listboxes down. Note that the entire listbox is invalidated (easiest to see with paint flashing turned on).
Status: NEW → ASSIGNED
Target Milestone: --- → mozilla0.9.9
Attached patch hack (obsolete) (deleted) — Splinter Review
Well, if we never set |forceInvalidate| during an incremental reflow, we won't force the text frame to reflow. I'm now trying to figure out why we thought we needed |forceInvalidate|. Cursory use (including attaching this patch) shows no artifacts from its removal.
I meant to say, ``...we'll never force the select frame to invalidate.''
Okay, removal of this code regresses bug 2222: we leave cruft after pulling lines up.
Attached patch less of a hack (obsolete) (deleted) — Splinter Review
So I *think* that the problem here is a sub-optimal invalidate implementation in nsBlockFrame::ReflowLine. Specifically, if |aDamageDirtyArea| is set, we'll _union_ the line's old combined area with its new combined area and invalidate the entire thing. I think what we want to do here is take the _difference_ of the old combined area and the new combined area (i.e., old combined area - new combined area), and invalidate _that_. IOW, if the new combined area is smaller than the old combined area, then the line shrank, and we need to invalidate the portions of the old combined area outside the shrinkage. This fixes bryner's problem without regression bug 2222.
cc'ing block folks. What do you think?
Attachment #65109 - Attachment is obsolete: true
Keywords: perf, review
Comment on attachment 65130 [details] [diff] [review] less of a hack Seeing some weirdness in plaintext editor.
Attachment #65130 - Flags: needs-work+
Specifically, in mail-news compose.
Well, the above patch ain't right. After digging a bit futher, I'm now realizing that the block-and-line's design is based on doing the invalidation at the line-level. More or less, the frame classes don't do any of their own invalidation during reflow. (Text frame is an exception, but I think that's been hacked -- poorly, too. The invalidation area is always empty during the text frame's initial reflow. During an incremental reflow, the invalidation area doesn't include the frame's x and y coordinates: for continuations, that code is likely to be invalidating some other random area of the screen.) Doing invalidation at the line level seems fairly reasonable: doing it at a finer grain could be complicated, and would probably result in more invalidates being issued. So I'm gonna try barking up a different tree for a bit. Specifically, why does nsBoxFrame need to call ReflowDirtyChild?
> Text frame is an exception, but I think that's been hacked -- poorly, too. I happened to have hunted for some up pointers about this on bug 103266. (At the time, I was curious about the textarea that sometimes doesn't repaint.)
Depends on: 120650
Attached patch work-in-progress patch (obsolete) (deleted) — Splinter Review
Mmm, I bet _everyone_ is excited to see me cough up a large patch to block & line two weeks before I go on sabbatical. :-) I think I'm getting warmer to fixing bryner's problem. Here's what this patch does: 1. Alters nsBox so that it never calls ReflowDirtyChild on its parent. Instead, it schedules a dirty reflow (or style change reflow), with itself as the target. 2. Fixes block so that we are more conservative about force-invalidating a dirty line during an incremental reflow. Specifically, a block will now only force-invalidate a dirty line during an incremental reflow if the target frame is contained _directly_ within the box that is the target of the reflow. That is, blocks ``higher up'' along the reflow chain do not force-invalidate their lines. (I need to prove that this is guaranteed to work, or find a counter-example.) 3. Removes the nsTextFrame::Reflow Invalidate hack, which should no longer be necessary. 4. Hoists force-invalidate computation out of the loop in ReflowDirtyLines. 5. Propagates a reflow reason of `dirty' (as opposed to `resize') when we're reflowing a block that is the target of an incremental reflow. This guarantees that we'll force-invalidate the dirty lines in that block, and in any dirty block children of that block.
Attachment #65130 - Attachment is obsolete: true
Attached patch whoops (obsolete) (deleted) — Splinter Review
Oops, I'd re-written some of the code without testing it first. (At least I didn't check it in, like I did last night :-/.) This patch fixes a bug in NeedsForceInvalidate.
Attachment #65527 - Attachment is obsolete: true
Attachment #65534 - Flags: needs-work+
Sigh, the last patch (attachment 65534 [details] [diff] [review]) isn't right either. It was incorrectly returning `false' from NeedsForceInvalidate because aState.mNextRCFrame is _never_ going to be aBlockFrame: it's the next frame _inside_ the block, dummy!
Keywords: review
The more I think about this, the less I think that we can handle this at the block level given the current way we've designed reflow and invalidation. (That's not to say these are immutable, but...it may be easier to pursue a solution at the scrollbar level here.) The block frame has been designed to handle invalidation at the line-level. In other words, when a line is marked dirty, the entire line is invalidated so that individual inline frames don't need to concern themselves with taking care of that task. This may not be optimal for typing, DHTML, or reflowing select frames, but it's a reasonable trade-off given that most of the time we're blasting HTML to the screen (imagine invalidating each individual span of text while rendering an LXR page, for example). Since the line containg the <select>'s box frame has been marked dirty (it has to be marked dirty for ReflowDirtyLines to notice it, and propagate the incremental reflow down to it), we invalidate the line. The whole line, including the select's box frame. Perhaps instead of dirtying the line, we could maintain a mNextRCLine member and test for _that_ during ReflowDirtyLines (I'll do a quick experiment to try that, but I don't immediately see how this would generalize to typing, etc). Or perhaps this is another argument for preferring a dirty-bit design over the reflow command design. Either way, we're looking at a hefty change. Kicking this out to `future'. Sorry, bryner. :-(
Priority: -- → P4
Target Milestone: mozilla0.9.9 → Future
Here's a work-in-progress patch, if anyone wants to pick it up. It doesn't solve bryner's problem, though. I'll probably pick this up after I get back from sabbatical as (IMO) it cleans up some stuff that warranted cleanin'.
Attachment #65534 - Attachment is obsolete: true
This looks like it's block/inline-ish.... Leaving in this component for now, though.
Assignee: waterson → form
Status: ASSIGNED → NEW
Priority: P4 → --
QA Contact: madhur → desale
Target Milestone: Future → ---
roc, as long as we're defining the invalidation model, we should keep this in mind.
Assignee: layout.form-controls → nobody
QA Contact: desale → layout.form-controls
Component: Layout: Form Controls → Layout: Block and Inline
QA Contact: layout.form-controls → layout.block-and-inline
Summary: Extra invalidates on XBL listbox controls → Reconsider line-level invalidation
Depends on: dlbi
I don't know how to evaluate if bug 539356 fixed this. I think that dlbi made us reconsider line-level invalidation and did something different, and so I'm going to close this.
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: