Version: (using KDE KDE 3.97.0) Installed from: Ubuntu Packages OS: Linux (regression vs konqueror 3.5.8) *buntu 8.04 amd athlon 2100+ 768mb ddr1 2700 ati 9600se 128mb (xorg ati driver) hi. in kde 3.5.8, konqueror was able to browse & scroll around textra.podshow.com without noticeable problems. in kde 4.0rc2... it causes xorg to max out and konqueror only manages to refresh every 5 seconds or so. appears to be a massive performance regression. (default settings on both browsers & kde environments)
Confirmed. Both konqueror and Xorg process reach about 30% of CPU use (top).
this is caused by prodigal use of CSS opacity feature which is expensive (and wasn't implemented in 3.5). AFAIKS all browsers supporting opacity have the same problem with this site. It's every bit as sluggish in Mozilla's and Opera's recent browsers here. For a very limited gain, I can make the renderer avoid to bother draw anything that has 'opacity: 0' (complete transparency) as I see this site is using that wording in a few places. But that is not going to make a practical difference I'm afraid. Now there might be room for deeper optimizations as the site does not *visibly* use opacity so much. It could be that some transparent elements are entirely covered by opaque ones. At this level of expense, it would be quite worth calculating all visible layers rects as we do to have proper z-order on flash widgets, and prune every layer with opacity that is entirely covered. An interesting chalenge.
I can confirm this being due to opacity, but it's also due to Qt being spectacularily stupid about how it implements most operations with opacity. FiNeX, are you building from source? I have some patches that might help, but it's not bad enough on my machine for me to be sure if they do help. P.S. We seem to be missing an image here --- or did I mess it up when trying to optimize things? ---------------------------- #0 0xb7f37410 in __kernel_vsyscall () #1 0xb62d84c7 in poll () from /lib/i686/libc.so.6 #2 0xb73f9990 in ?? () from /usr/lib/libX11.so.6 #3 0xb73f9d81 in _XRead () from /usr/lib/libX11.so.6 #4 0xb73fa711 in _XReply () from /usr/lib/libX11.so.6 #5 0xb73dd483 in XGetImage () from /usr/lib/libX11.so.6 #6 0xb6839c69 in QPixmap::toImage (this=0x89bc3d8) at image/qpixmap_x11.cpp:756 #7 0xb685b642 in QTexturedBrushData::image (this=0x896fc20) at painting/qbrush.cpp:156 #8 0xb685849e in QBrush::textureImage (this=0x8c621d0) at painting/qbrush.cpp:738 #9 0xb68c82f1 in QSpanData::setup (this=0x8c62318, brush=@0x8c621d0, alpha=230) at painting/qpaintengine_raster.cpp:4841 #10 0xb68d07f8 in QRasterPaintEngine::updateState (this=0x898fcd0, state=@0x9032418) at painting/qpaintengine_raster.cpp:1285 #11 0xb686def9 in QPainterPrivate::updateState (this=0x901cbc8, newState=0x9032418) at painting/qpainter.cpp:600 #12 0xb6877247 in QPainter::drawPath (this=0xbff8ac48, path=@0xbff8ae18) at painting/qpainter.cpp:2486 #13 0xb687365b in QPainterPrivate::draw_helper (this=0x8c74720, originalPath=@0xbff8ae18, op=QPainterPrivate::StrokeAndFillDraw) at painting/qpainter.cpp:235 #14 0xb687599b in QPainter::drawRects (this=0xbff8bbac, rects=0xbff8af10, rectCount=1) at painting/qpainter.cpp:2629 #15 0xb77ac6dc in QPainter::drawRect (this=0xbff8bbac, rect=@0xbff8af10) at /home/maksim/kde4/src/qt-copy/include/QtGui/../../src/gui/painting/qpainter.h:559 #16 0xb6876e57 in QPainter::drawPixmap (this=0xbff8bbac, r=@0xbff8b020, pm=@0x918e458, sr=@0xbff8b000) at painting/qpainter.cpp:4258 #17 0xb6838710 in QPainter::drawPixmap (this=0xbff8bbac, x=158, y=1507, pm=@0x918e458, sx=0, sy=3, sw=64, sh=61) at ../../include/QtGui/../../src/gui/painting/qpainter.h:733 #18 0xb26c4bb0 in khtmlImLoad::PixmapPlane::paint (this=0x9612b90, dx=158, dy=1507, p=0xbff8bbac, sx=0, sy=3, sWidth=75, sHeight=65) at /home/maksim/kde4/src/kdelibs/khtml/imload/pixmapplane.cpp:115 #19 0xb26c511c in khtmlImLoad::ImagePainter::paint (this=0x857f228, dx=158, dy=1507, p=0xbff8bbac, sx=0, sy=3, width=75, height=65) at /home/maksim/kde4/src/kdelibs/khtml/imload/imagepainter.cpp:126 #20 0xb257d667 in khtml::RenderImage::paint (this=0x94ee084, paintInfo=@0xbff8b390, _tx=158, _ty=1504) at /home/maksim/kde4/src/kdelibs/khtml/rendering/render_image.cpp:310 ---------------------------- #0 0xb7f07410 in __kernel_vsyscall () #1 0xb62a84c7 in poll () from /lib/i686/libc.so.6 #2 0xb73ca08f in ?? () from /usr/lib/libX11.so.6 #3 0xb73ca4ce in _XSend () from /usr/lib/libX11.so.6 #4 0xb73bce79 in ?? () from /usr/lib/libX11.so.6 #5 0xb73bbe6b in ?? () from /usr/lib/libX11.so.6 #6 0xb73bd0e6 in XPutImage () from /usr/lib/libX11.so.6 #7 0xb680ce31 in QPixmap::fromImage (img=@0xbfe141f4, flags=@0xbfe1421c) at image/qpixmap_x11.cpp:1210 #8 0xb683800a in QPaintEngine::drawImage (this=0x8174fd0, r=@0xbfe14510, image=@0xbfe1444c, sr=@0xbfe144f0, flags=@0xbfe14300) at painting/qpaintengine.cpp:529 #9 0xb68cad1e in QX11PaintEngine::drawImage (this=0x8174fd0, r=@0xbfe14510, image=@0xbfe1444c, sr=@0xbfe144f0, flags=@0xbfe144ec) at painting/qpaintengine_x11.cpp:1588 #10 0xb6843761 in QPainterPrivate::draw_helper (this=0x8b76f18, originalPath=@0xbfe14618, op=QPainterPrivate::StrokeAndFillDraw) at painting/qpainter.cpp:245 #11 0xb684547b in QPainter::drawRects (this=0xbfe1523c, rects=0xbfe14710, rectCount=1) at painting/qpainter.cpp:2680 #12 0xb76a86ec in QPainter::drawRect (this=0xbfe1523c, r=@0xbfe14710) at /home/maksim/kde4/src/qt-copy/include/QtGui/../../src/gui/painting/qpainter.h:570 #13 0xb68456b6 in QPainter::fillRect (this=0xbfe1523c, r=@0xbfe14710, brush=@0xbfe14888) at painting/qpainter.cpp:5345 #14 0xb7ea3ab4 in QPainter::fillRect (this=0xbfe1523c, x=356, y=3189, w=402, h=189, b=@0xbfe14888) at /home/maksim/kde4/src/qt-copy/include/QtGui/../../src/gui/painting/qpainter.h:671 #15 0xb24347f1 in khtml::RenderBox::paintBackgroundExtended (this=0x91fa094, p=0xbfe1523c, c=@0xbfe149ec, bgLayer=0x91fd8ac, clipr= {x1 = 356, y1 = 3189, x2 = 757, y2 = 3377}, _tx=356, _ty=3189, w=402, h=363, bleft=0, bright=0, pleft=1, pright=1, btop=0, bbottom=0, ptop=1, pbottom=1) at /home/maksim/kde4/src/kdelibs/khtml/rendering/render_box.cpp:534 #16 0xb242e685 in khtml::RenderBox::paintBackground (this=0x91fa094, p=0xbfe1523c, c=@0xbfe149ec, bgLayer=0x91fd8ac, clipr= {x1 = 356, y1 = 3189, x2 = 757, y2 = 3377}, _tx=356, _ty=3189, w=402, height=363) at /home/maksim/kde4/src/kdelibs/khtml/rendering/render_box.cpp:461
If a non-opaque layer is rendered on a pixmap with full opacity, a possible workaround is to reduce the opacity of the pixmap using DestinationIn before the pixmap is rendered, like this: QPainter p(&pixmap); p.setCompositionMode(QPainter::DestinationIn); p.fillRect(pixmap.rect(), QColor(0, 0, 0, opacity)); Care must be taken to ensure that the pixmap has an alpha channel, by calling pixmap.fill(Qt::transparent) when it's created for this to work. This opacity reduction can be accelerated by the open source Intel driver, and the ATI driver on R100 and R200 based cards, when in EXA mode. I expect the proprietary NVidia driver to be able to accelerate it as well.
Yes Maksim, send me your patches. I'll test with pleasure :)
Created attachment 22645 [details] attempt to workaround -- partly Here it is. Still quite slow, but may be a bit better? Thanks for testing
this is a good playground too (lot of transforming images with opacity): http://www.dhteumeuleu.com/runscript.php?scr=photo3D.html it used to be fast in 3.5 ;/
I can't say I see a significant amelioration with the patch. Timing scrolling on the site, I get identical figures. (using Qt 4.3.2...)
SVN commit 752353 by ggarand: optimize instances of opacity: 0; CCBUG: 154420 M +3 -0 render_layer.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=752353
I've just tried the patches but without improvement :-(
Thanks FiNeX. It's good to know, at least. Germain: it seems that RenderLayer::paintLayer can recurse, and if there are separate opacities set, they don't multiply, right? I guess then to implement Fredrik's suggestion we would have to push the parent alpha down and divide out..
Maks: it should in fact multiply. But looking back at the CSS3 spec, I see opacity is supposed to be a post-rendering, atomic operation anyway. I'll have a shot at rendering the layer off-screen and blend it in one go, if I can stole enough time to my family.
Created attachment 22790 [details] patch for test/review. OK, there were several things seriously wrong with our opacity implementation which this patch addresses (most notably, transparent objects must establish a stacking context to have proper transparency stacking). Also, opacity is now applied atomically, as the CSS3 spec draft wants. Additionnaly, patch provides an extension to the paint buffer to try to speed things even more. I'm not completely sure it's worth the trouble though, as it would need benchmarking on release mode binaries, which I have no time to compile at the moment. If anyone has a fully optimized build, please try enabling/removing #define USE_PIXMAP_CACHE and do some timings on e.g scrolling the http://textra.podshow.com site. All in all, observe a doubling of opacity rendering speed with this patch applied.
SVN commit 756740 by ggarand: rework CSS3 opacity, for correctness and workable speed. .Try hard to minimize the painting region. .Blend layers atomically after off-screen rendering. .Rework the PaintBuffer so that it can provide multiple buffers. .Each transparent object must define a new stacking context so that their rendering sub-tree appears as atomic to ancestors, as wanted by CSS3. CCBUG: 154420 M +163 -20 misc/paintbuffer.cpp M +83 -3 misc/paintbuffer.h M +22 -9 rendering/render_layer.cpp M +5 -4 rendering/render_object.cpp M +3 -2 rendering/render_replaced.cpp M +6 -6 rendering/render_style.h WebSVN link: http://websvn.kde.org/?view=rev&revision=756740
(by the way Maksim, OT but if I go to the reported site with debugger enabled, I get a crash - dereference of a null Document pointer in DebugWindow::enterContext)
SVN commit 759026 by orlovich: Fix the debugger crash spart noticed on 154420. We were killing source code information on eval fragments which had functions which escaped.. Inellegant, but effective CCBUG:154420 M +11 -0 debugdocument.cpp M +7 -0 debugdocument.h M +8 -3 debugwindow.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=759026
SVN commit 809426 by fredrik: Improve performance when rendering CSS opacity layers, by using CompositionMode_DestinationIn to reduce the alpha of the layers before rendering them, instead of using QPainter::setOpacity(). With this change we no longer end up in QPainterPrivate::draw_helper(), and the rendering is fully accelerated in hardware with drivers that accelerate Xrender. BUG: 154420 M +4 -1 paintbuffer.h WebSVN link: http://websvn.kde.org/?view=rev&revision=809426
http://www.dhteumeuleu.com/runscript.php?scr=photo3D.html is still CPU consuming (about 30-40% of a P4@2600Mhz), moreover there is a lot of flickering. Instead http://textra.podshow.com is better, the CPU use is quite regular.