On Wed, Oct 12, 2011 at 10:36 PM, Oliver Eichler <[email protected]>wrote:

> 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.
>
>
 No, COsmTilesHash::slotRequestFinished will add object for new tile to the
list and do emit newImageReady, but this method will break idea with
internal buffer, and it will not help a lot to make map scrolling smooth :(


>
>
>> 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.
>

 If alfa channel is needed, this method will not wok :( QImages with such
pixel format are being drawn to screen slowly.


> 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.
>
>
 I've compared qlandkarte with web applications, like
http://www.openstreetmap.org/ and maps.google.com - web apps works
excellent, i don't see any delays at all, but in qlandkarte update rate is
small :( Please, try to run qlandkarte with patch in attachment and check
output, on my system - fedora 15, Core(TM)2 Duo CPU  E6750, nvidia adapter,
screen size 1600x1200 and with maximized window it shows about 11 FPS :(
With pixmaps it shows 40-400 fps (maybe some problem with qt events and
synchronization exists, paintEvent works 2.5 ms, so it can be always
400fps).


>
>> 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 ;)
>
>
 Maybe create one separate method, which will be called only from GUI thread
and second - method, which must be thread safe. In simplest case first will
just call second, but when some optimization is possible - we can add fast
and thread-unsafe code for drawing to screen ?


> Oliver
>
>
>
>
>>> -------- Original-Nachricht --------
>>>
>>>> Datum: Wed, 12 Oct 2011 11:11:27 +0400
>>>> Von: Dmitry Guryanov<dmitry.guryanov@**gmail.com<[email protected]>
>>>> >
>>>> An: 
>>>> qlandkartegt-users@lists.**sourceforge.net<[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<http://p.sf.net/sfu/splunk-d2d-oct>
>>>> ______________________________**_________________
>>>> Qlandkartegt-users mailing list
>>>> Qlandkartegt-users@lists.**sourceforge.net<[email protected]>
>>>> https://lists.sourceforge.net/**lists/listinfo/qlandkartegt-**users<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