| Differences between
and this patch
- a/WebCore/ChangeLog +19 lines
Lines 1-3 a/WebCore/ChangeLog_sec1
1
2010-06-09  Sam Magnuson  <smagnuson@netflix.com>
2
3
        Reviewed by NOBODY (OOPS!).
4
5
        [Qt] When any geometry change happens to a node it will resize the
6
        backing cache
7
        https://bugs.webkit.org/show_bug.cgi?id=40378
8
9
        Continue to grow the cache, but never toss it. When the pixmap
10
        cache gets too big it will be lost and created at the right size
11
        next time.
12
13
        No new tests: this is an optimization.
14
15
        * platform/graphics/qt/GraphicsLayerQt.cpp:
16
        (WebCore::GraphicsLayerQtImpl::recache):
17
        (WebCore::GraphicsLayerQtImpl::paint):
18
        (WebCore::GraphicsLayerQtImpl::flushChanges):
19
1
2010-06-21  Sheriff Bot  <webkit.review.bot@gmail.com>
20
2010-06-21  Sheriff Bot  <webkit.review.bot@gmail.com>
2
21
3
        Unreviewed, rolling out r61585.
22
        Unreviewed, rolling out r61585.
- a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp -23 / +106 lines
Lines 41-46 a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp_sec1
41
#include <QtGui/qpixmapcache.h>
41
#include <QtGui/qpixmapcache.h>
42
#include <QtGui/qstyleoption.h>
42
#include <QtGui/qstyleoption.h>
43
43
44
45
#define QT_DEBUG_RECACHE 0
46
#define QT_DEBUG_CACHEDUMP 0
47
44
namespace WebCore {
48
namespace WebCore {
45
49
46
#ifndef QT_NO_GRAPHICSEFFECT
50
#ifndef QT_NO_GRAPHICSEFFECT
Lines 225-231 public: a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp_sec2
225
    int m_changeMask;
229
    int m_changeMask;
226
230
227
    QSizeF m_size;
231
    QSizeF m_size;
228
    QPixmapCache::Key m_backingStoreKey;
232
    struct {
233
        QPixmapCache::Key key;
234
        QSizeF size;
235
    } m_backingStore;
229
#ifndef QT_NO_ANIMATION
236
#ifndef QT_NO_ANIMATION
230
    QList<QWeakPointer<QAbstractAnimation> > m_animations;
237
    QList<QWeakPointer<QAbstractAnimation> > m_animations;
231
#endif
238
#endif
Lines 339-374 const GraphicsLayerQtImpl* GraphicsLayerQtImpl::rootLayer() const a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp_sec3
339
346
340
QPixmap GraphicsLayerQtImpl::recache(const QRegion& regionToUpdate)
347
QPixmap GraphicsLayerQtImpl::recache(const QRegion& regionToUpdate)
341
{
348
{
342
    if (!m_layer->drawsContent() || m_size.isEmpty() ||!m_size.isValid())
349
    if (!m_layer->drawsContent() || m_size.isEmpty() || !m_size.isValid())
343
        return QPixmap();
350
        return QPixmap();
344
351
345
    QRegion region = regionToUpdate;
346
    QPixmap pixmap;
352
    QPixmap pixmap;
353
    QRegion region = regionToUpdate;
354
    if (QPixmapCache::find(m_backingStore.key, &pixmap)) {
355
        if (region.isEmpty())
356
            return pixmap;
357
        QPixmapCache::remove(m_backingStore.key); // Remove the reference to the pixmap in the cache to avoid a detach.
358
    }
347
359
348
    // We might be drawing into an existing cache.
360
    {
349
    if (!QPixmapCache::find(m_backingStoreKey, &pixmap))
361
        bool erased = false;
350
        region = QRegion(QRect(0, 0, m_size.width(), m_size.height()));
351
362
352
    if (m_size != pixmap.size()) {
363
        // If the pixmap is not in the cache or the view has grown since last cached.
353
        pixmap = QPixmap(m_size.toSize());
364
        if (pixmap.isNull() || m_size != m_backingStore.size) {
354
        if (!m_layer->contentsOpaque())
365
#if QT_DEBUG_RECACHE
355
            pixmap.fill(Qt::transparent);
366
            if (pixmap.isNull())
356
        m_pendingContent.regionToUpdate = QRegion(QRect(QPoint(0, 0), m_size.toSize()));
367
                qDebug() << "CacheMiss" << this << m_size;
357
    }
368
#endif
369
            bool fill = true;
370
            QRegion newRegion;
371
            QPixmap oldPixmap = pixmap;
372
373
            // If the pixmap is two small to hold the view contents we enlarge, otherwise just use the old (large) pixmap.
374
            if (pixmap.width() < m_size.width() || pixmap.height() < m_size.height()) {
375
#if QT_DEBUG_RECACHE
376
                qDebug() << "CacheGrow" << this << m_size;
377
#endif
378
                pixmap = QPixmap(m_size.toSize());
379
                pixmap.fill(Qt::transparent);
380
                newRegion = QRegion(0, 0, m_size.width(), m_size.height());
381
            }
382
383
#if 1
384
            // Blit the contents of oldPixmap back into the cached pixmap as we are just adding new pixels.
385
            if (!oldPixmap.isNull()) {
386
                const QRegion cleanRegion = (QRegion(0, 0, m_size.width(), m_size.height())
387
                                             & QRegion(0, 0, m_backingStore.size.width(), m_backingStore.size.height())) - regionToUpdate;
388
                if (!cleanRegion.isEmpty()) {
389
#if QT_DEBUG_RECACHE
390
                    qDebug() << "CacheBlit" << this << cleanRegion;
391
#endif
392
                    const QRect cleanBounds(cleanRegion.boundingRect());
393
                    QPainter painter(&pixmap);
394
                    painter.setCompositionMode(QPainter::CompositionMode_Source);
395
                    painter.drawPixmap(cleanBounds.topLeft(), oldPixmap, cleanBounds);
396
                    newRegion -= cleanRegion;
397
                    fill = false; // We cannot just fill the pixmap.
398
                }
399
                oldPixmap = QPixmap();
400
            }
401
#endif
402
            region += newRegion;
403
            if (fill && !region.isEmpty()) { // Clear the entire pixmap with the background.
404
#if QT_DEBUG_RECACHE
405
                qDebug() << "CacheErase" << this << m_size << background;
406
#endif
407
                erased = true;
408
                pixmap.fill(Qt::transparent);
409
            }
410
        }
411
        region &= QRegion(0, 0, m_size.width(), m_size.height());
412
413
        // If we have something to draw its time to erase it and render the contents.
414
        if (!region.isEmpty()) {
415
#if QT_DEBUG_CACHEDUMP
416
            static int recacheCount = 0;
417
            ++recacheCount;
418
            qDebug() << "**** CACHEDUMP" << recacheCount << this << m_layer << region << m_size;
419
            pixmap.save(QString().sprintf("/tmp/%05d_A.png", recacheCount), "PNG");
420
#endif
421
422
            QPainter painter(&pixmap);
423
            GraphicsContext gc(&painter);
424
425
            painter.setClipRegion(region);
358
426
359
    QPainter painter(&pixmap);
427
            if (!erased) { // Erase the area in cache that we're drawing into.
360
    GraphicsContext gc(&painter);
428
                painter.setCompositionMode(QPainter::CompositionMode_Clear);
429
                painter.fillRect(region.boundingRect(), Qt::transparent);
361
430
362
    // Clear the area in cache that we're drawing into
431
#if QT_DEBUG_CACHEDUMP
363
    painter.setCompositionMode(QPainter::CompositionMode_Clear);
432
                qDebug() << "**** CACHEDUMP" << recacheCount << this << m_layer << region << m_size;
364
    painter.fillRect(region.boundingRect(), Qt::transparent);
433
                pixmap.save(QString().sprintf("/tmp/%05d_B.png", recacheCount), "PNG");
434
#endif
435
            }
365
436
366
    // Render the actual contents into the cache
437
            // Render the actual contents into the cache.
367
    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
438
            painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
368
    m_layer->paintGraphicsLayerContents(gc, region.boundingRect());
439
            m_layer->paintGraphicsLayerContents(gc, region.boundingRect());
369
    painter.end();
440
            painter.end();
370
441
371
    m_backingStoreKey = QPixmapCache::insert(pixmap);
442
#if QT_DEBUG_CACHEDUMP
443
            qDebug() << "**** CACHEDUMP" << recacheCount << this << m_layer << region << m_size;
444
            pixmap.save(QString().sprintf("/tmp/%05d_C.png", recacheCount), "PNG");
445
#endif
446
        }
447
        m_backingStore.size = m_size; // Store the used size of the pixmap.
448
    }
449
450
    // Finally insert into the cache and allow a reference there.
451
    m_backingStore.key = QPixmapCache::insert(pixmap);
372
    return pixmap;
452
    return pixmap;
373
}
453
}
374
454
Lines 487-494 void GraphicsLayerQtImpl::paint(QPainter* painter, const QStyleOptionGraphicsIte a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp_sec4
487
        if (m_state.drawsContent) {
567
        if (m_state.drawsContent) {
488
            QPixmap backingStore;
568
            QPixmap backingStore;
489
            // We might need to recache, in case we try to paint and the cache was purged (e.g. if it was full).
569
            // We might need to recache, in case we try to paint and the cache was purged (e.g. if it was full).
490
            if (!QPixmapCache::find(m_backingStoreKey, &backingStore) || backingStore.size() != m_size.toSize())
570
            if (!QPixmapCache::find(m_backingStore.key, &backingStore) || backingStore.size() != m_size.toSize())
491
                backingStore = recache(QRegion(m_state.contentsRect));
571
                backingStore = recache(QRegion(m_state.contentsRect));
572
            const QRectF bounds(0, 0, m_backingStore.size.width(), m_backingStore.size.height());
492
            painter->drawPixmap(0, 0, backingStore);
573
            painter->drawPixmap(0, 0, backingStore);
493
        }
574
        }
494
        break;
575
        break;
Lines 674-684 void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp_sec5
674
    else
755
    else
675
#endif
756
#endif
676
    if (m_changeMask & DisplayChange) {
757
    if (m_changeMask & DisplayChange) {
758
#ifndef QT_GRAPHICS_LAYER_NO_RECACHE_ON_DISPLAY_CHANGE
677
        // Recache now: all the content is ready and we don't want to wait until the paint event.
759
        // Recache now: all the content is ready and we don't want to wait until the paint event.
678
        // We only need to do this for HTML content, there's no point in caching directly composited
760
        // We only need to do this for HTML content, there's no point in caching directly composited
679
        // content like images or solid rectangles.
761
        // content like images or solid rectangles.
680
        if (m_pendingContent.contentType == HTMLContentType)
762
        if (m_pendingContent.contentType == HTMLContentType)
681
            recache(m_pendingContent.regionToUpdate);
763
            recache(m_pendingContent.regionToUpdate);
764
#endif
682
        update(m_pendingContent.regionToUpdate.boundingRect());
765
        update(m_pendingContent.regionToUpdate.boundingRect());
683
        m_pendingContent.regionToUpdate = QRegion();
766
        m_pendingContent.regionToUpdate = QRegion();
684
    }
767
    }

Return to Bug 40378