Summary: | Background painting tries to paint too much | ||
---|---|---|---|
Product: | [Applications] konqueror | Reporter: | estevam |
Component: | general | Assignee: | Konqueror Developers <konq-bugs> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | maksim, raditzman, thundercloud |
Priority: | NOR | ||
Version: | unspecified | ||
Target Milestone: | --- | ||
Platform: | unspecified | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: |
Description
estevam
2005-10-23 15:14:24 UTC
Here is where it's getting stuck: #7 0xb7069eb5 in QPainter::drawTiledPixmap () from /opt/kde3.4/lib/libqt-mt.so.3 #8 0xb63d5b81 in khtml::RenderBox::paintBackgroundExtended (this=0x84f24f8, p=0x84bf5d0, c=@0xbfaa200c, bgLayer=0x851b254, clipy=706, cliph=128, _tx=0, _ty=0, w=780, h=34323, bleft=0, bright=0) at /home/maksim/kde3/kdelibs/khtml/rendering/render_box.cpp:539 538 if (cw>0 && ch>0) 539 p->drawTiledPixmap(cx, cy, cw, ch, bg->tiled_pixmap(c), sx, sy); (gdb) print ch 34323 this should clearly use cliph! Same problem in 3.5RC1. Fix it pls! *** Bug 107812 has been marked as a duplicate of this bug. *** *** Bug 111218 has been marked as a duplicate of this bug. *** SVN commit 502582 by orlovich: Speedup: Cleanup and consolidate the tiled_pixmap background handling code into just one path. This adds preblend and fixes other bugs in the alpha-specific path I added. The net result is that some web pages paint a lot faster. In particular, most of the stuff in #114938 and its dupes are pretty decent now. (I still need to investigate whether there was some truth in my original analysis, though, so keeping it open for now until I talk it over with Carewolf) Thanks to BCoppens and FredrikH for help with this, in particular in spotting the real problem. CCBUG:114938 M +20 -59 loader.cpp --- branches/KDE/3.5/kdelibs/khtml/misc/loader.cpp #502581:502582 @@ -492,8 +492,8 @@ const QPixmap &CachedImage::tiled_pixmap(const QColor& newc) { - static QRgb bgTransparant = qRgba( 0, 0, 0, 0xFF ); - if ( (bgColor != bgTransparant) && (bgColor != newc.rgb()) ) { + static QRgb bgTransparent = qRgba( 0, 0, 0, 0xFF ); + if ( (bgColor != bgTransparent) && (bgColor != newc.rgb()) ) { delete bg; bg = 0; } @@ -511,6 +511,21 @@ QSize s(pixmap_size()); int w = r.width(); int h = r.height(); + + const QPixmap* src; //source for pretiling, if any + //See whether we can - and should - pre-blend + if (isvalid && (r.hasAlphaChannel() || r.mask() )) { + bg = new QPixmap(w, h); + bg->fill(newc); + bitBlt(bg, 0, 0, &r); + bgColor = newc.rgb(); + src = bg; + } else { + src = &r; + bgColor = bgTransparent; + } + + //See whether to pre-tile. if ( w*h < 8192 ) { if ( r.width() < BGMINWIDTH ) @@ -519,74 +534,20 @@ h = ((BGMINHEIGHT / s.height())+1) * s.height(); } -#ifdef Q_WS_X11 - if ( r.hasAlphaChannel() && - ((w != r.width()) || (h != r.height())) ) + if ( w != r.width() || h != r.height() ) { bg = new QPixmap(w, h); //Tile horizontally on the first stripe for (int x = 0; x < w; x += r.width()) - copyBlt(bg, x, 0, &r, 0, 0, r.width(), r.height()); + copyBlt(bg, x, 0, src, 0, 0, r.width(), r.height()); //Copy first stripe down for (int y = r.height(); y < h; y += r.height()) copyBlt(bg, 0, y, bg, 0, 0, w, r.height()); - - return *bg; } -#endif - if ( -#ifdef Q_WS_X11 - !r.hasAlphaChannel() && -#endif - ( (w != r.width()) || (h != r.height()) || (isvalid && r.mask())) ) - { - QPixmap pix = r; - if ( w != r.width() || (isvalid && pix.mask())) - { - bg = new QPixmap(w, r.height()); - QPainter p(bg); - if(isvalid) p.fillRect(0, 0, w, r.height(), newc); - p.drawTiledPixmap(0, 0, w, r.height(), pix); - p.end(); - - if(!isvalid && pix.mask()) - { - // unfortunately our anti-transparency trick doesn't work here - // we need to create a mask. - QBitmap newmask(w, r.height()); - QPainter pm(&newmask); - pm.drawTiledPixmap(0, 0, w, r.height(), *pix.mask()); - bg->setMask(newmask); - bgColor = bgTransparant; - } - else - bgColor= newc.rgb(); - pix = *bg; - } - if ( h != r.height() ) - { - delete bg; - bg = new QPixmap(w, h); - QPainter p(bg); - if(isvalid) p.fillRect(0, 0, w, h, newc); - p.drawTiledPixmap(0, 0, w, h, pix); - if(!isvalid && pix.mask()) - { - // unfortunately our anti-transparency trick doesn't work here - // we need to create a mask. - QBitmap newmask(w, h); - QPainter pm(&newmask); - pm.drawTiledPixmap(0, 0, w, h, *pix.mask()); - bg->setMask(newmask); - bgColor = bgTransparant; - } - else - bgColor= newc.rgb(); - } + if (bg) return *bg; - } return r; } Well with 3.5.2 this seems to be mostly fixed. At least konqueror doesn't slow down very much. There is something weird still going on though. When I load the page, konqueror CPU is low, but then climbs to about 30% as I scroll down the page. Then the CPU usage of Xorg goes to about 65% and stays there. When I click "stop animations", konqueror CPU usage goes to zero, and xorg drops to 30%. This happens even with no animated images on the screen. The exact complain of this bug report have been fixed in 3.5.3 (background restrained to clip). And the linked webpage doesn't seem so slow either. |