Merge lp:~stellarium/stellarium/textures-cleanup into lp:stellarium

Proposed by Guillaume Chereau
Status: Merged
Merged at revision: 6321
Proposed branch: lp:~stellarium/stellarium/textures-cleanup
Merge into: lp:stellarium
Diff against target: 576 lines (+154/-228)
5 files modified
CMakeLists.txt (+20/-4)
src/core/StelTexture.cpp (+99/-126)
src/core/StelTexture.hpp (+29/-50)
src/core/StelTextureMgr.cpp (+5/-40)
src/core/StelTextureMgr.hpp (+1/-8)
To merge this branch: bzr merge lp:~stellarium/stellarium/textures-cleanup
Reviewer Review Type Date Requested Status
Alexander Wolf Needs Fixing
Review via email: mp+188775@code.launchpad.net

Description of the change

Clean the threaded texture loading, using QtConcurrent.

QtConcurrent will automatically use the global Qt threads pool to balance the load. The number of threads in the pool is chosen by Qt depending on the number of CPU available on the machine. This is nice when we have many textures loaded at the same time.

To see the improvement, check the fading of the constellation arts the first time we show them. It should be smoother.

To post a comment you must log in.
Revision history for this message
Alexander Wolf (alexwolf) wrote :

Displaying textures of constellations was really smoothly. But I found one regress in general for Stellarium/Qt5 - zooming is not smoothly and if area contains many textures then I catch "steps" zooming.

Possible that regress can be fixed within this branch.

review: Needs Fixing
Revision history for this message
Guillaume Chereau (guillaume-chereau) wrote :

On Wed, Oct 2, 2013 at 10:43 PM, Alexander Wolf <email address hidden> wrote:
> Review: Needs Fixing
>
> Displaying textures of constellations was really smoothly. But I found one regress in general for Stellarium/Qt5 - zooming is not smoothly and if area contains many textures then I catch "steps" zooming.

Since the Qt5 port, the actual loading of the QImage into an opengl
texture is indeed much slower. This branch does not really address
the issue, but I can already try to move the slow conversion from
QImage to opengl compatible data into the loading thread, maybe it
will make things a little bit better. I'll do some tests.

--
Guillaume
<email address hidden>
+886 970422910

6270. By Guillaume Chereau

convert QImage to opengl compatible data in the loading threads

This might improve the fluidity of the application, even though on my machine
it is hard to tell if there is much difference.

Revision history for this message
barrykgerdes (barrygastro) wrote :

Back in revision 6257 Fabien announced that sound was now switched to Qmultimedia in lieu of phonon.

Sound now compiles without any bother but does not play sound from any of the old sound test scripts.

Do I need to change the calls

"core.loadSound( "file name", "type")

"core.playSound ("type")

"core.dropSound("type")

Barry

>

Revision history for this message
Fabien Chéreau (xalioth) wrote :

Hi Barry,
when I run the regular test script for sound, it works just fine on my
linux computer. Which are the "old" sound test script?
Fabien

On Wed, Oct 9, 2013 at 5:40 AM, barrykgerdes <email address hidden>wrote:

> Back in revision 6257 Fabien announced that sound was now switched to
> Qmultimedia in lieu of phonon.
>
>
>
> Sound now compiles without any bother but does not play sound from any of
> the old sound test scripts.
>
>
>
> Do I need to change the calls
>
> "core.loadSound( "file name", "type")
>
> "core.playSound ("type")
>
> "core.dropSound("type")
>
>
>
> Barry
>
>
> >
> --
>
> https://code.launchpad.net/~stellarium/stellarium/textures-cleanup/+merge/188775
> You are subscribed to branch lp:stellarium.
>

Revision history for this message
barrykgerdes (barrygastro) wrote :

Hi Fab

The standard sound test "audiotest.ssc" ,"audiotest.wav" ,"audiotest. ogg" and "audiotest.mp3" as distributed with Stellarium.

I am compiling in Windows on five different computers XP, 2x Win 7 , win 8 and Win 8.1. I also have a (79.4 seconds) script that plays a timelapsed video of the sky from dask to dawn with background music that goes great in Stellarium 0.12.4. I would love to be able to run it in 0.13.0

I can't get a Linux compile to work yet. I have Qt5 installed on one computer but the install program does not work on the other computers and I still need to export the paths etc yet. I have not had trouble on linux before, even when I had to compile Qt 4 myself.

Barry

> To: <email address hidden>
> From: <email address hidden>
> Subject: Re: Sound in 0.13.0
> Date: Wed, 9 Oct 2013 08:45:36 +0000
>
> Hi Barry,
> when I run the regular test script for sound, it works just fine on my
> linux computer. Which are the "old" sound test script?
> Fabien
>
>
> On Wed, Oct 9, 2013 at 5:40 AM, barrykgerdes <email address hidden>wrote:
>
> > Back in revision 6257 Fabien announced that sound was now switched to
> > Qmultimedia in lieu of phonon.
> >
> >
> >
> > Sound now compiles without any bother but does not play sound from any of
> > the old sound test scripts.
> >
> >
> >
> > Do I need to change the calls
> >
> > "core.loadSound( "file name", "type")
> >
> > "core.playSound ("type")
> >
> > "core.dropSound("type")
> >
> >
> >
> > Barry
> >
> >
> > >
> > --
> >
> > https://code.launchpad.net/~stellarium/stellarium/textures-cleanup/+merge/188775
> > You are subscribed to branch lp:stellarium.
> >
>
> --
> https://code.launchpad.net/~stellarium/stellarium/textures-cleanup/+merge/188775
> Your team Stellarium is subscribed to branch lp:~stellarium/stellarium/textures-cleanup.

Revision history for this message
gzotti (georg-zotti) wrote :

Dear Barry,

I have it working on Win7.

