aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/util/qdeclarativepixmapcache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/util/qdeclarativepixmapcache.cpp')
-rw-r--r--src/declarative/util/qdeclarativepixmapcache.cpp197
1 files changed, 167 insertions, 30 deletions
diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp
index a29854fa84..dcce7db813 100644
--- a/src/declarative/util/qdeclarativepixmapcache.cpp
+++ b/src/declarative/util/qdeclarativepixmapcache.cpp
@@ -47,6 +47,10 @@
#include <private/qdeclarativeglobal_p.h>
#include <private/qdeclarativeengine_p.h>
+#include <qsgtexture.h>
+#include <private/qsgtexture_p.h>
+#include <private/qsgcontext_p.h>
+
#include <QCoreApplication>
#include <QImageReader>
#include <QHash>
@@ -75,7 +79,7 @@ QT_BEGIN_NAMESPACE
#if defined(Q_WS_QWS) || defined(Q_WS_WINCE)
static int cache_limit = 2048 * 1024; // 2048 KB cache limit for embedded
#else
-static int cache_limit = 10240 * 1024; // 10 MB cache limit for desktop
+static int cache_limit = 128 * 1024; // 10 MB cache limit for desktop
#endif
class QDeclarativePixmapReader;
@@ -98,14 +102,18 @@ public:
class Event : public QEvent {
public:
- Event(ReadError, const QString &, const QSize &, const QImage &);
+ Event(ReadError, const QString &, const QSize &, const QImage &image);
+ Event(ReadError, const QString &, const QSize &, QSGTexture *t, QSGContext *context);
ReadError error;
QString errorString;
QSize implicitSize;
QImage image;
+ QSGTexture *texture;
+ QSGContext *context;
};
void postReply(ReadError, const QString &, const QSize &, const QImage &);
+ void postReply(ReadError, const QString &, const QSize &, QSGTexture *t, QSGContext *context);
Q_SIGNALS:
@@ -184,32 +192,46 @@ class QDeclarativePixmapData
public:
QDeclarativePixmapData(const QUrl &u, const QSize &s, const QString &e)
: refCount(1), inCache(false), pixmapStatus(QDeclarativePixmap::Error),
- url(u), errorString(e), requestSize(s), reply(0), prevUnreferenced(0),
+ url(u), errorString(e), requestSize(s), texture(0), context(0), reply(0), prevUnreferenced(0),
prevUnreferencedPtr(0), nextUnreferenced(0)
{
}
QDeclarativePixmapData(const QUrl &u, const QSize &r)
: refCount(1), inCache(false), pixmapStatus(QDeclarativePixmap::Loading),
- url(u), requestSize(r), reply(0), prevUnreferenced(0), prevUnreferencedPtr(0),
+ url(u), requestSize(r), texture(0), context(0), reply(0), prevUnreferenced(0), prevUnreferencedPtr(0),
nextUnreferenced(0)
{
}
QDeclarativePixmapData(const QUrl &u, const QPixmap &p, const QSize &s, const QSize &r)
- : refCount(1), inCache(false), privatePixmap(false), pixmapStatus(QDeclarativePixmap::Ready),
- url(u), pixmap(p), implicitSize(s), requestSize(r), reply(0), prevUnreferenced(0),
+ : refCount(1), inCache(false), privatePixmap(false), pixmapStatus(QDeclarativePixmap::Ready),
+ url(u), pixmap(p), implicitSize(s), requestSize(r), texture(0), context(0), reply(0), prevUnreferenced(0),
+ prevUnreferencedPtr(0), nextUnreferenced(0)
+ {
+ }
+
+ QDeclarativePixmapData(const QUrl &u, QSGTexture *t, QSGContext *c, const QSize &s, const QSize &r)
+ : refCount(1), inCache(false), privatePixmap(false), pixmapStatus(QDeclarativePixmap::Ready),
+ url(u), implicitSize(s), requestSize(r), texture(t), context(c), reply(0), prevUnreferenced(0),
prevUnreferencedPtr(0), nextUnreferenced(0)
{
}
QDeclarativePixmapData(const QPixmap &p)
: refCount(1), inCache(false), privatePixmap(true), pixmapStatus(QDeclarativePixmap::Ready),
- pixmap(p), implicitSize(p.size()), requestSize(p.size()), reply(0), prevUnreferenced(0),
+ pixmap(p), implicitSize(p.size()), requestSize(p.size()), texture(0), context(0), reply(0), prevUnreferenced(0),
prevUnreferencedPtr(0), nextUnreferenced(0)
{
}
+ ~QDeclarativePixmapData()
+ {
+ if (texture && context) {
+ context->schdelueTextureForCleanup(texture);
+ }
+ }
+
int cost() const;
void addref();
void release();
@@ -228,6 +250,9 @@ public:
QSize implicitSize;
QSize requestSize;
+ QSGTexture *texture;
+ QSGContext *context;
+
QDeclarativePixmapReply *reply;
QDeclarativePixmapData *prevUnreferenced;
@@ -248,15 +273,28 @@ int QDeclarativePixmapReader::downloadProgress = -1;
int QDeclarativePixmapReader::threadNetworkRequestDone = -1;
-void QDeclarativePixmapReply::postReply(ReadError error, const QString &errorString,
+void QDeclarativePixmapReply::postReply(ReadError error, const QString &errorString,
const QSize &implicitSize, const QImage &image)
{
loading = false;
QCoreApplication::postEvent(this, new Event(error, errorString, implicitSize, image));
}
+void QDeclarativePixmapReply::postReply(ReadError error, const QString &errorString,
+ const QSize &implicitSize, QSGTexture *texture,
+ QSGContext *context)
+{
+ loading = false;
+ QCoreApplication::postEvent(this, new Event(error, errorString, implicitSize, texture, context));
+}
+
QDeclarativePixmapReply::Event::Event(ReadError e, const QString &s, const QSize &iSize, const QImage &i)
-: QEvent(QEvent::User), error(e), errorString(s), implicitSize(iSize), image(i)
+ : QEvent(QEvent::User), error(e), errorString(s), implicitSize(iSize), image(i)
+{
+}
+
+QDeclarativePixmapReply::Event::Event(ReadError e, const QString &s, const QSize &iSize, QSGTexture *t, QSGContext *c)
+ : QEvent(QEvent::User), error(e), errorString(s), implicitSize(iSize), texture(t), context(c)
{
}
@@ -355,6 +393,8 @@ void QDeclarativePixmapReader::networkRequestDone(QNetworkReply *reply)
}
QImage image;
+ QSGTexture *texture = 0;
+ QSGContext *ctx = QDeclarativeEnginePrivate::get(engine)->sgContext;
QDeclarativePixmapReply::ReadError error = QDeclarativePixmapReply::NoError;
QString errorString;
QSize readSize;
@@ -365,13 +405,26 @@ void QDeclarativePixmapReader::networkRequestDone(QNetworkReply *reply)
QByteArray all = reply->readAll();
QBuffer buff(&all);
buff.open(QIODevice::ReadOnly);
- if (!readImage(reply->url(), &buff, &image, &errorString, &readSize, job->requestSize)) {
- error = QDeclarativePixmapReply::Decoding;
+ if (ctx && ctx->canDecodeImageToTexture())
+ texture = ctx->decodeImageToTexture(&buff, &readSize, job->requestSize);
+ if (!texture) {
+ if (!readImage(reply->url(), &buff, &image, &errorString, &readSize, job->requestSize)) {
+ error = QDeclarativePixmapReply::Decoding;
+ } else if (ctx) {
+ texture = ctx->createTexture(image);
+ }
}
}
// send completion event to the QDeclarativePixmapReply
mutex.lock();
- if (!cancelled.contains(job)) job->postReply(error, errorString, readSize, image);
+ if (!cancelled.contains(job)) {
+ if (texture)
+ job->postReply(error, errorString, readSize, texture, ctx);
+ else
+ job->postReply(error, errorString, readSize, image);
+ } else {
+ delete texture;
+ }
mutex.unlock();
}
reply->deleteLater();
@@ -446,23 +499,46 @@ void QDeclarativePixmapReader::processJobs()
void QDeclarativePixmapReader::processJob(QDeclarativePixmapReply *runningJob, const QUrl &url,
const QSize &requestSize)
{
+ QSGContext *sgContext = QDeclarativeEnginePrivate::get(engine)->sgContext;
+
// fetch
if (url.scheme() == QLatin1String("image")) {
// Use QmlImageProvider
QSize readSize;
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
- QImage image = ep->getImageFromProvider(url, &readSize, requestSize);
+ QDeclarativeImageProvider::ImageType imageType = ep->getImageProviderType(url);
+
+ if (imageType == QDeclarativeImageProvider::Image) {
+ QImage image = ep->getImageFromProvider(url, &readSize, requestSize);
+ QDeclarativePixmapReply::ReadError errorCode = QDeclarativePixmapReply::NoError;
+ QString errorStr;
+ if (image.isNull()) {
+ errorCode = QDeclarativePixmapReply::Loading;
+ errorStr = QDeclarativePixmap::tr("Failed to get image from provider: %1").arg(url.toString());
+ }
+ mutex.lock();
+ if (!cancelled.contains(runningJob)) {
+ if (sgContext)
+ runningJob->postReply(errorCode, errorStr, readSize, sgContext->createTexture(image), sgContext);
+ else
+ runningJob->postReply(errorCode, errorStr, readSize, image);
+ }
+ mutex.unlock();
+ } else {
+ QSGTexture *t = ep->getTextureFromProvider(url, &readSize, requestSize);
+ QDeclarativePixmapReply::ReadError errorCode = QDeclarativePixmapReply::NoError;
+ QString errorStr;
+ if (!t) {
+ errorCode = QDeclarativePixmapReply::Loading;
+ errorStr = QDeclarativePixmap::tr("Failed to get texture from provider: %1").arg(url.toString());
+ }
+ mutex.lock();
+ if (!cancelled.contains(runningJob))
+ runningJob->postReply(errorCode, errorStr, readSize, t, sgContext);
+ mutex.unlock();
- QDeclarativePixmapReply::ReadError errorCode = QDeclarativePixmapReply::NoError;
- QString errorStr;
- if (image.isNull()) {
- errorCode = QDeclarativePixmapReply::Loading;
- errorStr = QDeclarativePixmap::tr("Failed to get image from provider: %1").arg(url.toString());
}
- mutex.lock();
- if (!cancelled.contains(runningJob)) runningJob->postReply(errorCode, errorStr, readSize, image);
- mutex.unlock();
} else {
QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url);
if (!lf.isEmpty()) {
@@ -472,15 +548,30 @@ void QDeclarativePixmapReader::processJob(QDeclarativePixmapReply *runningJob, c
QString errorStr;
QFile f(lf);
QSize readSize;
+ QSGTexture *texture = 0;
if (f.open(QIODevice::ReadOnly)) {
- if (!readImage(url, &f, &image, &errorStr, &readSize, requestSize))
- errorCode = QDeclarativePixmapReply::Loading;
+ if (sgContext && sgContext ->canDecodeImageToTexture())
+ texture = sgContext->decodeImageToTexture(&f, &readSize, requestSize);
+ if (!texture) {
+ if (!readImage(url, &f, &image, &errorStr, &readSize, requestSize)) {
+ errorCode = QDeclarativePixmapReply::Loading;
+ } else if (sgContext) {
+ texture = sgContext->createTexture(image);
+ }
+ }
} else {
errorStr = QDeclarativePixmap::tr("Cannot open: %1").arg(url.toString());
errorCode = QDeclarativePixmapReply::Loading;
}
mutex.lock();
- if (!cancelled.contains(runningJob)) runningJob->postReply(errorCode, errorStr, readSize, image);
+ if (!cancelled.contains(runningJob)) {
+ if (texture)
+ runningJob->postReply(errorCode, errorStr, readSize, texture, sgContext);
+ else
+ runningJob->postReply(errorCode, errorStr, readSize, image);
+ } else {
+ delete texture;
+ }
mutex.unlock();
} else {
// Network resource
@@ -704,7 +795,11 @@ bool QDeclarativePixmapReply::event(QEvent *event)
data->pixmapStatus = (de->error == NoError) ? QDeclarativePixmap::Ready : QDeclarativePixmap::Error;
if (data->pixmapStatus == QDeclarativePixmap::Ready) {
- data->pixmap = QPixmap::fromImage(de->image);
+ if (de->texture) {
+ data->texture = de->texture;
+ data->context = de->context;
+ } else
+ data->pixmap = QPixmap::fromImage(de->image);
data->implicitSize = de->implicitSize;
} else {
data->errorString = de->errorString;
@@ -774,17 +869,32 @@ void QDeclarativePixmapData::removeFromCache()
static QDeclarativePixmapData* createPixmapDataSync(QDeclarativeEngine *engine, const QUrl &url, const QSize &requestSize, bool *ok)
{
+ QSGContext *sgContext = QDeclarativeEnginePrivate::get(engine)->sgContext;
+
if (url.scheme() == QLatin1String("image")) {
QSize readSize;
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
QDeclarativeImageProvider::ImageType imageType = ep->getImageProviderType(url);
switch (imageType) {
+ case QDeclarativeImageProvider::Texture:
+ {
+ QSGTexture *texture = ep->getTextureFromProvider(url, &readSize, requestSize);
+ if (texture) {
+ *ok = true;
+ return new QDeclarativePixmapData(url, texture, sgContext, readSize, requestSize);
+ }
+ }
+
case QDeclarativeImageProvider::Image:
{
QImage image = ep->getImageFromProvider(url, &readSize, requestSize);
if (!image.isNull()) {
*ok = true;
+ if (sgContext) {
+ QSGTexture *t = sgContext->createTexture(image);
+ return new QDeclarativePixmapData(url, t, sgContext,readSize, requestSize);
+ }
return new QDeclarativePixmapData(url, QPixmap::fromImage(image), readSize, requestSize);
}
}
@@ -793,6 +903,10 @@ static QDeclarativePixmapData* createPixmapDataSync(QDeclarativeEngine *engine,
QPixmap pixmap = ep->getPixmapFromProvider(url, &readSize, requestSize);
if (!pixmap.isNull()) {
*ok = true;
+ if (sgContext) {
+ QSGTexture *t = sgContext->createTexture(pixmap.toImage());
+ return new QDeclarativePixmapData(url, t, sgContext,readSize, requestSize);
+ }
return new QDeclarativePixmapData(url, pixmap, readSize, requestSize);
}
}
@@ -812,11 +926,29 @@ static QDeclarativePixmapData* createPixmapDataSync(QDeclarativeEngine *engine,
QString errorString;
if (f.open(QIODevice::ReadOnly)) {
+ QSGContext *ctx = QDeclarativeEnginePrivate::get(engine)->sgContext;
+ QSGTexture *texture = 0;
QImage image;
- if (readImage(url, &f, &image, &errorString, &readSize, requestSize)) {
+
+ if (ctx && ctx->canDecodeImageToTexture()) {
+ texture = ctx->decodeImageToTexture(&f, &readSize, requestSize);
*ok = true;
- return new QDeclarativePixmapData(url, QPixmap::fromImage(image), readSize, requestSize);
}
+
+ if (!texture) {
+ if (readImage(url, &f, &image, &errorString, &readSize, requestSize))
+ *ok = true;
+
+ if (ok && ctx) {
+ texture = ctx->createTexture(image);
+ }
+ }
+
+ if (texture)
+ return new QDeclarativePixmapData(url, texture, ctx, readSize, requestSize);
+ else
+ return new QDeclarativePixmapData(url, QPixmap::fromImage(image), readSize, requestSize);
+
} else {
errorString = QDeclarativePixmap::tr("Cannot open: %1").arg(url.toString());
}
@@ -916,6 +1048,11 @@ const QSize &QDeclarativePixmap::requestSize() const
return nullPixmap()->size;
}
+QSGTexture *QDeclarativePixmap::texture() const
+{
+ return d ? d->texture : 0;
+}
+
const QPixmap &QDeclarativePixmap::pixmap() const
{
if (d)
@@ -935,7 +1072,7 @@ void QDeclarativePixmap::setPixmap(const QPixmap &p)
int QDeclarativePixmap::width() const
{
if (d)
- return d->pixmap.width();
+ return d->texture ? d->texture->textureSize().width() : d->pixmap.width();
else
return 0;
}
@@ -943,7 +1080,7 @@ int QDeclarativePixmap::width() const
int QDeclarativePixmap::height() const
{
if (d)
- return d->pixmap.height();
+ return d->texture? d->texture->textureSize().height() : d->pixmap.height();
else
return 0;
}
@@ -951,7 +1088,7 @@ int QDeclarativePixmap::height() const
QRect QDeclarativePixmap::rect() const
{
if (d)
- return d->pixmap.rect();
+ return d->texture ? QRect(QPoint(), d->texture->textureSize()) : d->pixmap.rect();
else
return QRect();
}