Permalink
Browse files

big speedup using try_lock and creating only 1 texture per frame

  • Loading branch information...
1 parent 1d72e75 commit 271ad4dd1f729a1eb17257e6126bd103893690be @RandomEtc committed Aug 2, 2011
Showing with 25 additions and 22 deletions.
  1. +0 −3 README
  2. +1 −1 include/TileLoader.h
  3. +14 −9 src/Map.cpp
  4. +10 −9 src/TileLoader.cpp
View
3 README
@@ -11,9 +11,6 @@ http://forum.libcinder.org/#topic/23286000000108063
Now supports multitouch, rotations and works on ipad (not battle tested yet).
-Next task: clarify the use of 'new' for providers and projections - perhaps
-std::auto_ptr is the clarification needed?
-
I'd also like to be able to create textures in the background thread, the
creation of another OpenGL context for this seems promising:
http://forum.libcinder.org/#Topic/23286000000650007
View
@@ -11,7 +11,7 @@
namespace cinder { namespace modestmaps {
// limit simultaneous calls to loadImage
-#define MAX_PENDING 8
+#define MAX_PENDING 2
class TileLoader;
typedef std::shared_ptr<TileLoader> TileLoaderRef;
View
@@ -10,7 +10,7 @@ void Map::setup( MapProviderRef _mapProvider, Vec2d _size )
size = _size;
centerCoordinate = Coordinate(0.5,0.5,0); // half the world width,height at zoom 0
// fit to screen
- double z = log(std::min(size.x,size.y) / 256.0) / log(2); // FIXME: use provider's getTileSize
+ double z = log2(std::min(size.x,size.y) / 256.0); // FIXME: use provider's getTileSize
centerCoordinate = centerCoordinate.zoomTo(z);
// start with north up:
rotation = 0.0;
@@ -207,7 +207,7 @@ void Map::scaleBy(const double &s, const double &cx, const double &cy) {
rotateBy(-prevRotation,cx,cy);
Vec2d center = size * 0.5;
panBy(-cx+center.x, -cy+center.y);
- centerCoordinate = centerCoordinate.zoomBy(log(s) / log(2.0));
+ centerCoordinate = centerCoordinate.zoomBy(log2(s));
panBy(cx-center.x, cy-center.y);
rotateBy(prevRotation,cx,cy);
}
@@ -265,7 +265,7 @@ void Map::setExtent( const MapExtent &extent, bool forceIntZoom )
const double hFactor = (BR.column - TL.column) / (size.x / tileSize.x);
// multiplication factor expressed as base-2 logarithm, for zoom difference
- const double hZoomDiff = log(hFactor) / log(2);
+ const double hZoomDiff = log2(hFactor);
// possible horizontal zoom to fit geographical extent in map width
const double hPossibleZoom = TL.zoom - (forceIntZoom ? ceil(hZoomDiff) : hZoomDiff);
@@ -274,7 +274,7 @@ void Map::setExtent( const MapExtent &extent, bool forceIntZoom )
const double vFactor = (BR.row - TL.row) / (size.y / tileSize.y);
// multiplication factor expressed as base-2 logarithm, for zoom difference
- const double vZoomDiff = log(vFactor) / log(2);
+ const double vZoomDiff = log2(vFactor);
// possible vertical zoom to fit geographical extent in map height
const double vPossibleZoom = TL.zoom - (forceIntZoom ? ceil(vZoomDiff) : vZoomDiff);
@@ -366,12 +366,17 @@ void Map::panTo(const Location &location) {
//////////////////////////////////////////////////////////////////////////
void Map::grabTile(const Coordinate &coord) {
- bool isPending = tileLoader->isPending(coord);
- bool isQueued = find(queue.begin(), queue.end(), coord) != queue.end();
bool isAlreadyLoaded = images.count(coord) > 0;
- if (!isPending && !isQueued && !isAlreadyLoaded) {
- queue.push_back(coord);
- }
+ if (!isAlreadyLoaded) {
+ bool isQueued = find(queue.begin(), queue.end(), coord) != queue.end();
+ if (!isQueued) {
+ // do this one last because it blocks TileLoader
+ bool isPending = tileLoader->isPending(coord);
+ if (!isPending) {
+ queue.push_back(coord);
+ }
+ }
+ }
}
void Map::processQueue() {
View
@@ -62,16 +62,17 @@ void TileLoader::processQueue(std::vector<Coordinate> &queue )
void TileLoader::transferTextures(std::map<Coordinate, gl::Texture> &images)
{
- // TODO: consider using try_lock here because we can just wait til next frame if it fails
- pendingCompleteMutex.lock();
- while (!completed.empty()) {
- std::map<Coordinate, Surface>::iterator iter = completed.begin();
- if (iter->second) {
- images[iter->first] = gl::Texture(iter->second);
+ // use try_lock because we can just wait until next frame if needed
+ if (pendingCompleteMutex.try_lock()) {
+ if (!completed.empty()) {
+ std::map<Coordinate, Surface>::iterator iter = completed.begin();
+ if (iter->second) {
+ images[iter->first] = gl::Texture(iter->second);
+ }
+ completed.erase(iter);
}
- completed.erase(iter);
- }
- pendingCompleteMutex.unlock();
+ pendingCompleteMutex.unlock();
+ }
}
bool TileLoader::isPending(const Coordinate &coord)

0 comments on commit 271ad4d

Please sign in to comment.