diff options
author | Teng-Hui Zhu <ztenghui@google.com> | 2010-11-10 15:31:59 -0800 |
---|---|---|
committer | Teng-Hui Zhu <ztenghui@google.com> | 2010-11-17 13:35:59 -0800 |
commit | 28040489d744e0c5d475a88663056c9040ed5320 (patch) | |
tree | c463676791e4a63e452a95f0a12b2a8519730693 /WebCore/platform/graphics/qt/GraphicsLayerQt.cpp | |
parent | eff9be92c41913c92fb1d3b7983c071f3e718678 (diff) | |
download | external_webkit-28040489d744e0c5d475a88663056c9040ed5320.zip external_webkit-28040489d744e0c5d475a88663056c9040ed5320.tar.gz external_webkit-28040489d744e0c5d475a88663056c9040ed5320.tar.bz2 |
Merge WebKit at r71558: Initial merge by git.
Change-Id: Ib345578fa29df7e4bc72b4f00e4a6fddcb754c4c
Diffstat (limited to 'WebCore/platform/graphics/qt/GraphicsLayerQt.cpp')
-rw-r--r-- | WebCore/platform/graphics/qt/GraphicsLayerQt.cpp | 116 |
1 files changed, 113 insertions, 3 deletions
diff --git a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp index aa7ed2f..49387a2 100644 --- a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp +++ b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp @@ -37,12 +37,21 @@ #include <QtGui/qgraphicseffect.h> #include <QtGui/qgraphicsitem.h> #include <QtGui/qgraphicsscene.h> +#include <QtGui/qgraphicsview.h> #include <QtGui/qgraphicswidget.h> #include <QtGui/qpainter.h> #include <QtGui/qpixmap.h> #include <QtGui/qpixmapcache.h> #include <QtGui/qstyleoption.h> +#if ENABLE(TILED_BACKING_STORE) +#include "TiledBackingStore.h" +#include "TiledBackingStoreClient.h" + +// The minimum width/height for tiling. We use the same value as the Windows implementation. +#define GRAPHICS_LAYER_TILING_THRESHOLD 2000 +#endif + #define QT_DEBUG_RECACHE 0 #define QT_DEBUG_CACHEDUMP 0 @@ -112,7 +121,11 @@ public: }; #endif // QT_NO_GRAPHICSEFFECT -class GraphicsLayerQtImpl : public QGraphicsObject { +class GraphicsLayerQtImpl : public QGraphicsObject +#if ENABLE(TILED_BACKING_STORE) +, public virtual TiledBackingStoreClient +#endif +{ Q_OBJECT public: @@ -182,6 +195,16 @@ public: // ChromeClientQt::scheduleCompositingLayerSync (meaning the sync will happen ASAP) void flushChanges(bool recursive = true, bool forceTransformUpdate = false); +#if ENABLE(TILED_BACKING_STORE) + // reimplementations from TiledBackingStoreClient + virtual void tiledBackingStorePaintBegin(); + virtual void tiledBackingStorePaint(GraphicsContext*, const IntRect&); + virtual void tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea); + virtual IntRect tiledBackingStoreContentsRect(); + virtual IntRect tiledBackingStoreVisibleRect(); + virtual Color tiledBackingStoreBackgroundColor() const; +#endif + public slots: // We need to notify the client (ie. the layer compositor) when the animation actually starts. void notifyAnimationStarted(); @@ -232,6 +255,10 @@ public: int m_changeMask; +#if ENABLE(TILED_BACKING_STORE) + TiledBackingStore* m_tiledBackingStore; +#endif + QSizeF m_size; struct { QPixmapCache::Key key; @@ -303,6 +330,9 @@ GraphicsLayerQtImpl::GraphicsLayerQtImpl(GraphicsLayerQt* newLayer) , m_opacityAnimationRunning(false) , m_blockNotifySyncRequired(false) , m_changeMask(NoChanges) +#if ENABLE(TILED_BACKING_STORE) + , m_tiledBackingStore(0) +#endif #if ENABLE(3D_CANVAS) , m_gc3D(0) #endif @@ -330,7 +360,9 @@ GraphicsLayerQtImpl::~GraphicsLayerQtImpl() item->setParentItem(0); } } - +#if ENABLE(TILED_BACKING_STORE) + delete m_tiledBackingStore; +#endif #ifndef QT_NO_ANIMATION // We do, however, own the animations. QList<QWeakPointer<QAbstractAnimation> >::iterator it; @@ -352,6 +384,27 @@ QPixmap GraphicsLayerQtImpl::recache(const QRegion& regionToUpdate) if (!m_layer->drawsContent() || m_size.isEmpty() || !m_size.isValid()) return QPixmap(); +#if ENABLE(TILED_BACKING_STORE) + const bool requiresTiling = (m_state.drawsContent && m_currentContent.contentType == HTMLContentType) && (m_size.width() > GRAPHICS_LAYER_TILING_THRESHOLD || m_size.height() > GRAPHICS_LAYER_TILING_THRESHOLD); + if (requiresTiling && !m_tiledBackingStore) { + m_tiledBackingStore = new TiledBackingStore(this); + m_tiledBackingStore->setTileCreationDelay(0); + setFlag(ItemUsesExtendedStyleOption, true); + } else if (!requiresTiling && m_tiledBackingStore) { + delete m_tiledBackingStore; + m_tiledBackingStore = 0; + setFlag(ItemUsesExtendedStyleOption, false); + } + + if (m_tiledBackingStore) { + m_tiledBackingStore->adjustVisibleRect(); + const QVector<QRect> rects = regionToUpdate.rects(); + for (int i = 0; i < rects.size(); ++i) + m_tiledBackingStore->invalidate(rects[i]); + return QPixmap(); + } +#endif + QPixmap pixmap; QRegion region = regionToUpdate; if (QPixmapCache::find(m_backingStore.key, &pixmap)) { @@ -562,8 +615,15 @@ QRectF GraphicsLayerQtImpl::boundingRect() const void GraphicsLayerQtImpl::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { +#if ENABLE(TILED_BACKING_STORE) + // FIXME: There's currently no Qt API to know if a new region of an item is exposed outside of the paint event. + // Suggested for Qt: http://bugreports.qt.nokia.com/browse/QTBUG-14877. + if (m_tiledBackingStore) + m_tiledBackingStore->adjustVisibleRect(); +#endif + if (m_currentContent.backgroundColor.isValid()) - painter->fillRect(option->rect, QColor(m_currentContent.backgroundColor)); + painter->fillRect(option->exposedRect, QColor(m_currentContent.backgroundColor)); switch (m_currentContent.contentType) { case HTMLContentType: @@ -828,6 +888,56 @@ afterLayerChanges: } } +#if ENABLE(TILED_BACKING_STORE) +/* \reimp (TiledBackingStoreClient.h) +*/ +void GraphicsLayerQtImpl::tiledBackingStorePaintBegin() +{ +} + +/* \reimp (TiledBackingStoreClient.h) +*/ +void GraphicsLayerQtImpl::tiledBackingStorePaint(GraphicsContext* gc, const IntRect& rect) +{ + m_layer->paintGraphicsLayerContents(*gc, rect); +} + +/* \reimp (TiledBackingStoreClient.h) +*/ +void GraphicsLayerQtImpl::tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea) +{ + for (int i = 0; i < paintedArea.size(); ++i) + update(QRectF(paintedArea[i])); +} + +/* \reimp (TiledBackingStoreClient.h) +*/ +IntRect GraphicsLayerQtImpl::tiledBackingStoreContentsRect() +{ + return m_layer->contentsRect(); +} + +/* \reimp (TiledBackingStoreClient.h) +*/ +Color GraphicsLayerQtImpl::tiledBackingStoreBackgroundColor() const +{ + if (m_currentContent.contentType == PixmapContentType && !m_currentContent.pixmap.hasAlphaChannel()) + return Color(0, 0, 0); + // We return a transparent color so that the tiles initialize with alpha. + return Color(0, 0, 0, 0); +} + +IntRect GraphicsLayerQtImpl::tiledBackingStoreVisibleRect() +{ + const QGraphicsView* view = scene()->views().isEmpty() ? 0 : scene()->views().first(); + if (!view) + return mapFromScene(scene()->sceneRect()).boundingRect().toAlignedRect(); + + // All we get is the viewport's visible region. We have to map it to the scene and then to item coordinates. + return mapFromScene(view->mapToScene(view->viewport()->visibleRegion().boundingRect()).boundingRect()).boundingRect().toAlignedRect(); +} +#endif + void GraphicsLayerQtImpl::notifyAnimationStarted() { // WebCore notifies javascript when the animation starts. Here we're letting it know. |