Closed
Bug 382392
Opened 18 years ago
Closed 17 years ago
FF3 20070528: scrolling non-fixed-pos content when fixed-pos content present is extremely sluggish
Categories
(Core :: Layout, defect)
Tracking
()
RESOLVED
FIXED
People
(Reporter: thomasverelst, Assigned: roc)
References
()
Details
(Keywords: perf, regression, testcase)
Attachments
(5 files)
(deleted),
text/html
|
Details | |
(deleted),
text/html
|
Details | |
(deleted),
patch
|
Details | Diff | Splinter Review | |
(deleted),
patch
|
vlad
:
review+
mtschrep
:
approval1.9+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
vlad
:
review+
|
Details | Diff | Splinter Review |
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.9a5pre) Gecko/20070528 Minefield/3.0a5pre
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.9a5pre) Gecko/20070528 Minefield/3.0a5pre
Starting with this build:
Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.9a5pre) Gecko/20070528 Minefield/3.0a5pre
(download folder: 2007-05-28-04-trunk)
...when scrolling up/down a page which has both fixed and non-fixed positioned content, I observe the following issues:
- scrolling is extremely sluggish
- temporary repainting problems of non-fixed positioned content in varying locations during scrolling, even scrolling slowly (chunks of text disappearing below each other like colliding tectonic plates; also, horizontal lines appear at the same height in those areas)
- scrollbar knob trails behind the cursor at quite a distance while dragging it
This may be due to fixing bug 343430
Reproducible: Always
Reporter | ||
Updated•18 years ago
|
Version: unspecified → Trunk
Updated•18 years ago
|
Component: General → Layout
Product: Firefox → Core
QA Contact: general → layout
Comment 1•18 years ago
|
||
The main problem seems to be caused by bug 368247, although bug 343430 made it look uglier. This could be a duplicate of one of the bug 368247 blocking bugs.
Blocks: 368247
I can't reproduce this -- scrolling is quite fast for me on that page. However, there is a long dotted border on that page, so this could be something like bug 379834
Reporter | ||
Comment 3•18 years ago
|
||
A quick test removing the dotted border shows that the border is the cause of the performance issue; removing it also fixes the rest of the stuff I posted in the main post.
I did notice a minor performance degradation while scrolling for some time and, just like with bug 379834, traced it down to the change from 20070430 to 20070501.
The impact on performance became more apparent for me since build 20070528 but I guess that the severity level is irrelevant if removing the border fixes it.
Status: UNCONFIRMED → RESOLVED
Closed: 18 years ago
Resolution: --- → DUPLICATE
Reporter | ||
Comment 4•18 years ago
|
||
Hmm... well...
Using 3.0a5 build 20070531, the scrolling is back to normal but the "tectonic plate" effect is still there (very noticeable when scrolling down slowly using the scrollbar knob).
It's like there are two layers. The layer in the back spans the entire viewport and the front layer covers the top half of the viewport. When scrolling down, the front layer moves upwards correctly but the back layer comes in a little late.
Whatever... I don't know how to explain this any better...
Comment 5•18 years ago
|
||
I'm not seeing much improvement either. I'm getting a bit seasick when I scroll down. I think it also depends on the performance of the computer, but the regression is still there.
Updated•18 years ago
|
Status: UNCONFIRMED → NEW
Ever confirmed: true
Comment 6•18 years ago
|
||
So removing the 1px dotted border improves the scrolling quite a bit, so that part is basically bug 379834 revisited.
However, even after removing that, scrolling performance isn't quite as good as on branch.
Depends on: 379834
Flags: blocking1.9?
Comment 7•18 years ago
|
||
A fixed positioned object with a lot of text on the right seems to be another reason for reduced scrolling performance on current trunk builds.
Comment 8•17 years ago
|
||
This testcases makes the performance regression even more clear.
With current trunk build I get 27235ms.
With a branch build, I get 13531ms.
Updated•17 years ago
|
Flags: blocking1.9? → blocking1.9-
Whiteboard: [wanted-1.9]
Updated•17 years ago
|
Comment 9•17 years ago
|
||
I guess that this bug is what causes scrolling at gmail to be extremly sluggish when a chat window is present.
Comment 11•17 years ago
|
||
Please try to scroll page http://www.javalobby.org/java/forums/t104390.html
Updated•17 years ago
|
Flags: wanted1.9+
Whiteboard: [wanted-1.9]
Assignee | ||
Updated•17 years ago
|
Assignee: nobody → roc
Assignee | ||
Comment 13•17 years ago
|
||
In testcase 2, the display list code and view manager are doing the right thing: they order a bitblit scroll and invalidate the non-moving DIV on the left and the scrolled-into-view strip at the top or bottom of the window. On Mac, we end up repainting the whole window because Appkit seems to take the union of the dirty rects and pass that back to us as the rect to paint --- no region information available :-(.
I'm looking into Windows next...
Assignee | ||
Comment 14•17 years ago
|
||
Windows has similar problems. We don't have a repaint region for it, just a bounding rectangle.
Assignee | ||
Comment 15•17 years ago
|
||
Separating the paint of the scrolled-into-view strips from the paint of any non-moving content, by inserting an extra Composite() call, fixes the problem on Mac.
On Windows things are more complicated because we have logic to restrict the area we scroll, so even with the extra Composite() call, the invalidation of the non-moving, non-scrolled content invalidates two strips whose union is most of the window. Removing that special Windows logic fixes that, but regresses bug 343430.
This fixes bug 424915.
Regressing bug 343430 isn't really acceptable, so I'm going to try to keep the XP_WIN block and make Windows nsWindow::OnPaint get and pass down the update region.
Assignee | ||
Comment 16•17 years ago
|
||
On GTK2 the problem is that there is no way to scroll just part of a window. So we either scroll the whole window and get jerky results for the fixed-pos stuff, which is bug 343430, or we scroll none of the window and repaint everything instead, which is slow. So I'm not going to try to fix this for GTK2 which is unfortunate since it means 424915 won't be fixed.
Assignee | ||
Comment 17•17 years ago
|
||
That extra-Composite trick regresses bug 343430 on Mac, so we don't really want to do that. On Mac we're in a similar situation to GTK2, we currently don't support scrolling of a partial window so we either get jerkiness or slowness.
Assignee | ||
Comment 18•17 years ago
|
||
So in the end I can only fix this on Windows. But at least this fix makes total sense and is basically a good thing all round.
Attachment #312476 -
Flags: review?(vladimir)
Comment 19•17 years ago
|
||
(In reply to comment #17)
> On Mac we're in a similar situation to GTK2, we currently don't
> support scrolling of a partial window so we either get jerkiness or slowness.
Let's expose a preference option for this! :)
Roc - do you have any idea on how it may influence the DHTML animation performance on windows?
If I understand the concept we'll start redrawing only a region of window on each frame. Should it result in better performance or smoothness or it's just for such edge cases like this one?
Assignee | ||
Comment 20•17 years ago
|
||
It would certainly improve some tests, but could hurt others, partly depending on what Windows does internally.
Currently when we paint on Windows we always paint everything inside the bounding-rectangle of what really needs to be painted. With this patch we can paint only the region that really needs to be painted. This makes a big difference when the area that needs to be painted is, say, a small rectangle at the top-left of the window and a small rectangle at the bottom-right of the window.
However, tracking complex regions can take more time and even space, so it's not always a win, especially if they're really complex.
Comment 21•17 years ago
|
||
thanks for this explanation.
do you want any testing to be done around this? Unfortunately I don't have Windows build env, but I can spend a few hours running a build with this through my testcasebase :)
Assignee | ||
Comment 22•17 years ago
|
||
Sure, that'd be really useful. You can use the try-servers I guess.
Comment on attachment 312476 [details] [diff] [review]
Windows fix
Hah, I actually had this same patch a long while ago but I didn't see any perf difference, so I never went anywhere with it... I didn't have the right testcase for it, looks like. (I love "GetRandomRgn", probably my favourite windows API name. I also love how they changed the coorinate space between OS revisions...)
Attachment #312476 -
Flags: review?(vladimir) → review+
Comment 24•17 years ago
|
||
the try-servers either down or they don't like me at all :(
Assignee | ||
Comment 25•17 years ago
|
||
Comment on attachment 312476 [details] [diff] [review]
Windows fix
Fixes a performance regression on real sites. Fairly low risk since the region painting path has been used by GTK2 for ages. GetRandomRgn is a weird API but it is documented as the right way to do what we need to do here.
Attachment #312476 -
Flags: approval1.9?
Updated•17 years ago
|
Attachment #312476 -
Flags: approval1.9? → approval1.9+
Updated•17 years ago
|
Keywords: checkin-needed
Comment 26•17 years ago
|
||
Checking in widget/src/windows/nsWindow.cpp;
/cvsroot/mozilla/widget/src/windows/nsWindow.cpp,v <-- nsWindow.cpp
new revision: 3.735; previous revision: 3.734
done
Is this bug fixed then, even if only a Windows fix could be found?
Status: NEW → ASSIGNED
Keywords: checkin-needed
Assignee | ||
Comment 27•17 years ago
|
||
Dunno. It seems a shame to not mark anything fixed, but we should probably leave this open for Mac/Linux.
OS: Windows 2000 → All
Comment 28•17 years ago
|
||
I backed this out, as I believe it caused the crashes in bug 426369.
Depends on: 426369
Assignee | ||
Comment 29•17 years ago
|
||
Yes, stuart pointed out that the patch fails to free paintRgn and this causes us to crash in other places when we run out of GDI objects and fail to check errors properly. Oops. New patch coming up.
It would be nice if our leak tracking tracked GDI objects somehow...
Assignee | ||
Comment 30•17 years ago
|
||
Call DeleteObject.
I ran an APNG demo for a while watching the Task Manager's GDI object count. No leak.
Attachment #312971 -
Flags: review?(vladimir)
Assignee | ||
Updated•17 years ago
|
Whiteboard: [needs review]
Comment 31•17 years ago
|
||
I filed bug 426412 when I saw the GDI leak (before comment 29 appeared), becuase I never had a crash, like bug 426369, just a large leak. But everything is ok now, with the 3th update from today (Gecko/2008040112) where this was backed out.
Comment on attachment 312971 [details] [diff] [review]
Windows fix that doesn't leak
Looks good; r=me
Attachment #312971 -
Flags: review?(vladimir) → review+
Assignee | ||
Comment 33•17 years ago
|
||
Relanded
Status: ASSIGNED → RESOLVED
Closed: 18 years ago → 17 years ago
Resolution: --- → FIXED
Updated•17 years ago
|
Flags: in-litmus?
Comment 34•17 years ago
|
||
In reference to #16:
> On GTK2 the problem is that there is no way to scroll just part of a window.
What's wrong with?
http://library.gnome.org/devel/gdk/stable/gdk-Windows.html#gdk-window-move-region
(Since 2.8 means that it's been in stable releases of GTK+ since Aug. 2005)
Assignee | ||
Comment 35•17 years ago
|
||
Wow. Cool. How does that interact with child widgets?
Whiteboard: [needs review]
Comment 36•17 years ago
|
||
What gdk_window_move_region() does:
- It shifts the bits in the region
- It shifts existing invalid regions that were contained in the region
- It creates new invalidations corresponding to parts of the source region
that were not within the bounds of the window
- It puts an item in the translation queue, so if an expose was generated
by the X server before the move_region() and received after, it gets
shifted appropriately
What it does not do by design:
- It does not move child windows
- It does not adjust the allocations of child widgets, since they are
at the GTK layer, not the GDK layer.
If you have "NO_WINDOW" widgets that overlap the moved region, then
their bits will then have been moved, but their allocations will not
have been updated, and any child windows (like the input-only window that
takes clicks on a button) will not have been moved. The simple way
to fix up is to loop over immediate children of the owner of the
window, and if they are !NO_WINDOW, compute their new allocations and
call gtk_widget_size_allocate(), which will update the allocation,
move the child windows, and redraw the new and old locations. Advice
on complex, sneaky ways of doing things that don't generate the
extra redraws available on request.
What it does not do as implementation limitation:
- It does not generate client side invalidations for areas that
"scroll" out from under child windows; these areas will get redrawn
only when a GraphicsExpose event is received back from the server.
(Generally not a big deal unless you have a lot of latency in your
X connection, though some trailing may be visible in these areas.)
- It does not generate client side invalidations for areas that
"scroll" out from overlaying windows, again these will wait on
events received back from the X server.
Assignee | ||
Comment 37•17 years ago
|
||
Thanks for the info! It sounds like that might actually work if we make GTK do what we do Windows.
But here's a question that is not quite clear from your answer: if we have !NO_WINDOW children and we do the fixup loop that you suggest, do we get flicker or not? With gdk_window_scroll we don't get flicker; if gdk_window_move_region regresses that, that would be a big problem. Is that where your complex, sneaky advice?
A long time ago I read
http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt
which seems to only apply to scrolling the whole window, which made me think that getting scrolling right with child widgets and scrolling only part of the window wasn't an option with X.
Unfortunately it's very late to do a big change here for Firefox 3, and post-FF3 I'm planning to basically eliminate use of child widgets altogether which will make this easy.
Comment 38•17 years ago
|
||
The question to me is whether you want the !NO_WINDOW children to scroll
or not.
- If you don't want them to scroll, no fixup is necessary
- If you do want them to scroll, then (just like with OffsetRgn on windows)
you'll have to scroll, then move the children, and you'll get a bit of
jitter. But a complete redraw of the window contents doesn't help that
particular jitter either - the only way to fix that jitter would be to
coordinate with the compositing manager to prevent an intermediate
screen refresh (in the composited case), or to get rid of child windows.
Jitter like this where parts of the window move out of sync is not
wonderfully pretty, but it's much better than gdk_window_scroll() then
redrawing the fixed elements, since if you do that the fixed elements
bounce around.
Yes - guffaw scrolling is in fact only applicable to scrolling the whole
window.
Assignee | ||
Comment 39•17 years ago
|
||
Yeah, we want them to move. So I agree gdk_window_move_region would be an improvement. I've filed bug 427431 on that. I'm not sure if it's worth trying to ram that in at this point.
You need to log in
before you can comment on or make changes to this bug.
Description
•