Am 12.10.2011 12:35, schrieb Dmitry Guryanov:
> On Wed, Oct 12, 2011 at 1:16 PM, Oliver Eichler<[email protected]>wrote:
>
>> Hi Dmitry,
>>
>> I know, but QPixmap is not threadsafe. As there are already some thread
>> functions that use the draw handlers, too, and future development might tend
>> to do map rendering in a thread, the current implementation should avoid the
>> usage of QPixmap in the objects that inherit IMap.
>>
>>
> I know 3 another ways to increase rendering speed:
>
> 1. Don't draw to the QImage in COsmTilesHash::getImage. Create some class,
> which store qimage and qpoint (where qimage must be draw) and put object of
> this class to list, then in CMapOSM::draw iterate through this list and draw
> each tile to screen directly - I've checked this method, and it reduces
> render time about 2 times.

If I recall right Marc's idea (the guy who implemented all OSM/TMS 
support) was to update the screen with each tile received, to give 
feedback to the user. If I understand your idea correctly the screen 
would just update after all tiles are loaded.


>
> 2. Try to guess pixel format of screen and create QImages with that pixel
> format - this change significantly improves performance.

As long as this does not affect the IMap::buffer QImage it's a good 
idea. This buffer, common to all map objects, has to be able to handle 
the alpha channel, as Garmin or raster maps use transparency. Even in 
CMapOSM transparency is need when drawing a vector map as overlay.

On my Linux boxes and my win7 netbook the OSM drawing performance has 
never been a problem. But if it's such a performance ditch on your 
system I think your idea is fair enough.

>
> 3. Create separate hash for storing tiles in QPixmaps and convert QImages to
> QPixmaps in GUI thread.

Well the method CMapOSM::draw(QPainter& p) can be called by the GUI 
thread or from any other point. If that does make sense in the case of 
CMapOSM can be discussed, as the method will just trigger tile download 
and draw the current IMap::buffer. CMapOSM will update itself 
automatically until all visible tiles are loaded. This is no real 
concept for a background thread, that expects a complete map after the call.

Thus it would be an option to bypass the IMap::buffer use QPixmap 
completely for CMapOSM and COsmTilesHash. But CMapOSM::draw(QPainter& p) 
should make sure just be called in the main thread. Not sure if that can 
be checked by the Qt API to make it portable.

It's possible but my intuition tells me that I will regret one day ;)


Oliver



>>
>> -------- Original-Nachricht --------
>>> Datum: Wed, 12 Oct 2011 11:11:27 +0400
>>> Von: Dmitry Guryanov<[email protected]>
>>> An: [email protected]
>>> CC: [email protected]
>>> Betreff: [Qlandkartegt-users] [PATCH] use QPixmap instead of QImage for
>>      drawing OSM map
>>
>>> QImage is optimized for IO, as states QT documentation,
>>> and operation like drawing one QImage to another or
>>> drawing QImage to screen are very slow, especially when
>>> pixel format of QImage not same as screen (on my system
>>> pixel format of screen is rgb32, but qlandkarte use
>>> QImage::Format_ARGB32_Premultiplied).
>>>
>>> Using QPixmap speeds up paintEvent handler, before this
>>> patch time of CCanvas::paintEvent was ~85ms, after - ~2.5ms.
>>> Update rate is still not high, about 40FPS, because
>>> of qt events, but map moves more smoothly.
>>> ---
>>>   src/CMapOSM.cpp       |    8 ++++----
>>>   src/CMapOSM.h         |    5 +++--
>>>   src/COsmTilesHash.cpp |   16 ++++++++++------
>>>   src/COsmTilesHash.h   |    8 ++++----
>>>   4 files changed, 21 insertions(+), 16 deletions(-)
>>>
>>> diff --git a/src/CMapOSM.cpp b/src/CMapOSM.cpp
>>> index 5c25462..c9cb2d7 100644
>>> --- a/src/CMapOSM.cpp
>>> +++ b/src/CMapOSM.cpp
>>> @@ -216,7 +216,7 @@ void CMapOSM::setNewTileUrl(int cbIndex)
>>>           }
>>>
>>>           osmTiles = new COsmTilesHash(tileList.at(index).path);
>>> -
>>>
>> connect(osmTiles,SIGNAL(newImageReady(QImage,bool)),this,SLOT(newImageReady(QImage,bool)));
>>> +
>>>
>> connect(osmTiles,SIGNAL(newImageReady(QPixmap,bool)),this,SLOT(newImageReady(QPixmap,bool)));
>>>
>>>           needsRedraw = true;
>>>           emit sigChanged();
>>> @@ -370,7 +370,7 @@ void CMapOSM::draw(QPainter&  p)
>>>           draw();
>>>       }
>>>
>>> -    p.drawImage(0,0,buffer);
>>> +    p.drawPixmap(0, 0, image);
>>>
>>>       // render overlay
>>>       if(!ovlMap.isNull()&&  lastTileLoaded&&  !doFastDraw)
>>> @@ -437,9 +437,9 @@ void CMapOSM::draw()
>>>   }
>>>
>>>
>>> -void CMapOSM::newImageReady(QImage image, bool done)
>>> +void CMapOSM::newImageReady(QPixmap image, bool done)
>>>   {
>>> -    buffer            = image;
>>> +    this->image       = image;
>>>       lastTileLoaded    = done;
>>>       needsRedraw       = false;
>>>       emit sigChanged();
>>> diff --git a/src/CMapOSM.h b/src/CMapOSM.h
>>> index 6b7e2f8..2a44081 100644
>>> --- a/src/CMapOSM.h
>>> +++ b/src/CMapOSM.h
>>> @@ -21,6 +21,7 @@
>>>   #define CMAPOSM_H
>>>
>>>   #include<IMap.h>
>>> +#include<QPixmap>
>>>   #include "CMapOSMType.h"
>>>
>>>   class COsmTilesHash;
>>> @@ -49,14 +50,14 @@ class CMapOSM : public IMap
>>>           bool rebuildServerList();
>>>
>>>       public slots:
>>> -        void newImageReady(QImage image, bool lastTileLoaded);
>>> +        void newImageReady(QPixmap image, bool lastTileLoaded);
>>>           void setNewTileUrl(int cbIndex = -1);
>>>       private:
>>>           QComboBox *cb;
>>>           QWidget *parent;
>>>           int currentTileListIndex;
>>>           QList<CMapOSMType>  tileList;
>>> -        QImage image;
>>> +        QPixmap image;
>>>           bool lastTileLoaded;
>>>           void draw();
>>>           COsmTilesHash *osmTiles;
>>> diff --git a/src/COsmTilesHash.cpp b/src/COsmTilesHash.cpp
>>> index 3455cc0..7471f36 100644
>>> --- a/src/COsmTilesHash.cpp
>>> +++ b/src/COsmTilesHash.cpp
>>> @@ -183,7 +183,7 @@ void COsmTilesHash::startNewDrawing( double lon,
>>> double lat, int osm_zoom, const
>>>
>>>       //qDebug()<<  xCount<<  yCount<<  window;
>>>
>>> -    image = QImage(window.size(),QImage::Format_ARGB32_Premultiplied);
>>> +    image = QPixmap(window.size());
>>>       image.fill(Qt::white);
>>>       for(int x=0; x<xCount; x++)
>>>       {
>>> @@ -212,7 +212,7 @@ void COsmTilesHash::getImage(int osm_zoom, int osm_x,
>>> int osm_y, QPoint point)
>>>       if (tiles.contains(osmUrlPart))
>>>       {
>>>           QPainter p(&image);
>>> -        p.drawImage(point,tiles.value(osmUrlPart));
>>> +        p.drawPixmap(point,tiles.value(osmUrlPart));
>>>   #ifdef COSMTILESHASHDEBUG
>>>           p.drawRect(QRect(point,QSize(255,255)));
>>>           p.drawText(point + QPoint(10,10), "cached " + osmUrlPart);
>>> @@ -229,9 +229,11 @@ void COsmTilesHash::getImage(int osm_zoom, int
>> osm_x,
>>> int osm_y, QPoint point)
>>>
>>>               if(img1.format() != QImage::Format_Invalid)
>>>               {
>>> +                QPixmap pix1(img1.size());
>>> +                pix1.convertFromImage(img1);
>>>                   QPainter p(&image);
>>> -                p.drawImage(point,img1);
>>> -                tiles.insert(osmUrlPart,img1);
>>> +                p.drawPixmap(point,pix1);
>>> +                tiles.insert(osmUrlPart,pix1);
>>>                   int days =
>>>
>> QFileInfo(osmFilePath).lastModified().daysTo(QDateTime::currentDateTime());
>>>                   if ( days<  8)
>>>                   {
>>> @@ -309,10 +311,12 @@ void COsmTilesHash::slotRequestFinished(int id,
>> bool
>>> error)
>>>           img1.save (&f);
>>>       }
>>>
>>> -    tiles.insert(osmUrlPart,img1);
>>> +    QPixmap pix1(img1.size());
>>> +    pix1.convertFromImage(img1);
>>> +    tiles.insert(osmUrlPart,pix1);
>>>       // if (osmUrlPart.startsWith(QString("/%1/").arg(osm_zoom))) {
>>>       QPainter p(&image);
>>> -    p.drawImage(startPointHash.value(id),img1);
>>> +    p.drawPixmap(startPointHash.value(id),pix1);
>>>   #ifdef COSMTILESHASHDEBUG
>>>       p.drawRect(QRect(startPointHash.value(id),QSize(255,255)));
>>>       p.drawText(startPointHash.value(id) + QPoint(10,10),
>>> QString::number(id) + osmUrlPartHash.value(id));
>>> diff --git a/src/COsmTilesHash.h b/src/COsmTilesHash.h
>>> index f5f6e8f..5ee7d68 100644
>>> --- a/src/COsmTilesHash.h
>>> +++ b/src/COsmTilesHash.h
>>> @@ -20,7 +20,7 @@
>>>   #include<QString>
>>>   #include<QRect>
>>>   #include<QPainter>
>>> -#include<QImage>
>>> +#include<QPixmap>
>>>   #include<QHash>
>>>
>>>   class QHttp;
>>> @@ -34,7 +34,7 @@ class COsmTilesHash: public QObject
>>>           void startNewDrawing( double lon, double lat, int osm_zoom,
>> const
>>> QRect&  window);
>>>           static const QString&getCacheFolder(void) { return cacheFolder;
>>> };
>>>           signals:
>>> -        void newImageReady(QImage image, bool lastTileLoaded);
>>> +        void newImageReady(QPixmap image, bool lastTileLoaded);
>>>       private:
>>>           QString tileServer;
>>>           QString tileUrlPart;
>>> @@ -48,12 +48,12 @@ class COsmTilesHash: public QObject
>>>           double tile2long(int x, int zoom);
>>>           double tile2lat(int y, int zoom);
>>>           void getImage(int osm_zoom, int osm_x, int osm_y, QPoint
>>> startPoint);
>>> -        QImage image;
>>> +        QPixmap image;
>>>           QHttp *tilesConnection;
>>>           //         CMapOSM *cmapOSM;
>>>           QString osmTileBaseUrl;
>>>           bool requestInProgress;
>>> -        QHash<QString,QImage>  tiles;
>>> +        QHash<QString,QPixmap>  tiles;
>>>           int getid;
>>>           static QString cacheFolder;
>>>       private slots:
>>> --
>>> 1.7.6.4
>>>
>>>
>>>
>> ------------------------------------------------------------------------------
>>> All the data continuously generated in your IT infrastructure contains a
>>> definitive record of customers, application performance, security
>>> threats, fraudulent activity and more. Splunk takes this data and makes
>>> sense of it. Business sense. IT sense. Common sense.
>>> http://p.sf.net/sfu/splunk-d2d-oct
>>> _______________________________________________
>>> Qlandkartegt-users mailing list
>>> [email protected]
>>> https://lists.sourceforge.net/lists/listinfo/qlandkartegt-users
>>
>


------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure contains a
definitive record of customers, application performance, security
threats, fraudulent activity and more. Splunk takes this data and makes
sense of it. Business sense. IT sense. Common sense.
http://p.sf.net/sfu/splunk-d2d-oct
_______________________________________________
Qlandkartegt-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/qlandkartegt-users

Reply via email to