There is a nuisance in the Qt/cmake build system: In the top-level
CMakeLists.txt, line 157, you have to SET_ENABLE_SOUND 1...
I would have expected that re-running cmake config steps, the next build
would include sound support. But one apparently has to clean the whole
builds directory manually before running cmake and building the project.
(check the logfile if in doubt whether it's activated.)

With this enabled all three files play within the script.

HTH, G.

On Mi, 9.10.2013, 11:21, barrykgerdes wrote:
> Hi Fab
>
>
>
> The standard sound test "audiotest.ssc" ,"audiotest.wav" ,"audiotest. ogg"
> and "audiotest.mp3" as distributed with Stellarium.
>
> I am compiling in Windows on five different computers XP, 2x Win 7 , win 8
> and Win 8.1. I also have a (79.4 seconds) script that plays a timelapsed
> video of the sky from dask to dawn with background music that goes great
> in Stellarium 0.12.4. I would love to be able to run it in 0.13.0
>
>
>
> I can't get a Linux compile to work yet. I have Qt5 installed on one
> computer but the install program does not work on the other computers and
> I still need to export the paths etc yet. I have not had trouble on linux
> before, even when I had to compile Qt 4 myself.
>
>
>
> Barry
>
>
>
>
>
>> To: <email address hidden>
>> From: <email address hidden>
>> Subject: Re: Sound in 0.13.0
>> Date: Wed, 9 Oct 2013 08:45:36 +0000
>>
>> Hi Barry,
>> when I run the regular test script for sound, it works just fine on my
>> linux computer. Which are the "old" sound test script?
>> Fabien
>>
>>
>> On Wed, Oct 9, 2013 at 5:40 AM, barrykgerdes
>> <email address hidden>wrote:
>>
>> > Back in revision 6257 Fabien announced that sound was now switched to
>> > Qmultimedia in lieu of phonon.
>> >
>> >
>> >
>> > Sound now compiles without any bother but does not play sound from any
>> of
>> > the old sound test scripts.
>> >
>> >
>> >
>> > Do I need to change the calls
>> >
>> > "core.loadSound( "file name", "type")
>> >
>> > "core.playSound ("type")
>> >
>> > "core.dropSound("type")
>> >
>> >
>> >
>> > Barry
>> >
>> >
>> > >
>> > --
>> >
>> > https://code.launchpad.net/~stellarium/stellarium/textures-cleanup/+merge/188775
>> > You are subscribed to branch lp:stellarium.
>> >
>>
>> --
>> https://code.launchpad.net/~stellarium/stellarium/textures-cleanup/+merge/188775
>> Your team Stellarium is subscribed to branch
>> lp:~stellarium/stellarium/textures-cleanup.
>
> --
> https://code.launchpad.net/~stellarium/stellarium/textures-cleanup/+merge/188775
> Your team Stellarium is subscribed to branch
> lp:~stellarium/stellarium/textures-cleanup.
>

Revision history for this message
barrykgerdes (barrygastro) wrote :
Download full text (3.4 KiB)

Hi Georg
I tried it again on win8. This time I changed the cmakelists.txt to 1
I cleaned the build folder as before
the cmakecache txt was then automatically set to sound =1

Still no sound. just the text that accompanies it.
tested 0.12.4:- works OK

Barry

> To: <email address hidden>
> From: <email address hidden>
> Subject: RE: Sound in 0.13.0
> Date: Wed, 9 Oct 2013 11:21:39 +0000
>
> Dear Barry,
>
> I have it working on Win7.
>
> There is a nuisance in the Qt/cmake build system: In the top-level
> CMakeLists.txt, line 157, you have to SET_ENABLE_SOUND 1...
> I would have expected that re-running cmake config steps, the next build
> would include sound support. But one apparently has to clean the whole
> builds directory manually before running cmake and building the project.
> (check the logfile if in doubt whether it's activated.)
>
> With this enabled all three files play within the script.
>
> HTH, G.
>
>
> On Mi, 9.10.2013, 11:21, barrykgerdes wrote:
> > Hi Fab
> >
> >
> >
> > The standard sound test "audiotest.ssc" ,"audiotest.wav" ,"audiotest. ogg"
> > and "audiotest.mp3" as distributed with Stellarium.
> >
> > I am compiling in Windows on five different computers XP, 2x Win 7 , win 8
> > and Win 8.1. I also have a (79.4 seconds) script that plays a timelapsed
> > video of the sky from dask to dawn with background music that goes great
> > in Stellarium 0.12.4. I would love to be able to run it in 0.13.0
> >
> >
> >
> > I can't get a Linux compile to work yet. I have Qt5 installed on one
> > computer but the install program does not work on the other computers and
> > I still need to export the paths etc yet. I have not had trouble on linux
> > before, even when I had to compile Qt 4 myself.
> >
> >
> >
> > Barry
> >
> >
> >
> >
> >
> >> To: <email address hidden>
> >> From: <email address hidden>
> >> Subject: Re: Sound in 0.13.0
> >> Date: Wed, 9 Oct 2013 08:45:36 +0000
> >>
> >> Hi Barry,
> >> when I run the regular test script for sound, it works just fine on my
> >> linux computer. Which are the "old" sound test script?
> >> Fabien
> >>
> >>
> >> On Wed, Oct 9, 2013 at 5:40 AM, barrykgerdes
> >> <email address hidden>wrote:
> >>
> >> > Back in revision 6257 Fabien announced that sound was now switched to
> >> > Qmultimedia in lieu of phonon.
> >> >
> >> >
> >> >
> >> > Sound now compiles without any bother but does not play sound from any
> >> of
> >> > the old sound test scripts.
> >> >
> >> >
> >> >
> >> > Do I need to change the calls
> >> >
> >> > "core.loadSound( "file name", "type")
> >> >
> >> > "core.playSound ("type")
> >> >
> >> > "core.dropSound("type")
> >> >
> >> >
> >> >
> >> > Barry
> >> >
> >> >
> >> > >
> >> > --
> >> >
> >> > https://code.launchpad.net/~stellarium/stellarium/textures-cleanup/+merge/188775
> >> > You are subscribed to branch lp:stellarium.
> >> >
> >>
> >> --
> >> https://code.launchpad.net/~stellarium/stellarium/textures-cleanup/+merge/188775
> >> Your team Stellarium is subscribed to branch
> >> lp:~stellarium/stellarium/textures-cleanup.
> >
> > --
> > https://code.launchpad.net/~stellarium/stellarium/textures-cleanup/+merge/188775
> > Your team Stellarium is subscrib...

Read more...

6271. By Guillaume Chereau

merge from trunk

6272. By Guillaume Chereau

reintroduce texture mipmap support

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2013-10-10 20:18:24 +0000
3+++ CMakeLists.txt 2013-10-13 08:07:31 +0000
4@@ -248,10 +248,26 @@
5 FIND_PACKAGE(Qt5Svg REQUIRED)
6 FIND_PACKAGE(Qt5Network REQUIRED)
7 FIND_PACKAGE(Qt5Declarative REQUIRED)
8-IF(WIN32)
9- # This modules need for Windows (WTF???)
10- FIND_PACKAGE(Qt5Sql REQUIRED)
11- FIND_PACKAGE(Qt5XmlPatterns REQUIRED)
12+FIND_PACKAGE(Qt5Concurrent REQUIRED)
13+FIND_PACKAGE(Qt5Test)
14+IF(WIN32)
15+ # This modules need for Windows (WTF???)
16+ FIND_PACKAGE(Qt5Sql REQUIRED)
17+ FIND_PACKAGE(Qt5XmlPatterns REQUIRED)
18+ENDIF()
19+
20+INCLUDE_DIRECTORIES(${Qt5Core_INCLUDE_DIRS})
21+INCLUDE_DIRECTORIES(${Qt5Gui_INCLUDE_DIRS})
22+INCLUDE_DIRECTORIES(${Qt5Widgets_INCLUDE_DIRS})
23+INCLUDE_DIRECTORIES(${Qt5OpenGL_INCLUDE_DIRS})
24+INCLUDE_DIRECTORIES(${Qt5Network_INCLUDE_DIRS})
25+INCLUDE_DIRECTORIES(${Qt5Declarative_INCLUDE_DIRS})
26+INCLUDE_DIRECTORIES(${Qt5Concurrent_INCLUDE_DIRS})
27+INCLUDE_DIRECTORIES(${Qt5Sql_INCLUDE_DIRS})
28+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}")
29+IF(WIN32)
30+ INCLUDE_DIRECTORIES(${Qt5XmlPatterns_INCLUDE_DIRS})
31+ INCLUDE_DIRECTORIES(${Qt5Test_INCLUDE_DIRS})
32 ENDIF()
33
34 # Tell CMake to run moc when necessary:
35
36=== modified file 'src/core/StelTexture.cpp'
37--- src/core/StelTexture.cpp 2013-09-03 07:30:08 +0000
38+++ src/core/StelTexture.cpp 2013-10-13 08:07:31 +0000
39@@ -25,80 +25,17 @@
40 #include "StelUtils.hpp"
41 #include "StelPainter.hpp"
42
43-#include <QThread>
44-#include <QMutexLocker>
45-#include <QSemaphore>
46 #include <QImageReader>
47-#include <QDir>
48-#include <QFile>
49-#include <QTemporaryFile>
50 #include <QSize>
51 #include <QDebug>
52 #include <QUrl>
53 #include <QImage>
54 #include <QNetworkReply>
55-#include <QTimer>
56 #include <QtEndian>
57-
58-ImageLoader::ImageLoader(const QString& path, int delay)
59- : QObject(), path(path), networkReply(NULL)
60-{
61- QTimer::singleShot(delay, this, SLOT(start()));
62-}
63-
64-void ImageLoader::abort()
65-{
66- // XXX: Assert that we are in the main thread.
67- if (networkReply != NULL)
68- {
69- networkReply->abort();
70- }
71-}
72-
73-void ImageLoader::start()
74-{
75- if (path.startsWith("http://")) {
76- QNetworkRequest req = QNetworkRequest(QUrl(path));
77- // Define that preference should be given to cached files (no etag checks)
78- req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
79- req.setRawHeader("User-Agent", StelUtils::getApplicationName().toLatin1());
80- networkReply = StelApp::getInstance().getNetworkAccessManager()->get(req);
81- connect(networkReply, SIGNAL(finished()), this, SLOT(onNetworkReply()));
82- } else {
83- // At next loop iteration we start to load from the file.
84- QTimer::singleShot(0, this, SLOT(directLoad()));
85- }
86-
87- // Move this object outside of the main thread.
88- StelTextureMgr* textureMgr = &StelApp::getInstance().getTextureManager();
89- moveToThread(textureMgr->loaderThread);
90-}
91-
92-
93-void ImageLoader::onNetworkReply()
94-{
95- if (networkReply->error() != QNetworkReply::NoError) {
96- emit error(networkReply->errorString());
97- } else {
98- QByteArray data = networkReply->readAll();
99- QImage image = QImage::fromData(data);
100- if (image.isNull()) {
101- emit error("Unable to parse image data");
102- } else {
103- emit finished(image);
104- }
105- }
106- networkReply->deleteLater();
107- networkReply = NULL;
108-}
109-
110-void ImageLoader::directLoad() {
111- QImage image = QImage(path);
112- emit finished(image);
113-}
114-
115-StelTexture::StelTexture() : loader(NULL), downloaded(false), isLoadingImage(false),
116- errorOccured(false), id(0), avgLuminance(-1.f)
117+#include <QFuture>
118+#include <QtConcurrent>
119+
120+StelTexture::StelTexture() : networkReply(NULL), loader(NULL), errorOccured(false), id(0), avgLuminance(-1.f)
121 {
122 width = -1;
123 height = -1;
124@@ -119,10 +56,13 @@
125 }
126 id = 0;
127 }
128+ if (networkReply != NULL)
129+ {
130+ networkReply->abort();
131+ networkReply->deleteLater();
132+ }
133 if (loader != NULL) {
134- loader->abort();
135- // Don't forget that the loader has no parent.
136- loader->deleteLater();
137+ delete loader;
138 loader = NULL;
139 }
140 }
141@@ -134,18 +74,40 @@
142 {
143 errorOccured = true;
144 errorMessage = aerrorMessage;
145- isLoadingImage = false;
146 // Report failure of texture loading
147 emit(loadingProcessFinished(true));
148 }
149
150+StelTexture::GLData StelTexture::imageToGLData(const QImage &image)
151+{
152+ GLData ret;
153+ if (image.isNull())
154+ return ret;
155+ ret.width = image.width();
156+ ret.height = image.height();
157+ ret.data = convertToGLFormat(image, &ret.format, &ret.type);
158+ return ret;
159+}
160+
161+/*************************************************************************
162+ Defined to be passed to QtConcurrent::run
163+ *************************************************************************/
164+StelTexture::GLData StelTexture::loadFromPath(const QString &path)
165+{
166+ return imageToGLData(QImage(path));
167+}
168+
169+StelTexture::GLData StelTexture::loadFromData(const QByteArray& data)
170+{
171+ return imageToGLData(QImage::fromData(data));
172+}
173+
174 /*************************************************************************
175 Bind the texture so that it can be used for openGL drawing (calls glBindTexture)
176 *************************************************************************/
177
178 bool StelTexture::bind()
179 {
180- // qDebug() << "TEST bind" << fullPath;
181 if (id != 0)
182 {
183 // The texture is already fully loaded, just bind and return true;
184@@ -156,24 +118,49 @@
185 if (errorOccured)
186 return false;
187
188- if (!isLoadingImage && loader == NULL) {
189- isLoadingImage = true;
190- loader = new ImageLoader(fullPath, 100);
191- connect(loader, SIGNAL(finished(QImage)), this, SLOT(onImageLoaded(QImage)));
192- connect(loader, SIGNAL(error(QString)), this, SLOT(onLoadingError(QString)));
193- }
194-
195- return false;
196-}
197-
198-void StelTexture::onImageLoaded(QImage image)
199-{
200- qImage = image;
201- Q_ASSERT(!qImage.isNull());
202- glLoad();
203- isLoadingImage = false;
204- loader->deleteLater();
205+ // If the file is remote, start a network connection.
206+ if (loader == NULL && networkReply == NULL && fullPath.startsWith("http://")) {
207+ QNetworkRequest req = QNetworkRequest(QUrl(fullPath));
208+ // Define that preference should be given to cached files (no etag checks)
209+ req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
210+ req.setRawHeader("User-Agent", StelUtils::getApplicationName().toLatin1());
211+ networkReply = StelApp::getInstance().getNetworkAccessManager()->get(req);
212+ connect(networkReply, SIGNAL(finished()), this, SLOT(onNetworkReply()));
213+ return false;
214+ }
215+ // The network connection is still running.
216+ if (networkReply != NULL)
217+ return false;
218+ // Not a remote file, start a loader from local file.
219+ if (loader == NULL)
220+ {
221+ loader = new QFuture<GLData>(QtConcurrent::run(loadFromPath, fullPath));
222+ return false;
223+ }
224+ // Wait until the loader finish.
225+ if (!loader->isFinished())
226+ return false;
227+ // Finally load the data in the main thread.
228+ glLoad(loader->result());
229+ delete loader;
230 loader = NULL;
231+ return true;
232+}
233+
234+void StelTexture::onNetworkReply()
235+{
236+ Q_ASSERT(loader == NULL);
237+ if (networkReply->error() != QNetworkReply::NoError)
238+ {
239+ reportError(networkReply->errorString());
240+ }
241+ else
242+ {
243+ QByteArray data = networkReply->readAll();
244+ loader = new QFuture<GLData>(QtConcurrent::run(loadFromData, data));
245+ }
246+ networkReply->deleteLater();
247+ networkReply = NULL;
248 }
249
250 /*************************************************************************
251@@ -183,25 +170,15 @@
252 {
253 if (width<0 || height<0)
254 {
255-
256- if (!qImage.isNull())
257- {
258- width = qImage.width();
259- height = qImage.height();
260- }
261- else
262- {
263- // Try to get the size from the file without loading data
264- QImageReader im(fullPath);
265- if (!im.canRead())
266- {
267- return false;
268- }
269- QSize size = im.size();
270- width = size.width();
271- height = size.height();
272- }
273-
274+ // Try to get the size from the file without loading data
275+ QImageReader im(fullPath);
276+ if (!im.canRead())
277+ {
278+ return false;
279+ }
280+ QSize size = im.size();
281+ width = size.width();
282+ height = size.height();
283 }
284 awidth = width;
285 aheight = height;
286@@ -274,37 +251,33 @@
287 return ret;
288 }
289
290-
291-// Actually load the texture to openGL memory
292-bool StelTexture::glLoad()
293+bool StelTexture::glLoad(const GLData& data)
294 {
295- if (qImage.isNull())
296+ if (data.data.isEmpty())
297 {
298- errorOccured = true;
299 reportError("Unknown error");
300 return false;
301 }
302+ width = data.width;
303+ height = data.height;
304 glActiveTexture(GL_TEXTURE0);
305 glGenTextures(1, &id);
306 glBindTexture(GL_TEXTURE_2D, id);
307 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, loadParams.filtering);
308 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, loadParams.filtering);
309-
310- GLint format, type;
311- QByteArray data = convertToGLFormat(qImage, &format, &type);
312- glTexImage2D(GL_TEXTURE_2D, 0, format, qImage.width(), qImage.height(), 0, format,
313- type, data.constData());
314- bool genMipmap = false;
315- if (genMipmap)
316- glGenerateMipmap(GL_TEXTURE_2D);
317-
318+ glTexImage2D(GL_TEXTURE_2D, 0, data.format, width, height, 0, data.format,
319+ data.type, data.data.constData());
320 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, loadParams.wrapMode);
321 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, loadParams.wrapMode);
322-
323- // Release shared memory
324- qImage = QImage();
325-
326+ if (loadParams.generateMipmaps)
327+ glGenerateMipmap(GL_TEXTURE_2D);
328 // Report success of texture loading
329 emit(loadingProcessFinished(false));
330 return true;
331 }
332+
333+// Actually load the texture to openGL memory
334+bool StelTexture::glLoad(const QImage& image)
335+{
336+ return glLoad(imageToGLData(image));
337+}
338
339=== modified file 'src/core/StelTexture.hpp'
340--- src/core/StelTexture.hpp 2013-09-03 07:30:08 +0000
341+++ src/core/StelTexture.hpp 2013-10-13 08:07:31 +0000
342@@ -29,39 +29,12 @@
343 class QFile;
344 class StelTextureMgr;
345 class QNetworkReply;
346+template <class T> class QFuture;
347
348 #ifndef GL_CLAMP_TO_EDGE
349 #define GL_CLAMP_TO_EDGE 0x812F
350 #endif
351
352-// This class is just used internally to load the texture data.
353-class ImageLoader : QObject
354-{
355- Q_OBJECT
356-
357-private:
358- friend class StelTextureMgr;
359- friend class StelTexture;
360-
361- ImageLoader(const QString& path, int delay);
362- void abort();
363-
364-signals:
365- void finished(QImage);
366- void error(const QString& errorMsg);
367-
368-public slots:
369- void start();
370-
371-private slots:
372- void onNetworkReply();
373- void directLoad();
374-
375-private:
376- QString path;
377- QNetworkReply* networkReply;
378-};
379-
380 //! @class StelTexture
381 //! Base texture class. For creating an instance, use StelTextureMgr::createTexture() and StelTextureMgr::createTextureThread()
382 //! @sa StelTextureSP
383@@ -109,12 +82,7 @@
384 const QString& getFullPath() const {return fullPath;}
385
386 //! Return whether the image is currently being loaded
387- bool isLoading() const {return isLoadingImage && !canBind();}
388-
389- //! Load the texture already in the RAM to the openGL memory
390- //! This function uses openGL routines and must be called in the main thread
391- //! @return false if an error occured
392- bool glLoad();
393+ bool isLoading() const {return (loader || networkReply) && !canBind();}
394
395 signals:
396 //! Emitted when the texture is ready to be bind(), i.e. when downloaded, imageLoading and glLoading is over
397@@ -124,14 +92,25 @@
398 void loadingProcessFinished(bool error);
399
400 private slots:
401- //! Called by the loader when the data has finished loading
402- void onImageLoaded(QImage image);
403- //! Called by the loader in case of an error
404- void onLoadingError(const QString& errorMessage) {reportError(errorMessage);}
405+ void onNetworkReply();
406
407 private:
408 friend class StelTextureMgr;
409- friend class TextureLoader;
410+
411+ //! structure returned by the loader threads, containing all the
412+ //! data and information to create the OpenGL texture.
413+ struct GLData
414+ {
415+ QByteArray data;
416+ int width;
417+ int height;
418+ GLint format;
419+ GLint type;
420+ };
421+ //! Those static methods can be called by QtConcurrent::run
422+ static GLData imageToGLData(const QImage &image);
423+ static GLData loadFromPath(const QString &path);
424+ static GLData loadFromData(const QByteArray& data);
425
426 //! Private constructor
427 StelTexture();
428@@ -143,25 +122,25 @@
429 //! @param errorMessage the human friendly error message
430 void reportError(const QString& errorMessage);
431
432+ //! Load the texture already in the RAM to the openGL memory
433+ //! This function uses openGL routines and must be called in the main thread
434+ //! @return false if an error occured
435+ bool glLoad(const QImage& image);
436+ //! Same as glLoad(QImage), but with an image already in OpenGl format
437+ bool glLoad(const GLData& data);
438+
439 StelTextureParams loadParams;
440
441+ //! Used to handle the connection for remote textures.
442+ QNetworkReply *networkReply;
443+
444 //! The loader object
445- ImageLoader* loader;
446+ QFuture<GLData>* loader;
447
448- //! Define if the texture was already downloaded if it was a remote one
449- bool downloaded;
450- //! Define whether the image is already loading
451- bool isLoadingImage;
452
453 //! The URL where to download the file
454 QString fullPath;
455
456- //! The data that was loaded from http
457- QImage qImage;
458-
459- //! Used ony when creating temporary file
460- QString fileExtension;
461-
462 //! True when something when wrong in the loading process
463 bool errorOccured;
464
465
466=== modified file 'src/core/StelTextureMgr.cpp'
467--- src/core/StelTextureMgr.cpp 2013-09-22 20:28:42 +0000
468+++ src/core/StelTextureMgr.cpp 2013-10-13 08:07:31 +0000
469@@ -33,25 +33,10 @@
470 #include <QOpenGLContext>
471
472
473-StelTextureMgr::StelTextureMgr()
474-{
475- // This thread is doing nothing but will contains all the loader objects.
476- loaderThread = new QThread(this);
477- loaderThread->start(QThread::LowestPriority);
478-}
479-
480-StelTextureMgr::~StelTextureMgr()
481-{
482- // Hopefully this doesn't take much time.
483- loaderThread->quit();
484- loaderThread->wait();
485-}
486-
487 void StelTextureMgr::init()
488 {
489 }
490
491-
492 StelTextureSP StelTextureMgr::createTexture(const QString& afilename, const StelTexture::StelTextureParams& params)
493 {
494 if (afilename.isEmpty())
495@@ -60,46 +45,26 @@
496 StelTextureSP tex = StelTextureSP(new StelTexture());
497 tex->fullPath = afilename;
498
499- tex->qImage = QImage(tex->fullPath);
500- if (tex->qImage.isNull())
501+ QImage image(tex->fullPath);
502+ if (image.isNull())
503 return StelTextureSP();
504
505 tex->loadParams = params;
506- tex->downloaded = true;
507-
508- if (tex->glLoad())
509+ if (tex->glLoad(image))
510 return tex;
511 else
512 return StelTextureSP();
513 }
514
515
516-StelTextureSP StelTextureMgr::createTextureThread(const QString& url, const StelTexture::StelTextureParams& params, const QString& fileExtension, bool lazyLoading)
517+StelTextureSP StelTextureMgr::createTextureThread(const QString& url, const StelTexture::StelTextureParams& params, bool lazyLoading)
518 {
519 if (url.isEmpty())
520 return StelTextureSP();
521
522 StelTextureSP tex = StelTextureSP(new StelTexture());
523 tex->loadParams = params;
524- if (!url.startsWith("http://"))
525- {
526- // Assume a local file
527- tex->fullPath = url;
528- tex->downloaded = true;
529- }
530- else
531- {
532- tex->fullPath = url;
533- if (fileExtension.isEmpty())
534- {
535- const int idx = url.lastIndexOf('.');
536- if (idx!=-1)
537- tex->fileExtension = url.right(url.size()-idx-1);
538- }
539- }
540- if (!fileExtension.isEmpty())
541- tex->fileExtension = fileExtension;
542-
543+ tex->fullPath = url;
544 if (!lazyLoading)
545 {
546 tex->bind();
547
548=== modified file 'src/core/StelTextureMgr.hpp'
549--- src/core/StelTextureMgr.hpp 2013-08-25 21:13:39 +0000
550+++ src/core/StelTextureMgr.hpp 2013-10-13 08:07:31 +0000
551@@ -33,9 +33,6 @@
552 class StelTextureMgr : QObject
553 {
554 public:
555- StelTextureMgr();
556- virtual ~StelTextureMgr();
557-
558 //! Initialize some variable from the openGL contex.
559 //! Must be called after the creation of the GLContext.
560 void init();
561@@ -50,16 +47,12 @@
562 //! @param url the texture file name or URL, can be absolute path if starts with '/' otherwise
563 //! the file will be looked in stellarium standard textures directories.
564 //! @param params the texture creation parameters.
565- //! @param fileExtension the file extension to assume. If not set the extension is determined from url
566 //! @param lazyLoading define whether the texture should be actually loaded only when needed, i.e. when bind() is called the first time.
567- StelTextureSP createTextureThread(const QString& url, const StelTexture::StelTextureParams& params=StelTexture::StelTextureParams(), const QString& fileExtension=QString(), bool lazyLoading=true);
568+ StelTextureSP createTextureThread(const QString& url, const StelTexture::StelTextureParams& params=StelTexture::StelTextureParams(), bool lazyLoading=true);
569
570 private:
571 friend class StelTexture;
572 friend class ImageLoader;
573-
574- //! A thread that is used by the TextureLoader object to avoid pausing the main thread too long.
575- QThread* loaderThread;
576 };
577
578