Merge lp:~aacid/ubuntu-ui-toolkit/save_stat_loading_already_loaded_image into lp:ubuntu-ui-toolkit/staging

Proposed by Albert Astals Cid
Status: Merged
Approved by: Cris Dywan
Approved revision: 2177
Merged at revision: 2169
Proposed branch: lp:~aacid/ubuntu-ui-toolkit/save_stat_loading_already_loaded_image
Merge into: lp:ubuntu-ui-toolkit/staging
Diff against target: 268 lines (+120/-20)
9 files modified
src/UbuntuToolkit/ucqquickimageextension.cpp (+53/-2)
src/UbuntuToolkit/ucqquickimageextension_p.h (+1/-0)
tests/unit/qquick_image_extension/borderInName.sci (+0/-7)
tests/unit/qquick_image_extension/data/borderInName.sci (+7/-0)
tests/unit/qquick_image_extension/data/hundred_faces.qml (+13/-0)
tests/unit/qquick_image_extension/data/test@18.sci (+7/-0)
tests/unit/qquick_image_extension/qquick_image_extension.pro (+1/-1)
tests/unit/qquick_image_extension/test@18.sci (+0/-7)
tests/unit/qquick_image_extension/tst_qquick_image_extension.cpp (+38/-3)
To merge this branch: bzr merge lp:~aacid/ubuntu-ui-toolkit/save_stat_loading_already_loaded_image
Reviewer Review Type Date Requested Status
ubuntu-sdk-build-bot continuous-integration Approve
Cris Dywan Approve
Zsombor Egri Needs Fixing
Review via email: mp+316235@code.launchpad.net

Commit message

Save a stat if the image we're loading is already in the cache

No need to call UCUnits::resolveResource to learn we just need to load it normally because the fact that we already loaded it normally means we need to load it normally.

Description of the change

Adding some description, i think CI may be failing because i don't have one.

To post a comment you must log in.
Revision history for this message
Cris Dywan (kalikiana) wrote :

That looks quite nice. Any chance we can unit test it? At least to see that no scaling is applied when unneeded.

review: Needs Information
Revision history for this message
Zsombor Egri (zsombi) wrote :

I have one small request to it, otherwise good.

review: Needs Fixing
2170. By Albert Astals Cid

Use a registered type

2171. By Albert Astals Cid

comment++

2172. By Albert Astals Cid

Add a test that proves this is working

Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
2173. By Albert Astals Cid

Need core private here

Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
2174. By Albert Astals Cid

Fix gles build

Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
2175. By Albert Astals Cid

"Better" way of waiting for the image to have the source size set

Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
2176. By Albert Astals Cid

workaround qqmlengine_p.h using foreach

Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Needs Fixing (continuous-integration)
2177. By Albert Astals Cid

Unfortunately can't cache the ixd, causes crashes in some tests

Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Cris Dywan (kalikiana) wrote :

Finally seems to be passing CI. And thanks for adding the test case (especially since the implementation is not straight-forward now)!

review: Approve
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/UbuntuToolkit/ucqquickimageextension.cpp'
--- src/UbuntuToolkit/ucqquickimageextension.cpp 2016-09-12 09:03:50 +0000
+++ src/UbuntuToolkit/ucqquickimageextension.cpp 2017-02-06 13:21:12 +0000
@@ -22,7 +22,13 @@
22#include <QtCore/QFile>22#include <QtCore/QFile>
23#include <QtCore/QFileInfo>23#include <QtCore/QFileInfo>
24#include <QtGui/QGuiApplication>24#include <QtGui/QGuiApplication>
25#include <QtQuick/private/qquickitem_p.h>
25#include <QtQuick/private/qquickimagebase_p.h>26#include <QtQuick/private/qquickimagebase_p.h>
27#include <QtQuick/private/qquickpixmapcache_p.h>
28
29#define foreach Q_FOREACH
30#include <QtQml/private/qqmlengine_p.h>
31#undef foreach
2632
27#include "ucunits_p.h"33#include "ucunits_p.h"
2834
@@ -61,11 +67,35 @@
61 return m_source;67 return m_source;
62}68}
6369
70
64void UCQQuickImageExtension::setSource(const QUrl& url)71void UCQQuickImageExtension::setSource(const QUrl& url)
65{72{
66 if (url != m_source) {73 if (url != m_source) {
67 m_source = url;74 m_source = url;
68 reloadSource();75 // We need to wait until the component is complete
76 // so that m_image->sourceSize() is actually valid
77 if (QQuickItemPrivate::get(m_image)->componentComplete) {
78 reloadSource();
79 } else {
80 // This is a bit convoluted but i couldn't find a better way to get notified of when
81 // the image actually finishes constructing.
82 // Since what we're interested in reloadSource() is the image having the sourceSize set,
83 // what we do is connect to the sourceSizeChanged signal.
84 // The problem is that this signal isn't fired if the Image {} doesn't have sourceSize set
85 // so we tell the engine to fire the sourceSizeChanged signal when the image finishes constructing
86 // This way if the Image {} has a sourceSize set the lambda gets called because of it
87 // and if there's no sourceSize set the lambda gets called because we registered the finalize callback
88
89 connect(m_image, &QQuickImageBase::sourceSizeChanged,
90 this,
91 [&] {
92 QObject::disconnect(m_image, &QQuickImageBase::sourceSizeChanged, this, nullptr);
93 reloadSource();
94 });
95
96 QQmlEnginePrivate *engPriv = QQmlEnginePrivate::get(qmlEngine(m_image));
97 engPriv->registerFinalizeCallback(m_image, m_image->metaObject()->indexOfSignal("sourceSizeChanged()"));
98 }
69 }99 }
70}100}
71101
@@ -80,6 +110,25 @@
80 return;110 return;
81 }111 }
82112
113 // If the url we're trying to load is already in the cache and
114 // the devicePixelRatio is 1, we save calling UCUnits::resolveResource
115 // and just set that image directly.
116 // UCUnits::resolveResource is not cheap (does a stat on disk)
117 if (qFuzzyCompare(qGuiApp->devicePixelRatio(), (qreal)1.0)) {
118 QSize ss = m_image->sourceSize();
119 if (ss.isNull() && m_image->image().isNull()) {
120 // For some reason QQuickImage returns 0x0 as sourceSize
121 // when the sourceSize is not set (and the image has not yet been loaded)
122 // so set it back to -1x-1
123 ss = QSize(-1, -1);
124 }
125
126 if (QQuickPixmap::isCached(m_source, ss)) {
127 m_image->setSource(m_source);
128 return;
129 }
130 }
131
83 QString resolved = UCUnits::instance()->resolveResource(m_source);132 QString resolved = UCUnits::instance()->resolveResource(m_source);
84133
85 if (resolved.isEmpty()) {134 if (resolved.isEmpty()) {
@@ -98,7 +147,9 @@
98 || selectedFilePath.endsWith(QStringLiteral(".svgz"))) {147 || selectedFilePath.endsWith(QStringLiteral(".svgz"))) {
99 // Take care to pass the original fragment148 // Take care to pass the original fragment
100 QUrl selectedFileUrl(QUrl::fromLocalFile(selectedFilePath));149 QUrl selectedFileUrl(QUrl::fromLocalFile(selectedFilePath));
101 selectedFileUrl.setFragment(fragment);150 if (m_source.hasFragment()) {
151 selectedFileUrl.setFragment(fragment);
152 }
102 m_image->setSource(selectedFileUrl);153 m_image->setSource(selectedFileUrl);
103 } else {154 } else {
104 // Need to scale the pixel-based image to suit the devicePixelRatio setting ourselves.155 // Need to scale the pixel-based image to suit the devicePixelRatio setting ourselves.
105156
=== modified file 'src/UbuntuToolkit/ucqquickimageextension_p.h'
--- src/UbuntuToolkit/ucqquickimageextension_p.h 2016-09-09 17:49:07 +0000
+++ src/UbuntuToolkit/ucqquickimageextension_p.h 2017-02-06 13:21:12 +0000
@@ -19,6 +19,7 @@
19#ifndef UCQQUICKIMAGEEXTENSION_P_H19#ifndef UCQQUICKIMAGEEXTENSION_P_H
20#define UCQQUICKIMAGEEXTENSION_P_H20#define UCQQUICKIMAGEEXTENSION_P_H
2121
22#include <QtCore/QEvent>
22#include <QtCore/QByteArray>23#include <QtCore/QByteArray>
23#include <QtCore/QObject>24#include <QtCore/QObject>
24#include <QtCore/QSharedPointer>25#include <QtCore/QSharedPointer>
2526
=== removed file 'tests/unit/qquick_image_extension/borderInName.sci'
--- tests/unit/qquick_image_extension/borderInName.sci 2013-05-06 16:33:54 +0000
+++ tests/unit/qquick_image_extension/borderInName.sci 1970-01-01 00:00:00 +0000
@@ -1,7 +0,0 @@
1source: "borderInName.png"
2border.left: 9
3border.right: 2
4border.top: 9
5border.bottom: 0
6horizontalTileMode: Stretch
7verticalTileMode: Stretch
80
=== added directory 'tests/unit/qquick_image_extension/data'
=== added file 'tests/unit/qquick_image_extension/data/borderInName.sci'
--- tests/unit/qquick_image_extension/data/borderInName.sci 1970-01-01 00:00:00 +0000
+++ tests/unit/qquick_image_extension/data/borderInName.sci 2017-02-06 13:21:12 +0000
@@ -0,0 +1,7 @@
1source: "borderInName.png"
2border.left: 9
3border.right: 2
4border.top: 9
5border.bottom: 0
6horizontalTileMode: Stretch
7verticalTileMode: Stretch
08
=== added file 'tests/unit/qquick_image_extension/data/face.png'
1Binary files tests/unit/qquick_image_extension/data/face.png 1970-01-01 00:00:00 +0000 and tests/unit/qquick_image_extension/data/face.png 2017-02-06 13:21:12 +0000 differ9Binary files tests/unit/qquick_image_extension/data/face.png 1970-01-01 00:00:00 +0000 and tests/unit/qquick_image_extension/data/face.png 2017-02-06 13:21:12 +0000 differ
=== added file 'tests/unit/qquick_image_extension/data/hundred_faces.qml'
--- tests/unit/qquick_image_extension/data/hundred_faces.qml 1970-01-01 00:00:00 +0000
+++ tests/unit/qquick_image_extension/data/hundred_faces.qml 2017-02-06 13:21:12 +0000
@@ -0,0 +1,13 @@
1
2import QtQuick 2.4
3import Ubuntu.Components 1.3
4
5Repeater {
6 width: 400
7 height: 600
8
9 model: 100
10 delegate: Image {
11 source: "face.png"
12 }
13}
014
=== added file 'tests/unit/qquick_image_extension/data/test@18.sci'
--- tests/unit/qquick_image_extension/data/test@18.sci 1970-01-01 00:00:00 +0000
+++ tests/unit/qquick_image_extension/data/test@18.sci 2017-02-06 13:21:12 +0000
@@ -0,0 +1,7 @@
1source: "test@18.png"
2border.left: 9
3border.right: 2
4border.top: 9
5border.bottom: 0
6horizontalTileMode: Stretch
7verticalTileMode: Stretch
08
=== modified file 'tests/unit/qquick_image_extension/qquick_image_extension.pro'
--- tests/unit/qquick_image_extension/qquick_image_extension.pro 2016-05-31 09:02:35 +0000
+++ tests/unit/qquick_image_extension/qquick_image_extension.pro 2017-02-06 13:21:12 +0000
@@ -1,3 +1,3 @@
1include(../test-include.pri)1include(../test-include.pri)
2SOURCES += tst_qquick_image_extension.cpp2SOURCES += tst_qquick_image_extension.cpp
3QT += quick-private3QT += core-private quick-private
44
=== removed file 'tests/unit/qquick_image_extension/test@18.sci'
--- tests/unit/qquick_image_extension/test@18.sci 2013-05-06 16:33:54 +0000
+++ tests/unit/qquick_image_extension/test@18.sci 1970-01-01 00:00:00 +0000
@@ -1,7 +0,0 @@
1source: "test@18.png"
2border.left: 9
3border.right: 2
4border.top: 9
5border.bottom: 0
6horizontalTileMode: Stretch
7verticalTileMode: Stretch
80
=== modified file 'tests/unit/qquick_image_extension/tst_qquick_image_extension.cpp'
--- tests/unit/qquick_image_extension/tst_qquick_image_extension.cpp 2016-09-09 17:49:07 +0000
+++ tests/unit/qquick_image_extension/tst_qquick_image_extension.cpp 2017-02-06 13:21:12 +0000
@@ -23,6 +23,8 @@
23#define protected public23#define protected public
24#include <UbuntuToolkit/private/ucqquickimageextension_p.h>24#include <UbuntuToolkit/private/ucqquickimageextension_p.h>
25#undef protected25#undef protected
26#include <QtCore/private/qabstractfileengine_p.h>
27#include <QQuickView>
2628
27UT_USE_NAMESPACE29UT_USE_NAMESPACE
2830
@@ -32,6 +34,20 @@
32 return QDir::temp().entryList(nameFilters, QDir::Files).count();34 return QDir::temp().entryList(nameFilters, QDir::Files).count();
33}35}
3436
37int nFaces = 0;
38
39class DummyFileEngineHandler : public QAbstractFileEngineHandler
40{
41public:
42 QAbstractFileEngine *create(const QString &fileName) const
43 {
44 if (fileName.endsWith("/face.png"))
45 nFaces++;
46
47 return nullptr;
48 }
49};
50
35class tst_UCQQuickImageExtension : public QObject51class tst_UCQQuickImageExtension : public QObject
36{52{
37 Q_OBJECT53 Q_OBJECT
@@ -78,7 +94,7 @@
7894
79 void rewriteContainsBorderInName() {95 void rewriteContainsBorderInName() {
80 UCQQuickImageExtension image;96 UCQQuickImageExtension image;
81 QString sciFilePath = "borderInName.sci";97 QString sciFilePath = "data/borderInName.sci";
82 QString result;98 QString result;
8399
84 QTextStream resultStream(&result);100 QTextStream resultStream(&result);
@@ -86,7 +102,7 @@
86102
87 QString expected;103 QString expected;
88 QTextStream expectedStream(&expected);104 QTextStream expectedStream(&expected);
89 expectedStream << "source: \"image://scaling/1/./borderInName.png\"" << endl;105 expectedStream << "source: \"image://scaling/1/data/borderInName.png\"" << endl;
90 expectedStream << "border.left: 9" << endl;106 expectedStream << "border.left: 9" << endl;
91 expectedStream << "border.right: 2" << endl;107 expectedStream << "border.right: 2" << endl;
92 expectedStream << "border.top: 9" << endl;108 expectedStream << "border.top: 9" << endl;
@@ -105,7 +121,7 @@
105 QQuickImageBase baseImage;121 QQuickImageBase baseImage;
106 UCQQuickImageExtension* image1 = new UCQQuickImageExtension(&baseImage);122 UCQQuickImageExtension* image1 = new UCQQuickImageExtension(&baseImage);
107 UCQQuickImageExtension* image2 = new UCQQuickImageExtension(&baseImage);123 UCQQuickImageExtension* image2 = new UCQQuickImageExtension(&baseImage);
108 QUrl sciFileUrl = QUrl::fromLocalFile("./test.sci");124 QUrl sciFileUrl = QUrl::fromLocalFile("./data/test.sci");
109125
110 unsigned int initialNumberOfSciFiles = numberOfTemporarySciFiles();126 unsigned int initialNumberOfSciFiles = numberOfTemporarySciFiles();
111127
@@ -124,6 +140,25 @@
124 delete image2;140 delete image2;
125 QCOMPARE(numberOfTemporarySciFiles(), initialNumberOfSciFiles + 1);141 QCOMPARE(numberOfTemporarySciFiles(), initialNumberOfSciFiles + 1);
126 }142 }
143
144 void onlyOneStatRepeatedImage() {
145 DummyFileEngineHandler handler;
146
147 QQuickView view(QUrl::fromLocalFile("./data/hundred_faces.qml"));
148
149 // Wait until the app is idle
150 bool idle = false;
151 while (!idle) {
152 QEventLoop l;
153 idle = !l.processEvents();
154 }
155 // We have actually loaded the image
156 QVERIFY(nFaces > 0);
157 // The number at the moment of writing this test is 4, but we
158 // can't know what Qt does internally, so i'm going for a relatively safe <10
159 // the important part is that is not 100 times (i.e. one for every Image item)
160 QVERIFY(nFaces < 10);
161 }
127};162};
128163
129QTEST_MAIN(tst_UCQQuickImageExtension)164QTEST_MAIN(tst_UCQQuickImageExtension)

Subscribers

People subscribed via source and target branches