Closed Bug 124554 Opened 24 years ago Closed 24 years ago

Scrolling of non-root HTML content does full refresh

Categories

(Core :: Web Painting, defect, P1)

All
Linux
defect

Tracking

()

RESOLVED FIXED
mozilla1.0

People

(Reporter: roc, Assigned: roc)

Details

Attachments

(1 file, 2 obsolete files)

http://lxr.mozilla.org/seamonkey/source/view/src/nsScrollPortView.cpp#496 nsScrollPortView::CannotBitBlit has a heinous bug: > return ((trans || opacity) && !(mScrollProperties & NS_SCROLL_PROPERTY_ALWAYS_BLIT)) || ... "opacity" is a float. It is almost always 1.0. Therefore unless ALWAYS_BLIT is set, we will do a full refresh on every scroll operation. Oops. This bug has been around for over two years. nsScrollingView has the same code and bug.
Unfortunately the obvious fix for this exposes a larger problem, which is that when a view is scrolled and it has overlapping sibling views which do not have widgets, the pixels painted by those views will be incorrectly scrolled unless we do something about it, and currently we don't. In general when we scroll a view we need to look at the display list for its bounds and see if all the elements of the display list are going to scroll along with the view. If there are non-scrolling views (i.e. views that aren't children of the scrolling view) we will have to do something; refreshing the entire view will suffice. We don't need to consider areas that are covered by widgets when we compute this display list, because the platform widget library will cut them out of the scroll area. Thus fixed-position elements (which have widgets which are above the main document in z-order) won't prevent a document from being efficiently scrolled. This general check will subsume transparency and opacity checking. If a non-scrolled view is visible through the scrolled view, it will show up in the display list and blitting will be disabled. To do this right requires that we trust that widget z-ordering actually works on every platform. Up till now the view manager has not assumed that. However, people have assumed that in other contexts, e.g. the fix to bug 43410. We can speed up painting and scrolling a lot if we know widget z-ordering works, so I'm going to start using that assumption.
Status: NEW → ASSIGNED
Priority: -- → P1
Target Milestone: --- → mozilla1.0
Attached patch Scrolling performance fix (obsolete) — Splinter Review
This patch does what I said it would do :-). When scrolling we check to see if the "after scrolling" pixels are completely determined by views that are being scrolled. If so, then we can just scroll the widget. If not, we have to repaint it manually.
Attached patch Better patch (obsolete) — Splinter Review
This patch makes a scroll operation non-blittable if any non-blittable view (e.g., fixed background attachment) is going to be displayed in the final rendering. This almost never happens because fixed background attachments are almost always on the document canvas, and CanScrollWithBitBlt is not called for those because the blittable flags for a document canvas are checked in nsScrollingView/nsScrollPortView.
Attachment #72332 - Attachment is obsolete: true
Comment on attachment 72403 [details] [diff] [review] Better patch sr=attinasi Could you please comment in the routine nsViewManager::CanScrollWithBitBlt about how the memory management of the display works. It seems that BuildDisplayLost allocates and then you have to clean it up locally - maybe this is common knowledge to you, but it sems interesting to me.
Attachment #72403 - Flags: superreview+
Attached patch Revised fixSplinter Review
I was adding comments to the code when I realized that I couldn't give a clear explanation of why CanScrollBitBlt was correct. Then I realized that it actually wasn't correct :-). I hope the new explanation makes sense; I had to fix the code to mark aView-descendants as transparent for the optimization pass to prevent some rather obscure problems. I also had to suppress the AddCoveringWidgetsToOpaqueRegion pass, which I did by removing it from BuildDisplayList entirely (and moving it to RenderViews). I also did some more testing with Viewer Demo #9 (nested frames and IFRAMEs) and realized that CanScrollBitBlt should just look at the scroll area after rather than the view's whole area to avoid scrolling being unnecessarily suppressed. Then I realized (well, I knew all along but suddenly it mattered) that nsView::GetClippedView doesn't take account of clipping due to scrollers (which use the nsIClipView hack). So I fixed that too, by explicitly setting the childcliprect on nsIClipViews. (This has the nice side effect of fixing some unnecessary repaints. If you go to Viewer Demo #9 with a trunk debug build and turn on paint flashing, you can see that when the animated eyes are scrolled just out of the IFRAME their area keeps getting repainted anyway.) With this patch, all the IFRAMEs in demo #9 scroll using bitblt, and I haven't been able to find any places where I get buggy rendering because of scrolling when we should have repainted. This patch will need to be reviewed again, sorry...
Attachment #72403 - Attachment is obsolete: true
Comment on attachment 74590 [details] [diff] [review] Revised fix The two CannotBitBlt methods sure look like they have a lot in common. Why not factor the actual test and just allow each variant to provide the viewManager, scrolledViewFlags and scrollProperties? +#define VIEW_ISSCROLLED 0x00000080 what happened to 0x00000040? Thanks for the detailed description - the code looks nice too. sr=attinasi
Attachment #74590 - Flags: superreview+
> The two CannotBitBlt methods sure look like they have a lot in common. Once we have XBL form controls checked in and on by default, we should be rid of all uses of native scrollbars, at which point I will gladly consign nsScrollingView to a watery grave (and there will be only one CannotBitBlt method remaining). > #define VIEW_ISSCROLLED 0x00000080 ISSCROLLED is private to CanScrollWithBitblt. I wanted to separate the private flags from the used-everwhere flags but make sure the flags field still fits in a byte.
Comment on attachment 74590 [details] [diff] [review] Revised fix a=asa (on behalf of drivers) for checkin to the 1.0 trunk
Attachment #74590 - Flags: approval+
Checked in.
Status: ASSIGNED → RESOLVED
Closed: 24 years ago
Resolution: --- → FIXED
Component: Layout: View Rendering → Layout: Web Painting
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: