diff options
-rw-r--r-- | src/corelib/codecs/qtextcodec_symbian.cpp | 6 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeengine.cpp | 15 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeengine_p.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeimageprovider.cpp | 4 | ||||
-rw-r--r-- | src/gui/image/qpixmap.cpp | 3 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_gl.cpp | 6 | ||||
-rw-r--r-- | tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp | 105 | ||||
-rw-r--r-- | tests/auto/qpixmap/tst_qpixmap.cpp | 18 |
8 files changed, 131 insertions, 28 deletions
diff --git a/src/corelib/codecs/qtextcodec_symbian.cpp b/src/corelib/codecs/qtextcodec_symbian.cpp index e4db9d7..20e0cfc 100644 --- a/src/corelib/codecs/qtextcodec_symbian.cpp +++ b/src/corelib/codecs/qtextcodec_symbian.cpp @@ -53,8 +53,10 @@ struct QSymbianCodecInitData { const char *aliases; }; -/* This table contains the known Symbian codecs aliases. It is ordered by charsetId. - It is required as symbian does not provide have aliases. +/* This table contains the known Symbian codecs aliases. + It is required because symbian does not provide aliases for codecs. + It is also faster to have a name here than asking the system. + It is ordered by charsetId to allow binary search lookup */ static const QSymbianCodecInitData codecsData[] = { { /*268439485*/ KCharacterSetIdentifierShiftJis, 17, "Shift_JIS\0MS_Kanji\0csShiftJIS\0MS_KANJI\0SJIS\0" }, diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 513fc65..bc7468f 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -674,7 +674,7 @@ void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativ { Q_D(QDeclarativeEngine); QMutexLocker locker(&d->mutex); - d->imageProviders.insert(providerId, provider); + d->imageProviders.insert(providerId, QSharedPointer<QDeclarativeImageProvider>(provider)); } /*! @@ -684,7 +684,7 @@ QDeclarativeImageProvider *QDeclarativeEngine::imageProvider(const QString &prov { Q_D(const QDeclarativeEngine); QMutexLocker locker(&d->mutex); - return d->imageProviders.value(providerId); + return d->imageProviders.value(providerId).data(); } /*! @@ -698,13 +698,14 @@ void QDeclarativeEngine::removeImageProvider(const QString &providerId) { Q_D(QDeclarativeEngine); QMutexLocker locker(&d->mutex); - delete d->imageProviders.take(providerId); + d->imageProviders.take(providerId); } QDeclarativeImageProvider::ImageType QDeclarativeEnginePrivate::getImageProviderType(const QUrl &url) { QMutexLocker locker(&mutex); - QDeclarativeImageProvider *provider = imageProviders.value(url.host()); + QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host()); + locker.unlock(); if (provider) return provider->imageType(); return static_cast<QDeclarativeImageProvider::ImageType>(-1); @@ -714,7 +715,8 @@ QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url, QSize *s { QMutexLocker locker(&mutex); QImage image; - QDeclarativeImageProvider *provider = imageProviders.value(url.host()); + QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host()); + locker.unlock(); if (provider) image = provider->requestImage(url.path().mid(1), size, req_size); return image; @@ -724,7 +726,8 @@ QPixmap QDeclarativeEnginePrivate::getPixmapFromProvider(const QUrl &url, QSize { QMutexLocker locker(&mutex); QPixmap pixmap; - QDeclarativeImageProvider *provider = imageProviders.value(url.host()); + QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host()); + locker.unlock(); if (provider) pixmap = provider->requestPixmap(url.path().mid(1), size, req_size); return pixmap; diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index 3b5dd5a..db2db35 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -232,7 +232,7 @@ public: mutable QNetworkAccessManager *networkAccessManager; mutable QDeclarativeNetworkAccessManagerFactory *networkAccessManagerFactory; - QHash<QString,QDeclarativeImageProvider*> imageProviders; + QHash<QString,QSharedPointer<QDeclarativeImageProvider> > imageProviders; QDeclarativeImageProvider::ImageType getImageProviderType(const QUrl &url); QImage getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size); QPixmap getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size); diff --git a/src/declarative/qml/qdeclarativeimageprovider.cpp b/src/declarative/qml/qdeclarativeimageprovider.cpp index ea68327..ef31be7 100644 --- a/src/declarative/qml/qdeclarativeimageprovider.cpp +++ b/src/declarative/qml/qdeclarativeimageprovider.cpp @@ -161,7 +161,9 @@ QDeclarativeImageProvider::QDeclarativeImageProvider(ImageType type) } /*! - \internal + Destroys the QDeclarativeImageProvider + + \note The destructor of your derived class need to be thread safe. */ QDeclarativeImageProvider::~QDeclarativeImageProvider() { diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index ef9be8f..1c0ceff 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -830,9 +830,6 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers return false; QFileInfo info(fileName); - if (!info.exists()) - return false; - QString key = QLatin1Literal("qt_pixmap") % info.absoluteFilePath() % HexString<uint>(info.lastModified().toTime_t()) diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index 653e805..1efd398 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -367,7 +367,7 @@ void QGLPixmapData::ensureCreated() const } void QGLPixmapData::fromImage(const QImage &image, - Qt::ImageConversionFlags /*flags*/) + Qt::ImageConversionFlags flags) { if (image.size() == QSize(w, h)) setSerialNumber(++qt_gl_pixmap_serial); @@ -381,7 +381,9 @@ void QGLPixmapData::fromImage(const QImage &image, if (qApp->desktop()->depth() == 16) format = QImage::Format_RGB16; - if (image.hasAlphaChannel() && const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()) + if (image.hasAlphaChannel() + && ((flags & Qt::NoOpaqueDetection) + || const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels())) format = QImage::Format_ARGB32_Premultiplied;; m_source = image.convertToFormat(format); diff --git a/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp b/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp index e0b46f0..4a9224e 100644 --- a/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp +++ b/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp @@ -44,6 +44,7 @@ #include <QtDeclarative/qdeclarativeimageprovider.h> #include <private/qdeclarativeimage_p.h> #include <QImageReader> +#include <QWaitCondition> #ifdef Q_OS_SYMBIAN // In Symbian OS test data is located in applications private dir @@ -85,6 +86,8 @@ private slots: void removeProvider_data(); void removeProvider(); + void threadTest(); + private: QString newImageFileName() const; void fillRequestTestsData(const QString &id); @@ -95,9 +98,15 @@ private: class TestQImageProvider : public QDeclarativeImageProvider { public: - TestQImageProvider() - : QDeclarativeImageProvider(Image) + TestQImageProvider(bool *deleteWatch = 0) + : QDeclarativeImageProvider(Image), deleteWatch(deleteWatch) + { + } + + ~TestQImageProvider() { + if (deleteWatch) + *deleteWatch = true; } QImage requestImage(const QString &id, QSize *size, const QSize& requestedSize) @@ -114,6 +123,8 @@ public: image = image.scaled(requestedSize); return image; } + + bool *deleteWatch; }; Q_DECLARE_METATYPE(TestQImageProvider*); @@ -121,11 +132,17 @@ Q_DECLARE_METATYPE(TestQImageProvider*); class TestQPixmapProvider : public QDeclarativeImageProvider { public: - TestQPixmapProvider() - : QDeclarativeImageProvider(Pixmap) + TestQPixmapProvider(bool *deleteWatch = 0) + : QDeclarativeImageProvider(Pixmap), deleteWatch(deleteWatch) { } + ~TestQPixmapProvider() + { + if (deleteWatch) + *deleteWatch = true; + } + QPixmap requestPixmap(const QString &id, QSize *size, const QSize& requestedSize) { if (id == QLatin1String("no-such-file.png")) @@ -140,6 +157,8 @@ public: image = image.scaled(requestedSize); return image; } + + bool *deleteWatch; }; Q_DECLARE_METATYPE(TestQPixmapProvider*); @@ -225,7 +244,9 @@ void tst_qdeclarativeimageprovider::requestImage_sync_data() void tst_qdeclarativeimageprovider::requestImage_sync() { - runTest(false, new TestQImageProvider); + bool deleteWatch = false; + runTest(false, new TestQImageProvider(&deleteWatch)); + QVERIFY(deleteWatch); } void tst_qdeclarativeimageprovider::requestImage_async_data() @@ -235,7 +256,9 @@ void tst_qdeclarativeimageprovider::requestImage_async_data() void tst_qdeclarativeimageprovider::requestImage_async() { - runTest(true, new TestQImageProvider); + bool deleteWatch = false; + runTest(true, new TestQImageProvider(&deleteWatch)); + QVERIFY(deleteWatch); } void tst_qdeclarativeimageprovider::requestPixmap_sync_data() @@ -245,13 +268,15 @@ void tst_qdeclarativeimageprovider::requestPixmap_sync_data() void tst_qdeclarativeimageprovider::requestPixmap_sync() { - runTest(false, new TestQPixmapProvider); + bool deleteWatch = false; + runTest(false, new TestQPixmapProvider(&deleteWatch)); + QVERIFY(deleteWatch); } void tst_qdeclarativeimageprovider::requestPixmap_async() { QDeclarativeEngine engine; - QDeclarativeImageProvider *provider = new TestQPixmapProvider; + QDeclarativeImageProvider *provider = new TestQPixmapProvider(); engine.addImageProvider("test", provider); QVERIFY(engine.imageProvider("test") != 0); @@ -305,6 +330,70 @@ void tst_qdeclarativeimageprovider::removeProvider() delete obj; } +class TestThreadProvider : public QDeclarativeImageProvider +{ + public: + TestThreadProvider() : QDeclarativeImageProvider(Image), ok(false) {} + + ~TestThreadProvider() {} + + QImage requestImage(const QString &id, QSize *size, const QSize& requestedSize) + { + mutex.lock(); + if (!ok) + cond.wait(&mutex); + mutex.unlock(); + QVector<int> v; + for (int i = 0; i < 10000; i++) + v.prepend(i); //do some computation + QImage image(50,50, QImage::Format_RGB32); + image.fill(QColor(id).rgb()); + if (size) + *size = image.size(); + if (requestedSize.isValid()) + image = image.scaled(requestedSize); + return image; + } + + QWaitCondition cond; + QMutex mutex; + bool ok; +}; + + +void tst_qdeclarativeimageprovider::threadTest() +{ + QDeclarativeEngine engine; + + TestThreadProvider *provider = new TestThreadProvider; + + engine.addImageProvider("test_thread", provider); + QVERIFY(engine.imageProvider("test_thread") != 0); + + QString componentStr = "import Qt 4.7\nItem { \n" + "Image { source: \"image://test_thread/blue\"; asynchronous: true; }\n" + "Image { source: \"image://test_thread/red\"; asynchronous: true; }\n" + "Image { source: \"image://test_thread/green\"; asynchronous: true; }\n" + "Image { source: \"image://test_thread/yellow\"; asynchronous: true; }\n" + " }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QObject *obj = component.create(); + //MUST not deadlock + QVERIFY(obj != 0); + QList<QDeclarativeImage *> images = obj->findChildren<QDeclarativeImage *>(); + QCOMPARE(images.count(), 4); + QTest::qWait(100); + foreach(QDeclarativeImage *img, images) { + QCOMPARE(img->status(), QDeclarativeImage::Loading); + } + provider->ok = true; + provider->cond.wakeAll(); + foreach(QDeclarativeImage *img, images) { + TRY_WAIT(img->status() == QDeclarativeImage::Ready); + } +} + QTEST_MAIN(tst_qdeclarativeimageprovider) diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index f22edf6..e461b64 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -1673,31 +1673,39 @@ void tst_QPixmap::preserveDepth() void tst_QPixmap::loadAsBitmapOrPixmap() { QImage tmp(10, 10, QImage::Format_RGB32); - tmp.save("tmp.png"); + tmp.save("temp_image.png"); bool ok; // Check that we can load the pixmap as a pixmap and that it then turns into a pixmap - QPixmap pixmap("tmp.png"); + QPixmap pixmap("temp_image.png"); QVERIFY(!pixmap.isNull()); QVERIFY(pixmap.depth() > 1); QVERIFY(!pixmap.isQBitmap()); pixmap = QPixmap(); - ok = pixmap.load("tmp.png"); + ok = pixmap.load("temp_image.png"); + QVERIFY(ok); + QVERIFY(!pixmap.isNull()); + QVERIFY(pixmap.depth() > 1); + QVERIFY(!pixmap.isQBitmap()); + + //now we can try to load it without an extension + pixmap = QPixmap(); + ok = pixmap.load("temp_image"); QVERIFY(ok); QVERIFY(!pixmap.isNull()); QVERIFY(pixmap.depth() > 1); QVERIFY(!pixmap.isQBitmap()); // The do the same check for bitmaps.. - QBitmap bitmap("tmp.png"); + QBitmap bitmap("temp_image.png"); QVERIFY(!bitmap.isNull()); QVERIFY(bitmap.depth() == 1); QVERIFY(bitmap.isQBitmap()); bitmap = QBitmap(); - ok = bitmap.load("tmp.png"); + ok = bitmap.load("temp_image.png"); QVERIFY(ok); QVERIFY(!bitmap.isNull()); QVERIFY(bitmap.depth() == 1); |