Changeset 153522 in webkit


Ignore:
Timestamp:
Jul 31, 2013 7:39:38 AM (11 years ago)
Author:
allan.jensen@digia.com
Message:

[Qt] Images are down-scaled badly
https://bugs.webkit.org/show_bug.cgi?id=119263

Reviewed by Jocelyn Turcotte.

QPainter only does bilinear filtering, which means it will downscaling beyond
0.5x will start skipping pixel and start to degrade the end result. Scaling in
QImage and QPixmap however uses a better but much more expensive sampling that
counts all pixels.

To get the high quality downscaling we must therefore prescale the images before
painting them. To avoid a performance impact on repeated paints the prescaled
image are saved in the QPixmapCache.

  • platform/graphics/qt/ImageQt.cpp:

(WebCore::BitmapImage::draw):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r153515 r153522  
     12013-07-31  Allan Sandfeld Jensen  <allan.jensen@digia.com>
     2
     3        [Qt] Images are down-scaled badly
     4        https://bugs.webkit.org/show_bug.cgi?id=119263
     5
     6        Reviewed by Jocelyn Turcotte.
     7
     8        QPainter only does bilinear filtering, which means it will downscaling beyond
     9        0.5x will start skipping pixel and start to degrade the end result. Scaling in
     10        QImage and QPixmap however uses a better but much more expensive sampling that
     11        counts all pixels.
     12
     13        To get the high quality downscaling we must therefore prescale the images before
     14        painting them. To avoid a performance impact on repeated paints the prescaled
     15        image are saved in the QPixmapCache.
     16
     17        * platform/graphics/qt/ImageQt.cpp:
     18        (WebCore::BitmapImage::draw):
     19
    1202013-07-31  Grzegorz Czajkowski  <g.czajkowski@samsung.com>
    221
  • trunk/Source/WebCore/platform/graphics/qt/ImageQt.cpp

    r147750 r153522  
    4848#include <QPainter>
    4949#include <QPixmap>
     50#include <QPixmapCache>
    5051#include <QTransform>
     52#include <private/qhexstring_p.h>
    5153
    5254#include <math.h>
     
    246248    if (!image)
    247249        return;
     250    QPixmap prescaled;
    248251
    249252    if (mayFillWithSolidColor()) {
     
    255258    normalizedSrc = adjustSourceRectForDownSampling(normalizedSrc, image->size());
    256259#endif
     260
     261    QPainter* painter = ctxt->platformContext();
     262    // The quality of down scaling at 0.5x and below in QPainter is not very good
     263    // due only using bilinear sampling, so for high quality scaling we need to
     264    // perform scaling ourselves.
     265#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
     266    const float pixelRatio = painter->device()->devicePixelRatio();
     267#else
     268    const float pixelRatio = 1;
     269#endif
     270    if (painter->renderHints() & QPainter::SmoothPixmapTransform
     271        && (normalizedDst.width() * 2 * pixelRatio < normalizedSrc.width()
     272            || normalizedDst.height() * 2 * pixelRatio < normalizedSrc.height())) {
     273        // This may not work right with subpixel positions, but that can not currently happen.
     274        QRect pixelSrc = normalizedSrc.toRect();
     275        QSize scaledSize(normalizedDst.width() * pixelRatio, normalizedDst.height() * pixelRatio);
     276        QString key = QStringLiteral("qtwebkit_prescaled_")
     277            % HexString<qint64>(image->cacheKey())
     278            % HexString<int>(pixelSrc.x()) % HexString<int>(pixelSrc.y())
     279            % HexString<int>(pixelSrc.width()) % HexString<int>(pixelSrc.height())
     280            % HexString<int>(scaledSize.width()) % HexString<int>(scaledSize.height());
     281        if (!QPixmapCache::find(key, &prescaled)) {
     282            if (pixelSrc != image->rect())
     283                prescaled = image->copy(pixelSrc).scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
     284            else
     285                prescaled = image->scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
     286            QPixmapCache::insert(key, prescaled);
     287        }
     288        normalizedSrc = QRectF(QPointF(), prescaled.size());
     289        image = &prescaled;
     290    }
    257291
    258292    CompositeOperator previousOperator = ctxt->compositeOperation();
Note: See TracChangeset for help on using the changeset viewer.