Closed
Bug 439881
Opened 17 years ago
Closed 9 years ago
Very slow canvas rendering in FF3 on Linux (FF2 works fine)
Categories
(Core :: Graphics: Canvas2D, defect)
Tracking
()
RESOLVED
WORKSFORME
People
(Reporter: k, Unassigned)
References
()
Details
Attachments
(1 file)
|
1.18 KB,
patch
|
jrmuizel
:
review-
|
Details | Diff | Splinter Review |
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008052912 Firefox/3.0
Build Identifier: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008052912 Firefox/3.0
The URL leads to a page which draws an animation with multiple layered canvas elements. The drawing is done as fast as possible. This works fine in Firefox 2 on all operating systems and with Firefox 3 on Windows. But Firefox 3 on Linux (Ubuntu 8.10, tried the debian package AND the binary from getfirefox.com) has severe problems with it. The animation is not smooth and the whole system grinds to a halt for a second periodically.
Because it's working fine on the same machine with Firefox 2 I would say this is a regression.
I've tested this on two machines. One is running Ubuntu 8.10 on a Dell Latitude D820 (Commercial NVidia driver) and one is running Kubuntu 8.10 on a IBM notebook with Open Source Intel graphics driver.
Reproducible: Always
Steps to Reproduce:
1. Open the URL mentioned in the bug report.
2. Just watch the poor performance
3. Try the same in Firefox 2 and see how it should look like.
Actual Results:
Very poor performance and grave impact on system performance.
Expected Results:
Smooth animation, 100% CPU usage but no impact on system performance.
Updated•17 years ago
|
Component: General → Layout: Canvas
Product: Firefox → Core
QA Contact: general → layout.canvas
Version: unspecified → 1.9.0 Branch
| Reporter | ||
Comment 1•17 years ago
|
||
I'm no longer sure if this is just a canvas problem. Looks like it's more a general problem. I noticed that when my system is pretty busy (For example while doing SVN updates on large projects in Eclipse IDE) then Firefox 3 is the ONLY application which stops responding without any recognizable reason. Thunderbird, Gajim (Jabber client) and all the terminal windows which are open during the time have no problems with the high system load.
Maybe Firefox regularly performs some system calls which are blocked because the system is so busy.
To make this more clear I explain how it looks like: I'm using the 3D desktop in Ubuntu 8.10 which means that windows that no longer respond to Gnome are "grayed out". I have three applications running: Firefox 3 (With some static HTML pages displayed in it (No Flash, no animations, just HTML)), Thunderbird and Eclipse. I start a SVN update in Eclipse (With very large projects). This takes a minute or so and the CPU and the harddisk has a lot to do during this time. During the update I do NOTHING, just watching the output of eclipse and I can see the windows of Firefox and Thunderbird. The Firefox window is going gray for some seconds multiple times during the SVN update while the Thunderbird window and the Eclipse window are not grayed out because they are responding fine to the Window Manager.
So this may be hard to reproduce, don't know. I just want to let you know that this bug may be a general bug (Maybe produces by unnecessary system class in Firefox 3?) and not related only to canvas rendering.
Comment 2•17 years ago
|
||
The regression still affects FF3.0.1
I am able to reproduce on a Mandriva 2008.1 with Nvidia driver 173.14.05
If I open one of these URL which demo HTML canvas:
http://www.blobsallad.se/
http://arapehlivanian.com/wp-content/uploads/2007/02/canvas.html
http://andrewwooldridge.com/canvas/canvasgame001/canvasgame002.html
on the same machine, FF3.0.1 performance is 20-30x slower than FF2.0.15
The bug seems to be Linux related (no regression observed if I do the same test on Windows)
Under firefox 3, canvas uses xlib/xrender for its rendering. Under firefox 2, it was just doing pure software rendering. Unfortunately, the state of xrender is a disaster on many systems and drivers. A profile would be useful here.
Comment 4•16 years ago
|
||
This bug is a major concern as it avoids Bespin from being used on Linux.
On my c2duo 3GHz + NVidia 6800GT, it is just unusable !
Comment 5•16 years ago
|
||
Of course, I'm not the original reporter of the bug, so I may not be seeing identical symptoms. But on my system, (Linux 2.6.30-rc6, xserver and xf86-video-intel from git), on top of Debian unstable, and with an Intel GM45 I'm seeing sysprof pointing at pixman_rasterize_edges at a nice 87%.
I like that because I was just in the middle of doing a fix for UXA trapezoid rendering on this driver and this will be a nice test case to see how much it helps.
Although, I'm not quite sure how useful the benchmark actually is. The claim is that it draws "as fast as possible". I'm currently seeing it use 100% CPU, and even if I fix the known bug with UXA-trapezoid rendering, I would still expect it to use 100% CPU if it is drawing "as fast as possible".
A more reasonable example of practical rendering code would render at some desired framerate. It can be useful for benchmarks to run as fast as possible, but in that case they should actually report something such as an achieved framerate so that we can determine if changes we make help, and how much. It should not be expected that drawing as fast as possible results in anything looking smooth at all.
-Carl
From the description, the problem may actually be that work is being off-loaded to the GPU *too* efficiently. If all software fallbacks are avoided then you get, for example:
- a whole bunch of drawing gets queued up for the gpu
- the timing for this drawing is all close together (so animations move slowly)
- then the queue fills up, and the application blocks
- Eventually, the app starts drawing again with a big gap in the time
So you can get a stuttering effect from the animation timing.
Drawing without waiting for the GPU does not give smooth drawing. It might be interesting to try inserting a 1x1 XGetImage() after firefox completes a redraw cycle to force X to wait for the GPU.
Comment 7•16 years ago
|
||
@otaylor
Where would you suggest "lies that blame"?
(In reply to comment #7)
> @otaylor
>
> Where would you suggest "lies that blame"?
It's a combination of:
A) A completely artificial example
B) Lack of good facilities in X for synchronizing application display
C) Firefox not taking advantage of the facilities that do exist
I made a specific recommendation above of something that could be done to the Firefox display loop at least experimentally.
Comment 9•16 years ago
|
||
For what it's worth, in this case "as fast as possible" just means "as fast as possible using setTimeout", which is the same as "target frame rate of 100fps".
I pointed Dany at nsViewManager::Refresh as a reasonable spot to try hacking in an XGetImage, but maybe somewhere in widget-land is better? roc?
nsWindow::OnExposeEvent in widget/src/gtk2/nsWindow.cpp is probably the best place.
Comment 11•16 years ago
|
||
I'm in a bit of a tangle here.
I tried to add the following snippet:
XImage *my_image;
// nsWindow::OnExposeEvent's code
my_surface = ctx->OriginalSurface()->CairoSurface();
my_image = XGetImage(cairo_xlib_surface_get_display(my_surface),
cairo_xlib_surface_get_drawable(my_surface),
1, 1,
1, 1,
(unsigned long)~0L, ZPixmap);
I also included the cairo-xlib.h header.
But, when I compile, I get to following error:
http://pastebin.mozilla.org/655676
I don't know how to proceed from here.
Comment 12•16 years ago
|
||
(In reply to comment #11)
> (snip)
Do you maybe need to add the cairo lib to the linker options in the Makefile.in in that directory? Specifically MOZ_CAIRO_LIBS to the EXTRA_DSO_LDOPTS section?
Comment 13•16 years ago
|
||
(In reply to comment #11)
> I'm in a bit of a tangle here.
> I tried to add the following snippet:
> XImage *my_image;
>
> // nsWindow::OnExposeEvent's code
>
> my_surface = ctx->OriginalSurface()->CairoSurface();
>
> my_image = XGetImage(cairo_xlib_surface_get_display(my_surface),
> cairo_xlib_surface_get_drawable(my_surface),
> 1, 1,
> 1, 1,
> (unsigned long)~0L, ZPixmap);
>
> I also included the cairo-xlib.h header.
>
> But, when I compile, I get to following error:
> http://pastebin.mozilla.org/655676
>
> I don't know how to proceed from here.
The snippet looks fine to me, (with a very quick read).
Here's one potential explanation of what could be going wrong:
The mozilla code includes a copy of the cairo library and is careful to rename all of its symbols to avoid a collision from another instance of cairo gettting linked in, (for example, through a toolkit depending on cairo). So it may be that you are including cairo headers without the magic header that does the symbol renaming. Or perhaps you are getting the renaming header, but its missing support for these cairo_xlib symbols or something.
It shouldn't be too hard to find the magic header if you start with some file in the mozilla source code that's making cairo calls, and then chase its includes a bit.
Good luck,
-Carl
Comment 14•16 years ago
|
||
I used XSync as someone (I'm afraid I forgot his name and beg for his forgiveness) on the cairo IRC channel suggested.
This seems to fix the problem on my machine. There's still some jitter left, but it's negligible compared to how it was before I made that "fix".
Updated•16 years ago
|
Attachment #383506 -
Flags: review?
Updated•16 years ago
|
Attachment #383506 -
Flags: review? → review?(jmuizelaar)
Comment 15•16 years ago
|
||
Shouldn't we just be using cairo_surface_flush() here and have the xlib surface do the right thing? (cairo_xlib_surface currently does nothing in cairo_surface_flush()).
Comment 16•16 years ago
|
||
It would also be good to have some rationale for why we should use XSync instead of XGetImage.
Comment 17•16 years ago
|
||
My impression from reading the above was that XSync was used because it was easier. To clarify the difference
XSync: wait for the server to send all rendering to the GPU
1x1 GetImage: wait for rendering on the GPU to complete
If the X server isn't managing to queue up too many operations on the GPU - and that is probably the normal case right now - they will be pretty much identical.
cairo_surface_flush() should definitely not XSync(), or GetImage: it should not do a blocking wait for rendering to complete. The application might well be going on to draw to another surface within the same "frame". It might be clever enough to asynchronously wait for rendering to complete. (*). Etc.
cairo_surface_flush() is defined as flushing out internal state to Cairo - specifically to allow the user to use native API on the surface. Throwing other random stuff in there would not be a good idea.
(*) E.g., instead of doing an X sync, change a property and wait for the PropertyNotify.
Comment 18•16 years ago
|
||
Alright, I'm convinced that cairo_surface_flush() should not call XSync() or XGetImage(). However, I would think it probably makes sense to add API to cairo to convey these semantics. For example with a gl backend I would expect cairo_surface_flush() to do nothing, but it would be nice to have a function like cairo_surface_done_drawing() that would call glFlush() and cairo_surface_done_drawing_and_wait() that would call glFinish().
Comment 19•15 years ago
|
||
Comment on attachment 383506 [details] [diff] [review]
Fix for the slow/jittery rendering
This patch still scares me a bit but here are some review comments anyways:
We don't need to get the display from the cairo surface and we should only do an XSync on X11.
I.e. the following would be better:
#ifdef MOZ_X11
XSync(GDK_DISPLAY(), False);
#endif /* MOZ_X11 */
Has the problem described in this bug improved without this change or is it still a problem?
Attachment #383506 -
Flags: review?(jmuizelaar) → review-
Updated•14 years ago
|
QA Contact: canvas.2d → jmuizelaar
Comment 20•9 years ago
|
||
Six years since review. Is patch still neeeded?
Flags: needinfo?(jmuizelaar)
Flags: needinfo?(danzat)
| Reporter | ||
Comment 21•9 years ago
|
||
I'm no longer using Ubuntu 8 and Compiz so I can't check if the problem still exists in this environment (And if it does then I guess nobody cares). I have no performance/freeze problems with current Firefox in Gnome Shell on Debian Jessie. Well, it's still slower than Chrome but I consider this to be normal and not related to this ancient bug :-)
Updated•9 years ago
|
Status: UNCONFIRMED → RESOLVED
Closed: 9 years ago
Flags: needinfo?(jmuizelaar)
Resolution: --- → WORKSFORME
Updated•9 years ago
|
Flags: needinfo?(danzat)
You need to log in
before you can comment on or make changes to this bug.
Description
•