Closed Bug 266582 Opened 20 years ago Closed 11 years ago

Very slow font rendering with XFT on page with hidden divs

Categories

(Core :: Widget: Gtk, defect)

x86
Linux
defect
Not set
normal

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: dialate, Unassigned)

References

()

Details

(Keywords: perf)

Attachments

(1 obsolete file)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.3) Gecko/20041026 Firefox/1.0RC1
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.3) Gecko/20041026 Firefox/1.0RC1

http://www.sectormedicalcorp.com renders very slowly under Linux (running either
SuSE Pro 9.1 or Gentoo). It acts like it did before I did some optimization,
when all the layers were simply stacked on top of each other without
visibility:hidden. So, my best guess is that under Linux, the hidden layers are
still being silently rendered.

Reproducible: Always
Steps to Reproduce:
1. Go to www.sectormedicalcorp.com
2. Go to a section with enough text, like What Is Sleep Apnea -> Treatment
3. Try to scroll
Actual Results:  
1-2 FPS scroll speed.

Expected Results:  
Regular scroll speed.

I compared the performance on boxes with identical hardware, so it isn't
hardware (particularly not with 3D-accel nVidia FX5900). The speed with
Konqueror is fine, so it probably isn't a OS error. Under Windows 2000/XP, speed
is fine.
Works fine with a current trunk build on Linux...
Hmm. I just tried both the gtk2/xft nightly and the regular nightly. The xft one
is very slow. The regular build is very zippy.

Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8a5) Gecko/20041109
Ah, ok.  I do see this with an XFT build.  I profiled the XFT build (with --sync
so that I get somewhat useful data out; the profile without --sync just shows
lots of time spent waiting on the X server, but it's not so helpful for knowing
which function calls really take a long time to complete).

The breakdown looks like this:

Total hit count: 469715
Count %Total  Function Name
324654   69.1     select
21785   4.6     __libc_poll
8681   1.8     write
7127   1.5     read

The caller of select() is _XRead(), which is ultimately called from XSync(). 
The callers of XSync() are as follows:

             235573 XRenderCompositeText8
              49975 XChangeGC
              14244 XDrawLine
               8417 XSetClipMask
               8223 XFillRectangle
               7779 XSetClipRectangles
               6072 XCopyArea
               3518 XCreatePixmap
               2695 XRenderFreePicture
               2609 XSetTSOrigin

etc.  I didn't bother with callers that had fewer calls into the function. 
Without --sync, XChangeGC took a lot less time, but XRenderCompositeText8 took
even more, seemingly...  The real problem is the time taken by
XRenderCompositeText8 -- over 50% of the total time on this testcase.

The profile without --sync also has find_current_serial calling XSync(), so it
looks like that function takes a lot of time...  I know that's come up in
profiles of this sort of thing before.

I do wonder whether the hidden divs are even needed to reproduce this problem. 
A minimal testcase that shows the performance issue would be vere helpful here!
Component: Layout → GFX: Gtk
Keywords: perf, qawanted
Summary: visibility:hidden DIVs silently rendering under Linux → Very slow font rendering with XFT on page with hidden divs
Assignee: nobody → blizzard
Status: UNCONFIRMED → NEW
Ever confirmed: true
QA Contact: core.layout → ian
I only have Windows and I don't see this bug, so it's kinda difficult for me to
make a minimal testcase.

But maybe this is a start. Is there a difference between scrolling speed between
these pages?
* http://martijn.heelveel.info/test/mozilla/xft/withpopupmenu.htm
  This is with the hidden divs from the semi-transparent popupmenu and   with
the 26 extra hidden 'page' divs.  
* http://martijn.heelveel.info/test/mozilla/xft/withoutpopupmenu.htm
  This is without the hidden divs from the popupmenu, but with the 26 extra
hidden 'page' divs.  
* http://martijn.heelveel.info/test/mozilla/xft/withoutpopupmenu_14_hidden_divs.htm
  Without the hidden popupmenu divs, but with only 14 extra hidden 'page' divs.
