Painting native-themed form controls to canvas is very slow




12 years ago
12 years ago


(Reporter: bzbarsky, Assigned: bzbarsky)


Bug Flags:
in-testsuite ?

Firefox Tracking Flags

(Not tracked)



(1 attachment, 1 obsolete attachment)

Trying to paint the following document:

  data:text/html,<input type="button"><select><option>aaa</select>

To a canvas over here takes 3-4 seconds of 100% CPU.  Hovering over a non-foreground bugzilla tab (with the bug page scrolled to the top) in Seamonkey (which should paint it into a canvas and show that as the preview image) hangs my X for about 30-40 seconds and never shows the preview (because I think the timer for it runs out before we're done painting).

I get the same situation with when it's scrolled to the top.  If I scroll down until I no longer see the form elements, things suddenly work.

The CPU usage is split between X and mozilla (about 50-50, for the most part), and we allocate and deallocate large chunks of memory over and over in mozilla during the whole time (over here, it oscillates between about 200MB and 500MB RAM usage).
Flags: blocking1.9?

Comment 1

12 years ago
The stack goes into thebes, which I know nothing about... 
Does this happen with XUL as well?
You might want to check the surface sizes being allocated in cairo-xlib-utils.c
I don't know whether it happens with XUL; do you have an easy-to-use testcase with lots of XUL native-themed stuff in it that calls drawWindow?

Will check on surface sizes.
roc, good call!  Some typical surface sizes being created by _create_temp_xlib_surface:

11460x1380 -- combobox background
14100x1380 -- combobox background
6960x1380 -- combobox background
19680x1320 -- text control background
19680x1320 -- text control background
19680x1320 -- text control background

Looking at nsNativeThemeGTK::DrawWidgetBackground, we seem to be passing rects in twips down to the gfxXlibNativeRenderer code....

I wonder why this is not a problem when painting on screen, at least as far as I can tell.
I guess in the screen case we go through draw_with_xlib_direct, eh?
I think that, or maybe that in DrawWidgetBackground, when snapXY is true we convert to pixels, otherwise we don't...

So NSAppUnitsToIntPixels should be added to the !snapXY path. I'd review that patch :-)
Uh... I'm not sure I follow.  The snapXY path rounds the width and height to an integer number of pixels (twice, in fact, which seems silly).  Using NSAppUnitsToIntPixels on the !snapXY path woudl make it do exactly the same rounding.  Why have two paths, then?

Note that in this case snapXY is false because of:

(gdb) p current
$3 = {xx = 0.23166023194789886, yx = 0, xy = 0, yy = 0.23209549486637115, 
  x0 = 33.092664133757353, y0 = 15.585212480276825}

presumably because the canvas size is smaller than the window size of the window we're painting into it....
Created attachment 268275 [details] [diff] [review]
Proposed patch

This seems to fix things over here.
Assignee: nobody → bzbarsky
Attachment #268275 - Flags: superreview?(roc)
Attachment #268275 - Flags: review?(roc)
Created attachment 268278 [details] [diff] [review]
Rounding up
Attachment #268275 - Attachment is obsolete: true
Attachment #268278 - Flags: superreview?(roc)
Attachment #268278 - Flags: review?(roc)
Attachment #268275 - Flags: superreview?(roc)
Attachment #268275 - Flags: review?(roc)
Attachment #268278 - Flags: superreview?(roc)
Attachment #268278 - Flags: superreview+
Attachment #268278 - Flags: review?(roc)
Attachment #268278 - Flags: review+
Checked in.
Last Resolved: 12 years ago
Resolution: --- → FIXED


12 years ago
Flags: in-testsuite-
I think we should be able to test these sort of things...
Flags: in-testsuite?
Flags: in-testsuite-
Flags: blocking1.9?
You need to log in before you can comment on or make changes to this bug.