diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-07-05 04:20:14 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-07-05 08:31:07 (GMT) |
commit | 09f07b98dfdaec2e48749768b967a48e588d3f7f (patch) | |
tree | afb3d254883bef441614a2c9453be8ac9bf51e5f /src/declarative/graphicsitems/qdeclarativeborderimage.cpp | |
parent | b2aedd1d57a5a681b1185bf8908683ff563de4d6 (diff) | |
download | Qt-09f07b98dfdaec2e48749768b967a48e588d3f7f.zip Qt-09f07b98dfdaec2e48749768b967a48e588d3f7f.tar.gz Qt-09f07b98dfdaec2e48749768b967a48e588d3f7f.tar.bz2 |
Make declarative pixmap cache easier to use
The QDeclarativePixmapCache was both slow, and very trickey to use correctly.
Many QML elements did not correctly cancel outstanding requests, which leads
to pixmaps leaking indefinately. Other elements, such as Text, were
subject to race conditions that meant they may never actually load all their
images.
QDeclarativePixmap is a single class than encapsulates the action of
fetching a pixmap, as well as the pixmap itself and the responsibility of
canceling outstanding requests. Rather than relying on Qt's pixmap cache
that doesn't cache all the information QML needs, QDeclarativePixmap
implements its own cache, that correctly degrades over time (unlike
QPixmapCache that can stop expiring items in some conditions).
Reviewed-by: Warwick Allison
Diffstat (limited to 'src/declarative/graphicsitems/qdeclarativeborderimage.cpp')
-rw-r--r-- | src/declarative/graphicsitems/qdeclarativeborderimage.cpp | 100 |
1 files changed, 35 insertions, 65 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp index d4ca9eb..44c206b 100644 --- a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp @@ -94,8 +94,6 @@ QDeclarativeBorderImage::~QDeclarativeBorderImage() Q_D(QDeclarativeBorderImage); if (d->sciReply) d->sciReply->deleteLater(); - if (d->sciPendingPixmapCache) - QDeclarativePixmapCache::cancel(d->sciurl, this); } /*! \qmlproperty enumeration BorderImage::status @@ -164,15 +162,6 @@ void QDeclarativeBorderImage::setSource(const QUrl &url) d->sciReply = 0; } - if (d->pendingPixmapCache) { - QDeclarativePixmapCache::cancel(d->url, this); - d->pendingPixmapCache = false; - } - if (d->sciPendingPixmapCache) { - QDeclarativePixmapCache::cancel(d->sciurl, this); - d->sciPendingPixmapCache = false; - } - d->url = url; d->sciurl = QUrl(); emit sourceChanged(d->url); @@ -190,7 +179,7 @@ void QDeclarativeBorderImage::load() } if (d->url.isEmpty()) { - d->pix = QPixmap(); + d->pix.clear(); d->status = Null; setImplicitWidth(0); setImplicitHeight(0); @@ -224,26 +213,24 @@ void QDeclarativeBorderImage::load() thisSciRequestFinished, Qt::DirectConnection); } } else { - QSize impsize; - QString errorString; - QDeclarativePixmapReply::Status status = QDeclarativePixmapCache::get(d->url, &d->pix, &errorString, &impsize, d->async); - if (status != QDeclarativePixmapReply::Ready && status != QDeclarativePixmapReply::Error) { - QDeclarativePixmapReply *reply = QDeclarativePixmapCache::request(qmlEngine(this), d->url); - d->pendingPixmapCache = true; - connect(reply, SIGNAL(finished()), this, SLOT(requestFinished())); - connect(reply, SIGNAL(downloadProgress(qint64,qint64)), - this, SLOT(requestProgress(qint64,qint64))); + + d->pix.load(qmlEngine(this), d->url, d->async); + + if (d->pix.isLoading()) { + d->pix.connectFinished(this, SLOT(requestFinished())); + d->pix.connectDownloadProgress(this, SLOT(requestProgress(qint64,qint64))); } else { - //### should be unified with requestFinished + QSize impsize = d->pix.implicitSize(); setImplicitWidth(impsize.width()); setImplicitHeight(impsize.height()); - if (d->pix.isNull()) { + if (d->pix.isReady()) { + d->status = Ready; + } else { d->status = Error; - qmlInfo(this) << errorString; + qmlInfo(this) << d->pix.error(); } - if (d->status == Loading) - d->status = Ready; + d->progress = 1.0; emit statusChanged(d->status); emit progressChanged(d->progress); @@ -343,47 +330,40 @@ void QDeclarativeBorderImage::setGridScaledImage(const QDeclarativeGridScaledIma d->verticalTileMode = sci.verticalTileRule(); d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl())); - QSize impsize; - QString errorString; - QDeclarativePixmapReply::Status status = QDeclarativePixmapCache::get(d->sciurl, &d->pix, &errorString, &impsize, d->async); - if (status != QDeclarativePixmapReply::Ready && status != QDeclarativePixmapReply::Error) { - QDeclarativePixmapReply *reply = QDeclarativePixmapCache::request(qmlEngine(this), d->sciurl); - d->sciPendingPixmapCache = true; - - static int replyDownloadProgress = -1; - static int replyFinished = -1; + + d->pix.load(qmlEngine(this), d->sciurl, d->async); + + if (d->pix.isLoading()) { static int thisRequestProgress = -1; static int thisRequestFinished = -1; - if (replyDownloadProgress == -1) { - replyDownloadProgress = - QDeclarativePixmapReply::staticMetaObject.indexOfSignal("downloadProgress(qint64,qint64)"); - replyFinished = - QDeclarativePixmapReply::staticMetaObject.indexOfSignal("finished()"); + if (thisRequestProgress == -1) { thisRequestProgress = QDeclarativeBorderImage::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)"); thisRequestFinished = QDeclarativeBorderImage::staticMetaObject.indexOfSlot("requestFinished()"); } - QMetaObject::connect(reply, replyFinished, this, - thisRequestFinished, Qt::DirectConnection); - QMetaObject::connect(reply, replyDownloadProgress, this, - thisRequestProgress, Qt::DirectConnection); + d->pix.connectFinished(this, thisRequestFinished); + d->pix.connectDownloadProgress(this, thisRequestProgress); + } else { - //### should be unified with requestFinished + + QSize impsize = d->pix.implicitSize(); setImplicitWidth(impsize.width()); setImplicitHeight(impsize.height()); - if (d->pix.isNull()) { + if (d->pix.isReady()) { + d->status = Ready; + } else { d->status = Error; - qmlInfo(this) << errorString; + qmlInfo(this) << d->pix.error(); } - if (d->status == Loading) - d->status = Ready; + d->progress = 1.0; emit statusChanged(d->status); emit progressChanged(1.0); update(); + } } } @@ -392,27 +372,17 @@ void QDeclarativeBorderImage::requestFinished() { Q_D(QDeclarativeBorderImage); - QSize impsize; - if (d->url.path().endsWith(QLatin1String(".sci"))) { - d->sciPendingPixmapCache = false; - QString errorString; - if (QDeclarativePixmapCache::get(d->sciurl, &d->pix, &errorString, &impsize, d->async) != QDeclarativePixmapReply::Ready) { - d->status = Error; - qmlInfo(this) << errorString; - } + QSize impsize = d->pix.implicitSize(); + if (d->pix.isError()) { + d->status = Error; + qmlInfo(this) << d->pix.error(); } else { - d->pendingPixmapCache = false; - QString errorString; - if (QDeclarativePixmapCache::get(d->url, &d->pix, &errorString, &impsize, d->async) != QDeclarativePixmapReply::Ready) { - d->status = Error; - qmlInfo(this) << errorString; - } + d->status = Ready; } + setImplicitWidth(impsize.width()); setImplicitHeight(impsize.height()); - if (d->status == Loading) - d->status = Ready; d->progress = 1.0; emit statusChanged(d->status); emit progressChanged(1.0); |