* http://martijn.heelveel.info/test/mozilla/xft/withoutpopupmenu_1_hidden_div.htm
  Without the hidden popupmenu divs, but with only 1 extra hidden 'page' div.

http://martijn.heelveel.info/test/mozilla/xft/
Martijn-

For the XFT build, the first three test cases seem to be as slow as the original
site. The last test case is faster, but there is still some intermittent frame lag.

For the non-XFT build, all render in the same speedy manner.
OK, the hidden divs are definitely required to show the bug....

Robert, it looks like removing "overflow:auto" from the hidden divs speeds up
the rendering significantly.  Is there some way the overflow settings on the
hidden-visibility elements could cause trouble here?  Perhaps by having the
scrollwidgets around or something?
It's probably the extra widgets, yeah. But why would this slow down Xft and not
non-Xft?
The XFT build is GTK2, while the non-xft build is GTK1.  Since it's not possible
to do a GTK2 build without XFT or an XFT build without GTK2 (or so I'm told), I
can't do a controlled experiment.  So this could be a GTK2 widget code issue as
well...
Ah right. Yes it's probably GTK2.
Looking at nsWindow::Invalidate(), the likely culprit is that we pass PR_TRUE as
the last ("invalidate_children") argument to gdk_window_invalidate_rect()....
This will invalidate the rect in every single one of the scrollwidgets.  Then
when we go to paint we'll paint the same bit of page over and over again N times
(where N = number of hidden widgets).

Given that the view manager already handles child widgets itself, I'd think the
nsWindow code should just pass PR_FALSE (or even FALSE, since this is a
gboolean, not a PRBool).  Running Mozilla on that page over remote X is a perf
disaster for both toolkits, so I won't be able to test this theory until I get home.
This does NOT help the testcase significantly... I thought about it some more,
and realized that the parent widget will still invalidate this region in all
the child widgets, since it has no way to know whether they cover each other.

So even with this patch we'll still end up painting the text 26 times.

Note that we will do this for both the XFT build and the non-XFT one, as far as
I can tell.  It's just that text painting is a good deal slower in XFT
builds...
Comment on attachment 165813 [details] [diff] [review]
Patch to not do recursive invalidation

I think this is still worth taking.
Attachment #165813 - Flags: superreview?(bryner)
Attachment #165813 - Flags: review?(blizzard)
Comment on attachment 165813 [details] [diff] [review]
Patch to not do recursive invalidation

My only concern is whether this would stop us from invalidating, say, a plugin
when we need to.
nsObjectFrames have a view and widget of their own (parent of the plugin's
widget).  That widget will get invalidated, so we'll call the frame's Paint()
method, which will paint the plugin, as I understand..
Comment on attachment 165813 [details] [diff] [review]
Patch to not do recursive invalidation

Ah, ok.  Sounds good then.
Attachment #165813 - Flags: superreview?(bryner) → superreview+
Depends on: 274144
Attachment #165813 - Flags: review?(blizzard) → review+
Comment on attachment 165813 [details] [diff] [review]
Patch to not do recursive invalidation

Checked in this patch.	It helps a bit, but not enough...
Attachment #165813 - Attachment is obsolete: true
Depends on: 328811
http://www.sectormedicalcorp.com is 404.
I tried http://www.medicalcorp.com which looks related but it's just
a link farm, no useful pages to test on that I could find.
Boris, did you save the original page by any chance?
Assignee: blizzard → nobody
Component: GFX: Gtk → Widget: Gtk
QA Contact: ian → gtk
No, sorry.  I should really have known better.  :(

But we know what's going on here... We can just easily construct a testcase if really desired.  Just lots of text with lots of overflow:auto visibility:hidden divs overlayed on top of it.

In any case, the right fix for this will come with bug 352093, I suspect.
Depends on: widget-removal
Closing this bug, since neither http://www.sectormedicalcorp.com nor none of the links from comment 4 aren't available anymore.

Please reopen the bug if anyone can still reproduce it.
Status: NEW → RESOLVED
Closed: 11 years ago
Keywords: qawanted
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: