• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

marble

  • sources
  • kde-4.12
  • kdeedu
  • marble
  • src
  • lib
  • marble
StackedTileLoader.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the Marble Virtual Globe.
3  *
4  * Copyright 2005-2007 Torsten Rahn <tackat@kde.org>
5  * Copyright 2007 Inge Wallin <ingwa@kde.org>
6  * Copyright 2008, 2009, 2010 Jens-Michael Hoffmann <jensmh@gmx.de>
7  * Copyright 2010-2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB. If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24 
25 #include "StackedTileLoader.h"
26 
27 #include "GeoSceneTiled.h"
28 #include "MarbleDebug.h"
29 #include "MergedLayerDecorator.h"
30 #include "StackedTile.h"
31 #include "TileLoader.h"
32 #include "TileLoaderHelper.h"
33 #include "MarbleGlobal.h"
34 
35 #include <QCache>
36 #include <QHash>
37 #include <QReadWriteLock>
38 #include <QImage>
39 
40 
41 namespace Marble
42 {
43 
44 class StackedTileLoaderPrivate
45 {
46 public:
47  StackedTileLoaderPrivate( MergedLayerDecorator *mergedLayerDecorator )
48  : m_layerDecorator( mergedLayerDecorator )
49  {
50  m_tileCache.setMaxCost( 20000 * 1024 ); // Cache size measured in bytes
51  }
52 
53  MergedLayerDecorator *const m_layerDecorator;
54  QHash <TileId, StackedTile*> m_tilesOnDisplay;
55  QCache <TileId, StackedTile> m_tileCache;
56  QReadWriteLock m_cacheLock;
57 };
58 
59 StackedTileLoader::StackedTileLoader( MergedLayerDecorator *mergedLayerDecorator, QObject *parent )
60  : QObject( parent ),
61  d( new StackedTileLoaderPrivate( mergedLayerDecorator ) )
62 {
63 }
64 
65 StackedTileLoader::~StackedTileLoader()
66 {
67  qDeleteAll( d->m_tilesOnDisplay );
68  delete d;
69 }
70 
71 int StackedTileLoader::tileColumnCount( int level ) const
72 {
73  return d->m_layerDecorator->tileColumnCount( level );
74 }
75 
76 int StackedTileLoader::tileRowCount( int level ) const
77 {
78  return d->m_layerDecorator->tileRowCount( level );
79 }
80 
81 GeoSceneTiled::Projection StackedTileLoader::tileProjection() const
82 {
83  return d->m_layerDecorator->tileProjection();
84 }
85 
86 QSize StackedTileLoader::tileSize() const
87 {
88  return d->m_layerDecorator->tileSize();
89 }
90 
91 void StackedTileLoader::resetTilehash()
92 {
93  QHash<TileId, StackedTile*>::const_iterator it = d->m_tilesOnDisplay.constBegin();
94  QHash<TileId, StackedTile*>::const_iterator const end = d->m_tilesOnDisplay.constEnd();
95  for (; it != end; ++it ) {
96  Q_ASSERT( it.value()->used() && "contained in m_tilesOnDisplay should imply used()" );
97  it.value()->setUsed( false );
98  }
99 }
100 
101 void StackedTileLoader::cleanupTilehash()
102 {
103  // Make sure that tiles which haven't been used during the last
104  // rendering of the map at all get removed from the tile hash.
105 
106  QHashIterator<TileId, StackedTile*> it( d->m_tilesOnDisplay );
107  while ( it.hasNext() ) {
108  it.next();
109  if ( !it.value()->used() ) {
110  // If insert call result is false then the cache is too small to store the tile
111  // but the item will get deleted nevertheless and the pointer we have
112  // doesn't get set to zero (so don't delete it in this case or it will crash!)
113  d->m_tileCache.insert( it.key(), it.value(), it.value()->byteCount() );
114  d->m_tilesOnDisplay.remove( it.key() );
115  }
116  }
117 }
118 
119 const StackedTile* StackedTileLoader::loadTile( TileId const & stackedTileId )
120 {
121  // check if the tile is in the hash
122  d->m_cacheLock.lockForRead();
123  StackedTile * stackedTile = d->m_tilesOnDisplay.value( stackedTileId, 0 );
124  d->m_cacheLock.unlock();
125  if ( stackedTile ) {
126  stackedTile->setUsed( true );
127  return stackedTile;
128  }
129  // here ends the performance critical section of this method
130 
131  d->m_cacheLock.lockForWrite();
132 
133  // has another thread loaded our tile due to a race condition?
134  stackedTile = d->m_tilesOnDisplay.value( stackedTileId, 0 );
135  if ( stackedTile ) {
136  Q_ASSERT( stackedTile->used() && "other thread should have marked tile as used" );
137  d->m_cacheLock.unlock();
138  return stackedTile;
139  }
140 
141  // the tile was not in the hash so check if it is in the cache
142  stackedTile = d->m_tileCache.take( stackedTileId );
143  if ( stackedTile ) {
144  Q_ASSERT( !stackedTile->used() && "tiles in m_tileCache are invisible and should thus be marked as unused" );
145  stackedTile->setUsed( true );
146  d->m_tilesOnDisplay[ stackedTileId ] = stackedTile;
147  d->m_cacheLock.unlock();
148  return stackedTile;
149  }
150 
151  // tile (valid) has not been found in hash or cache, so load it from disk
152  // and place it in the hash from where it will get transferred to the cache
153 
154  mDebug() << "load tile from disk:" << stackedTileId;
155 
156  stackedTile = d->m_layerDecorator->loadTile( stackedTileId );
157  Q_ASSERT( stackedTile );
158  stackedTile->setUsed( true );
159 
160  d->m_tilesOnDisplay[ stackedTileId ] = stackedTile;
161  d->m_cacheLock.unlock();
162 
163  emit tileLoaded( stackedTileId );
164 
165  return stackedTile;
166 }
167 
168 quint64 StackedTileLoader::volatileCacheLimit() const
169 {
170  return d->m_tileCache.maxCost() / 1024;
171 }
172 
173 QList<TileId> StackedTileLoader::visibleTiles() const
174 {
175  return d->m_tilesOnDisplay.keys();
176 }
177 
178 int StackedTileLoader::tileCount() const
179 {
180  return d->m_tileCache.count() + d->m_tilesOnDisplay.count();
181 }
182 
183 void StackedTileLoader::setVolatileCacheLimit( quint64 kiloBytes )
184 {
185  mDebug() << QString("Setting tile cache to %1 kilobytes.").arg( kiloBytes );
186  d->m_tileCache.setMaxCost( kiloBytes * 1024 );
187 }
188 
189 void StackedTileLoader::updateTile( TileId const &tileId, QImage const &tileImage )
190 {
191  const TileId stackedTileId( 0, tileId.zoomLevel(), tileId.x(), tileId.y() );
192 
193  StackedTile * displayedTile = d->m_tilesOnDisplay.take( stackedTileId );
194  if ( displayedTile ) {
195  Q_ASSERT( !d->m_tileCache.contains( stackedTileId ) );
196 
197  StackedTile *const stackedTile = d->m_layerDecorator->updateTile( *displayedTile, tileId, tileImage );
198  stackedTile->setUsed( true );
199  d->m_tilesOnDisplay.insert( stackedTileId, stackedTile );
200 
201  delete displayedTile;
202  displayedTile = 0;
203 
204  emit tileLoaded( stackedTileId );
205  } else {
206  d->m_tileCache.remove( stackedTileId );
207  }
208 }
209 
210 void StackedTileLoader::clear()
211 {
212  mDebug() << Q_FUNC_INFO;
213 
214  qDeleteAll( d->m_tilesOnDisplay );
215  d->m_tilesOnDisplay.clear();
216  d->m_tileCache.clear(); // clear the tile cache in physical memory
217 
218  emit cleared();
219 }
220 
221 }
222 
223 #include "StackedTileLoader.moc"
TileLoader.h
Marble::TileId::zoomLevel
int zoomLevel() const
Definition: TileId.h:57
Marble::StackedTileLoader::tileLoaded
void tileLoaded(TileId const &tileId)
Marble::GeoSceneTiled::Projection
Projection
Definition: GeoSceneTiled.h:47
Marble::TileId::y
int y() const
Definition: TileId.h:67
QObject
Marble::StackedTileLoader::StackedTileLoader
StackedTileLoader(MergedLayerDecorator *mergedLayerDecorator, QObject *parent=0)
Creates a new tile loader.
Definition: StackedTileLoader.cpp:59
MarbleDebug.h
Marble::StackedTile
A single tile that consists of a stack of Tile layers.
Definition: StackedTile.h:56
Marble::StackedTileLoader::clear
void clear()
Effectively triggers a reload of all tiles that are currently in use and clears the tile cache in phy...
Definition: StackedTileLoader.cpp:210
Marble::MergedLayerDecorator
Definition: MergedLayerDecorator.h:40
Marble::StackedTileLoader::~StackedTileLoader
virtual ~StackedTileLoader()
Definition: StackedTileLoader.cpp:65
Marble::StackedTile::used
bool used() const
Definition: StackedTile.cpp:232
Marble::StackedTileLoader::setVolatileCacheLimit
void setVolatileCacheLimit(quint64 kiloBytes)
Set the limit of the volatile (in RAM) cache.
Definition: StackedTileLoader.cpp:183
Marble::StackedTileLoader::cleanupTilehash
void cleanupTilehash()
Cleans up the internal tile hash.
Definition: StackedTileLoader.cpp:101
Marble::StackedTileLoader::updateTile
void updateTile(TileId const &tileId, QImage const &tileImage)
Definition: StackedTileLoader.cpp:189
Marble::StackedTileLoader::tileSize
QSize tileSize() const
Definition: StackedTileLoader.cpp:86
Marble::StackedTile::setUsed
void setUsed(bool used)
Definition: StackedTile.cpp:227
MarbleGlobal.h
Marble::TileId::x
int x() const
Definition: TileId.h:62
Marble::StackedTileLoader::visibleTiles
QList< TileId > visibleTiles() const
Reloads the tiles that are currently displayed.
Definition: StackedTileLoader.cpp:173
MergedLayerDecorator.h
Marble::StackedTileLoader::tileColumnCount
int tileColumnCount(int level) const
Definition: StackedTileLoader.cpp:71
Marble::StackedTileLoader::tileRowCount
int tileRowCount(int level) const
Definition: StackedTileLoader.cpp:76
Marble::TileId
Definition: TileId.h:27
GeoSceneTiled.h
Marble::StackedTileLoader::tileProjection
GeoSceneTextureTile::Projection tileProjection() const
Definition: StackedTileLoader.cpp:81
Marble::StackedTileLoader::cleared
void cleared()
StackedTile.h
Marble::StackedTileLoader::tileCount
int tileCount() const
Return the number of tiles in the cache.
Definition: StackedTileLoader.cpp:178
Marble::StackedTileLoader::volatileCacheLimit
quint64 volatileCacheLimit() const
Returns the limit of the volatile (in RAM) cache.
Definition: StackedTileLoader.cpp:168
TileLoaderHelper.h
Marble::mDebug
QDebug mDebug()
a function to replace qDebug() in Marble library code
Definition: MarbleDebug.cpp:31
Marble::StackedTileLoader::resetTilehash
void resetTilehash()
Resets the internal tile hash.
Definition: StackedTileLoader.cpp:91
Marble::StackedTileLoader::loadTile
const StackedTile * loadTile(TileId const &stackedTileId)
Loads a tile and returns it.
Definition: StackedTileLoader.cpp:119
StackedTileLoader.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:38:53 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal