Closed Bug 266702 Opened 20 years ago Closed 2 years ago

dotted Row/Cell borders cause 80% CPU hit, slow scrolling/paging

Categories

(Core :: Layout: Tables, defect)

defect

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: anon-mozilla, Unassigned)

References

()

Details

(Keywords: testcase)

Attachments

(5 files, 2 obsolete files)

User-Agent:       Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7) Gecko/20040803 Firefox/0.9.3
Build Identifier: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7) Gecko/20040803 Firefox/0.9.3

A table with no CSS renders instantly and scrolls smoothly. Adding CSS, with
dotted-line cell borders, causes the CPU to jump to 80% usage during
pageup/pagedown/scroll/mousewheel/new window open. A simple page up or page down
takes ~30 seconds to complete; this is accompanied by the spinning pizza wheel.

Reproducible: Always
Steps to Reproduce:
1. load sample page http://sitefoundry.com/misc/slowtable.html
2. page down, or scroll, or click scrolling widget
3. go get a cup of water. The screen might have refreshed by the time you return.

Actual Results:  
The screen did not update to show the scrolled page. Instead, the cursor became
a spinning pizza wheel. CPU usage for the firefox process peaks above 75%.

Expected Results:  
The screen should update more quickly. There should be no pizza wheel.

My computer is a 1 GHz G4 Macintosh running OS X 10.3.5.

I just realized, while writing this bug, that the problem is DOTTED borders.
Changing to solid borders all but cures the problem. Apparently the
dotted-border rendering code is terribly CPU-intensive. Compare:
http://sitefoundry.com/misc/fastertable.html

Note too that this bug exists in Camino 0.8 too; it's not specific to Firefox.
I can reproduce this on a recent Windows build. Mouse cursor doesn't change, but
scrolling is very slow and CPU usage goes to 70-90%. Page down takes 10 seconds
on Athlon XP 2200+, 1800MHz.

Mozilla/5.0 (Windows; U; Windows NT 5.1; en-gb; rv:1.7.3) Gecko/20041024 Firefox/1.0
Yeah, that page absolutely crawls here too.

P4 3GHz, 1024mb memory.

Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.3) Gecko/20041026
Firefox/1.0RC1
For me it used up to 94% of CPU power when scrolling.

Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.3) Gecko/20041026
Firefox/1.0RC1

Changing status to new.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Assignee: firefox → nobody
Component: General → Layout: Tables
Product: Firefox → Browser
QA Contact: firefox.general → core.layout.tables
Version: unspecified → 1.7 Branch
I guess the problem goes also away if you change the border collapse from
collapse to seperate while maintaining the dotted border?
Another observation: the problem is just with the bottom borders. If I change 
their style to solid but leave the left border's style dotted the page is fast, 
too.
I'm seeing this with a current GTK1 Linux build too.  Profiling shows:

Total hit count: 200059
Count %Total  Function Name
53876   26.9     nsGCCache::GetGC(_GdkWindow*, _GdkGCValues*, GdkGCValuesMask,
_GdkRegion*)
29687   14.8     select
24977   12.5     write
19013   9.5     nsRenderingContextGTK::UpdateGC()
12877   6.4     .L250

and more to the point:

 91643 6843   174317 nsRenderingContextGTK::FillRect(int, int, int, int)
              83009 nsRenderingContextGTK::UpdateGC()
              60489 gdk_draw_rectangle

FillRect() is called from DrawSolidBorderSegment(), called by
nsCSSRendering::DrawTableBorderSegment.

I don't see DrawTableBorderSegment() being particularly slower than the normal
code we use for drawing dashed borders... is the problem here that we redraw all
the borders for the entire table every time?  The problem is gone with separated
borders.

One other thing.  Note that I increased the border-width in the testcase to make
it obvious that we are NOT drawing a dashed or dotted border.  It's coming out
solid.  So maybe we're just drawing way too much stuff?
OS: MacOS X → All
Hardware: Macintosh → All
Version: 1.7 Branch → Trunk
Attached file Slightly simpler testcase (deleted) β€”
>One other thing.  Note that I increased the border-width in the testcase to make
it obvious that we are NOT drawing a dashed or dotted border.  It's coming out
solid.  So maybe we're just drawing way too much stuff?

Boris, I don't get that sentence. Could you explain that more in detail. 
Whn I view the testcase I attached, I see solid black horizontal lines 5px thick
instead of seeing the dotted or dashed lines I would expect.  So _something_ is
broken in the drawing code.  All I was saying is that the something may also be
the root of the performance problem.
The problem seems to be, that the whole border is drawn, if some part of a
border needs to be drawn.

nsCSSRendering::DrawTableBorderSegment() does not use an aDirtyRect to
determine, which part of the border to draw.

nsTableFrame::PaintBCBorders() calls DrawTableBorderSegment() with position and
size of the whole border segment, if part of that border segment intersects with
aDirtyRect.

Unfortunately, you can't just use something like
  segRect.IntersectRect(segRect, aDirtyRect);
in PaintBCBorders() before passing segRect to DrawTableBorderSegment(), because
that would not look very nice with dashed/dotted borders.
Jan, see comment 6.  If the problem is that we don't use the dirty rect, why is
there no issue with solid borders?  Those should take about as much time to
draw, I would think....
There is no issue with solid borders, because you only have to draw one (huge)
rectangle for each border segment. In nsCSSRendering::DrawTableBorderSegment
dashed and dotted borders are drawn like this:
  for (PRInt32 spaceX = 0; spaceX < numDashSpaces; spaceX++) {
    rect.x += rect.width + dashLength;
    rect.width = (spaceX == (numDashSpaces - 1)) ? endDashLength : dashLength;
    DrawSolidBorderSegment(aContext, rect, PR_TRUE);
  }
So you have to draw thousands of solid border segments for each dashed/dotted
border segment.
The initial problem is that these routines exist at all and dont use standard
paintingin routines but rather reimplement them.
Attached patch use dirty rect for dashed/dotted borders (obsolete) (deleted) β€” β€” Splinter Review
I've tried to make nsCSSRendering::DrawTableBorderSegment() use a dirty rect
for dashed borders. The current code tries to make dashes meet in corners by
adjusting the size of the first and last dash. I've failed to use dirty rects
with that code. The code that determines where borders start and end seems to
be somewhat broken, eg with some tables dashes have different positions
depending on the dirty rect in nsTableFrame::PaintBCBorders(). I have then made
the positions of the dashes not depend on the start end end of the border
segment. This makes the corners look much less nice.
Fixing the initial problem from comment 13 would be a much better idea. I vote
for marking this bug depend on bug 203686.
Attached patch use dirty rect for dashed/dotted borders (obsolete) (deleted) β€” β€” Splinter Review
Sorry, missed one line.
Attachment #180894 - Attachment is obsolete: true
 loading locally mozilla/layout/html/tests/table/marvin/backgr_index.html and
observing  the testcases while scrolling and when another object masks the
tables partially would be a good test for the patch.
Attached patch use dirty rect for dashed/dotted borders (deleted) β€” β€” Splinter Review
Next try, handles negative border positions. Thanks for the link to the
testcases, Bernd.
Attachment #180901 - Attachment is obsolete: true
when you think that you are ready ask me for review 
Comment on attachment 180943 [details] [diff] [review]
use dirty rect for dashed/dotted borders

Patch works now AFAICT. Corners still look ugly, but I can't change that.
Attachment #180943 - Flags: review?(bernd_mozilla)
Attached patch easier?? patch (deleted) β€” β€” Splinter Review
Jan, why don't you check just the intersection for not being empty I believe
the even a large number of these comparisons is cheap computation wise. It
would not require to make the painting at the corners worse.
(In reply to comment #20)
> Jan, why don't you check just the intersection for not being empty I believe
> the even a large number of these comparisons is cheap computation wise. It
> would not require to make the painting at the corners worse.

That would solve this bug without changing much code, but the position of the
dashes would still depend on the dirty rect in nsTableFrame::PaintBCBorders().
If you take mozilla/layout/html/tests/table/marvin/backgr_simple-table.html and
cover and then uncover some part of a border segment, the positions of the
dashes change. (This is the current behaviour, I haven't found any bug for it.)
>the positions of the dashes change
Is that fixed by your patch? I don't see where the dirty rect could influence
the border, while I see the bug itself.
(In reply to comment #22)
> >the positions of the dashes change
> Is that fixed by your patch?

Yes, the positions of the dashes don't change (at the expense of less nice corners).

> I don't see where the dirty rect could influence
> the border, while I see the bug itself.

I have no idea where that bug comes from, could be anywhere in the BC code.
I'd like to add we have noted it in FF 1.07 and 2.0x by just using CSS underlined links, thus with a very much smaller amount of drawing involved. Hovever, hovering links caused the described CPU hit, affecting site usability.
So is this still a problem with cairo?
It is; for it to not be a problem we'd need to fix nsCSSRendering -- afaik, it draws dotted lines as a bunch of little rects (or lines), one per dot.  This should get significantly better if that code is converted to actually draw dotted lines using thebes.
Comment on attachment 180943 [details] [diff] [review]
use dirty rect for dashed/dotted borders

the borders should be switched to thebes.
Attachment #180943 - Flags: review?(bernd_mozilla) → review-
Keywords: testcase
Blocks: 527728
This bug is ruined scrolling on launchpad.net in latest FF builds (Mozilla/5.0 (X11; Linux i686; rv:1.9.3a4pre) Gecko/20100316 Minefield/3.7a4pre)
Mike: can you provide a URL that shows the problem?
Yeah, see https://launchpad.net/ubuntu/+milestone/ubuntu-10.04-beta-1
Although it might not be the only reason of extreme slow rendering/scrolling (https://bugs.launchpad.net/ubuntu/+source/firefox-3.0/+bug/223238)
(In reply to comment #30)
> Yeah, see https://launchpad.net/ubuntu/+milestone/ubuntu-10.04-beta-1

Cannot reproduce.
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6
I can reproduce this in 3.0, 3.5. 3.6 and 3.7a4pre builds, all on Ubuntu 10.04, using Mike's page.
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.19pre) Gecko/2010032304 GranParadiso/3.0.19pre
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3pre) Gecko/20100323 Namoroka/3.6.3pre
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.3a4pre) Gecko/20100322 Minefield/3.7a4pre

Here's a clearer example that includes both non-dotted-border and dotted-border sections:
 https://bugs.launchpad.net/ubuntu/+source/linux-source-2.6.17/+bug/61235

This new page has dotted borders *just* at the top (the table under Affects|Status|etc).  As a result, if you drag/jiggle the scrollbar rapidly up & down, it's highly responsive for all of the page **except** for the section at the top (where the dotted borders are visible).  There, it gets very choppy (only updating page & scrollbar position at around half-second intervals).

'top' attributes all of the excess CPU usage to the Xorg process. (but it's still presumably firefox/cairo's fault in part, because that's what's making Xorg repaint)  I'm testing with Compiz effects enabled (the default if your graphics card supports it) in Ubuntu 10.04 beta.
bug 521746 comes into mind when I read Xorg
(In reply to comment #33)
> bug 521746 comes into mind when I read Xorg
I have nvidia card (official binary driver) on ubuntu 9.10, without compiz
Testcases from bug 521746 displayed OK
comment 0 still reproducible wiht Mozilla/5.0 (Windows NT 5.1; rv:2.0b8pre) Gecko/20101014 Firefox/4.0b8pre
Hello. 
On my Fedora 14 with firefox4-4.0-0.14.rc2.fc14 is affected too.
DE: Gnome 2.32.0 with Clearlooks theme. 

I often see launchpad and make packages for Ubuntu. With this bug working with the site is too hardy.
I use ff4 nightly-build from ppa on Ubuntu 10.04 and scrolling on this page http://sitefoundry.com/misc/slowtable.html are very slow
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b13pre) Gecko/20110322 Firefox/4.0b13pre

(In reply to comment #37)

> I use ff4 nightly-build from ppa on Ubuntu 10.04 and scrolling on this page
> http://sitefoundry.com/misc/slowtable.html are very slow

On Windows 7 x64, using Minefield that page scrolls very slow + freezes Firefox.
i have firefox-4.0-1.fc14.remi.i686 on Fedora 14 and it scrolls very slow and with 100% of usage on 1 of my CPUs when visit that page
Attached file Simple DIV dotted border-bottom testcase (deleted) β€”
Slow performance on Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0

Observations in a new user profile:
1. Curiously, the performance of my testcase is greatly enhanced when "Restart with Add-ons disabled..." is used. Trying to mimic the same by manually disabling all add-ons does not reproduce the performance enhancement effect. The slowtables test case also loads faster, but I still had to kill Firefox due to lack of responsiveness when scrolling.
2. Problem also visible on other elements. Tested on DIV, P, and A.
3. "border-top" and "border-bottom" have severe performance slowdown.
4. "border-left" and "border-right" have less performance impact, but still noticeably slower than solid.
5. When switching to another tab or application and then,returning, Firefox appears to spend time redrawing the borders.
6. MSIE8.0 does not exhibit any noticeable performance slow down when rendering the same test case.

I hope this contributes to the bug stomping.
> the performance of my testcase is greatly enhanced when "Restart
> with Add-ons disabled..." is used.

This is in safe mode, right?  Doesn't that also disable hardware acceleration?  Does turning that off explicitly make things faster too?
> Does turning that off explicitly make things faster too?

Disabling the hardware acceleration, through the Options, actually does make the rendering of my test a lot faster. From a clear lag to almost no lag.
OK.  Could you please file a separate bug on that, then?  This bug predates the existence of the hardware accelerated rendering paths, and it sounds like your issue is with those.
Ok. It is filed as bug 645333.
CONFIRMED with Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20100101 Firefox/14.0.1.
On the same PC, no problem with Opera 11.64 and (gosh..) IE8.
Blocks: 422330
Severity: minor → S4

The severity field for this bug is relatively low, S4. However, the bug has 12 votes.
:dholbert, could you consider increasing the bug severity?

For more information, please visit auto_nag documentation.

Flags: needinfo?(dholbert)

The last needinfo from me was triggered in error by recent activity on the bug. I'm clearing the needinfo since this is a very old bug and I don't know if it's still relevant.

Flags: needinfo?(dholbert)
Attached file dotted-border-scrolling-test-case.html (deleted) β€”

Profile of the test case from comment 48: https://share.firefox.dev/3WbmkXB

Daniel, what do you think? Is it okay to close this bug now?

Flags: needinfo?(dholbert)

Yeah, I think we can call this worksforme.

Status: NEW → RESOLVED
Closed: 2 years ago
Flags: needinfo?(dholbert)
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: